[ Index ] |
PHP Cross Reference of phpBB-3.2.11-deutsch |
[Summary view] [Print] [Text view]
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\ExpressionLanguage\ExpressionFunctionProviderInterface; 15 use Symfony\Component\ExpressionLanguage\ExpressionLanguage; 16 use Symfony\Component\HttpFoundation\Request; 17 use Symfony\Component\Routing\Exception\MethodNotAllowedException; 18 use Symfony\Component\Routing\Exception\ResourceNotFoundException; 19 use Symfony\Component\Routing\RequestContext; 20 use Symfony\Component\Routing\Route; 21 use Symfony\Component\Routing\RouteCollection; 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 protected $context; 35 protected $allow = array(); 36 protected $routes; 37 protected $request; 38 protected $expressionLanguage; 39 40 /** 41 * @var ExpressionFunctionProviderInterface[] 42 */ 43 protected $expressionLanguageProviders = array(); 44 45 public function __construct(RouteCollection $routes, RequestContext $context) 46 { 47 $this->routes = $routes; 48 $this->context = $context; 49 } 50 51 /** 52 * {@inheritdoc} 53 */ 54 public function setContext(RequestContext $context) 55 { 56 $this->context = $context; 57 } 58 59 /** 60 * {@inheritdoc} 61 */ 62 public function getContext() 63 { 64 return $this->context; 65 } 66 67 /** 68 * {@inheritdoc} 69 */ 70 public function match($pathinfo) 71 { 72 $this->allow = array(); 73 74 if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) { 75 return $ret; 76 } 77 78 throw 0 < \count($this->allow) 79 ? new MethodNotAllowedException(array_unique($this->allow)) 80 : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo)); 81 } 82 83 /** 84 * {@inheritdoc} 85 */ 86 public function matchRequest(Request $request) 87 { 88 $this->request = $request; 89 90 $ret = $this->match($request->getPathInfo()); 91 92 $this->request = null; 93 94 return $ret; 95 } 96 97 public function addExpressionLanguageProvider(ExpressionFunctionProviderInterface $provider) 98 { 99 $this->expressionLanguageProviders[] = $provider; 100 } 101 102 /** 103 * Tries to match a URL with a set of routes. 104 * 105 * @param string $pathinfo The path info to be parsed 106 * @param RouteCollection $routes The set of routes 107 * 108 * @return array An array of parameters 109 * 110 * @throws ResourceNotFoundException If the resource could not be found 111 * @throws MethodNotAllowedException If the resource was found but the request method is not allowed 112 */ 113 protected function matchCollection($pathinfo, RouteCollection $routes) 114 { 115 foreach ($routes as $name => $route) { 116 $compiledRoute = $route->compile(); 117 118 // check the static prefix of the URL first. Only use the more expensive preg_match when it matches 119 if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { 120 continue; 121 } 122 123 if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { 124 continue; 125 } 126 127 $hostMatches = array(); 128 if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { 129 continue; 130 } 131 132 $status = $this->handleRouteRequirements($pathinfo, $name, $route); 133 134 if (self::REQUIREMENT_MISMATCH === $status[0]) { 135 continue; 136 } 137 138 // check HTTP method requirement 139 if ($requiredMethods = $route->getMethods()) { 140 // HEAD and GET are equivalent as per RFC 141 if ('HEAD' === $method = $this->context->getMethod()) { 142 $method = 'GET'; 143 } 144 145 if (!\in_array($method, $requiredMethods)) { 146 if (self::REQUIREMENT_MATCH === $status[0]) { 147 $this->allow = array_merge($this->allow, $requiredMethods); 148 } 149 150 continue; 151 } 152 } 153 154 if (self::ROUTE_MATCH === $status[0]) { 155 return $status[1]; 156 } 157 158 return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); 159 } 160 } 161 162 /** 163 * Returns an array of values to use as request attributes. 164 * 165 * As this method requires the Route object, it is not available 166 * in matchers that do not have access to the matched Route instance 167 * (like the PHP and Apache matcher dumpers). 168 * 169 * @param Route $route The route we are matching against 170 * @param string $name The name of the route 171 * @param array $attributes An array of attributes from the matcher 172 * 173 * @return array An array of parameters 174 */ 175 protected function getAttributes(Route $route, $name, array $attributes) 176 { 177 $attributes['_route'] = $name; 178 179 return $this->mergeDefaults($attributes, $route->getDefaults()); 180 } 181 182 /** 183 * Handles specific route requirements. 184 * 185 * @param string $pathinfo The path 186 * @param string $name The route name 187 * @param Route $route The route 188 * 189 * @return array The first element represents the status, the second contains additional information 190 */ 191 protected function handleRouteRequirements($pathinfo, $name, Route $route) 192 { 193 // expression condition 194 if ($route->getCondition() && !$this->getExpressionLanguage()->evaluate($route->getCondition(), array('context' => $this->context, 'request' => $this->request ?: $this->createRequest($pathinfo)))) { 195 return array(self::REQUIREMENT_MISMATCH, null); 196 } 197 198 // check HTTP scheme requirement 199 $scheme = $this->context->getScheme(); 200 $status = $route->getSchemes() && !$route->hasScheme($scheme) ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; 201 202 return array($status, null); 203 } 204 205 /** 206 * Get merged default parameters. 207 * 208 * @param array $params The parameters 209 * @param array $defaults The defaults 210 * 211 * @return array Merged default parameters 212 */ 213 protected function mergeDefaults($params, $defaults) 214 { 215 foreach ($params as $key => $value) { 216 if (!\is_int($key)) { 217 $defaults[$key] = $value; 218 } 219 } 220 221 return $defaults; 222 } 223 224 protected function getExpressionLanguage() 225 { 226 if (null === $this->expressionLanguage) { 227 if (!class_exists('Symfony\Component\ExpressionLanguage\ExpressionLanguage')) { 228 throw new \RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.'); 229 } 230 $this->expressionLanguage = new ExpressionLanguage(null, $this->expressionLanguageProviders); 231 } 232 233 return $this->expressionLanguage; 234 } 235 236 /** 237 * @internal 238 */ 239 protected function createRequest($pathinfo) 240 { 241 if (!class_exists('Symfony\Component\HttpFoundation\Request')) { 242 return null; 243 } 244 245 return Request::create($this->context->getScheme().'://'.$this->context->getHost().$this->context->getBaseUrl().$pathinfo, $this->context->getMethod(), $this->context->getParameters(), array(), array(), array( 246 'SCRIPT_FILENAME' => $this->context->getBaseUrl(), 247 'SCRIPT_NAME' => $this->context->getBaseUrl(), 248 )); 249 } 250 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Nov 11 20:33:01 2020 | Cross-referenced by PHPXref 0.7.1 |