Passed
Push — master ( 410431...1494d3 )
by Atanas
03:46
created

Router::sortMiddleware()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 1
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
namespace WPEmerge\Routing;
4
5
use Exception;
6
use Psr\Http\Message\ResponseInterface;
7
use WPEmerge\Facades\Framework;
8
use WPEmerge\Requests\Request;
9
use WPEmerge\Facades\Response;
10
11
/**
12
 * Provide routing for site requests (i.e. all non-api requests)
13
 */
14
class Router implements HasRoutesInterface {
15
	use HasRoutesTrait {
16
		addRoute as traitAddRoute;
17
	}
18
19
	/**
20
	 * Current request.
21
	 *
22
	 * @var Request
23
	 */
24
	protected $request = null;
25
26
	/**
27
	 * Global middleware.
28
	 *
29
	 * @var array
30
	 */
31
	protected $middleware = [];
32
33
	/**
34
	 * Global middleware priority.
35
	 *
36
	 * @var array
37
	 */
38
	protected $middleware_priority = [];
39
40
	/**
41
	 * Default global middleware priority.
42
	 *
43
	 * @var integer
44
	 */
45
	protected $default_middleware_priority = 0;
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $default_middleware_priority exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
46
47
	/**
48
	 * Current active route.
49
	 *
50
	 * @var RouteInterface
51
	 */
52
	protected $current_route = null;
53
54
	/**
55
	 * Constructor.
56
	 *
57
	 * @codeCoverageIgnore
58
	 * @param Request $request
59
	 * @param array   $middleware
60
	 * @param array   $middleware_priority
61
	 * @param integer $default_middleware_priority
62
	 */
63
	public function __construct( Request $request, $middleware, $middleware_priority, $default_middleware_priority ) {
0 ignored issues
show
Comprehensibility Naming introduced by
The variable name $default_middleware_priority exceeds the maximum configured length of 20.

Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.

Loading history...
64
		$this->request = $request;
65
		$this->middleware_priority = $middleware_priority;
66
		$this->default_middleware_priority = $default_middleware_priority;
67
		$this->middleware = $this->sortMiddleware( $middleware );
68
	}
69
70
	/**
71
	 * Hook into WordPress actions.
72
	 *
73
	 * @codeCoverageIgnore
74
	 * @return void
75
	 */
76
	public function boot() {
77
		add_action( 'init', [$this, 'registerRewriteRules'], 1000 );
78
		add_action( 'template_include', [$this, 'execute'], 1000 );
79
	}
80 7
81 7
	/**
82
	 * Register route rewrite rules with WordPress.
83 7
	 *
84 7
	 * @codeCoverageIgnore
85 7
	 * @return void
86
	 */
87 7
	public function registerRewriteRules() {
88 7
		$rules = apply_filters( 'wpemerge.routing.rewrite_rules', [] );
89 5
		foreach ( $rules as $rule => $rewrite_to ) {
90 5
			add_rewrite_rule( $rule, $rewrite_to, 'top' );
91
		}
92 2
	}
93
94 2
	/**
95
	 * Get middleware priority.
96
	 *
97
	 * @param  mixed   $middleware
98
	 * @return integer
99
	 */
100
	protected function getMiddlewarePriority( $middleware ) {
101
		if ( is_string( $middleware ) && isset( $this->middleware_priority[ $middleware ] ) ) {
102
			return $this->middleware_priority[ $middleware ];
103
		}
104
105
		return $this->default_middleware_priority;
106 4
	}
107 4
108
	/**
109 4
	 * Sort middleware by priority in ascending order.
110 2
	 *
111 1
	 * @param  array $middleware
112
	 * @return array
113 1
	 */
114 1
	protected function sortMiddleware( $middleware ) {
115
		usort( $middleware, function( $a, $b ) {
0 ignored issues
show
Comprehensibility introduced by
Avoid variables with short names like $a. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
Comprehensibility introduced by
Avoid variables with short names like $b. Configured minimum length is 3.

Short variable names may make your code harder to understand. Variable names should be self-descriptive. This check looks for variable names who are shorter than a configured minimum.

Loading history...
116 3
			return $this->getMiddlewarePriority( $a ) - $this->getMiddlewarePriority( $b );
117 2
		} );
118 3
119
		return $middleware;
120 3
	}
121
122
	/**
123
	 * {@inheritDoc}
124
	 */
125
	public function addRoute( $route ) {
126
		$route->addMiddleware( $this->middleware );
127
		return $this->traitAddRoute( $route );
128 1
	}
129 1
130
	/**
131
	 * Execute the first satisfied route, if any.
132
	 *
133
	 * @param  string $view
134
	 * @return string
135
	 */
136
	public function execute( $view ) {
137
		$routes = $this->getRoutes();
138 1
139 1
		foreach ( $routes as $route ) {
140 1
			if ( $route->isSatisfied( $this->request ) ) {
141
				$this->setCurrentRoute( $route );
142
				return $this->handle( $this->request, $route, $view );
143
			}
144
		}
145
146
		return $view;
147
	}
148 1
149
	/**
150
	 * Execute a route.
151
	 *
152 1
	 * @throws Exception
153
	 * @param  Request        $request
154
	 * @param  RouteInterface $route
155
	 * @param  string         $view
156
	 * @return string
157
	 */
158
	protected function handle( Request $request, RouteInterface $route, $view ) {
159
		$response = $route->handle( $request, $view );
160
161
		if ( ! $response instanceof ResponseInterface ) {
162
			if ( Framework::debugging() ) {
163
				throw new Exception( 'Response returned by controller is not valid (expectected ' . ResponseInterface::class . '; received ' . gettype( $response ) . ').' );
164
			}
165
			$response = Response::error( 500 );
166
		}
167
168
		add_filter( 'wpemerge.response', function() use ( $response ) {
169
			return $response;
170
		} );
171
172
		return WPEMERGE_DIR . DIRECTORY_SEPARATOR . 'src' . DIRECTORY_SEPARATOR . 'view.php';
173
	}
174
175
	/**
176
	 * Get the current route.
177
	 *
178
	 * @return RouteInterface
179
	 */
180
	public function getCurrentRoute() {
181
		return $this->current_route;
182
	}
183
184
	/**
185
	 * Set the current route.
186
	 *
187
	 * @param  RouteInterface
188
	 * @return void
189
	 */
190
	public function setCurrentRoute( RouteInterface $current_route ) {
191
		$this->current_route = $current_route;
192
	}
193
194
	/**
195
	 * Handle ALL requests.
196
	 *
197
	 * @param  string|Closure|null $handler
198
	 * @return RouteInterface
199
	 */
200
	public function handleAll( $handler = null ) {
201
		// match ANY request method
202
		// match ANY url
203
		// by default, use built-in WordPress controller
204
		return $this->any( '*', $handler );
205
	}
206
}
207