Passed
Push — master ( a216c7...6c8b41 )
by Atanas
07:11 queued 35s
created

HasMiddlewareTrait::setMiddleware()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 2
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * @package   WPEmerge
4
 * @author    Atanas Angelov <[email protected]>
5
 * @copyright 2018 Atanas Angelov
6
 * @license   https://www.gnu.org/licenses/gpl-2.0.html GPL-2.0
7
 * @link      https://wpemerge.com/
8
 */
9
10
namespace WPEmerge\Middleware;
11
12
use Closure;
13
use WPEmerge\Exceptions\Exception;
14
use WPEmerge\Facades\Router;
15
use WPEmerge\Helpers\MixedType;
16
use WPEmerge\Requests\RequestInterface;
17
18
/**
19
 * Allow objects to have middleware
20
 */
21
trait HasMiddlewareTrait {
22
	/**
23
	 * Array of all registered middleware.
24
	 *
25
	 * @var array
26
	 */
27
	protected $middleware = [];
28
29
	/**
30
	 * Check if the passed entity is a valid middleware.
31
	 *
32
	 * @param  mixed   $middleware
33
	 * @return boolean
34
	 */
35 7
	protected function isMiddleware( $middleware ) {
36
		return (
37 7
			$middleware instanceof Closure
38
			||
39 7
			is_a( $middleware, MiddlewareInterface::class, true )
40
		);
41
	}
42
43
	/**
44
	 * Get registered middleware.
45
	 *
46
	 * @return array
47
	 */
48 5
	public function getMiddleware() {
49 5
		return $this->middleware;
50
	}
51
52
	/**
53
	 * Set registered middleware.
54
	 *
55
	 * @param  array $middleware
56
	 * @return void
57
	 */
58 1
	public function setMiddleware( $middleware ) {
59 1
		$this->middleware = $middleware;
60 1
	}
61
62
	/**
63
	 * Add middleware.
64
	 * Accepts: a class name, an instance of a class, a Closure or an array of any of the previous.
65
	 *
66
	 * @throws Exception
67
	 * @param  string|\Closure|\WPEmerge\Middleware\MiddlewareInterface|array $middleware
68
	 * @return static                                                         $this
69
	 */
70 7
	public function addMiddleware( $middleware ) {
71 7
		$middleware = MixedType::toArray( $middleware );
72
73 7
		foreach ( $middleware as $item ) {
74 7
			if ( ! $this->isMiddleware( $item ) ) {
75 2
				throw new Exception(
76
					'Passed middleware must be a closure or the name or instance of a class which ' .
77 7
					'implements the ' . MiddlewareInterface::class . ' interface.'
78
				);
79
			}
80
		}
81
82 5
		$this->middleware = Router::sortMiddleware( array_merge( $this->getMiddleware(), $middleware ) );
83 5
		return $this;
84
	}
85
86
	/**
87
	 * Alias for addMiddleware.
88
	 *
89
	 * @codeCoverageIgnore
90
	 * @param  string|\Closure|\WPEmerge\Middleware\MiddlewareInterface|array $middleware
91
	 * @return static                                                         $this
92
	 */
93
	public function add( $middleware ) {
94
		return call_user_func_array( [$this, 'addMiddleware'], func_get_args() );
95
	}
96
97
	/**
98
	 * Execute an array of middleware recursively (last in, first out).
99
	 *
100
	 * @param  array                               $middleware
101
	 * @param  RequestInterface                    $request
102
	 * @param  Closure                             $next
103
	 * @return \Psr\Http\Message\ResponseInterface
104
	 */
105 5
	public function executeMiddleware( $middleware, RequestInterface $request, Closure $next ) {
106 5
		$top_middleware = array_shift( $middleware );
107
108 5
		if ( $top_middleware === null ) {
109 5
			return $next( $request );
110
		}
111
112 4
		$top_middleware_next = function ( $request ) use ( $middleware, $next ) {
113 4
			return $this->executeMiddleware( $middleware, $request, $next );
114 4
		};
115
116
		return MixedType::value( $top_middleware, [$request, $top_middleware_next], 'handle' );
117
	}
118
}
119