Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
UrlMatcher.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\Routing\Matcher;
013
014 use Symfony\Component\Routing\Exception\MethodNotAllowedException;
015 use Symfony\Component\Routing\Exception\ResourceNotFoundException;
016 use Symfony\Component\Routing\RouteCollection;
017 use Symfony\Component\Routing\RequestContext;
018 use Symfony\Component\Routing\Route;
019 use Symfony\Component\HttpFoundation\Request;
020 use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
021 use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
022
023 /**
024 * UrlMatcher matches URL based on a set of routes.
025 *
026 * @author Fabien Potencier <fabien@symfony.com>
027 */
028 class UrlMatcher implements UrlMatcherInterface, RequestMatcherInterface
029 {
030 const REQUIREMENT_MATCH = 0;
031 const REQUIREMENT_MISMATCH = 1;
032 const ROUTE_MATCH = 2;
033
034 /**
035 * @var RequestContext
036 */
037 protected $context;
038
039 /**
040 * @var array
041 */
042 protected $allow = array();
043
044 /**
045 * @var RouteCollection
046 */
047 protected $routes;
048
049 protected $request;
050 protected $expressionLanguage;
051
052 /**
053 * @var ExpressionFunctionProviderInterface[]
054 */
055 protected $expressionLanguageProviders = array();
056
057 /**
058 * Constructor.
059 *
060 * @param RouteCollection $routes A RouteCollection instance
061 * @param RequestContext $context The context
062 */
063 public function __construct(RouteCollection $routes, RequestContext $context)
064 {
065 $this->routes = $routes;
066 $this->context = $context;
067 }
068
069 /**
070 * {@inheritdoc}
071 */
072 public function setContext(RequestContext $context)
073 {
074 $this->context = $context;
075 }
076
077 /**
078 * {@inheritdoc}
079 */
080 public function getContext()
081 {
082 return $this->context;
083 }
084
085 /**
086 * {@inheritdoc}
087 */
088 public function match($pathinfo)
089 {
090 $this->allow = array();
091
092 if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) {
093 return $ret;
094 }
095
096 throw 0 < count($this->allow)
097 ? new MethodNotAllowedException(array_unique($this->allow))
098 : new ResourceNotFoundException(sprintf('No routes found for "%s".', $pathinfo));
099 }
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 }
252