Mercurial > hg > isophonics-drupal-site
comparison vendor/symfony/routing/Matcher/UrlMatcher.php @ 17:129ea1e6d783
Update, including to Drupal core 8.6.10
author | Chris Cannam |
---|---|
date | Thu, 28 Feb 2019 13:21:36 +0000 |
parents | 1fec387a4317 |
children |
comparison
equal
deleted
inserted
replaced
16:c2387f117808 | 17:129ea1e6d783 |
---|---|
9 * file that was distributed with this source code. | 9 * file that was distributed with this source code. |
10 */ | 10 */ |
11 | 11 |
12 namespace Symfony\Component\Routing\Matcher; | 12 namespace Symfony\Component\Routing\Matcher; |
13 | 13 |
14 use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; | |
15 use Symfony\Component\ExpressionLanguage\ExpressionLanguage; | |
16 use Symfony\Component\HttpFoundation\Request; | |
14 use Symfony\Component\Routing\Exception\MethodNotAllowedException; | 17 use Symfony\Component\Routing\Exception\MethodNotAllowedException; |
15 use Symfony\Component\Routing\Exception\NoConfigurationException; | 18 use Symfony\Component\Routing\Exception\NoConfigurationException; |
16 use Symfony\Component\Routing\Exception\ResourceNotFoundException; | 19 use Symfony\Component\Routing\Exception\ResourceNotFoundException; |
17 use Symfony\Component\Routing\RouteCollection; | |
18 use Symfony\Component\Routing\RequestContext; | 20 use Symfony\Component\Routing\RequestContext; |
19 use Symfony\Component\Routing\Route; | 21 use Symfony\Component\Routing\Route; |
20 use Symfony\Component\HttpFoundation\Request; | 22 use Symfony\Component\Routing\RouteCollection; |
21 use Symfony\Component\ExpressionLanguage\ExpressionLanguage; | |
22 use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface; | |
23 | 23 |
24 /** | 24 /** |
25 * UrlMatcher matches URL based on a set of routes. | 25 * UrlMatcher matches URL based on a set of routes. |
26 * | 26 * |
27 * @author Fabien Potencier <fabien@symfony.com> | 27 * @author Fabien Potencier <fabien@symfony.com> |
31 const REQUIREMENT_MATCH = 0; | 31 const REQUIREMENT_MATCH = 0; |
32 const REQUIREMENT_MISMATCH = 1; | 32 const REQUIREMENT_MISMATCH = 1; |
33 const ROUTE_MATCH = 2; | 33 const ROUTE_MATCH = 2; |
34 | 34 |
35 protected $context; | 35 protected $context; |
36 protected $allow = array(); | 36 protected $allow = []; |
37 protected $routes; | 37 protected $routes; |
38 protected $request; | 38 protected $request; |
39 protected $expressionLanguage; | 39 protected $expressionLanguage; |
40 | 40 |
41 /** | 41 /** |
42 * @var ExpressionFunctionProviderInterface[] | 42 * @var ExpressionFunctionProviderInterface[] |
43 */ | 43 */ |
44 protected $expressionLanguageProviders = array(); | 44 protected $expressionLanguageProviders = []; |
45 | 45 |
46 public function __construct(RouteCollection $routes, RequestContext $context) | 46 public function __construct(RouteCollection $routes, RequestContext $context) |
47 { | 47 { |
48 $this->routes = $routes; | 48 $this->routes = $routes; |
49 $this->context = $context; | 49 $this->context = $context; |
68 /** | 68 /** |
69 * {@inheritdoc} | 69 * {@inheritdoc} |
70 */ | 70 */ |
71 public function match($pathinfo) | 71 public function match($pathinfo) |
72 { | 72 { |
73 $this->allow = array(); | 73 $this->allow = []; |
74 | 74 |
75 if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) { | 75 if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) { |
76 return $ret; | 76 return $ret; |
77 } | 77 } |
78 | 78 |
79 if ('/' === $pathinfo && !$this->allow) { | 79 if ('/' === $pathinfo && !$this->allow) { |
80 throw new NoConfigurationException(); | 80 throw new NoConfigurationException(); |
81 } | 81 } |
82 | 82 |
83 throw 0 < count($this->allow) | 83 throw 0 < \count($this->allow) |
84 ? new MethodNotAllowedException(array_unique($this->allow)) | 84 ? new MethodNotAllowedException(array_unique($this->allow)) |
85 : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo)); | 85 : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo)); |
86 } | 86 } |
87 | 87 |
88 /** | 88 /** |
116 * @throws ResourceNotFoundException If the resource could not be found | 116 * @throws ResourceNotFoundException If the resource could not be found |
117 * @throws MethodNotAllowedException If the resource was found but the request method is not allowed | 117 * @throws MethodNotAllowedException If the resource was found but the request method is not allowed |
118 */ | 118 */ |
119 protected function matchCollection($pathinfo, RouteCollection $routes) | 119 protected function matchCollection($pathinfo, RouteCollection $routes) |
120 { | 120 { |
121 // HEAD and GET are equivalent as per RFC | |
122 if ('HEAD' === $method = $this->context->getMethod()) { | |
123 $method = 'GET'; | |
124 } | |
125 $supportsTrailingSlash = '/' !== $pathinfo && '' !== $pathinfo && $this instanceof RedirectableUrlMatcherInterface; | |
126 | |
121 foreach ($routes as $name => $route) { | 127 foreach ($routes as $name => $route) { |
122 $compiledRoute = $route->compile(); | 128 $compiledRoute = $route->compile(); |
129 $staticPrefix = $compiledRoute->getStaticPrefix(); | |
130 $requiredMethods = $route->getMethods(); | |
123 | 131 |
124 // check the static prefix of the URL first. Only use the more expensive preg_match when it matches | 132 // check the static prefix of the URL first. Only use the more expensive preg_match when it matches |
125 if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { | 133 if ('' === $staticPrefix || 0 === strpos($pathinfo, $staticPrefix)) { |
126 continue; | 134 // no-op |
127 } | 135 } elseif (!$supportsTrailingSlash || ($requiredMethods && !\in_array('GET', $requiredMethods)) || 'GET' !== $method) { |
128 | 136 continue; |
129 if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { | 137 } elseif ('/' === substr($staticPrefix, -1) && substr($staticPrefix, 0, -1) === $pathinfo) { |
130 continue; | 138 return $this->allow = []; |
131 } | 139 } else { |
132 | 140 continue; |
133 $hostMatches = array(); | 141 } |
142 $regex = $compiledRoute->getRegex(); | |
143 | |
144 if ($supportsTrailingSlash && $pos = strpos($regex, '/$')) { | |
145 $regex = substr($regex, 0, $pos).'/?$'.substr($regex, $pos + 2); | |
146 $hasTrailingSlash = true; | |
147 } else { | |
148 $hasTrailingSlash = false; | |
149 } | |
150 | |
151 if (!preg_match($regex, $pathinfo, $matches)) { | |
152 continue; | |
153 } | |
154 | |
155 if ($hasTrailingSlash && '/' !== substr($pathinfo, -1)) { | |
156 if ((!$requiredMethods || \in_array('GET', $requiredMethods)) && 'GET' === $method) { | |
157 return $this->allow = []; | |
158 } | |
159 continue; | |
160 } | |
161 | |
162 $hostMatches = []; | |
134 if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { | 163 if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { |
135 continue; | 164 continue; |
136 } | 165 } |
137 | 166 |
138 $status = $this->handleRouteRequirements($pathinfo, $name, $route); | 167 $status = $this->handleRouteRequirements($pathinfo, $name, $route); |
140 if (self::REQUIREMENT_MISMATCH === $status[0]) { | 169 if (self::REQUIREMENT_MISMATCH === $status[0]) { |
141 continue; | 170 continue; |
142 } | 171 } |
143 | 172 |
144 // check HTTP method requirement | 173 // check HTTP method requirement |
145 if ($requiredMethods = $route->getMethods()) { | 174 if ($requiredMethods) { |
146 // HEAD and GET are equivalent as per RFC | 175 if (!\in_array($method, $requiredMethods)) { |
147 if ('HEAD' === $method = $this->context->getMethod()) { | |
148 $method = 'GET'; | |
149 } | |
150 | |
151 if (!in_array($method, $requiredMethods)) { | |
152 if (self::REQUIREMENT_MATCH === $status[0]) { | 176 if (self::REQUIREMENT_MATCH === $status[0]) { |
153 $this->allow = array_merge($this->allow, $requiredMethods); | 177 $this->allow = array_merge($this->allow, $requiredMethods); |
154 } | 178 } |
155 | 179 |
156 continue; | 180 continue; |
157 } | 181 } |
158 } | 182 } |
159 | 183 |
160 return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : array())); | 184 return $this->getAttributes($route, $name, array_replace($matches, $hostMatches, isset($status[1]) ? $status[1] : [])); |
161 } | 185 } |
186 | |
187 return []; | |
162 } | 188 } |
163 | 189 |
164 /** | 190 /** |
165 * Returns an array of values to use as request attributes. | 191 * Returns an array of values to use as request attributes. |
166 * | 192 * |
191 * @return array The first element represents the status, the second contains additional information | 217 * @return array The first element represents the status, the second contains additional information |
192 */ | 218 */ |
193 protected function handleRouteRequirements($pathinfo, $name, Route $route) | 219 protected function handleRouteRequirements($pathinfo, $name, Route $route) |
194 { | 220 { |
195 // expression condition | 221 // expression condition |
196 if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) { | 222 if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), ['context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)])) { |
197 return array(self::REQUIREMENT_MISMATCH, null); | 223 return [self::REQUIREMENT_MISMATCH, null]; |
198 } | 224 } |
199 | 225 |
200 // check HTTP scheme requirement | 226 // check HTTP scheme requirement |
201 $scheme = $this->context->getScheme(); | 227 $scheme = $this->context->getScheme(); |
202 $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; | 228 $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; |
203 | 229 |
204 return array($status, null); | 230 return [$status, null]; |
205 } | 231 } |
206 | 232 |
207 /** | 233 /** |
208 * Get merged default parameters. | 234 * Get merged default parameters. |
209 * | 235 * |
213 * @return array Merged default parameters | 239 * @return array Merged default parameters |
214 */ | 240 */ |
215 protected function mergeDefaults($params, $defaults) | 241 protected function mergeDefaults($params, $defaults) |
216 { | 242 { |
217 foreach ($params as $key => $value) { | 243 foreach ($params as $key => $value) { |
218 if (!is_int($key)) { | 244 if (!\is_int($key)) { |
219 $defaults[$key] = $value; | 245 $defaults[$key] = $value; |
220 } | 246 } |
221 } | 247 } |
222 | 248 |
223 return $defaults; | 249 return $defaults; |
242 { | 268 { |
243 if (!class_exists('Symfony\Component\HttpFoundation\Request')) { | 269 if (!class_exists('Symfony\Component\HttpFoundation\Request')) { |
244 return null; | 270 return null; |
245 } | 271 } |
246 | 272 |
247 return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), array(), array(), array( | 273 return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), [], [], [ |
248 'SCRIPT_FILENAME' => $this->context->getBaseUrl(), | 274 'SCRIPT_FILENAME' => $this->context->getBaseUrl(), |
249 'SCRIPT_NAME' => $this->context->getBaseUrl(), | 275 'SCRIPT_NAME' => $this->context->getBaseUrl(), |
250 )); | 276 ]); |
251 } | 277 } |
252 } | 278 } |