Loading entity_clone.module +35 −3 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ */ use Drupal\Core\Access\AccessResult; use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Entity\ContentEntityTypeInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Routing\RouteMatchInterface; Loading Loading @@ -139,8 +140,39 @@ function entity_clone_entity_operation(EntityInterface $entity) { * Implements hook_entity_access(). */ function entity_clone_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { if ($operation === 'clone') { return AccessResult::allowedIfHasPermission($account, 'clone ' . $entity->getEntityTypeId() . ' entity'); } 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); } tests/src/Functional/EntityCloneEntityFormModeTest.php +2 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ class EntityCloneEntityFormModeTest extends BrowserTestBase { * * @var array */ public static $modules = ['entity_clone']; public static $modules = ['entity_clone', 'field_ui']; /** * Theme to enable by default Loading @@ -32,6 +32,7 @@ class EntityCloneEntityFormModeTest extends BrowserTestBase { */ protected $permissions = [ 'clone entity_form_mode entity', 'administer display modes', ]; /** Loading tests/src/Functional/EntityCloneEntityViewModeTest.php +2 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ class EntityCloneEntityViewModeTest extends BrowserTestBase { * * @var array */ public static $modules = ['entity_clone']; public static $modules = ['entity_clone', 'field_ui']; /** * Theme to enable by default Loading @@ -32,6 +32,7 @@ class EntityCloneEntityViewModeTest extends BrowserTestBase { */ protected $permissions = [ 'clone entity_view_mode entity', 'administer display modes', ]; /** Loading tests/src/Functional/EntityCloneParagraphTest.php +1 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ class EntityCloneParagraphTest extends NodeTestBase { */ protected $permissions = [ 'clone node entity', 'bypass node access', ]; /** Loading tests/src/Functional/EntityCloneShortcutSetTest.php +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ class EntityCloneShortcutSetTest extends BrowserTestBase { */ protected $permissions = [ 'clone shortcut_set entity', 'administer shortcuts', ]; /** Loading Loading
entity_clone.module +35 −3 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ */ use Drupal\Core\Access\AccessResult; use Drupal\Core\Cache\CacheableMetadata; use Drupal\Core\Entity\ContentEntityTypeInterface; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Routing\RouteMatchInterface; Loading Loading @@ -139,8 +140,39 @@ function entity_clone_entity_operation(EntityInterface $entity) { * Implements hook_entity_access(). */ function entity_clone_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { if ($operation === 'clone') { return AccessResult::allowedIfHasPermission($account, 'clone ' . $entity->getEntityTypeId() . ' entity'); } 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); }
tests/src/Functional/EntityCloneEntityFormModeTest.php +2 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ class EntityCloneEntityFormModeTest extends BrowserTestBase { * * @var array */ public static $modules = ['entity_clone']; public static $modules = ['entity_clone', 'field_ui']; /** * Theme to enable by default Loading @@ -32,6 +32,7 @@ class EntityCloneEntityFormModeTest extends BrowserTestBase { */ protected $permissions = [ 'clone entity_form_mode entity', 'administer display modes', ]; /** Loading
tests/src/Functional/EntityCloneEntityViewModeTest.php +2 −1 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ class EntityCloneEntityViewModeTest extends BrowserTestBase { * * @var array */ public static $modules = ['entity_clone']; public static $modules = ['entity_clone', 'field_ui']; /** * Theme to enable by default Loading @@ -32,6 +32,7 @@ class EntityCloneEntityViewModeTest extends BrowserTestBase { */ protected $permissions = [ 'clone entity_view_mode entity', 'administer display modes', ]; /** Loading
tests/src/Functional/EntityCloneParagraphTest.php +1 −0 Original line number Diff line number Diff line Loading @@ -38,6 +38,7 @@ class EntityCloneParagraphTest extends NodeTestBase { */ protected $permissions = [ 'clone node entity', 'bypass node access', ]; /** Loading
tests/src/Functional/EntityCloneShortcutSetTest.php +1 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ class EntityCloneShortcutSetTest extends BrowserTestBase { */ protected $permissions = [ 'clone shortcut_set entity', 'administer shortcuts', ]; /** Loading