Loading entity_clone.module +5 −1 Original line number Diff line number Diff line Loading @@ -148,7 +148,11 @@ function entity_clone_entity_access(EntityInterface $entity, $operation, Account $cache->addCacheContexts(['user.permissions']); // Deny access if the user cannot clone the entity. $access = AccessResult::forbiddenIf(!$account->hasPermission('clone ' . $entity->getEntityTypeId() . ' entity')); $access = AccessResult::forbiddenIf( !$account->hasPermission('clone ' . $entity->getEntityTypeId() . ' entity') && !$account->hasPermission('clone ' . $entity->bundle() . ' '. $entity->getEntityTypeId() . ' entities') ); if ($access->isForbidden()) { return $access->addCacheableDependency($cache); } Loading modules/entity_clone_extras/entity_clone_extras.info.yml 0 → 100644 +7 −0 Original line number Diff line number Diff line name: 'Entity Clone Extras' type: module description: 'Allow for bundle-level permissions for Node (and Media) entity types' core_version_requirement: ^8 || ^9 || ^10 package: 'Entity Clone' dependencies: - drupal:entity_clone modules/entity_clone_extras/entity_clone_extras.module 0 → 100644 +78 −0 Original line number Diff line number Diff line <?php /** * @file * Contains entity_clone_extras.module. */ use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; /** * Implements hook_help(). */ function entity_clone_extras_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { // Main module help for the entity_clone_extras module. case 'help.page.entity_clone_extras': $output = ''; $output .= '<h3>' . t('About') . '</h3>'; $output .= '<p>' . t('Allow for bundle-level permissions for Node (and Media) entity types') . '</p>'; return $output; default: } } /** * Implements hook_entity_operation_alter(). */ function entity_clone_extras_entity_operation_alter(array &$operations, EntityInterface $entity) { // Check if entity type supports cloning: if ($entity->hasLinkTemplate('clone-form')) { // If it does, get the current user. $user = \Drupal::currentUser(); $entity_types = _entity_clone_extra_supported_entity_types(); if (in_array($entity->getEntityTypeId(), $entity_types)) { if (!$user->hasPermission('clone ' . $entity->getEntityTypeId() . ' entity')) { // If we are dealing with a supported entity type, we handle permissions // per bundle. $bundle = $entity->bundle(); $entity_type = $entity->getEntityTypeId(); // Check the bundle access. if (!$user->hasPermission("clone $bundle $entity_type entities")) { // Remove the operation if the user has no access to it. unset($operations['clone']); } } } } } /** * Implements hook_entity_access(). */ function entity_clone_extras_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { $entity_types = _entity_clone_extra_supported_entity_types(); if ($operation === 'clone' && in_array($entity->getEntityTypeId(), $entity_types)) { return AccessResult::allowedIfHasPermission($account, 'clone ' . $entity->bundle() . ' ' . $entity->getEntityTypeId() . ' entities'); } return AccessResult::neutral(); } /** * Define the supported entity types. * * @return string[] * The entity types. */ function _entity_clone_extra_supported_entity_types() { $entity_types = ['node']; // Support media entities when media module is installed. if (\Drupal::moduleHandler()->moduleExists('media')) { $entity_types[] = 'media'; } return $entity_types; } modules/entity_clone_extras/entity_clone_extras.permissions.yml 0 → 100644 +2 −0 Original line number Diff line number Diff line permission_callbacks: - Drupal\entity_clone_extras\EntityCloneExtrasPermissions::permissions modules/entity_clone_extras/src/EntityCloneExtrasPermissions.php 0 → 100644 +102 −0 Original line number Diff line number Diff line <?php namespace Drupal\entity_clone_extras; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\StringTranslation\TranslationManager; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides dynamic permissions of the entity_clone module. */ class EntityCloneExtrasPermissions implements ContainerInjectionInterface { /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The string translation manager. * * @var \Drupal\Core\StringTranslation\TranslationManager */ protected $translationManager; /** * Module Handler. * * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected $moduleHandler; /** * Constructs a new EntityCloneExtrasPermissions instance. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager * The entity type manager. * @param \Drupal\Core\StringTranslation\TranslationManager $string_translation * The string translation manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * Module handler. */ public function __construct(EntityTypeManagerInterface $entity_manager, TranslationManager $string_translation, ModuleHandlerInterface $module_handler) { $this->entityTypeManager = $entity_manager; $this->translationManager = $string_translation; $this->moduleHandler = $module_handler; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('string_translation'), $container->get('module_handler') ); } /** * Returns an array of entity_clone_extras permissions. * * @return array * The permission list. */ public function permissions() { $permissions = []; // Fetch all available content types. $content_types = $this->entityTypeManager->getStorage('node_type') ->loadMultiple(); foreach ($content_types as $key => $type) { // Add a permission to clone each content type. $permissions['clone ' . $key . ' node entities'] = $this ->translationManager ->translate('Clone all <em>@label</em> node entities', [ '@label' => $type->label(), ]); } // Support media entities when media module is installed. if ($this->moduleHandler->moduleExists('media')) { // Fetch all available media types. $media_types = $this->entityTypeManager->getStorage('media_type') ->loadMultiple(); foreach ($media_types as $key => $type) { // Add a permission to clone each media type. $permissions['clone ' . $key . ' media entities'] = $this ->translationManager ->translate('Clone all <em>@label</em> media entities', [ '@label' => $type->label(), ]); } } return $permissions; } } Loading
entity_clone.module +5 −1 Original line number Diff line number Diff line Loading @@ -148,7 +148,11 @@ function entity_clone_entity_access(EntityInterface $entity, $operation, Account $cache->addCacheContexts(['user.permissions']); // Deny access if the user cannot clone the entity. $access = AccessResult::forbiddenIf(!$account->hasPermission('clone ' . $entity->getEntityTypeId() . ' entity')); $access = AccessResult::forbiddenIf( !$account->hasPermission('clone ' . $entity->getEntityTypeId() . ' entity') && !$account->hasPermission('clone ' . $entity->bundle() . ' '. $entity->getEntityTypeId() . ' entities') ); if ($access->isForbidden()) { return $access->addCacheableDependency($cache); } Loading
modules/entity_clone_extras/entity_clone_extras.info.yml 0 → 100644 +7 −0 Original line number Diff line number Diff line name: 'Entity Clone Extras' type: module description: 'Allow for bundle-level permissions for Node (and Media) entity types' core_version_requirement: ^8 || ^9 || ^10 package: 'Entity Clone' dependencies: - drupal:entity_clone
modules/entity_clone_extras/entity_clone_extras.module 0 → 100644 +78 −0 Original line number Diff line number Diff line <?php /** * @file * Contains entity_clone_extras.module. */ use Drupal\Core\Access\AccessResult; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; /** * Implements hook_help(). */ function entity_clone_extras_help($route_name, RouteMatchInterface $route_match) { switch ($route_name) { // Main module help for the entity_clone_extras module. case 'help.page.entity_clone_extras': $output = ''; $output .= '<h3>' . t('About') . '</h3>'; $output .= '<p>' . t('Allow for bundle-level permissions for Node (and Media) entity types') . '</p>'; return $output; default: } } /** * Implements hook_entity_operation_alter(). */ function entity_clone_extras_entity_operation_alter(array &$operations, EntityInterface $entity) { // Check if entity type supports cloning: if ($entity->hasLinkTemplate('clone-form')) { // If it does, get the current user. $user = \Drupal::currentUser(); $entity_types = _entity_clone_extra_supported_entity_types(); if (in_array($entity->getEntityTypeId(), $entity_types)) { if (!$user->hasPermission('clone ' . $entity->getEntityTypeId() . ' entity')) { // If we are dealing with a supported entity type, we handle permissions // per bundle. $bundle = $entity->bundle(); $entity_type = $entity->getEntityTypeId(); // Check the bundle access. if (!$user->hasPermission("clone $bundle $entity_type entities")) { // Remove the operation if the user has no access to it. unset($operations['clone']); } } } } } /** * Implements hook_entity_access(). */ function entity_clone_extras_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { $entity_types = _entity_clone_extra_supported_entity_types(); if ($operation === 'clone' && in_array($entity->getEntityTypeId(), $entity_types)) { return AccessResult::allowedIfHasPermission($account, 'clone ' . $entity->bundle() . ' ' . $entity->getEntityTypeId() . ' entities'); } return AccessResult::neutral(); } /** * Define the supported entity types. * * @return string[] * The entity types. */ function _entity_clone_extra_supported_entity_types() { $entity_types = ['node']; // Support media entities when media module is installed. if (\Drupal::moduleHandler()->moduleExists('media')) { $entity_types[] = 'media'; } return $entity_types; }
modules/entity_clone_extras/entity_clone_extras.permissions.yml 0 → 100644 +2 −0 Original line number Diff line number Diff line permission_callbacks: - Drupal\entity_clone_extras\EntityCloneExtrasPermissions::permissions
modules/entity_clone_extras/src/EntityCloneExtrasPermissions.php 0 → 100644 +102 −0 Original line number Diff line number Diff line <?php namespace Drupal\entity_clone_extras; use Drupal\Core\DependencyInjection\ContainerInjectionInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\StringTranslation\TranslationManager; use Symfony\Component\DependencyInjection\ContainerInterface; /** * Provides dynamic permissions of the entity_clone module. */ class EntityCloneExtrasPermissions implements ContainerInjectionInterface { /** * The entity type manager. * * @var \Drupal\Core\Entity\EntityTypeManagerInterface */ protected $entityTypeManager; /** * The string translation manager. * * @var \Drupal\Core\StringTranslation\TranslationManager */ protected $translationManager; /** * Module Handler. * * @var \Drupal\Core\Extension\ModuleHandlerInterface */ protected $moduleHandler; /** * Constructs a new EntityCloneExtrasPermissions instance. * * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_manager * The entity type manager. * @param \Drupal\Core\StringTranslation\TranslationManager $string_translation * The string translation manager. * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler * Module handler. */ public function __construct(EntityTypeManagerInterface $entity_manager, TranslationManager $string_translation, ModuleHandlerInterface $module_handler) { $this->entityTypeManager = $entity_manager; $this->translationManager = $string_translation; $this->moduleHandler = $module_handler; } /** * {@inheritdoc} */ public static function create(ContainerInterface $container) { return new static( $container->get('entity_type.manager'), $container->get('string_translation'), $container->get('module_handler') ); } /** * Returns an array of entity_clone_extras permissions. * * @return array * The permission list. */ public function permissions() { $permissions = []; // Fetch all available content types. $content_types = $this->entityTypeManager->getStorage('node_type') ->loadMultiple(); foreach ($content_types as $key => $type) { // Add a permission to clone each content type. $permissions['clone ' . $key . ' node entities'] = $this ->translationManager ->translate('Clone all <em>@label</em> node entities', [ '@label' => $type->label(), ]); } // Support media entities when media module is installed. if ($this->moduleHandler->moduleExists('media')) { // Fetch all available media types. $media_types = $this->entityTypeManager->getStorage('media_type') ->loadMultiple(); foreach ($media_types as $key => $type) { // Add a permission to clone each media type. $permissions['clone ' . $key . ' media entities'] = $this ->translationManager ->translate('Clone all <em>@label</em> media entities', [ '@label' => $type->label(), ]); } } return $permissions; } }