entity_agree-2.0.x-dev/src/Access/AgreementRestrictPages.php
src/Access/AgreementRestrictPages.php
<?php namespace Drupal\entity_agree\Access; use Drupal\Core\Access\AccessCheckInterface; use Drupal\Core\Access\AccessResult; use Drupal\Core\Access\AccessResultForbidden; use Drupal\Core\Access\AccessResultInterface; use Drupal\Core\Cache\RefinableCacheableDependencyInterface; use Drupal\Core\Routing\RouteMatchInterface; use Drupal\Core\Session\AccountInterface; use Drupal\entity_agree\AgreementHandlerRestrictPagesInterface; use Drupal\entity_agree\AgreementManager; use Drupal\entity_agree\Plugin\Field\FieldType\AgreementItem; use Symfony\Component\Routing\Route; /** * Access control to restrict access when an agreement is not agreed-to. */ class AgreementRestrictPages implements AccessCheckInterface { /** * The current user. * * @var \Drupal\Core\Session\AccountInterface */ protected $currentUser; /** * Agreement manager. * * @var \Drupal\entity_agree\AgreementManager */ protected $agreementManager; /** * Constructs an AgreementRestrictPages. * * @param \Drupal\Core\Session\AccountInterface $currentUser * The current user. * @param \Drupal\entity_agree\AgreementManager $agreementManager * Agreement manager. */ public function __construct(AccountInterface $currentUser, AgreementManager $agreementManager) { $this->currentUser = $currentUser; $this->agreementManager = $agreementManager; } /** * Determine access. * * @param \Drupal\Core\Routing\RouteMatchInterface $route_match * The route match for the route being checked. * * @return \Drupal\Core\Access\AccessResultInterface * The access result. */ public function access(RouteMatchInterface $route_match) { $outstanding = $this->agreementManager->getOutstandingAgreementEntities($this->currentUser); // If no outstanding agreements allow access. if (!$outstanding) { return $this->setCacheMeta(AccessResult::allowed()); } // See if any of the plugins restrict access. $restrict = FALSE; foreach ($outstanding as $agreements) { foreach ($agreements as $agreement) { foreach (AgreementItem::getEntityAgreementPlugins($agreement) as $plugins) { foreach ($plugins as $plugin) { if (!$plugin instanceof AgreementHandlerRestrictPagesInterface) { continue; } // Handler allows access. if ($plugin->allow($route_match)) { return $this->setCacheMeta(AccessResult::allowed()); } // We've got a handler restricting pages but has not allowed access. $restrict = TRUE; } } } } $result = $restrict ? AccessResultForbidden::forbidden('Entity agreement required.') : AccessResult::allowed(); return $this->setCacheMeta($result); } /** * {@inheritdoc} */ public function applies(Route $route) { return TRUE; } /** * Set cache metadata onto access result. */ protected function setCacheMeta(AccessResultInterface $result) { if (!$result instanceof RefinableCacheableDependencyInterface) { return $result; } return $result->addCacheContexts(['user']) ->addCacheTags([ 'entity_agree', "entity_agree:user:{$this->currentUser->id()}", ]); } }