diff options
author | Nicolas LÅ“uillet <nicolas.loeuillet@gmail.com> | 2013-08-03 19:26:54 +0200 |
---|---|---|
committer | Nicolas LÅ“uillet <nicolas.loeuillet@gmail.com> | 2013-08-03 19:26:54 +0200 |
commit | 4f5b44bd3bd490309eb2ba7b44df4769816ba729 (patch) | |
tree | 6cefe170dfe0a5a361cb1e2d1fc4d580a3316d02 /vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php | |
parent | 2b840e0cfb63a453bea67a98541f3df9c273c5f5 (diff) | |
download | wallabag-4f5b44bd3bd490309eb2ba7b44df4769816ba729.tar.gz wallabag-4f5b44bd3bd490309eb2ba7b44df4769816ba729.tar.zst wallabag-4f5b44bd3bd490309eb2ba7b44df4769816ba729.zip |
twig implementation
Diffstat (limited to 'vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php')
-rw-r--r-- | vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php b/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php new file mode 100644 index 00000000..db18ec4e --- /dev/null +++ b/vendor/symfony/routing/Symfony/Component/Routing/Matcher/UrlMatcher.php | |||
@@ -0,0 +1,208 @@ | |||
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 | |||
20 | /** | ||
21 | * UrlMatcher matches URL based on a set of routes. | ||
22 | * | ||
23 | * @author Fabien Potencier <fabien@symfony.com> | ||
24 | * | ||
25 | * @api | ||
26 | */ | ||
27 | class UrlMatcher implements UrlMatcherInterface | ||
28 | { | ||
29 | const REQUIREMENT_MATCH = 0; | ||
30 | const REQUIREMENT_MISMATCH = 1; | ||
31 | const ROUTE_MATCH = 2; | ||
32 | |||
33 | /** | ||
34 | * @var RequestContext | ||
35 | */ | ||
36 | protected $context; | ||
37 | |||
38 | /** | ||
39 | * @var array | ||
40 | */ | ||
41 | protected $allow = array(); | ||
42 | |||
43 | /** | ||
44 | * @var RouteCollection | ||
45 | */ | ||
46 | protected $routes; | ||
47 | |||
48 | /** | ||
49 | * Constructor. | ||
50 | * | ||
51 | * @param RouteCollection $routes A RouteCollection instance | ||
52 | * @param RequestContext $context The context | ||
53 | * | ||
54 | * @api | ||
55 | */ | ||
56 | public function __construct(RouteCollection $routes, RequestContext $context) | ||
57 | { | ||
58 | $this->routes = $routes; | ||
59 | $this->context = $context; | ||
60 | } | ||
61 | |||
62 | /** | ||
63 | * {@inheritdoc} | ||
64 | */ | ||
65 | public function setContext(RequestContext $context) | ||
66 | { | ||
67 | $this->context = $context; | ||
68 | } | ||
69 | |||
70 | /** | ||
71 | * {@inheritdoc} | ||
72 | */ | ||
73 | public function getContext() | ||
74 | { | ||
75 | return $this->context; | ||
76 | } | ||
77 | |||
78 | /** | ||
79 | * {@inheritdoc} | ||
80 | */ | ||
81 | public function match($pathinfo) | ||
82 | { | ||
83 | $this->allow = array(); | ||
84 | |||
85 | if ($ret = $this->matchCollection(rawurldecode($pathinfo), $this->routes)) { | ||
86 | return $ret; | ||
87 | } | ||
88 | |||
89 | throw 0 < count($this->allow) | ||
90 | ? new MethodNotAllowedException(array_unique(array_map('strtoupper', $this->allow))) | ||
91 | : new ResourceNotFoundException(); | ||
92 | } | ||
93 | |||
94 | /** | ||
95 | * Tries to match a URL with a set of routes. | ||
96 | * | ||
97 | * @param string $pathinfo The path info to be parsed | ||
98 | * @param RouteCollection $routes The set of routes | ||
99 | * | ||
100 | * @return array An array of parameters | ||
101 | * | ||
102 | * @throws ResourceNotFoundException If the resource could not be found | ||
103 | * @throws MethodNotAllowedException If the resource was found but the request method is not allowed | ||
104 | */ | ||
105 | protected function matchCollection($pathinfo, RouteCollection $routes) | ||
106 | { | ||
107 | foreach ($routes as $name => $route) { | ||
108 | $compiledRoute = $route->compile(); | ||
109 | |||
110 | // check the static prefix of the URL first. Only use the more expensive preg_match when it matches | ||
111 | if ('' !== $compiledRoute->getStaticPrefix() && 0 !== strpos($pathinfo, $compiledRoute->getStaticPrefix())) { | ||
112 | continue; | ||
113 | } | ||
114 | |||
115 | if (!preg_match($compiledRoute->getRegex(), $pathinfo, $matches)) { | ||
116 | continue; | ||
117 | } | ||
118 | |||
119 | $hostMatches = array(); | ||
120 | if ($compiledRoute->getHostRegex() && !preg_match($compiledRoute->getHostRegex(), $this->context->getHost(), $hostMatches)) { | ||
121 | continue; | ||
122 | } | ||
123 | |||
124 | // check HTTP method requirement | ||
125 | if ($req = $route->getRequirement('_method')) { | ||
126 | // HEAD and GET are equivalent as per RFC | ||
127 | if ('HEAD' === $method = $this->context->getMethod()) { | ||
128 | $method = 'GET'; | ||
129 | } | ||
130 | |||
131 | if (!in_array($method, $req = explode('|', strtoupper($req)))) { | ||
132 | $this->allow = array_merge($this->allow, $req); | ||
133 | |||
134 | continue; | ||
135 | } | ||
136 | } | ||
137 | |||
138 | $status = $this->handleRouteRequirements($pathinfo, $name, $route); | ||
139 | |||
140 | if (self::ROUTE_MATCH === $status[0]) { | ||
141 | return $status[1]; | ||
142 | } | ||
143 | |||
144 | if (self::REQUIREMENT_MISMATCH === $status[0]) { | ||
145 | continue; | ||
146 | } | ||
147 | |||
148 | return $this->getAttributes($route, $name, array_replace($matches, $hostMatches)); | ||
149 | } | ||
150 | } | ||
151 | |||
152 | /** | ||
153 | * Returns an array of values to use as request attributes. | ||
154 | * | ||
155 | * As this method requires the Route object, it is not available | ||
156 | * in matchers that do not have access to the matched Route instance | ||
157 | * (like the PHP and Apache matcher dumpers). | ||
158 | * | ||
159 | * @param Route $route The route we are matching against | ||
160 | * @param string $name The name of the route | ||
161 | * @param array $attributes An array of attributes from the matcher | ||
162 | * | ||
163 | * @return array An array of parameters | ||
164 | */ | ||
165 | protected function getAttributes(Route $route, $name, array $attributes) | ||
166 | { | ||
167 | $attributes['_route'] = $name; | ||
168 | |||
169 | return $this->mergeDefaults($attributes, $route->getDefaults()); | ||
170 | } | ||
171 | |||
172 | /** | ||
173 | * Handles specific route requirements. | ||
174 | * | ||
175 | * @param string $pathinfo The path | ||
176 | * @param string $name The route name | ||
177 | * @param Route $route The route | ||
178 | * | ||
179 | * @return array The first element represents the status, the second contains additional information | ||
180 | */ | ||
181 | protected function handleRouteRequirements($pathinfo, $name, Route $route) | ||
182 | { | ||
183 | // check HTTP scheme requirement | ||
184 | $scheme = $route->getRequirement('_scheme'); | ||
185 | $status = $scheme && $scheme !== $this->context->getScheme() ? self::REQUIREMENT_MISMATCH : self::REQUIREMENT_MATCH; | ||
186 | |||
187 | return array($status, null); | ||
188 | } | ||
189 | |||
190 | /** | ||
191 | * Get merged default parameters. | ||
192 | * | ||
193 | * @param array $params The parameters | ||
194 | * @param array $defaults The defaults | ||
195 | * | ||
196 | * @return array Merged default parameters | ||
197 | */ | ||
198 | protected function mergeDefaults($params, $defaults) | ||
199 | { | ||
200 | foreach ($params as $key => $value) { | ||
201 | if (!is_int($key)) { | ||
202 | $defaults[$key] = $value; | ||
203 | } | ||
204 | } | ||
205 | |||
206 | return $defaults; | ||
207 | } | ||
208 | } | ||