alert_types-8.x-1.x-dev/src/AlertAccessControlHandler.php
src/AlertAccessControlHandler.php
<?php namespace Drupal\alert_types; use Drupal\Component\Plugin\Exception\ContextException; use Symfony\Component\DependencyInjection\ContainerInterface; use Drupal\Core\Cache\Cache; use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Condition\ConditionAccessResolverTrait; use Drupal\Core\Condition\ConditionManager; use Drupal\Core\Condition\ConditionPluginCollection; use Drupal\Core\Entity\EntityAccessControlHandler; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Entity\EntityHandlerInterface; use Drupal\Core\Plugin\Context\ContextHandler; use Drupal\Core\Plugin\Context\ContextRepositoryInterface; use Drupal\Core\Plugin\ContextAwarePluginInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\Access\AccessResult; /** * Access controller for the Alert entity. * * @see \Drupal\alert_types\Entity\Alert. */ class AlertAccessControlHandler extends EntityAccessControlHandler implements EntityHandlerInterface { use ConditionAccessResolverTrait; /** * The condition manager. * * @var \Drupal\Core\Condition\ConditionManager */ protected $conditionManager; /** * The context handler. * * @var \Drupal\Core\Plugin\Context\ContextHandler */ protected $contextHandler; /** * The context repository. * * @var \Drupal\Core\Plugin\Context\ContextRepositoryInterface */ protected $contextRepository; /** * {@inheritdoc} */ public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) { return new static( $entity_type, $container->get('plugin.manager.condition'), $container->get('context.handler'), $container->get('context.repository') ); } /** * AlertAccessControlHandler constructor. * * @param \Drupal\Core\Entity\EntityTypeInterface $entity_type * The entity type definition. * @param \Drupal\Core\Condition\ConditionManager $condition_manager * The condition plugin manager. * @param \Drupal\Core\Plugin\Context\ContextHandler $contxt_handler * The context handler. * @param \Drupal\Core\Plugin\Context\ContextRepositoryInterface $context_repository * The context repository. */ public function __construct(EntityTypeInterface $entity_type, ConditionManager $condition_manager, ContextHandler $context_handler, ContextRepositoryInterface $context_repository) { parent::__construct($entity_type); $this->conditionManager = $condition_manager; $this->contextHandler = $context_handler; $this->contextRepository = $context_repository; } /** * {@inheritdoc} */ protected function checkAccess(EntityInterface $entity, $operation, AccountInterface $account) { switch ($operation) { case 'view': if (!$entity->isActive()) { return AccessResult::allowedIfHasPermission($account, 'view inactive alert entities'); } else { $conditions = []; if ($entity->getConditions()) { $conditionCollection = new ConditionPluginCollection($this->conditionManager, $entity->getConditions()); foreach ($conditionCollection as $condition_id => $condition) { if ($condition instanceof ContextAwarePluginInterface) { try { $contexts = $this->contextRepository->getRuntimeContexts(array_values($condition->getContextMapping())); $this->contextHandler->applyContextMapping($condition, $contexts); } catch (ContextException $e) { } } $conditions[$condition_id] = $condition; } } // TODO: Add support for OR. $allowed = $this->resolveConditions($conditions, 'and'); $access = $allowed ? AccessResult::allowed() : AccessResult::forbidden(); $this->mergeCacheabilityFromConditions($access, $conditions); return $access->addCacheableDependency($entity); } case 'update': return AccessResult::allowedIfHasPermission($account, 'edit alert entities'); case 'delete': return AccessResult::allowedIfHasPermission($account, 'delete alert entities'); } return AccessResult::neutral(); } /** * Merges cacheable metadata from conditions onto the access result object. * * @param \Drupal\Core\Access\AccessResult $access * The access result object. * @param \Drupal\Core\Condition\ConditionInterface[] $conditions * List of conditions conditions. */ protected function mergeCacheabilityFromConditions(AccessResult $access, array $conditions) { foreach ($conditions as $condition) { if ($condition instanceof CacheableDependencyInterface) { $access->addCacheTags($condition->getCacheTags()); $access->addCacheContexts($condition->getCacheContexts()); $access->setCacheMaxAge(Cache::mergeMaxAges($access->getCacheMaxAge(), $condition->getCacheMaxAge())); } } } /** * {@inheritdoc} */ protected function checkCreateAccess(AccountInterface $account, array $context, $entity_bundle = NULL) { return AccessResult::allowedIfHasPermission($account, 'add alert entities'); } }