diff --git a/rng.module b/rng.module index 7b31d2d..415e9b1 100644 --- a/rng.module +++ b/rng.module @@ -33,48 +33,9 @@ function rng_help($route_name, RouteMatchInterface $route_match) { * Implements hook_entity_access(). */ function rng_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { - if ($operation == 'manage event') { - /** @var EventTypeInterface $event_type */ - $event_type = \Drupal::service('rng.event_manager') - ->eventType($entity->getEntityTypeId(), $entity->bundle()); - if ($event_type && $event_type->getEventManageOperation()) { - // Prevents recursion: - if ($event_type->getEventManageOperation() != 'manage event') { - if ($entity->access($event_type->getEventManageOperation(), $account)) { - return AccessResult::allowed() - ->addCacheableDependency($entity); - } - } - } - } - - if ($operation == 'update') { - if ($entity instanceof ChannelInterface) { - if ($template_collection = TemplateCollection::getTemplateCollectionForTemplate($entity)) { - // Allow editing template if the user has 'manage event' for the event. - if ($owner = $template_collection->getOwner()) { - $event_manager = \Drupal::service('rng.event_manager'); - /** @var \Drupal\rng\EventManagerInterface $event_manager */ - if ($event_manager->isEvent($owner)) { - return AccessResult::allowedIf($owner->access('manage event')) - ->addCacheableDependency($owner); - } - } - } - } - } - - if ($operation == 'templates' && $entity instanceof TemplateCollectionInterface) { - $owner = $entity->getOwner(); - /** @var \Drupal\rng\EventManagerInterface $event_manager */ - $event_manager = \Drupal::service('rng.event_manager'); - if ($owner && $event_manager->isEvent($owner) && $owner->access('manage event')) { - return AccessResult::allowed() - ->addCacheableDependency($owner); - } - } - - return AccessResult::neutral(); + /** @var \Drupal\rng\RngEntityAccess $rng_model */ + $rng_model = \Drupal::service('rng.entity.access'); + return $rng_model->hook_entity_access($entity, $operation, $account); } /** diff --git a/rng.services.yml b/rng.services.yml index 18953f3..598273d 100644 --- a/rng.services.yml +++ b/rng.services.yml @@ -6,6 +6,9 @@ services: class: Drupal\rng\EventManager arguments: ['@entity.manager'] parent: container.trait + rng.entity.access: + class: Drupal\rng\RngEntityAccess + arguments: ['@rng.event_manager'] rng.entity.model: class: Drupal\rng\RngModel arguments: ['@rng.event_manager', '@plugin.manager.identity_channel'] diff --git a/src/RngEntityAccess.php b/src/RngEntityAccess.php new file mode 100644 index 0000000..131c27a --- /dev/null +++ b/src/RngEntityAccess.php @@ -0,0 +1,139 @@ +eventManager = $event_manager; + } + + /** + * Control entity operation access. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity to check access to. + * @param string $operation + * The operation that is to be performed on $entity. + * @param \Drupal\Core\Session\AccountInterface $account + * The account trying to access the entity. + * + * @return \Drupal\Core\Access\AccessResultInterface + * The access result. + * + * @see hook_entity_access(); + */ + public function hook_entity_access(EntityInterface $entity, $operation, AccountInterface $account) { + if (('manage event' == $operation) && $this->eventManager->isEvent($entity)) { + return $this->manageEventAccess($entity, $account); + } + + if (('update' == $operation) && $entity instanceof ChannelInterface) { + return $this->updateCourierMessageAccess($entity, $account); + } + + if (('templates' == $operation) && $entity instanceof TemplateCollectionInterface) { + return $this->templateCollectionTemplateAccess($entity, $account); + } + + return AccessResult::neutral(); + } + + /** + * Whether the account is permitted to manage event. + * + * This method is a proxy for a different permission name. + * + * @param \Drupal\Core\Entity\EntityInterface $entity + * The entity to check access to. + * @param \Drupal\Core\Session\AccountInterface $account + * The account trying to access the entity. + * + * @return \Drupal\Core\Access\AccessResultInterface + * The access result. + */ + protected function manageEventAccess($entity, AccountInterface $account) { + $event_type = $this->eventManager + ->eventType($entity->getEntityTypeId(), $entity->bundle()); + $manage_operation = $event_type->getEventManageOperation(); + + // Prevents recursion: + if (!empty($manage_operation) && ('manage event' != $manage_operation)) { + if ($entity->access($manage_operation, $account)) { + return AccessResult::allowed() + ->addCacheableDependency($entity); + } + } + + return AccessResult::neutral(); + } + + /** + * Allow editing template if the user has 'manage event' for the event. + * + * @param \Drupal\courier\ChannelInterface $entity + * A Courier template entity. + * @param \Drupal\Core\Session\AccountInterface $account + * The account trying to access the entity. + * + * @return \Drupal\Core\Access\AccessResultInterface + * The access result. + */ + protected function updateCourierMessageAccess(ChannelInterface $entity, AccountInterface $account) { + $template_collection = TemplateCollection::getTemplateCollectionForTemplate($entity); + if ($template_collection) { + $owner = $template_collection->getOwner(); + if ($owner && $this->eventManager->isEvent($owner)) { + return AccessResult::allowedIf($owner->access('manage event', $account)) + ->addCacheableDependency($owner); + } + } + + return AccessResult::neutral(); + } + + /** + * Determine whether the account can edit templates for a template collection. + * + * @param \Drupal\courier\TemplateCollectionInterface $entity + * A Courier template collection entity. + * @param \Drupal\Core\Session\AccountInterface $account + * The account trying to access the entity. + * + * @return \Drupal\Core\Access\AccessResultInterface + * The access result. + */ + protected function templateCollectionTemplateAccess(TemplateCollectionInterface $entity, AccountInterface $account) { + $owner = $entity->getOwner(); + if ($owner && $this->eventManager->isEvent($owner)) { + return AccessResult::allowedIf($owner->access('manage event', $account)) + ->addCacheableDependency($owner); + } + + return AccessResult::neutral(); + } + +}