Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
namespace Illuminate\Routing;
4
 
5
use Illuminate\Container\Container;
6
use Illuminate\Http\Request;
7
use Illuminate\Support\Collection;
8
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
9
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
10
use Symfony\Component\Routing\Exception\MethodNotAllowedException;
11
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
12
use Symfony\Component\Routing\Matcher\CompiledUrlMatcher;
13
use Symfony\Component\Routing\RequestContext;
14
 
15
class CompiledRouteCollection extends AbstractRouteCollection
16
{
17
    /**
18
     * The compiled routes collection.
19
     *
20
     * @var array
21
     */
22
    protected $compiled = [];
23
 
24
    /**
25
     * An array of the route attributes keyed by name.
26
     *
27
     * @var array
28
     */
29
    protected $attributes = [];
30
 
31
    /**
32
     * The dynamically added routes that were added after loading the cached, compiled routes.
33
     *
34
     * @var \Illuminate\Routing\RouteCollection|null
35
     */
36
    protected $routes;
37
 
38
    /**
39
     * The router instance used by the route.
40
     *
41
     * @var \Illuminate\Routing\Router
42
     */
43
    protected $router;
44
 
45
    /**
46
     * The container instance used by the route.
47
     *
48
     * @var \Illuminate\Container\Container
49
     */
50
    protected $container;
51
 
52
    /**
53
     * Create a new CompiledRouteCollection instance.
54
     *
55
     * @param  array  $compiled
56
     * @param  array  $attributes
57
     * @return void
58
     */
59
    public function __construct(array $compiled, array $attributes)
60
    {
61
        $this->compiled = $compiled;
62
        $this->attributes = $attributes;
63
        $this->routes = new RouteCollection;
64
    }
65
 
66
    /**
67
     * Add a Route instance to the collection.
68
     *
69
     * @param  \Illuminate\Routing\Route  $route
70
     * @return \Illuminate\Routing\Route
71
     */
72
    public function add(Route $route)
73
    {
74
        return $this->routes->add($route);
75
    }
76
 
77
    /**
78
     * Refresh the name look-up table.
79
     *
80
     * This is done in case any names are fluently defined or if routes are overwritten.
81
     *
82
     * @return void
83
     */
84
    public function refreshNameLookups()
85
    {
86
        //
87
    }
88
 
89
    /**
90
     * Refresh the action look-up table.
91
     *
92
     * This is done in case any actions are overwritten with new controllers.
93
     *
94
     * @return void
95
     */
96
    public function refreshActionLookups()
97
    {
98
        //
99
    }
100
 
101
    /**
102
     * Find the first route matching a given request.
103
     *
104
     * @param  \Illuminate\Http\Request  $request
105
     * @return \Illuminate\Routing\Route
106
     *
107
     * @throws \Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
108
     * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
109
     */
110
    public function match(Request $request)
111
    {
112
        $matcher = new CompiledUrlMatcher(
113
            $this->compiled, (new RequestContext)->fromRequest(
114
                $trimmedRequest = $this->requestWithoutTrailingSlash($request)
115
            )
116
        );
117
 
118
        $route = null;
119
 
120
        try {
121
            if ($result = $matcher->matchRequest($trimmedRequest)) {
122
                $route = $this->getByName($result['_route']);
123
            }
124
        } catch (ResourceNotFoundException|MethodNotAllowedException $e) {
125
            try {
126
                return $this->routes->match($request);
127
            } catch (NotFoundHttpException $e) {
128
                //
129
            }
130
        }
131
 
132
        if ($route && $route->isFallback) {
133
            try {
134
                $dynamicRoute = $this->routes->match($request);
135
 
136
                if (! $dynamicRoute->isFallback) {
137
                    $route = $dynamicRoute;
138
                }
139
            } catch (NotFoundHttpException|MethodNotAllowedHttpException $e) {
140
                //
141
            }
142
        }
143
 
144
        return $this->handleMatchedRoute($request, $route);
145
    }
146
 
147
    /**
148
     * Get a cloned instance of the given request without any trailing slash on the URI.
149
     *
150
     * @param  \Illuminate\Http\Request  $request
151
     * @return \Illuminate\Http\Request
152
     */
153
    protected function requestWithoutTrailingSlash(Request $request)
154
    {
155
        $trimmedRequest = $request->duplicate();
156
 
157
        $parts = explode('?', $request->server->get('REQUEST_URI'), 2);
158
 
159
        $trimmedRequest->server->set(
160
            'REQUEST_URI', rtrim($parts[0], '/').(isset($parts[1]) ? '?'.$parts[1] : '')
161
        );
162
 
163
        return $trimmedRequest;
164
    }
165
 
166
    /**
167
     * Get routes from the collection by method.
168
     *
169
     * @param  string|null  $method
170
     * @return \Illuminate\Routing\Route[]
171
     */
172
    public function get($method = null)
173
    {
174
        return $this->getRoutesByMethod()[$method] ?? [];
175
    }
176
 
177
    /**
178
     * Determine if the route collection contains a given named route.
179
     *
180
     * @param  string  $name
181
     * @return bool
182
     */
183
    public function hasNamedRoute($name)
184
    {
185
        return isset($this->attributes[$name]) || $this->routes->hasNamedRoute($name);
186
    }
187
 
188
    /**
189
     * Get a route instance by its name.
190
     *
191
     * @param  string  $name
192
     * @return \Illuminate\Routing\Route|null
193
     */
194
    public function getByName($name)
195
    {
196
        if (isset($this->attributes[$name])) {
197
            return $this->newRoute($this->attributes[$name]);
198
        }
199
 
200
        return $this->routes->getByName($name);
201
    }
202
 
203
    /**
204
     * Get a route instance by its controller action.
205
     *
206
     * @param  string  $action
207
     * @return \Illuminate\Routing\Route|null
208
     */
209
    public function getByAction($action)
210
    {
211
        $attributes = collect($this->attributes)->first(function (array $attributes) use ($action) {
212
            if (isset($attributes['action']['controller'])) {
213
                return trim($attributes['action']['controller'], '\\') === $action;
214
            }
215
 
216
            return $attributes['action']['uses'] === $action;
217
        });
218
 
219
        if ($attributes) {
220
            return $this->newRoute($attributes);
221
        }
222
 
223
        return $this->routes->getByAction($action);
224
    }
225
 
226
    /**
227
     * Get all of the routes in the collection.
228
     *
229
     * @return \Illuminate\Routing\Route[]
230
     */
231
    public function getRoutes()
232
    {
233
        return collect($this->attributes)
234
            ->map(function (array $attributes) {
235
                return $this->newRoute($attributes);
236
            })
237
            ->merge($this->routes->getRoutes())
238
            ->values()
239
            ->all();
240
    }
241
 
242
    /**
243
     * Get all of the routes keyed by their HTTP verb / method.
244
     *
245
     * @return array
246
     */
247
    public function getRoutesByMethod()
248
    {
249
        return collect($this->getRoutes())
250
            ->groupBy(function (Route $route) {
251
                return $route->methods();
252
            })
253
            ->map(function (Collection $routes) {
254
                return $routes->mapWithKeys(function (Route $route) {
255
                    return [$route->getDomain().$route->uri => $route];
256
                })->all();
257
            })
258
            ->all();
259
    }
260
 
261
    /**
262
     * Get all of the routes keyed by their name.
263
     *
264
     * @return \Illuminate\Routing\Route[]
265
     */
266
    public function getRoutesByName()
267
    {
268
        return collect($this->getRoutes())
269
            ->keyBy(function (Route $route) {
270
                return $route->getName();
271
            })
272
            ->all();
273
    }
274
 
275
    /**
276
     * Resolve an array of attributes to a Route instance.
277
     *
278
     * @param  array  $attributes
279
     * @return \Illuminate\Routing\Route
280
     */
281
    protected function newRoute(array $attributes)
282
    {
283
        if (empty($attributes['action']['prefix'] ?? '')) {
284
            $baseUri = $attributes['uri'];
285
        } else {
286
            $prefix = trim($attributes['action']['prefix'], '/');
287
 
288
            $baseUri = trim(implode(
289
                '/', array_slice(
290
                    explode('/', trim($attributes['uri'], '/')),
291
                    count($prefix !== '' ? explode('/', $prefix) : [])
292
                )
293
            ), '/');
294
        }
295
 
296
        return $this->router->newRoute($attributes['methods'], $baseUri === '' ? '/' : $baseUri, $attributes['action'])
297
            ->setFallback($attributes['fallback'])
298
            ->setDefaults($attributes['defaults'])
299
            ->setWheres($attributes['wheres'])
300
            ->setBindingFields($attributes['bindingFields'])
301
            ->block($attributes['lockSeconds'] ?? null, $attributes['waitSeconds'] ?? null)
302
            ->withTrashed($attributes['withTrashed'] ?? false);
303
    }
304
 
305
    /**
306
     * Set the router instance on the route.
307
     *
308
     * @param  \Illuminate\Routing\Router  $router
309
     * @return $this
310
     */
311
    public function setRouter(Router $router)
312
    {
313
        $this->router = $router;
314
 
315
        return $this;
316
    }
317
 
318
    /**
319
     * Set the container instance on the route.
320
     *
321
     * @param  \Illuminate\Container\Container  $container
322
     * @return $this
323
     */
324
    public function setContainer(Container $container)
325
    {
326
        $this->container = $container;
327
 
328
        return $this;
329
    }
330
}