Route   F
last analyzed

Complexity

Total Complexity 77

Size/Duplication

Total Lines 733
Duplicated Lines 0 %

Importance

Changes 6
Bugs 0 Features 0
Metric Value
eloc 152
c 6
b 0
f 0
dl 0
loc 733
rs 2.24
wmc 77

43 Methods

Rating   Name   Duplication   Size   Complexity  
A runResolverController() 0 3 1
A runResolverCallable() 0 6 1
A __construct() 0 12 2
A getAction() 0 3 1
A getRoute() 0 3 1
A domain() 0 9 2
A getController() 0 9 2
A controllerDispatcher() 0 3 1
A parseAction() 0 7 5
A isControllerAction() 0 3 1
A getName() 0 3 1
A getArguments() 0 3 1
A parseControllerCallback() 0 3 1
A getMethod() 0 3 1
A getControllerMethod() 0 3 1
A getDomain() 0 5 2
A runResolver() 0 12 4
A setParameter() 0 5 1
A setDefaults() 0 5 1
A prefix() 0 9 3
A middleware() 0 16 3
A parameter() 0 3 1
A httpsOnly() 0 3 1
A getMiddleware() 0 3 1
A secure() 0 3 1
A parseMethod() 0 13 5
A __get() 0 3 1
A name() 0 5 2
A named() 0 13 4
A setContainer() 0 5 1
A compileParamNames() 0 7 1
A httpOnly() 0 3 1
A parseRoutePath() 0 22 4
A bind() 0 5 1
A gatherMiddleware() 0 12 2
A setAction() 0 9 2
A controllerMiddleware() 0 9 2
A parseRoute() 0 9 2
A parameters() 0 7 2
A parameterNames() 0 7 2
A defaults() 0 5 1
A parametersWithouNulls() 0 4 1
A where() 0 9 3

How to fix   Complexity   

Complex Class

Complex classes like Route often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Route, and based on these observations, apply Extract Interface, too.

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 LogicException;
27
use ReflectionFunction;
28
use Syscodes\Support\Str;
29
use Syscodes\Http\Request;
30
use InvalidArgumentException;
31
use Syscodes\Collections\Arr;
32
use Syscodes\Container\Container;
33
use Syscodes\Controller\ControllerDispatcher;
34
use Syscodes\Http\Exceptions\HttpResponseException;
35
36
/**
37
 * A Route describes a route and its parameters.
38
 * 
39
 * @author Alexander Campo <[email protected]>
40
 */
41
class Route 
42
{
43
	use Concerns\RouteCondition,
0 ignored issues
show
Bug introduced by
The trait Syscodes\Routing\Concerns\RouteDependencyResolver requires the property $name which is not provided by Syscodes\Routing\Route.
Loading history...
44
	    Concerns\RouteDependencyResolver;
45
	
46
	/**
47
	 * Action that the route will use when called.
48
	 *
49
	 * @var \Closure|string|array $action
50
	 */
51
	public $action;
52
53
	/**
54
	 * The computed gathered middleware.
55
	 * 
56
	 * @var array|null $computedMiddleware
57
	 */
58
	public $computedMiddleware;
59
60
	/**
61
	 * The container instance used by the route.
62
	 * 
63
	 * @var \Syscodes\Container\Container $container
64
	 */
65
	protected $container;
66
67
	/**
68
	 * The controller instance.
69
	 * 
70
	 * @var string $controller
71
	 */
72
	public $controller;
73
74
	/**
75
	 * The default values for the route.
76
	 * 
77
	 * @var array $defaults
78
	 */
79
	public $defaults = [];
80
81
	/**
82
	 * Variable of HTTP method.
83
	 *  
84
	 * @var array|string $method
85
	 */
86
	public $method;
87
88
	/**
89
	 * The array of matched parameters.
90
	 * 
91
	 * @var array $parameters
92
	 */
93
	public $parameters = [];
94
95
	/**
96
	 * The parameter names for the route.
97
	 * 
98
	 * @var string|null $parameterNames
99
	 */
100
	public $parameterNames;
101
102
	/**
103
	* Patterns that should be replaced.
104
	*
105
	* @var array $patterns 
106
	*/
107
	public $patterns = [
108
		'~/~'                    =>  '\/',               // Slash
109
		'~{an:[^\/{}]+}~'        => '([0-9a-zA-Z]++)',   // Placeholder accepts alphabetic and numeric chars
110
		'~{n:[^\/{}]+}~'         => '([0-9]++)',         // Placeholder accepts only numeric
111
		'~{a:[^\/{}]+}~'         => '([a-zA-Z]++)',      // Placeholder accepts only alphabetic chars
112
		'~{w:[^\/{}]+}~'         => '([0-9a-zA-Z-_]++)', // Placeholder accepts alphanumeric and underscore
113
		'~{\*:[^\/{}]+}~'        => '(.++)',             // Placeholder match rest of url
114
		'~(\\\/)?{\?:[^\/{}]+}~' => '\/?([^\/]*)',		 // Optional placeholder
115
		'~{[^\/{}]+}~'           => '([^\/]++)'			 // Normal placeholder
116
	];
117
118
	/**
119
	 * The URI pattern the route responds to.
120
	 *
121
	 * @var array $uri
122
	 */
123
	public $uri = [];
124
125
	/**
126
	 * Contains the arguments of the current route.
127
	 *
128
	 * @var array $where
129
	 */
130
	public $wheres = [];
131
132
	/**
133
	 * Constructor. Initialize route.
134
	 *
135
	 * @param  array|string|null  $method  
136
	 * @param  string|null  $uri  
137
	 * @param  \Closure|string|null  $action  
138
	 *
139
	 * @return void
140
	 */
141
	public function __construct($method = null, $uri = null, $action = null)
142
	{
143
		$this->uri = $uri;
0 ignored issues
show
Documentation Bug introduced by
It seems like $uri can also be of type string. However, the property $uri is declared as type array. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
144
145
		// Set the method
146
		$this->method = $this->parseMethod($method);
0 ignored issues
show
Bug introduced by
It seems like $method can also be of type string; however, parameter $method of Syscodes\Routing\Route::parseMethod() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

146
		$this->method = $this->parseMethod(/** @scrutinizer ignore-type */ $method);
Loading history...
147
148
		// Set the action
149
		$this->action = Arr::except($this->parseAction($action), ['prefix']);
0 ignored issues
show
Bug introduced by
$this->parseAction($action) of type Syscodes\Routing\Route is incompatible with the type array expected by parameter $array of Syscodes\Collections\Arr::except(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

149
		$this->action = Arr::except(/** @scrutinizer ignore-type */ $this->parseAction($action), ['prefix']);
Loading history...
150
151
		if (is_null($prefix = Arr::get($this->action, 'prefix'))) {
152
			$this->prefix($prefix);
153
		}
154
	}
155
156
	// Getters
157
158
	/**
159
	 * Get the action of the current route.
160
	 *
161
	 * @return \Closure|string|array
162
	 */
163
	public function getAction()
164
	{
165
		return $this->action;
166
	}
167
168
	/**
169
	 * Get the arguments of the current route.
170
	 *
171
	 * @return array
172
	 */
173
	public function getArguments()
174
	{
175
		return $this->wheres;
176
	}
177
178
	/**
179
	 * Get the controller instance for the route.
180
	 * 
181
	 * @return mixed
182
	 */
183
	public function getController()
184
	{
185
		if ( ! $this->controller) {
186
			$class = $this->parseControllerCallback()[0];
187
 
188
			$this->controller = $this->container->make(ltrim($class, '\\'));
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->container->make(ltrim($class, '\')) of type object is incompatible with the declared type string of property $controller.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
189
		}
190
191
		return $this->controller;
192
	}
193
194
	/**
195
	 * Get the controller method used for the route.
196
	 * 
197
	 * @return string
198
	 */
199
	public function getControllerMethod()
200
	{
201
		return $this->parseControllerCallback()[1];
202
	}
203
204
	/**
205
	 * Get the request method of the current route.
206
	 *
207
	 * @return array|string
208
	 */
209
	public function getMethod()
210
	{
211
		return $this->method;
212
	}
213
214
	/**
215
	 * Get the url of the current route.
216
	 *
217
	 * @return string
218
	 */
219
	public function getName()
220
	{
221
		return $this->action['as'] ?? null;
222
	}
223
224
	/**
225
	 * Get the url of the current route.
226
	 *
227
	 * @return array
228
	 */
229
	public function getRoute()
230
	{
231
		return $this->uri;
232
	}
233
234
	/**
235
	 * Get or set the domain for the route.
236
	 * 
237
	 * @param  string|null  $domain  
238
	 * 
239
	 * @return $this
240
	 */
241
	public function domain($domain = null)
242
	{
243
		if (is_null($domain)) {
244
			return $this->getDomain();
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->getDomain() also could return the type string which is incompatible with the documented return type Syscodes\Routing\Route.
Loading history...
245
		}
246
247
		$this->action['domain'] = $this->parseRoute($domain);
248
249
		return $this;
250
	}
251
252
	/**
253
	 * Get the domain defined for the route.
254
	 * 
255
	 * @return string|null
256
	 */
257
	public function getDomain()
258
	{
259
		return isset($this->action['domain'])
260
				? str_replace(['http://', 'https://'], '', $this->action['domain'])
261
				: null;
262
	}
263
264
	/**
265
	 * Parse the controller.
266
	 * 
267
	 * @return array
268
	 */
269
	public function parseControllerCallback()
270
	{
271
		return Str::parseCallback($this->action['uses']);
272
	}
273
	
274
	/**
275
	 * Checks whether the route's action is a controller.
276
	 * 
277
	 * @return bool
278
	 */
279
	public function isControllerAction()
280
	{
281
		return is_string($this->action['uses']);
282
	}
283
284
	/**
285
	 * Get the dispatcher for the route's controller.
286
	 * 
287
	 * @return \Syscodes\Controller\ControllerDispatcher
288
	 */
289
	private function controllerDispatcher()
290
	{
291
		return new ControllerDispatcher($this->container);
292
	}
293
294
	// Setters
295
	
296
	/**
297
	 * Run the route action and return the response.
298
	 * 
299
	 * @return mixed
300
	 */
301
	public function runResolver()
302
	{
303
		$this->container = $this->container ?: new Container;
304
305
		try {
306
			if ($this->isControllerAction()) {
307
				return $this->runResolverController();
308
			}
309
310
			return $this->runResolverCallable();
311
		} catch (HttpResponseException $e) {
312
			return $e->getResponse();
313
		}
314
	}
315
316
	/**
317
	 * Run the route action and return the response.
318
	 *  
319
	 * @return mixed
320
	 */
321
	protected function runResolverCallable()
322
	{
323
		$callable = $this->action['uses'];
324
325
		return $callable(...array_values($this->resolveMethodDependencies(
326
			$this->parametersWithouNulls(), new ReflectionFunction($this->action['uses'])
327
		)));
328
	}
329
330
	/**
331
	 * Run the route action and return the response.
332
	 * 
333
	 * @return mixed
334
	 */
335
	protected function runResolverController()
336
	{
337
		return $this->controllerDispatcher()->dispatch($this, $this->getController(), $this->getControllerMethod());
338
	}
339
340
	/**
341
	 * Set the action.
342
	 *
343
	 * @param  \Closure|string  $action
344
	 *
345
	 * @return $this
346
	 *
347
	 * @throws \InvalidArgumentException
348
	 */
349
	public function parseAction($action)
350
	{
351
		if ( ! (is_object($action) && ($action instanceof Closure)) && ($action === null || $action === '')) {
352
			throw new InvalidArgumentException(__('route.actionClosureOrFunction'));
353
		}
354
355
		return RouteAction::parse($this->uri, $action);
0 ignored issues
show
Bug Best Practice introduced by
The expression return Syscodes\Routing\...se($this->uri, $action) returns the type array which is incompatible with the documented return type Syscodes\Routing\Route.
Loading history...
356
	}
357
358
	/**
359
	 * Set the method of the current route.
360
	 *
361
	 * @param  array  $method
362
	 *
363
	 * @return string $this
364
	 * 
365
	 * @throws \InvalidArgumentException
366
	 */
367
	public function parseMethod($method)
368
	{
369
		if ($method === null || empty($method)) {
370
			throw new InvalidArgumentException(__('route.methodNotProvided'));			
371
		}
372
373
		foreach ((array) $method as $httpMethod) {
374
			if ( ! in_array($httpMethod, ['GET', 'POST', 'PUT', 'DELETE', 'PATCH', 'OPTIONS', 'HEAD', 'ANY'])) {
375
				throw new InvalidArgumentException(__('route.methodNotAllowed'));				
376
			}
377
		}
378
379
	    return $method;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $method returns the type array which is incompatible with the documented return type string.
Loading history...
380
	}
381
382
	/**
383
	 * Set the route.
384
	 *
385
	 * @param  string|array|null  $uri
386
	 *
387
	 * @return string
388
	 *
389
	 * @throws  \InvalidArgumentException
390
	 */
391
	public function parseRoute($uri)
392
	{
393
		if ($uri === null) {
394
			throw new InvalidArgumentException(__('route.uriNotProvided'));
395
		}	
396
397
		$this->uri = $this->parseRoutePath($uri);
0 ignored issues
show
Bug introduced by
It seems like $uri can also be of type array; however, parameter $uri of Syscodes\Routing\Route::parseRoutePath() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

397
		$this->uri = $this->parseRoutePath(/** @scrutinizer ignore-type */ $uri);
Loading history...
Documentation Bug introduced by
It seems like $this->parseRoutePath($uri) of type string is incompatible with the declared type array of property $uri.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
398
399
		return $this;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this returns the type Syscodes\Routing\Route which is incompatible with the documented return type string.
Loading history...
400
	}
401
402
	/**
403
	 * Replace word patterns with regex in route uri.
404
	 * 
405
	 * @param  string  $uri
406
	 * 
407
	 * @return string
408
	 */
409
	protected function parseRoutePath($uri)
410
	{
411
		$uri = trim($uri, '\/?');
412
		$uri = trim($uri, '\/');
413
		
414
		preg_match_all('/\{([\w\:]+?)\??\}/', $uri, $matches);
415
		
416
		foreach ($matches[1] as $match) {
417
			if (strpos($match, ':') === false) {
418
				continue;
419
			}
420
			
421
			$pattern  = array_keys($this->patterns);
422
			$replace  = array_values($this->patterns);
423
			$segments = explode(':', trim($match, '{}?'));
424
			
425
			$uri = strpos($match, ':') !== false
426
					? preg_replace($pattern, $replace, $uri)
427
					: str_replace($match, '{'.$segments[0].'}', $uri);
428
		}
429
		
430
		return $uri;
431
	}
432
433
	/**
434
	 * Add a prefix to the route URI.
435
	 * 
436
	 * @param  string  $prefix
437
	 * 
438
	 * @return $this
439
	 */
440
	public function prefix($prefix)
441
	{
442
		if ( ! empty($newPrefix = trim(rtrim($prefix, '/').'/'.ltrim($this->action['prefix'] ?? '', '/'), '/'))) {
443
			$this->action['prefix'] = $newPrefix;
444
		}
445
		
446
		$uri = rtrim($prefix, '/').'/'.ltrim($this->uri, '/');
0 ignored issues
show
Bug introduced by
$this->uri of type array is incompatible with the type string expected by parameter $string of ltrim(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

446
		$uri = rtrim($prefix, '/').'/'.ltrim(/** @scrutinizer ignore-type */ $this->uri, '/');
Loading history...
447
		
448
		return $this->parseRoute($uri !== '/' ? trim($uri, '/') : $uri);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->parseRoute...trim($uri, '/') : $uri) returns the type string which is incompatible with the documented return type Syscodes\Routing\Route.
Loading history...
449
	}
450
451
	/**
452
	 * Set the action array for the route.
453
	 * 
454
	 * @param  array  $action
455
	 * 
456
	 * @return $this
457
	 */
458
	public function setAction(array $action)
459
	{
460
		$this->action = $action;
461
462
		if (isset($this->action['domain'])) {
463
			$this->domain($this->action['domain']);
464
		}
465
		
466
		return $this;
467
	}
468
469
	/**
470
	 * Set the name.
471
	 *
472
	 * @param  string  $name
473
	 *
474
	 * @return $this
475
	 */
476
	public function name($name)
477
	{
478
		$this->action['as'] = isset($this->action['as']) ? $this->action['as'].$name : $name;
479
480
		return $this;
481
	}
482
483
	/**
484
	 * Determine whether the route's name matches the given patterns.
485
	 * 
486
	 * @param  mixed  ...$patterns
487
	 * 
488
	 * @return bool
489
	 */
490
	public function named(...$patterns)
491
	{
492
		if (is_null($routeName = $this->getName())) {
0 ignored issues
show
introduced by
The condition is_null($routeName = $this->getName()) is always false.
Loading history...
493
			return false;
494
		}
495
496
		foreach ($patterns as $pattern) {
497
			if (Str::is($pattern, $routeName)) {
498
				return true;
499
			}
500
		}
501
502
		return false;
503
	}
504
505
	/**
506
	 * Set a default value for the route.
507
	 * 
508
	 * @param  string  $key
509
	 * @param  mixed   $value
510
	 * 
511
	 * @return $this
512
	 */
513
	public function defaults($key, $value)
514
	{
515
		$this->defaults[$key] = $value;
516
517
		return $this;
518
	}
519
520
	/**
521
	 * Set a default values for the route.
522
	 * 
523
	 * @param  string  $defaults
524
	 * 
525
	 * @return $this
526
	 */
527
	public function setDefaults(array $defaults)
528
	{
529
		$this->defaults = $defaults;
530
531
		return $this;
532
	}
533
534
	/**
535
	 * Set the where.
536
	 *
537
	 * @param  array|string  $name
538
	 * @param  string|null  $expression  
539
	 *
540
	 * @return $this
541
	 */
542
	public function where($name, string $expression = null)
543
	{
544
		$wheres = is_array($name) ? $name : [$name => $expression];
545
		
546
		foreach ($wheres as $name => $expression) {
0 ignored issues
show
introduced by
$name is overwriting one of the parameters of this function.
Loading history...
547
			$this->wheres[$name] = $expression;
548
		}
549
550
		return $this;
551
	}
552
553
	/**
554
	 * Bind the route to a given request for execution.
555
	 * 
556
	 * @param  \Syscodes\Http\Request  $request
557
	 * 
558
	 * @return $this
559
	 */
560
	public function bind(Request $request)
561
	{
562
		$this->parameters = (new RouteParamBinding($this))->parameters($request);
563
564
		return $this;
565
	}
566
567
	/**
568
	 * Get all of the parameter names for the route.
569
	 * 
570
	 * @return array
571
	 */
572
	public function parameterNames()
573
	{
574
		if (isset($this->parameterNames)) {
575
			return $this->parameterNames;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->parameterNames also could return the type string which is incompatible with the documented return type array.
Loading history...
576
		}
577
578
		return $this->parameterNames = $this->compileParamNames();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->compileParamNames() of type array is incompatible with the declared type null|string of property $parameterNames.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
579
	}
580
581
	/**
582
	 * Get the parameter names for the route.
583
	 * 
584
	 * @return array
585
	 */
586
	protected function compileParamNames()
587
	{
588
		preg_match_all('~[^\/\{(.*?)\}]~', $this->domain().$this->uri, $matches);
0 ignored issues
show
Bug introduced by
Are you sure $this->domain() of type Syscodes\Routing\Route can be used in concatenation? Consider adding a __toString()-method. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

588
		preg_match_all('~[^\/\{(.*?)\}]~', /** @scrutinizer ignore-type */ $this->domain().$this->uri, $matches);
Loading history...
589
590
		return array_map(function ($match) {
591
			return trim($match, '?');
592
		}, $matches[0]);
593
	}
594
595
	/**
596
	 * Get a given parameter from the route.
597
	 * 
598
	 * @param  string  $name
599
	 * @param  mixed  $default  
600
	 * 
601
	 * @return array
602
	 */
603
	public function parameter($name, $default = null)
604
	{
605
		return Arr::get($this->parameters(), $name, $default);
606
	}
607
608
	/**
609
	 * Set a parameter to the given value.
610
	 * 
611
	 * @param  string  $name
612
	 * @param  mixed  $value
613
	 * 
614
	 * @return array
615
	 */
616
	public function setParameter($name, $value)
617
	{
618
		$this->parameters();
619
620
		$this->parameters[$name] = $value;
621
	}
622
623
	/**
624
	 * Get the key / value list of parameters without null values.
625
	 * 
626
	 * @return array
627
	 */
628
	public function parametersWithouNulls()
629
	{
630
		return array_filter($this->parameters(), function ($parameter) {
631
			return ! is_null($parameter);
632
		});
633
	}
634
635
	/**
636
	 * Get the key / value list of parameters for the route.
637
	 * 
638
	 * @return array
639
	 */
640
	public function parameters()
641
	{
642
		if (isset($this->parameters)) {
643
			return $this->parameters;
644
		}
645
646
		throw new LogicException('The route is not bound.');
647
	}
648
649
	/**
650
	 * Get all middleware, including the ones from the controller.
651
	 * 
652
	 * @return array
653
	 */
654
	public function gatherMiddleware()
655
	{
656
		if ( ! is_null($this->computedMiddleware)) {
657
			return $this->computedMiddleware;
658
		}
659
660
		$this->computedMiddleware = [];
661
662
		return $this->computedMiddleware = array_unique(array_merge(
663
			$this->middleware(),
664
			$this->controllerMiddleware()
665
		), SORT_REGULAR);
666
	}
667
668
	/**
669
	 * Get or set the middlewares attached to the route.
670
	 * 
671
	 * @param  array|string|null  $middleware
672
	 * 
673
	 * @return $this|array
674
	 */
675
	public function middleware($middleware = null)
676
	{
677
		if (is_null($middleware)) {
678
			return $this->getMiddleware();
679
		}
680
681
		if (is_string($middleware)) {
682
			$middleware = func_get_args();
683
		}
684
685
		$this->action['middleware'] = array_merge(
686
			$this->getMiddleware(),
687
			$middleware
688
		);
689
690
		return $this;
691
	}
692
693
	/**
694
	 * Get the middlewares attached to the route.
695
	 * 
696
	 * @return array
697
	 */
698
	protected function getMiddleware()
699
	{
700
		return (array) ($this->action['middleware'] ?? []);
701
	}
702
703
	/**
704
	 * Get the middleware for the route's controller.
705
	 * 
706
	 * @return array
707
	 */
708
	public function controllerMiddleware()
709
	{
710
		if ( ! $this->isControllerAction()) {
711
			return [];
712
		}
713
714
		return $this->controllerDispatcher()->getMiddleware(
715
			$this->getController(),
0 ignored issues
show
Bug introduced by
$this->getController() of type string is incompatible with the type Syscodes\Controller\Controller expected by parameter $controller of Syscodes\Controller\Cont...atcher::getMiddleware(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

715
			/** @scrutinizer ignore-type */ $this->getController(),
Loading history...
716
			$this->getControllerMethod()
717
		);
718
	}
719
720
	/**
721
	 * Determine if the route only responds to HTTP requests.
722
	 * 
723
	 * @return bool
724
	 */
725
	public function httpOnly()
726
	{
727
		return in_array('http', $this->action, true);
728
	}
729
730
	/**
731
	 * Determine if the route only responds to HTTPS requests.
732
	 * 
733
	 * @return bool
734
	 */
735
	public function httpsOnly()
736
	{
737
		return $this->secure();
738
	}
739
740
	/**
741
	 * Determine if the route only responds to HTTPS requests.
742
	 * 
743
	 * @return bool
744
	 */
745
	public function secure()
746
	{
747
		return in_array('https', $this->action, true);
748
	}
749
750
	/**
751
	 * Set the container instance on the route.
752
	 * 
753
	 * @param  \Syscodes\Container\Container  $container
754
	 * 
755
	 * @return $this
756
	 */
757
	public function setContainer(Container $container)
758
	{
759
		$this->container = $container;
760
761
		return $this;
762
	}
763
764
	/**
765
	 * Dynamically access route parameters.
766
	 * 
767
	 * @param  string  $key
768
	 * 
769
	 * @return mixed
770
	 */
771
	public function __get($key)
772
	{
773
		return $this->parameter($key);
774
	}
775
}