annotate core/lib/Drupal/Core/Routing/AccessAwareRouter.php @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 129ea1e6d783
children
rev   line source
Chris@0 1 <?php
Chris@0 2
Chris@0 3 namespace Drupal\Core\Routing;
Chris@0 4
Chris@0 5 use Drupal\Core\Access\AccessManagerInterface;
Chris@0 6 use Drupal\Core\Access\AccessResultReasonInterface;
Chris@17 7 use Drupal\Core\Cache\CacheableDependencyInterface;
Chris@17 8 use Drupal\Core\Http\Exception\CacheableAccessDeniedHttpException;
Chris@0 9 use Drupal\Core\Session\AccountInterface;
Chris@0 10 use Symfony\Component\HttpFoundation\Request;
Chris@0 11 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
Chris@0 12 use Symfony\Component\Routing\Matcher\RequestMatcherInterface;
Chris@0 13 use Symfony\Component\Routing\RequestContext as SymfonyRequestContext;
Chris@0 14 use Symfony\Component\Routing\RequestContextAwareInterface;
Chris@0 15 use Symfony\Component\Routing\RouterInterface;
Chris@0 16
Chris@0 17 /**
Chris@0 18 * A router class for Drupal with access check and upcasting.
Chris@0 19 */
Chris@0 20 class AccessAwareRouter implements AccessAwareRouterInterface {
Chris@0 21
Chris@0 22 /**
Chris@0 23 * The router doing the actual routing.
Chris@0 24 *
Chris@0 25 * @var \Symfony\Component\Routing\Matcher\RequestMatcherInterface
Chris@0 26 */
Chris@0 27 protected $router;
Chris@0 28
Chris@0 29 /**
Chris@0 30 * The access manager.
Chris@0 31 *
Chris@0 32 * @var \Drupal\Core\Access\AccessManagerInterface
Chris@0 33 */
Chris@0 34 protected $accessManager;
Chris@0 35
Chris@0 36 /**
Chris@0 37 * The account to use in access checks.
Chris@0 38 *
Chris@17 39 * @var \Drupal\Core\Session\AccountInterface
Chris@0 40 */
Chris@0 41 protected $account;
Chris@0 42
Chris@0 43 /**
Chris@0 44 * Constructs a router for Drupal with access check and upcasting.
Chris@0 45 *
Chris@0 46 * @param \Symfony\Component\Routing\Matcher\RequestMatcherInterface $router
Chris@0 47 * The router doing the actual routing.
Chris@0 48 * @param \Drupal\Core\Access\AccessManagerInterface $access_manager
Chris@0 49 * The access manager.
Chris@0 50 * @param \Drupal\Core\Session\AccountInterface $account
Chris@0 51 * The account to use in access checks.
Chris@0 52 */
Chris@0 53 public function __construct(RequestMatcherInterface $router, AccessManagerInterface $access_manager, AccountInterface $account) {
Chris@0 54 $this->router = $router;
Chris@0 55 $this->accessManager = $access_manager;
Chris@0 56 $this->account = $account;
Chris@0 57 }
Chris@0 58
Chris@0 59 /**
Chris@0 60 * {@inheritdoc}
Chris@0 61 */
Chris@0 62 public function __call($name, $arguments) {
Chris@0 63 // Ensure to call every other function to the router.
Chris@0 64 return call_user_func_array([$this->router, $name], $arguments);
Chris@0 65 }
Chris@0 66
Chris@0 67 /**
Chris@0 68 * {@inheritdoc}
Chris@0 69 */
Chris@0 70 public function setContext(SymfonyRequestContext $context) {
Chris@0 71 if ($this->router instanceof RequestContextAwareInterface) {
Chris@0 72 $this->router->setContext($context);
Chris@0 73 }
Chris@0 74 }
Chris@0 75
Chris@0 76 /**
Chris@0 77 * {@inheritdoc}
Chris@0 78 */
Chris@0 79 public function getContext() {
Chris@0 80 if ($this->router instanceof RequestContextAwareInterface) {
Chris@0 81 return $this->router->getContext();
Chris@0 82 }
Chris@0 83 }
Chris@0 84
Chris@0 85 /**
Chris@0 86 * {@inheritdoc}
Chris@0 87 *
Chris@0 88 * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
Chris@0 89 * Thrown when access checking failed.
Chris@0 90 */
Chris@0 91 public function matchRequest(Request $request) {
Chris@0 92 $parameters = $this->router->matchRequest($request);
Chris@0 93 $request->attributes->add($parameters);
Chris@0 94 $this->checkAccess($request);
Chris@0 95 // We can not return $parameters because the access check can change the
Chris@0 96 // request attributes.
Chris@0 97 return $request->attributes->all();
Chris@0 98 }
Chris@0 99
Chris@0 100 /**
Chris@0 101 * Apply access check service to the route and parameters in the request.
Chris@0 102 *
Chris@0 103 * @param \Symfony\Component\HttpFoundation\Request $request
Chris@0 104 * The request to access check.
Chris@0 105 */
Chris@0 106 protected function checkAccess(Request $request) {
Chris@0 107 // The cacheability (if any) of this request's access check result must be
Chris@0 108 // applied to the response.
Chris@0 109 $access_result = $this->accessManager->checkRequest($request, $this->account, TRUE);
Chris@0 110 // Allow a master request to set the access result for a subrequest: if an
Chris@0 111 // access result attribute is already set, don't overwrite it.
Chris@0 112 if (!$request->attributes->has(AccessAwareRouterInterface::ACCESS_RESULT)) {
Chris@0 113 $request->attributes->set(AccessAwareRouterInterface::ACCESS_RESULT, $access_result);
Chris@0 114 }
Chris@0 115 if (!$access_result->isAllowed()) {
Chris@17 116 if ($access_result instanceof CacheableDependencyInterface && $request->isMethodCacheable()) {
Chris@17 117 throw new CacheableAccessDeniedHttpException($access_result, $access_result instanceof AccessResultReasonInterface ? $access_result->getReason() : NULL);
Chris@17 118 }
Chris@17 119 else {
Chris@17 120 throw new AccessDeniedHttpException($access_result instanceof AccessResultReasonInterface ? $access_result->getReason() : NULL);
Chris@17 121 }
Chris@0 122 }
Chris@0 123 }
Chris@0 124
Chris@0 125 /**
Chris@0 126 * {@inheritdoc}
Chris@0 127 */
Chris@0 128 public function getRouteCollection() {
Chris@0 129 if ($this->router instanceof RouterInterface) {
Chris@0 130 return $this->router->getRouteCollection();
Chris@0 131 }
Chris@0 132 }
Chris@0 133
Chris@0 134 /**
Chris@0 135 * {@inheritdoc}
Chris@0 136 */
Chris@0 137 public function generate($name, $parameters = [], $referenceType = self::ABSOLUTE_PATH) {
Chris@0 138 if ($this->router instanceof UrlGeneratorInterface) {
Chris@0 139 return $this->router->generate($name, $parameters, $referenceType);
Chris@0 140 }
Chris@0 141 }
Chris@0 142
Chris@0 143 /**
Chris@0 144 * {@inheritdoc}
Chris@0 145 *
Chris@0 146 * @throws \Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException
Chris@0 147 * Thrown when access checking failed.
Chris@0 148 */
Chris@0 149 public function match($pathinfo) {
Chris@0 150 return $this->matchRequest(Request::create($pathinfo));
Chris@0 151 }
Chris@0 152
Chris@0 153 }