Subversion Repositories php-qbpwcf

Rev

Details | Last modification | View Log | RSS feed

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