Passed
Push — master ( 2f1c34...4bc1b6 )
by Atanas
02:03
created

HasMiddlewareTrait::add()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Obsidian\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 array
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 6
	protected function isMiddleware( $middleware ) {
27 6
		if ( is_callable( $middleware ) ) {
28 1
			return true;
29
		}
30
31 5
		return is_a( $middleware, MiddlewareInterface::class, true );
32
	}
33
34
	/**
35
	 * Get registered middleware
36
	 *
37
	 * @return array
38
	 */
39 5
	public function getMiddleware() {
40 5
		return $this->middleware;
41
	}
42
43
	/**
44
	 * Add middleware
45
	 * Accepts: a class name, an instance of a class, a callable, an array of any of the previous
46
	 *
47
	 * @param  string|callable|\Obsidian\Middleware\MiddlewareInterface|array $middleware
48
	 * @return object                                                         $this
49
	 */
50 6
	public function addMiddleware( $middleware ) {
51 6
		if ( is_callable( $middleware ) && is_array( $middleware ) ) {
52 1
			$middleware = [$middleware];
53 1
		}
54
55 6
		if ( ! is_array( $middleware ) ) {
56 4
			$middleware = [$middleware];
57 4
		}
58
59 6
		foreach ( $middleware as $item ) {
60 6
			if ( ! $this->isMiddleware( $item ) ) {
61 1
				throw new Exception( 'Passed middleware must be a callable or the name or instance of a class which implements the ' . MiddlewareInterface::class . ' interface.' );
62
			}
63 5
		}
64
65 5
		$this->middleware = array_merge( $this->getMiddleware(), $middleware );
66 5
		return $this;
67
	}
68
69
	/**
70
	 * Alias for addMiddleware
71
	 *
72
	 * @codeCoverageIgnore
73
	 * @param  string|callable|\Obsidian\Middleware\middlewareInterface|array $middleware
74
	 * @return object                                                         $this
75
	 */
76
	public function add( $middleware ) {
77
		return call_user_func_array( [$this, 'addMiddleware'], func_get_args() );
78
	}
79
80
	/**
81
	 * Execute an array of middleware recursively (last in, first out)
82
	 *
83
	 * @param  array             $middleware
84
	 * @param  \Obsidian\Request $request
85
	 * @param  Closure           $next
86
	 * @return ResponseInterface
87
	 */
88 3
	public function executeMiddleware( $middleware, $request, Closure $next ) {
89 3
		$top_middleware = array_pop( $middleware );
90
91 3
		if ( $top_middleware === null ) {
92 3
			return $next( $request );
93
		}
94
95 2
		$top_middleware_next = function( $request ) use ( $middleware, $next ) {
96 2
			return $this->executeMiddleware( $middleware, $request, $next );
97 2
		};
98
99 2
		if ( is_callable( $top_middleware ) ) {
100 2
			return call_user_func( $top_middleware, $request, $top_middleware_next );
101
		}
102
103
		$instance = new $top_middleware();
104
		return $instance->handle( $request, $top_middleware_next );
105
	}
106
}
107