- last update
over 1 year ago 30 pass - Status changed to RTBC
4 months ago 10:25am 23 July 2024 - 🇬🇧United Kingdom villette
The path in #4 works well for us with version 2.1.0-beta1
Moving this issue to RTBC
The entity_clone_entity_access() implementation has been updated in beta7 version.
/**
* Implements hook_entity_access().
*/
function entity_clone_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation !== 'clone') {
return AccessResult::neutral();
}
$cache = new CacheableMetadata();
$cache->addCacheContexts(['user.permissions']);
// Deny access if the user cannot clone the entity.
$access = AccessResult::forbiddenIf(!$account->hasPermission('clone ' . $entity->getEntityTypeId() . ' entity'));
if ($access->isForbidden()) {
return $access->addCacheableDependency($cache);
}
// Deny access if the user can clone but cannot create new entities of this
// type. However, we have some exceptions in which the access control handler
// doesn't have a say in things. In these cases, we go based on the clone
// permission only.
$exceptions = [
'file',
'paragraph',
];
if (in_array($entity->getEntityTypeId(), $exceptions)) {
return AccessResult::allowed()->addCacheableDependency($cache);
}
$handler = \Drupal::entityTypeManager()->getAccessControlHandler($entity->getEntityTypeId());
$access = $handler->createAccess($entity->bundle(), $account, [], TRUE);
if (!$access->isAllowed()) {
$cache->addCacheableDependency($access);
$forbidden = AccessResult::forbidden();
return $forbidden->addCacheableDependency($cache);
}
return AccessResult::allowed()->addCacheableDependency($cache);
}
This implementation prevent others (custom or contrib) modules to alter the access to the clone operation because this implementation return explicity an AccessResult::forbidden(), so even if any other module give access to the operation then the access is still denied because there is at least one access forbidden. See processAccessHookResults() in https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Entity%21...
Inverse the logic. Return an access result allowed if condition are met (permissions, etc), and at the end return an access neutral, to give possibilities to other modules to give an access
This could be this implementation
/**
* Implements hook_entity_access().
*/
function entity_clone_entity_access(EntityInterface $entity, $operation, AccountInterface $account) {
if ($operation !== 'clone') {
return AccessResult::neutral();
}
$cache = new CacheableMetadata();
$cache->addCacheContexts(['user.permissions']);
// Allow access only if the user can clone and can create new entities of this
// type. However, we have some exceptions in which the access control handler
// doesn't have a say in things. In these cases, we go based on the clone
// permission only.
$exceptions = [
'file',
'paragraph',
];
if (in_array($entity->getEntityTypeId(), $exceptions)) {
return AccessResult::allowed()->addCacheableDependency($cache);
}
// Check access if the user can clone the entity.
$clone_access = AccessResult::allowedIf($account->hasPermission('clone ' . $entity->getEntityTypeId() . ' entity'));
$handler = \Drupal::entityTypeManager()->getAccessControlHandler($entity->getEntityTypeId());
$create_access = $handler->createAccess($entity->bundle(), $account, [], TRUE);
$cache->addCacheableDependency($clone_access)->addCacheableDependency($create_access);
if ($clone_access->isAllowed() && $create_access->isAllowed()) {
$allowed = AccessResult::allowed();
return $allowed->addCacheableDependency($cache);
}
return AccessResult::neutral()->addCacheableDependency($cache);
}
2.0
Code
Not all content is available!
It's likely this issue predates Contrib.social: some issue and comment data are missing.
The path in #4 works well for us with version 2.1.0-beta1
Moving this issue to RTBC