Passed
Push — master ( 379f19...9ce0c5 )
by
unknown
06:34
created

HasMiddlewareTrait::add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
1
<?php
2
3
namespace CarbonFramework\Middleware;
4
5
use Closure;
6
use Exception;
7
use Psr\Http\Message\ResponseInterface;
8
9
/**
10
 * Allow objects to have middleware
11
 */
12
trait HasMiddlewareTrait {
13
	/**
14
	 * Array of all registered middleware
15
	 *
16
	 * @var \CarbonFramework\Middleware\MiddlewareInterface[]
17
	 */
18
	protected $middleware = [];
19
20
	/**
21
	 * Check if the passed entity is a valid middleware
22
	 *
23
	 * @param  mixed   $middleware
24
	 * @return boolean
25
	 */
26
	protected function isMiddleware( $middleware ) {
27
		if ( is_callable( $middleware ) ) {
28
			return true;
29
		}
30
31
		if ( is_a( $middleware, MiddlewareInterface::class, true ) ) {
0 ignored issues
show
Unused Code introduced by
This if statement, and the following return statement can be replaced with return is_a($middleware,...nterface::class, true);.
Loading history...
32
			return true;
33
		}
34
35
		return false;
36
	}
37
38
	/**
39
	 * Get registered middleware
40
	 *
41
	 * @return \CarbonFramework\Middleware\MiddlewareInterface[]
42
	 */
43
	public function getMiddleware() {
44
		return $this->middleware;
45
	}
46
47
	/**
48
	 * Add middleware
49
	 *
50
	 * @param  string|callable|\CarbonFramework\Middleware\MiddlewareInterface|array $middleware
51
	 * @return object                                                                $this
1 ignored issue
show
Documentation introduced by
Should the return type not be HasMiddlewareTrait?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
52
	 */
53
	public function addMiddleware( $middleware ) {
54
		$middleware = is_array( $middleware ) ? $middleware : [$middleware];
55
56
		foreach ( $middleware as $item ) {
57
			if ( ! $this->isMiddleware( $item ) ) {
58
				throw new Exception( 'Passed middleware must be a callable or the name of a class which implements the ' . MiddlewareInterface::class . ' interface.' );
59
			}
60
		}
61
62
		$this->middleware = array_merge( $this->getMiddleware(), $middleware );
0 ignored issues
show
Documentation Bug introduced by
It seems like array_merge($this->getMiddleware(), $middleware) of type array is incompatible with the declared type array<integer,object<Car...e\MiddlewareInterface>> of property $middleware.

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...
63
		return $this;
64
	}
65
66
	/**
67
	 * Alias for addMiddleware
68
	 *
69
	 * @param  string|callable|\CarbonFramework\Middleware\middlewareInterface|array $middleware
70
	 * @return object                                                                $this
1 ignored issue
show
Documentation introduced by
Should the return type not be HasMiddlewareTrait?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
71
	 */
72
	public function add( $middleware ) {
73
		return $this->addMiddleware( $middleware );
74
	}
75
76
	/**
77
	 * Execute an array of middleware recursively (last in, first out)
78
	 *
79
	 * @param  \CarbonFramework\Middleware\MiddlewareInterface[] $middleware
80
	 * @param  \CarbonFramework\Request                          $request
81
	 * @param  Closure                                           $next
82
	 * @return ResponseInterface
83
	 */
84
	public function executeMiddleware( $middleware, $request, Closure $next ) {
85
		$top_middleware = array_pop( $middleware );
86
87
		if ( $top_middleware === null ) {
88
			return $next( $request );
89
		}
90
91
		$top_middleware_next = function( $request ) use ( $middleware, $next ) {
92
			return $this->executeMiddleware( $middleware, $request, $next );
93
		};
94
95
		if ( is_callable( $top_middleware ) ) {
96
			return call_user_func( $top_middleware, $request, $top_middleware_next );
97
		}
98
99
		$instance = new $top_middleware();
100
		return $instance->handle( $request, $top_middleware_next );
101
	}
102
}
103