Mercurial > hg > isophonics-drupal-site
diff core/lib/Drupal/Core/Routing/AccessAwareRouter.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 129ea1e6d783 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/core/lib/Drupal/Core/Routing/AccessAwareRouter.php Wed Nov 29 16:09:58 2017 +0000 @@ -0,0 +1,146 @@ +<?php + +namespace Drupal\Core\Routing; + +use Drupal\Core\Access\AccessManagerInterface; +use Drupal\Core\Access\AccessResultReasonInterface; +use Drupal\Core\Session\AccountInterface; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; +use Symfony\Component\Routing\Matcher\RequestMatcherInterface; +use Symfony\Component\Routing\RequestContext as SymfonyRequestContext; +use Symfony\Component\Routing\RequestContextAwareInterface; +use Symfony\Component\Routing\RouterInterface; + +/** + * A router class for Drupal with access check and upcasting. + */ +class AccessAwareRouter implements AccessAwareRouterInterface { + + /** + * The router doing the actual routing. + * + * @var \Symfony\Component\Routing\Matcher\RequestMatcherInterface + */ + protected $router; + + /** + * The access manager. + * + * @var \Drupal\Core\Access\AccessManagerInterface + */ + protected $accessManager; + + /** + * The account to use in access checks. + * + * @var \Drupal\Core\Session\AccountInterface; + */ + protected $account; + + /** + * Constructs a router for Drupal with access check and upcasting. + * + * @param \Symfony\Component\Routing\Matcher\RequestMatcherInterface $router + * The router doing the actual routing. + * @param \Drupal\Core\Access\AccessManagerInterface $access_manager + * The access manager. + * @param \Drupal\Core\Session\AccountInterface $account + * The account to use in access checks. + */ + public function __construct(RequestMatcherInterface $router, AccessManagerInterface $access_manager, AccountInterface $account) { + $this->router = $router; + $this->accessManager = $access_manager; + $this->account = $account; + } + + /** + * {@inheritdoc} + */ + public function __call($name, $arguments) { + // Ensure to call every other function to the router. + return call_user_func_array([$this->router, $name], $arguments); + } + + /** + * {@inheritdoc} + */ + public function setContext(SymfonyRequestContext $context) { + if ($this->router instanceof RequestContextAwareInterface) { + $this->router->setContext($context); + } + } + + /** + * {@inheritdoc} + */ + public function getContext() { + if ($this->router instanceof RequestContextAwareInterface) { + return $this->router->getContext(); + } + } + + /** + * {@inheritdoc} + * + * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + * Thrown when access checking failed. + */ + public function matchRequest(Request $request) { + $parameters = $this->router->matchRequest($request); + $request->attributes->add($parameters); + $this->checkAccess($request); + // We can not return $parameters because the access check can change the + // request attributes. + return $request->attributes->all(); + } + + /** + * Apply access check service to the route and parameters in the request. + * + * @param \Symfony\Component\HttpFoundation\Request $request + * The request to access check. + */ + protected function checkAccess(Request $request) { + // The cacheability (if any) of this request's access check result must be + // applied to the response. + $access_result = $this->accessManager->checkRequest($request, $this->account, TRUE); + // Allow a master request to set the access result for a subrequest: if an + // access result attribute is already set, don't overwrite it. + if (!$request->attributes->has(AccessAwareRouterInterface::ACCESS_RESULT)) { + $request->attributes->set(AccessAwareRouterInterface::ACCESS_RESULT, $access_result); + } + if (!$access_result->isAllowed()) { + throw new AccessDeniedHttpException($access_result instanceof AccessResultReasonInterface ? $access_result->getReason() : NULL); + } + } + + /** + * {@inheritdoc} + */ + public function getRouteCollection() { + if ($this->router instanceof RouterInterface) { + return $this->router->getRouteCollection(); + } + } + + /** + * {@inheritdoc} + */ + public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH) { + if ($this->router instanceof UrlGeneratorInterface) { + return $this->router->generate($name, $parameters, $referenceType); + } + } + + /** + * {@inheritdoc} + * + * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException + * Thrown when access checking failed. + */ + public function match($pathinfo) { + return $this->matchRequest(Request::create($pathinfo)); + } + +}