1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* Lenevor Framework |
5
|
|
|
* |
6
|
|
|
* LICENSE |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the new BSD license that is bundled |
9
|
|
|
* with this package in the file license.md. |
10
|
|
|
* It is also available through the world-wide-web at this URL: |
11
|
|
|
* https://lenevor.com/license |
12
|
|
|
* If you did not receive a copy of the license and are unable to |
13
|
|
|
* obtain it through the world-wide-web, please send an email |
14
|
|
|
* to [email protected] so we can send you a copy immediately. |
15
|
|
|
* |
16
|
|
|
* @package Lenevor |
17
|
|
|
* @subpackage Base |
18
|
|
|
* @link https://lenevor.com |
19
|
|
|
* @copyright Copyright (c) 2019 - 2021 Alexander Campo <[email protected]> |
20
|
|
|
* @license https://opensource.org/licenses/BSD-3-Clause New BSD license or see https://lenevor.com/license or see /license.md |
21
|
|
|
*/ |
22
|
|
|
|
23
|
|
|
namespace Syscodes\Routing; |
24
|
|
|
|
25
|
|
|
use Closure; |
26
|
|
|
use Syscodes\Http\Request; |
27
|
|
|
use BadMethodCallException; |
28
|
|
|
use Syscodes\Http\Response; |
29
|
|
|
use InvalidArgumentException; |
30
|
|
|
use Syscodes\Collections\Arr; |
31
|
|
|
use Syscodes\Http\RedirectResponse; |
32
|
|
|
use Syscodes\Contracts\Routing\Routable; |
33
|
|
|
use Syscodes\Contracts\Container\Container; |
34
|
|
|
use Syscodes\Controller\MiddlewareResolver; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* The Router class allows the integration of an easy-to-use routing system. |
38
|
|
|
* |
39
|
|
|
* @author Alexander Campo <[email protected]> |
40
|
|
|
*/ |
41
|
|
|
class Router implements Routable |
42
|
|
|
{ |
43
|
|
|
use Concerns\RouteMap, |
44
|
|
|
Concerns\RouteResolver; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* The registered route value binders. |
48
|
|
|
* |
49
|
|
|
* @var array $binders |
50
|
|
|
*/ |
51
|
|
|
protected $binders = []; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* The container instance used by the router. |
55
|
|
|
* |
56
|
|
|
* @var \Syscodes\Contracts\Container\Container $container |
57
|
|
|
*/ |
58
|
|
|
protected $container; |
59
|
|
|
|
60
|
|
|
/** |
61
|
|
|
* Variable of group route. |
62
|
|
|
* |
63
|
|
|
* @var array $groupStack |
64
|
|
|
*/ |
65
|
|
|
protected $groupStack = []; |
66
|
|
|
|
67
|
|
|
/** |
68
|
|
|
* The registered string macros. |
69
|
|
|
* |
70
|
|
|
* @var array $macros |
71
|
|
|
*/ |
72
|
|
|
protected $macros = []; |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* Middleware for function of filters |
76
|
|
|
* |
77
|
|
|
* @var array $middleware |
78
|
|
|
*/ |
79
|
|
|
protected $middleware = []; |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* All of the middleware groups. |
83
|
|
|
* |
84
|
|
|
* @var array $middlewareGroups |
85
|
|
|
*/ |
86
|
|
|
protected $middlewareGroups = []; |
87
|
|
|
|
88
|
|
|
/** |
89
|
|
|
* The priority-sorted list of middleware. |
90
|
|
|
* |
91
|
|
|
* @var array $middlewarePriority |
92
|
|
|
*/ |
93
|
|
|
public $middlewarePriority = []; |
94
|
|
|
|
95
|
|
|
/** |
96
|
|
|
* The globally available parameter patterns. |
97
|
|
|
* |
98
|
|
|
* @var array $patterns |
99
|
|
|
*/ |
100
|
|
|
protected $patterns = []; |
101
|
|
|
|
102
|
|
|
/** |
103
|
|
|
* The route collection instance. |
104
|
|
|
* |
105
|
|
|
* @var \Syscodes\Routing\RouteCollection $routes |
106
|
|
|
*/ |
107
|
|
|
protected $routes; |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* The Resource instance. |
111
|
|
|
* |
112
|
|
|
* @var \Syscodes\Routing\ResourceRegister $resources |
113
|
|
|
*/ |
114
|
|
|
protected $resources; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* Constructor. Create a new Router instance. |
118
|
|
|
* |
119
|
|
|
* @param \Syscodes\Contracts\Container\Container|null $container (null by default) |
120
|
|
|
* |
121
|
|
|
* @return void |
122
|
|
|
*/ |
123
|
|
|
public function __construct(Container $container = null) |
124
|
|
|
{ |
125
|
|
|
$this->routes = new RouteCollection(); |
126
|
|
|
|
127
|
|
|
$this->container = $container ?: new Container; |
128
|
|
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Get the prefix from the group on the stack. |
132
|
|
|
* |
133
|
|
|
* @return string |
134
|
|
|
*/ |
135
|
|
|
public function getGroupPrefix() |
136
|
|
|
{ |
137
|
|
|
if ( ! empty($this->groupStack)) { |
138
|
|
|
$last = end($this->groupStack); |
139
|
|
|
|
140
|
|
|
return $last['prefix'] ?? ''; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
return ''; |
144
|
|
|
} |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* Group a series of routes under a single URL segment. This is handy |
148
|
|
|
* for grouping items into an admin area, like: |
149
|
|
|
* |
150
|
|
|
* Example: |
151
|
|
|
* // Creates route: /admin show the word 'User' |
152
|
|
|
* Route::group(['prefix' => 'admin'], function() { |
153
|
|
|
* |
154
|
|
|
* Route::get('/user', function() { |
155
|
|
|
* echo 'Hello world..!'; |
156
|
|
|
* }); |
157
|
|
|
* |
158
|
|
|
* }); /admin/user |
159
|
|
|
* |
160
|
|
|
* @param array $attributes |
161
|
|
|
* @param \Closure|string $callback |
162
|
|
|
* |
163
|
|
|
* @return void |
164
|
|
|
*/ |
165
|
|
|
public function group(array $attributes, $callback) |
166
|
|
|
{ |
167
|
|
|
$this->updateGroupStack($attributes); |
168
|
|
|
|
169
|
|
|
$this->loadRoutes($callback); |
170
|
|
|
|
171
|
|
|
array_pop($this->groupStack); |
172
|
|
|
|
173
|
|
|
return $this; |
|
|
|
|
174
|
|
|
} |
175
|
|
|
|
176
|
|
|
/** |
177
|
|
|
* Update the group stack with the given attributes. |
178
|
|
|
* |
179
|
|
|
* @param array $attributes |
180
|
|
|
* |
181
|
|
|
* @return void |
182
|
|
|
*/ |
183
|
|
|
protected function updateGroupStack(array $attributes) |
184
|
|
|
{ |
185
|
|
|
if ( ! empty($this->groupStack)) { |
186
|
|
|
$attributes = $this->mergeGroup($attributes); |
187
|
|
|
} |
188
|
|
|
|
189
|
|
|
$this->groupStack[] = $attributes; |
190
|
|
|
} |
191
|
|
|
|
192
|
|
|
/** |
193
|
|
|
* Merge the given group attributes. |
194
|
|
|
* |
195
|
|
|
* @param array $new |
196
|
|
|
* |
197
|
|
|
* @return array |
198
|
|
|
*/ |
199
|
|
|
protected function mergeGroup($new) |
200
|
|
|
{ |
201
|
|
|
return RouteGroup::mergeGroup($new, end($this->groupStack)); |
202
|
|
|
} |
203
|
|
|
|
204
|
|
|
/** |
205
|
|
|
* Load the provided routes. |
206
|
|
|
* |
207
|
|
|
* @param \Closure|string $callback |
208
|
|
|
* |
209
|
|
|
* @return void |
210
|
|
|
*/ |
211
|
|
|
protected function loadRoutes($callback) |
212
|
|
|
{ |
213
|
|
|
if ($callback instanceof Closure) { |
214
|
|
|
$callback($this); |
215
|
|
|
} else { |
216
|
|
|
(new RouteFileRegister($this))->register($callback); |
217
|
|
|
} |
218
|
|
|
} |
219
|
|
|
|
220
|
|
|
/** |
221
|
|
|
* Add a route to the underlying route collection. |
222
|
|
|
* |
223
|
|
|
* @param array|string $method |
224
|
|
|
* @param string $route |
225
|
|
|
* @param mixed $action |
226
|
|
|
* |
227
|
|
|
* @return \Syscodes\Routing\Route |
228
|
|
|
*/ |
229
|
|
|
public function addRoute($method, $route, $action) |
230
|
|
|
{ |
231
|
|
|
return $this->routes->add($this->map($method, $route, $action)); |
|
|
|
|
232
|
|
|
} |
233
|
|
|
|
234
|
|
|
/** |
235
|
|
|
* Create a redirect from one URI to another. |
236
|
|
|
* |
237
|
|
|
* @param string $uri |
238
|
|
|
* @param string $destination |
239
|
|
|
* @param int $status (302 by default) |
240
|
|
|
* |
241
|
|
|
* @return \Syscodes\Routing\Route |
242
|
|
|
*/ |
243
|
|
|
public function redirect($uri, $destination, $status = 302) |
244
|
|
|
{ |
245
|
|
|
return $this->any($uri, function () use ($destination, $status) { |
|
|
|
|
246
|
|
|
return new RedirectResponse($destination, $status); |
247
|
|
|
}); |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* Register a new route that returns a view. |
252
|
|
|
* |
253
|
|
|
* @param string $uri |
254
|
|
|
* @param string $view |
255
|
|
|
* @param array $data |
256
|
|
|
* |
257
|
|
|
* @return \Syscodes\Routing\Route |
258
|
|
|
*/ |
259
|
|
|
public function view($uri, $view, $data = []) |
260
|
|
|
{ |
261
|
|
|
return $this->match(['GET', 'HEAD'], $uri, function () use ($view, $data) { |
|
|
|
|
262
|
|
|
return $this->container->make('view')->make($view, $data); |
263
|
|
|
}); |
264
|
|
|
} |
265
|
|
|
|
266
|
|
|
/** |
267
|
|
|
* Add new route to routes array. |
268
|
|
|
* |
269
|
|
|
* @param array|string $method |
270
|
|
|
* @param string $route |
271
|
|
|
* @param mixed $action |
272
|
|
|
* |
273
|
|
|
* @return void |
274
|
|
|
* |
275
|
|
|
* @throws \InvalidArgumentException |
276
|
|
|
*/ |
277
|
|
|
public function map($method, $route, $action) |
278
|
|
|
{ |
279
|
|
|
if ($this->actionReferencesController($action)) { |
280
|
|
|
$action = $this->convertToControllerAction($action); |
281
|
|
|
} |
282
|
|
|
|
283
|
|
|
$route = $this->newRoute( |
284
|
|
|
array_map('strtoupper', (array) $method), |
285
|
|
|
$this->prefix($route), |
286
|
|
|
$action |
287
|
|
|
); |
288
|
|
|
|
289
|
|
|
if ($this->hasGroupStack()) { |
290
|
|
|
$this->mergeGroupAttributesIntoRoute($route); |
291
|
|
|
} |
292
|
|
|
|
293
|
|
|
$this->addWhereClausesToRoute($route); |
294
|
|
|
|
295
|
|
|
return $route; |
|
|
|
|
296
|
|
|
} |
297
|
|
|
|
298
|
|
|
/** |
299
|
|
|
* Determine if the action is routing to a controller. |
300
|
|
|
* |
301
|
|
|
* @param array $action |
302
|
|
|
* |
303
|
|
|
* @return bool |
304
|
|
|
*/ |
305
|
|
|
protected function actionReferencesController($action) |
306
|
|
|
{ |
307
|
|
|
if ($action instanceof Closure) { |
|
|
|
|
308
|
|
|
return false; |
309
|
|
|
} |
310
|
|
|
|
311
|
|
|
return is_string($action) || (isset($action['uses']) && is_string($action['uses'])); |
312
|
|
|
} |
313
|
|
|
|
314
|
|
|
/** |
315
|
|
|
* Add a controller based route action to the action array. |
316
|
|
|
* |
317
|
|
|
* @param array|string $action |
318
|
|
|
* |
319
|
|
|
* @return array |
320
|
|
|
*/ |
321
|
|
|
protected function convertToControllerAction($action) |
322
|
|
|
{ |
323
|
|
|
if (is_string($action)) { |
324
|
|
|
$action = ['uses' => $action]; |
325
|
|
|
} |
326
|
|
|
|
327
|
|
|
if ( ! empty($this->groupStack)) { |
328
|
|
|
$action['uses'] = $this->prependGroupUses($action['uses']); |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
$action['controller'] = $action['uses']; |
332
|
|
|
|
333
|
|
|
return $action; |
334
|
|
|
} |
335
|
|
|
|
336
|
|
|
/** |
337
|
|
|
* Prepend the last group uses onto the use clause. |
338
|
|
|
* |
339
|
|
|
* @param string $uses |
340
|
|
|
* |
341
|
|
|
* @return string |
342
|
|
|
*/ |
343
|
|
|
protected function prependGroupUses($uses) |
344
|
|
|
{ |
345
|
|
|
$group = end($this->groupStack); |
346
|
|
|
|
347
|
|
|
return isset($group['namespace']) ? $group['namespace'].'\\'.$uses : $uses; |
348
|
|
|
} |
349
|
|
|
|
350
|
|
|
/** |
351
|
|
|
* Create a new Route object. |
352
|
|
|
* |
353
|
|
|
* @param array|string $method |
354
|
|
|
* @param string $uri |
355
|
|
|
* @param mixed $action |
356
|
|
|
* |
357
|
|
|
* @return \Syscodes\Routing\Route |
358
|
|
|
*/ |
359
|
|
|
public function newRoute($method, $uri, $action) |
360
|
|
|
{ |
361
|
|
|
return take(new Route($method, $uri, $action)) |
|
|
|
|
362
|
|
|
->setContainer($this->container); |
|
|
|
|
363
|
|
|
} |
364
|
|
|
|
365
|
|
|
/** |
366
|
|
|
* Determine if the router currently has a group stack. |
367
|
|
|
* |
368
|
|
|
* @return bool |
369
|
|
|
*/ |
370
|
|
|
public function hasGroupStack() |
371
|
|
|
{ |
372
|
|
|
return ! empty($this->groupStack); |
373
|
|
|
} |
374
|
|
|
|
375
|
|
|
/** |
376
|
|
|
* Merge the group stack with the controller action. |
377
|
|
|
* |
378
|
|
|
* @param \Syscpde\Routing\Route $route |
|
|
|
|
379
|
|
|
* |
380
|
|
|
* @return void |
381
|
|
|
*/ |
382
|
|
|
protected function mergeGroupAttributesIntoRoute($route) |
383
|
|
|
{ |
384
|
|
|
$action = static::mergeGroup($route->getAction(), end($this->groupStack)); |
|
|
|
|
385
|
|
|
|
386
|
|
|
$route->setAction($action); |
387
|
|
|
} |
388
|
|
|
|
389
|
|
|
/** |
390
|
|
|
* Add the necessary where clauses to the route based on its initial registration. |
391
|
|
|
* |
392
|
|
|
* @param \Syscodes\Routing\Route $route |
393
|
|
|
* |
394
|
|
|
* @return \Syscodes\Routing\Route |
395
|
|
|
*/ |
396
|
|
|
protected function addWhereClausesToRoute($route) |
397
|
|
|
{ |
398
|
|
|
return $route->where(array_merge( |
399
|
|
|
$this->patterns, Arr::get($route->getAction(), 'where', []) |
400
|
|
|
)); |
401
|
|
|
} |
402
|
|
|
|
403
|
|
|
/** |
404
|
|
|
* Add a prefix to the route URI. |
405
|
|
|
* |
406
|
|
|
* @param string $uri |
407
|
|
|
* |
408
|
|
|
* @return string |
409
|
|
|
*/ |
410
|
|
|
protected function prefix($uri) |
411
|
|
|
{ |
412
|
|
|
$uri = is_null($uri) ? '' : trim($uri, '/').'/'; |
|
|
|
|
413
|
|
|
|
414
|
|
|
$uri = filter_var($uri, FILTER_SANITIZE_STRING); |
415
|
|
|
|
416
|
|
|
// While we want to add a route within a group of '/', |
417
|
|
|
// it doens't work with matching, so remove them... |
418
|
|
|
if ($uri != '/') { |
419
|
|
|
$uri = ltrim($uri, '/'); |
420
|
|
|
} |
421
|
|
|
|
422
|
|
|
return trim(trim($this->getGroupPrefix(), '/').'/'.trim($uri, '/'), '/') ?: '/'; |
423
|
|
|
} |
424
|
|
|
|
425
|
|
|
/** |
426
|
|
|
* Set a global where pattern on all routes. |
427
|
|
|
* |
428
|
|
|
* @param string $name |
429
|
|
|
* @param string $pattern |
430
|
|
|
* |
431
|
|
|
* @return void |
432
|
|
|
*/ |
433
|
|
|
public function pattern($name, $pattern) |
434
|
|
|
{ |
435
|
|
|
return $this->patterns[$name] = $pattern; |
|
|
|
|
436
|
|
|
} |
437
|
|
|
|
438
|
|
|
/** |
439
|
|
|
* Set a group of global where patterns on all routes. |
440
|
|
|
* |
441
|
|
|
* @param array $patterns |
442
|
|
|
* |
443
|
|
|
* @return void |
444
|
|
|
*/ |
445
|
|
|
public function patterns($patterns) |
446
|
|
|
{ |
447
|
|
|
foreach ($patterns as $key => $pattern) { |
448
|
|
|
$this->patterns[$key] = $pattern; |
449
|
|
|
} |
450
|
|
|
} |
451
|
|
|
|
452
|
|
|
/** |
453
|
|
|
* Get a Resource instance. |
454
|
|
|
* |
455
|
|
|
* @return \Syscodes\Routing\ResourceRegister |
456
|
|
|
*/ |
457
|
|
|
public function getResource() |
458
|
|
|
{ |
459
|
|
|
if (isset($this->resources)) { |
460
|
|
|
return $this->resources; |
461
|
|
|
} |
462
|
|
|
|
463
|
|
|
return $this->resources = new ResourceRegister($this); |
464
|
|
|
} |
465
|
|
|
|
466
|
|
|
/** |
467
|
|
|
* Dispatches the given url and call the method that belongs to the route. |
468
|
|
|
* |
469
|
|
|
* @param \Syscodes\Http\Request $request |
470
|
|
|
* |
471
|
|
|
* @return mixed |
472
|
|
|
*/ |
473
|
|
|
public function dispatch(Request $request) |
474
|
|
|
{ |
475
|
|
|
return $this->resolve($request); |
476
|
|
|
} |
477
|
|
|
|
478
|
|
|
/** |
479
|
|
|
* Gather the middleware for the given route. |
480
|
|
|
* |
481
|
|
|
* @param \Syscodes\Routing\Route $route |
482
|
|
|
* |
483
|
|
|
* @return array |
484
|
|
|
*/ |
485
|
|
|
public function gatherRouteMiddleware(Route $route) |
486
|
|
|
{ |
487
|
|
|
$middleware = array_map(function ($name) { |
488
|
|
|
return MiddlewareResolver::resolve($name, $this->middleware, $this->middlewareGroups); |
489
|
|
|
}, $route->gatherMiddleware()); |
490
|
|
|
|
491
|
|
|
return Arr::flatten($middleware); |
492
|
|
|
} |
493
|
|
|
|
494
|
|
|
/** |
495
|
|
|
* Get all of the defined middleware |
496
|
|
|
* |
497
|
|
|
* @return array |
498
|
|
|
*/ |
499
|
|
|
public function getMiddleware() |
500
|
|
|
{ |
501
|
|
|
return $this->middleware; |
502
|
|
|
} |
503
|
|
|
|
504
|
|
|
/** |
505
|
|
|
* Register a short-hand name for a middleware. |
506
|
|
|
* |
507
|
|
|
* @param string $name |
508
|
|
|
* @param string $class |
509
|
|
|
* |
510
|
|
|
* @return $this |
511
|
|
|
*/ |
512
|
|
|
public function aliasMiddleware($name, $class) |
513
|
|
|
{ |
514
|
|
|
$this->middleware[$name] = $class; |
515
|
|
|
|
516
|
|
|
return $this; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
/** |
520
|
|
|
* Register a group of middleware. |
521
|
|
|
* |
522
|
|
|
* @param string $name |
523
|
|
|
* @param array $middleware |
524
|
|
|
* |
525
|
|
|
* @return $this |
526
|
|
|
*/ |
527
|
|
|
public function middlewareGroup($name, array $middleware) |
528
|
|
|
{ |
529
|
|
|
$this->middlewareGroups[$name] = $middleware; |
530
|
|
|
|
531
|
|
|
return $this; |
532
|
|
|
} |
533
|
|
|
|
534
|
|
|
/** |
535
|
|
|
* Check if a route with the given name exists. |
536
|
|
|
* |
537
|
|
|
* @param string $name |
538
|
|
|
* |
539
|
|
|
* @return bool |
540
|
|
|
*/ |
541
|
|
|
public function has($name) |
542
|
|
|
{ |
543
|
|
|
$names = is_array($name) ? $name : func_get_args(); |
544
|
|
|
|
545
|
|
|
foreach ($names as $value) { |
546
|
|
|
if ( ! $this->routes->hasNamedRoute($value)) { |
547
|
|
|
return false; |
548
|
|
|
} |
549
|
|
|
} |
550
|
|
|
|
551
|
|
|
return true; |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
/** |
555
|
|
|
* Get the currently dispatched route instance. |
556
|
|
|
* |
557
|
|
|
* @return \Syscodes\Routing\Route|null |
558
|
|
|
*/ |
559
|
|
|
public function current() |
560
|
|
|
{ |
561
|
|
|
return $this->current; |
562
|
|
|
} |
563
|
|
|
|
564
|
|
|
/** |
565
|
|
|
* Determine if the current route matches a pattern. |
566
|
|
|
* |
567
|
|
|
* @param mixed ...$patterns |
568
|
|
|
* |
569
|
|
|
* @return bool |
570
|
|
|
*/ |
571
|
|
|
public function is(...$patterns) |
572
|
|
|
{ |
573
|
|
|
return $this->currentRouteNamed(...$patterns); |
574
|
|
|
} |
575
|
|
|
|
576
|
|
|
/** |
577
|
|
|
* Determine if the current route matches a pattern. |
578
|
|
|
* |
579
|
|
|
* @param mixed ...$patterns |
580
|
|
|
* |
581
|
|
|
* @return bool |
582
|
|
|
*/ |
583
|
|
|
public function currentRouteNamed(...$patterns) |
584
|
|
|
{ |
585
|
|
|
return $this->current() && $this->current()->named(...$patterns); |
586
|
|
|
} |
587
|
|
|
|
588
|
|
|
/** |
589
|
|
|
* Register an array of resource controllers. |
590
|
|
|
* |
591
|
|
|
* @param array $resources |
592
|
|
|
* @param array $options |
593
|
|
|
* |
594
|
|
|
* @return void |
595
|
|
|
*/ |
596
|
|
|
public function resources(array $resources, array $options = []) |
597
|
|
|
{ |
598
|
|
|
foreach ($resources as $name => $controller) { |
599
|
|
|
$this->resource($name, $controller, $options); |
600
|
|
|
} |
601
|
|
|
} |
602
|
|
|
|
603
|
|
|
/** |
604
|
|
|
* Route a resource to a controller. |
605
|
|
|
* |
606
|
|
|
* @param string $name |
607
|
|
|
* @param string $controller |
608
|
|
|
* @param array $options |
609
|
|
|
* |
610
|
|
|
* @return \Syscodes\Routing\AwaitingResourceRegistration |
611
|
|
|
*/ |
612
|
|
|
public function resource($name, $controller, array $options = []) |
613
|
|
|
{ |
614
|
|
|
if ($this->container) { |
615
|
|
|
$register = $this->container->make(ResourceRegister::class); |
616
|
|
|
} else { |
617
|
|
|
$register = new ResourceRegister($this); |
618
|
|
|
} |
619
|
|
|
|
620
|
|
|
return new AwaitingResourceRegistration( |
621
|
|
|
$register, $name, $controller, $options |
622
|
|
|
); |
623
|
|
|
} |
624
|
|
|
|
625
|
|
|
/** |
626
|
|
|
* Get the route collection. |
627
|
|
|
* |
628
|
|
|
* @return array |
629
|
|
|
*/ |
630
|
|
|
public function getRoutes() |
631
|
|
|
{ |
632
|
|
|
return $this->routes; |
|
|
|
|
633
|
|
|
} |
634
|
|
|
|
635
|
|
|
/** |
636
|
|
|
* Get or set the verbs used in the resource URIs. |
637
|
|
|
* |
638
|
|
|
* @param array $verbs |
639
|
|
|
* |
640
|
|
|
* @return array|null |
641
|
|
|
*/ |
642
|
|
|
public function resourceVerbs(array $verbs = []) |
643
|
|
|
{ |
644
|
|
|
ResourceRegister::verbs($verbs); |
645
|
|
|
} |
646
|
|
|
|
647
|
|
|
/** |
648
|
|
|
* Register a custom macro. |
649
|
|
|
* |
650
|
|
|
* @param string $name |
651
|
|
|
* @param callable $callback |
652
|
|
|
* |
653
|
|
|
* @return void |
654
|
|
|
*/ |
655
|
|
|
public function macro($name, callable $callback) |
656
|
|
|
{ |
657
|
|
|
$this->macros[$name] = $callback; |
658
|
|
|
} |
659
|
|
|
|
660
|
|
|
/** |
661
|
|
|
* Checks if macro is registered. |
662
|
|
|
* |
663
|
|
|
* @param string $name |
664
|
|
|
* |
665
|
|
|
* @return boolean |
666
|
|
|
*/ |
667
|
|
|
public function hasMacro($name) |
668
|
|
|
{ |
669
|
|
|
return isset($this->macros[$name]); |
670
|
|
|
} |
671
|
|
|
|
672
|
|
|
/** |
673
|
|
|
* Dynamically handle calls into the router instance. |
674
|
|
|
* |
675
|
|
|
* @param string $method |
676
|
|
|
* @param array $parameters |
677
|
|
|
* |
678
|
|
|
* @return mixed |
679
|
|
|
*/ |
680
|
|
|
public function __call($method, $parameters) |
681
|
|
|
{ |
682
|
|
|
if (isset($this->macros[$method])) { |
683
|
|
|
$callback = $this->macros[$method]; |
684
|
|
|
|
685
|
|
|
return call_user_func_array($callback, $parameters); |
686
|
|
|
} |
687
|
|
|
|
688
|
|
|
return (new RouteRegister($this))->attribute($method, $parameters[0]); |
689
|
|
|
} |
690
|
|
|
} |