comparison vendor/symfony/routing/RouteCollectionBuilder.php @ 0:4c8ae668cc8c

Initial import (non-working)
author Chris Cannam
date Wed, 29 Nov 2017 16:09:58 +0000
parents
children 1fec387a4317
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;
13
14 use Symfony\Component\Config\Exception\FileLoaderLoadException;
15 use Symfony\Component\Config\Loader\LoaderInterface;
16 use Symfony\Component\Config\Resource\ResourceInterface;
17
18 /**
19 * Helps add and import routes into a RouteCollection.
20 *
21 * @author Ryan Weaver <ryan@knpuniversity.com>
22 */
23 class RouteCollectionBuilder
24 {
25 /**
26 * @var Route[]|RouteCollectionBuilder[]
27 */
28 private $routes = array();
29
30 private $loader;
31 private $defaults = array();
32 private $prefix;
33 private $host;
34 private $condition;
35 private $requirements = array();
36 private $options = array();
37 private $schemes;
38 private $methods;
39 private $resources = array();
40
41 /**
42 * @param LoaderInterface $loader
43 */
44 public function __construct(LoaderInterface $loader = null)
45 {
46 $this->loader = $loader;
47 }
48
49 /**
50 * Import an external routing resource and returns the RouteCollectionBuilder.
51 *
52 * $routes->import('blog.yml', '/blog');
53 *
54 * @param mixed $resource
55 * @param string|null $prefix
56 * @param string $type
57 *
58 * @return self
59 *
60 * @throws FileLoaderLoadException
61 */
62 public function import($resource, $prefix = '/', $type = null)
63 {
64 /** @var RouteCollection $collection */
65 $collection = $this->load($resource, $type);
66
67 // create a builder from the RouteCollection
68 $builder = $this->createBuilder();
69 foreach ($collection->all() as $name => $route) {
70 $builder->addRoute($route, $name);
71 }
72
73 foreach ($collection->getResources() as $resource) {
74 $builder->addResource($resource);
75 }
76
77 // mount into this builder
78 $this->mount($prefix, $builder);
79
80 return $builder;
81 }
82
83 /**
84 * Adds a route and returns it for future modification.
85 *
86 * @param string $path The route path
87 * @param string $controller The route's controller
88 * @param string|null $name The name to give this route
89 *
90 * @return Route
91 */
92 public function add($path, $controller, $name = null)
93 {
94 $route = new Route($path);
95 $route->setDefault('_controller', $controller);
96 $this->addRoute($route, $name);
97
98 return $route;
99 }
100
101 /**
102 * Returns a RouteCollectionBuilder that can be configured and then added with mount().
103 *
104 * @return self
105 */
106 public function createBuilder()
107 {
108 return new self($this->loader);
109 }
110
111 /**
112 * Add a RouteCollectionBuilder.
113 *
114 * @param string $prefix
115 * @param RouteCollectionBuilder $builder
116 */
117 public function mount($prefix, RouteCollectionBuilder $builder)
118 {
119 $builder->prefix = trim(trim($prefix), '/');
120 $this->routes[] = $builder;
121 }
122
123 /**
124 * Adds a Route object to the builder.
125 *
126 * @param Route $route
127 * @param string|null $name
128 *
129 * @return $this
130 */
131 public function addRoute(Route $route, $name = null)
132 {
133 if (null === $name) {
134 // used as a flag to know which routes will need a name later
135 $name = '_unnamed_route_'.spl_object_hash($route);
136 }
137
138 $this->routes[$name] = $route;
139
140 return $this;
141 }
142
143 /**
144 * Sets the host on all embedded routes (unless already set).
145 *
146 * @param string $pattern
147 *
148 * @return $this
149 */
150 public function setHost($pattern)
151 {
152 $this->host = $pattern;
153
154 return $this;
155 }
156
157 /**
158 * Sets a condition on all embedded routes (unless already set).
159 *
160 * @param string $condition
161 *
162 * @return $this
163 */
164 public function setCondition($condition)
165 {
166 $this->condition = $condition;
167
168 return $this;
169 }
170
171 /**
172 * Sets a default value that will be added to all embedded routes (unless that
173 * default value is already set).
174 *
175 * @param string $key
176 * @param mixed $value
177 *
178 * @return $this
179 */
180 public function setDefault($key, $value)
181 {
182 $this->defaults[$key] = $value;
183
184 return $this;
185 }
186
187 /**
188 * Sets a requirement that will be added to all embedded routes (unless that
189 * requirement is already set).
190 *
191 * @param string $key
192 * @param mixed $regex
193 *
194 * @return $this
195 */
196 public function setRequirement($key, $regex)
197 {
198 $this->requirements[$key] = $regex;
199
200 return $this;
201 }
202
203 /**
204 * Sets an opiton that will be added to all embedded routes (unless that
205 * option is already set).
206 *
207 * @param string $key
208 * @param mixed $value
209 *
210 * @return $this
211 */
212 public function setOption($key, $value)
213 {
214 $this->options[$key] = $value;
215
216 return $this;
217 }
218
219 /**
220 * Sets the schemes on all embedded routes (unless already set).
221 *
222 * @param array|string $schemes
223 *
224 * @return $this
225 */
226 public function setSchemes($schemes)
227 {
228 $this->schemes = $schemes;
229
230 return $this;
231 }
232
233 /**
234 * Sets the methods on all embedded routes (unless already set).
235 *
236 * @param array|string $methods
237 *
238 * @return $this
239 */
240 public function setMethods($methods)
241 {
242 $this->methods = $methods;
243
244 return $this;
245 }
246
247 /**
248 * Adds a resource for this collection.
249 *
250 * @param ResourceInterface $resource
251 *
252 * @return $this
253 */
254 private function addResource(ResourceInterface $resource)
255 {
256 $this->resources[] = $resource;
257
258 return $this;
259 }
260
261 /**
262 * Creates the final RouteCollection and returns it.
263 *
264 * @return RouteCollection
265 */
266 public function build()
267 {
268 $routeCollection = new RouteCollection();
269
270 foreach ($this->routes as $name => $route) {
271 if ($route instanceof Route) {
272 $route->setDefaults(array_merge($this->defaults, $route->getDefaults()));
273 $route->setOptions(array_merge($this->options, $route->getOptions()));
274
275 foreach ($this->requirements as $key => $val) {
276 if (!$route->hasRequirement($key)) {
277 $route->setRequirement($key, $val);
278 }
279 }
280
281 if (null !== $this->prefix) {
282 $route->setPath('/'.$this->prefix.$route->getPath());
283 }
284
285 if (!$route->getHost()) {
286 $route->setHost($this->host);
287 }
288
289 if (!$route->getCondition()) {
290 $route->setCondition($this->condition);
291 }
292
293 if (!$route->getSchemes()) {
294 $route->setSchemes($this->schemes);
295 }
296
297 if (!$route->getMethods()) {
298 $route->setMethods($this->methods);
299 }
300
301 // auto-generate the route name if it's been marked
302 if ('_unnamed_route_' === substr($name, 0, 15)) {
303 $name = $this->generateRouteName($route);
304 }
305
306 $routeCollection->add($name, $route);
307 } else {
308 /* @var self $route */
309 $subCollection = $route->build();
310 $subCollection->addPrefix($this->prefix);
311
312 $routeCollection->addCollection($subCollection);
313 }
314
315 foreach ($this->resources as $resource) {
316 $routeCollection->addResource($resource);
317 }
318 }
319
320 return $routeCollection;
321 }
322
323 /**
324 * Generates a route name based on details of this route.
325 *
326 * @return string
327 */
328 private function generateRouteName(Route $route)
329 {
330 $methods = implode('_', $route->getMethods()).'_';
331
332 $routeName = $methods.$route->getPath();
333 $routeName = str_replace(array('/', ':', '|', '-'), '_', $routeName);
334 $routeName = preg_replace('/[^a-z0-9A-Z_.]+/', '', $routeName);
335
336 // Collapse consecutive underscores down into a single underscore.
337 $routeName = preg_replace('/_+/', '_', $routeName);
338
339 return $routeName;
340 }
341
342 /**
343 * Finds a loader able to load an imported resource and loads it.
344 *
345 * @param mixed $resource A resource
346 * @param string|null $type The resource type or null if unknown
347 *
348 * @return RouteCollection
349 *
350 * @throws FileLoaderLoadException If no loader is found
351 */
352 private function load($resource, $type = null)
353 {
354 if (null === $this->loader) {
355 throw new \BadMethodCallException('Cannot import other routing resources: you must pass a LoaderInterface when constructing RouteCollectionBuilder.');
356 }
357
358 if ($this->loader->supports($resource, $type)) {
359 return $this->loader->load($resource, $type);
360 }
361
362 if (null === $resolver = $this->loader->getResolver()) {
363 throw new FileLoaderLoadException($resource);
364 }
365
366 if (false === $loader = $resolver->resolve($resource, $type)) {
367 throw new FileLoaderLoadException($resource);
368 }
369
370 return $loader->load($resource, $type);
371 }
372 }