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