Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/routing/Matcher/UrlMatcher.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 7a779792577d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 /* | |
4 * This file is part of the Symfony package. | |
5 * | |
6 * (c) Fabien Potencier <fabien@symfony.com> | |
7 * | |
8 * For the full copyright and license information, please view the LICENSE | |
9 * file that was distributed with this source code. | |
10 */ | |
11 | |
12 namespace Symfony\Component\Routing\Matcher; | |
13 | |
14 use Symfony\Component\Routing\Exception\MethodNotAllowedException; | |
15 use Symfony\Component\Routing\Exception\ResourceNotFoundException; | |
16 use Symfony\Component\Routing\RouteCollection; | |
17 use Symfony\Component\Routing\RequestContext; | |
18 use Symfony\Component\Routing\Route; | |
19 use Symfony\Component\HttpFoundation\Request; | |
20 use Symfony\Component\ExpressionLanguage\ExpressionLanguage; | |
21 use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; | |
22 | |
23 /** | |
24 * UrlMatcher matches URL based on a set of routes. | |
25 * | |
26 * @author Fabien Potencier <fabien@symfony.com> | |
27 */ | |
28 class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface | |
29 { | |
30 const REQUIREMENT_MATCH = 0; | |
31 const REQUIREMENT_MISMATCH = 1; | |
32 const ROUTE_MATCH = 2; | |
33 | |
34 /** | |
35 * @var RequestContext | |
36 */ | |
37 protected $context; | |
38 | |
39 /** | |
40 * @var array | |
41 */ | |
42 protected $allow = array(); | |
43 | |
44 /** | |
45 * @var RouteCollection | |
46 */ | |
47 protected $routes; | |
48 | |
49 protected $request; | |
50 protected $expressionLanguage; | |
51 | |
52 /** | |
53 * @var ExpressionFunctionProviderInterface[] | |
54 */ | |
55 protected $expressionLanguageProviders = array(); | |
56 | |
57 /** | |
58 * Constructor. | |
59 * | |
60 * @param RouteCollection $routes A RouteCollection instance | |
61 * @param RequestContext $context The context | |
62 */ | |
63 public function __construct(RouteCollection $routes, RequestContext $context) | |
64 { | |
65 $this->routes = $routes; | |
66 $this->context = $context; | |
67 } | |
68 | |
69 /** | |
70 * {@inheritdoc} | |
71 */ | |
72 public function setContext(RequestContext $context) | |
73 { | |
74 $this->context = $context; | |
75 } | |
76 | |
77 /** | |
78 * {@inheritdoc} | |
79 */ | |
80 public function getContext() | |
81 { | |
82 return $this->context; | |
83 } | |
84 | |
85 /** | |
86 * {@inheritdoc} | |
87 */ | |
88 public function match($pathinfo) | |
89 { | |
90 $this->allow = array(); | |
91 | |
92 if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) { | |
93 return $ret; | |
94 } | |
95 | |
96 throw 0 < count($this->allow) | |
97 ? new MethodNotAllowedException(array_unique($this->allow)) | |
98 : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo)); | |
99 } | |
100 | |
101 /** | |
102 * {@inheritdoc} | |
103 */ | |
104 public function matchRequest(Request $request) | |
105 { | |
106 $this->request = $request; | |
107 | |
108 $ret = $this->match($request->getPathInfo()); | |
109 | |
110 $this->request = null; | |
111 | |
112 return $ret; | |
113 } | |
114 | |
115 public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) | |
116 { | |
117 $this->expressionLanguageProviders[] = $provider; | |
118 } | |
119 | |
120 /** | |
121 * Tries to match a URL with a set of routes. | |
122 * | |
123 * @param string $pathinfo The path info to be parsed | |
124 * @param RouteCollection $routes The set of routes | |
125 * | |
126 * @return array An array of parameters | |
127 * | |
128 * @throws ResourceNotFoundException If the resource could not be found | |
129 * @throws MethodNotAllowedException If the resource was found but the request method is not allowed | |
130 */ | |
131 protected function matchCollection($pathinfo, RouteCollection $routes) | |
132 { | |
133 foreach ($routes as $name => $route) { | |
134 $compiledRoute = $route->compile(); | |
135 | |
136 // check the static prefix of the URL first. Only use the more expensive preg_match when it matches | |
137 if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { | |
138 continue; | |
139 } | |
140 | |
141 if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { | |
142 continue; | |
143 } | |
144 | |
145 $hostMatches = array(); | |
146 if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { | |
147 continue; | |
148 } | |
149 | |
150 // check HTTP method requirement | |
151 if ($requiredMethods = $route->getMethods()) { | |
152 // HEAD and GET are equivalent as per RFC | |
153 if ('HEAD' === $method = $this->context->getMethod()) { | |
154 $method = 'GET'; | |
155 } | |
156 | |
157 if (!in_array($method, $requiredMethods)) { | |
158 $this->allow = array_merge($this->allow, $requiredMethods); | |
159 | |
160 continue; | |
161 } | |
162 } | |
163 | |
164 $status = $this->handleRouteRequirements($pathinfo, $name, $route); | |
165 | |
166 if (self::ROUTE_MATCH === $status[0]) { | |
167 return $status[1]; | |
168 } | |
169 | |
170 if (self::REQUIREMENT_MISMATCH === $status[0]) { | |
171 continue; | |
172 } | |
173 | |
174 return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); | |
175 } | |
176 } | |
177 | |
178 /** | |
179 * Returns an array of values to use as request attributes. | |
180 * | |
181 * As this method requires the Route object, it is not available | |
182 * in matchers that do not have access to the matched Route instance | |
183 * (like the PHP and Apache matcher dumpers). | |
184 * | |
185 * @param Route $route The route we are matching against | |
186 * @param string $name The name of the route | |
187 * @param array $attributes An array of attributes from the matcher | |
188 * | |
189 * @return array An array of parameters | |
190 */ | |
191 protected function getAttributes(Route $route, $name, array $attributes) | |
192 { | |
193 $attributes['_route'] = $name; | |
194 | |
195 return $this->mergeDefaults($attributes, $route->getDefaults()); | |
196 } | |
197 | |
198 /** | |
199 * Handles specific route requirements. | |
200 * | |
201 * @param string $pathinfo The path | |
202 * @param string $name The route name | |
203 * @param Route $route The route | |
204 * | |
205 * @return array The first element represents the status, the second contains additional information | |
206 */ | |
207 protected function handleRouteRequirements($pathinfo, $name, Route $route) | |
208 { | |
209 // expression condition | |
210 if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request))) { | |
211 return array(self::REQUIREMENT_MISMATCH, null); | |
212 } | |
213 | |
214 // check HTTP scheme requirement | |
215 $scheme = $this->context->getScheme(); | |
216 $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; | |
217 | |
218 return array($status, null); | |
219 } | |
220 | |
221 /** | |
222 * Get merged default parameters. | |
223 * | |
224 * @param array $params The parameters | |
225 * @param array $defaults The defaults | |
226 * | |
227 * @return array Merged default parameters | |
228 */ | |
229 protected function mergeDefaults($params, $defaults) | |
230 { | |
231 foreach ($params as $key => $value) { | |
232 if (!is_int($key)) { | |
233 $defaults[$key] = $value; | |
234 } | |
235 } | |
236 | |
237 return $defaults; | |
238 } | |
239 | |
240 protected function getExpressionLanguage() | |
241 { | |
242 if (null === $this->expressionLanguage) { | |
243 if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { | |
244 throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); | |
245 } | |
246 $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders); | |
247 } | |
248 | |
249 return $this->expressionLanguage; | |
250 } | |
251 } |