Passed
Push — master ( e07512...4b3fd5 )
by Atanas
03:23
created

Route::executeMiddleware()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 2
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 3
dl 0
loc 2
ccs 0
cts 0
cp 0
crap 2
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\Routing;
11
12
use Closure;
13
use WPEmerge\Exceptions\Exception;
14
use WPEmerge\Facades\Framework;
15
use WPEmerge\Facades\RouteCondition;
16
use WPEmerge\Requests\RequestInterface;
17
use WPEmerge\Routing\Conditions\ConditionInterface;
18
use WPEmerge\Routing\Conditions\InvalidRouteConditionException;
19
use WPEmerge\Routing\Conditions\UrlCondition;
20
21
/**
22
 * Represent a route
23
 */
24
class Route implements RouteInterface {
25
	/**
26
	 * Allowed methods.
27
	 *
28
	 * @var string[]
29
	 */
30
	protected $methods = [];
31
32
	/**
33
	 * Route condition.
34
	 *
35
	 * @var ConditionInterface
36
	 */
37
	protected $condition = null;
38
39
	/**
40
	 * Route pipeline.
41
	 *
42
	 * @var Pipeline
43
	 */
44
	protected $pipeline = null;
45
46
	/**
47
	 * Query filter.
48
	 *
49
	 * @var callable
50
	 */
51
	protected $query_filter = null;
52
53
	/**
54
	 * Query filter action priority.
55
	 *
56
	 * @var integer
57
	 */
58
	protected $query_filter_priority = 1000;
59
60
	/**
61
	 * Constructor.
62
	 *
63
	 * @throws Exception
64
	 * @param  string[]        $methods
65
	 * @param  mixed           $condition
66
	 * @param  string|\Closure $handler
67
	 */
68 3
	public function __construct( $methods, $condition, $handler ) {
69 3
		if ( ! $condition instanceof ConditionInterface ) {
70
			try {
71 2
				$condition = RouteCondition::make( $condition );
72 1
			} catch ( InvalidRouteConditionException $e ) {
73 1
				throw new Exception( 'Route condition is not a valid route string or condition.' );
74
			}
75
		}
76
77 2
		$this->methods = $methods;
78 2
		$this->condition = $condition;
79 2
		$this->pipeline = new Pipeline( $handler );
80 2
	}
81
82
	/**
83
	 * Get allowed methods.
84
	 *
85
	 * @return string[]
86
	 */
87 1
	public function getMethods() {
88 1
		return $this->methods;
89
	}
90
91
	/**
92
	 * Get condition.
93
	 *
94
	 * @return ConditionInterface
95
	 */
96 1
	public function getCondition() {
97 1
		return $this->condition;
98
	}
99
100
	/**
101
	 * Get pipeline.
102
	 *
103
	 * @return Pipeline
104
	 */
105 1
	public function getPipeline() {
106 1
		return $this->pipeline;
107
	}
108
109
	/**
110
	 * Get the main WordPress query vars filter, if any.
111
	 *
112
	 * @return callable|null
113
	 */
114 1
	public function getQueryFilter() {
115 1
		return $this->query_filter;
116
	}
117
118
	/**
119
	 * Set the main WordPress query vars filter and add it to the appropriate WordPress action.
120
	 *
121
	 * @param  callable|null $query_filter
122
	 * @return void
123
	 */
124 1
	public function setQueryFilter( $query_filter ) {
125 1
		$this->query_filter = $query_filter;
126 1
	}
127
128
	/**
129
	 * Add the query filter to the appropriate WordPress action.
130
	 *
131
	 * @return void
132
	 */
133 1
	public function addQueryFilter() {
134 1
		$filter = [$this, 'applyQueryFilter'];
135
136 1
		if ( ! has_action( 'request', $filter ) ) {
137 1
			add_action( 'request', $filter, $this->query_filter_priority );
138
		}
139 1
	}
140
141
	/**
142
	 * Remove the query filter from the appropriate WordPress action.
143
	 *
144
	 * @return void
145
	 */
146 1
	public function removeQueryFilter() {
147 1
		$filter = [$this, 'applyQueryFilter'];
148
149 1
		if ( has_action( 'request', $filter ) ) {
150 1
			remove_action( 'request', $filter, $this->query_filter_priority );
151
		}
152 1
	}
153
154
	/**
155
	 * Apply the query filter, if any.
156
	 *
157
	 * @throws Exception
158
	 * @param  array<string, mixed> $query_vars
159
	 * @return array<string, mixed>
160
	 */
161 4
	public function applyQueryFilter( $query_vars ) {
162 4
		$request = Framework::resolve( WPEMERGE_REQUEST_KEY );
163 4
		$condition = $this->getCondition();
164
165 4
		if ( ! is_callable( $this->getQueryFilter() ) ) {
166 1
			return $query_vars;
167
		}
168
169 3
		if ( ! $condition instanceof UrlCondition ) {
170 1
			throw new Exception(
171
				'Routes with queries can only use URL conditions. ' .
172 1
				'Is the route in a non-URL route group?'
173
			);
174
		}
175
176 2
		if ( $this->getCondition()->isSatisfied( $request ) ) {
177 1
			$arguments = $this->getCondition()->getArguments( $request );
178 1
			$query_vars = call_user_func_array( $this->getQueryFilter(), array_merge( [$query_vars], $arguments ) );
179
		}
180
181 2
		return $query_vars;
182
	}
183
184
	/**
185
	 * Set the main WordPress query vars filter.
186
	 *
187
	 * @codeCoverageIgnore
188
	 * @param  callable $query_filter
189
	 * @return self     $this
190
	 */
191
	public function query( $query_filter ) {
192
		$this->setQueryFilter( $query_filter );
193
		$this->addQueryFilter();
194
		return $this;
195
	}
196
197
	/**
198
	 * {@inheritDoc}
199
	 */
200 2
	public function isSatisfied( RequestInterface $request ) {
201 2
		if ( ! in_array( $request->getMethod(), $this->methods ) ) {
202 1
			return false;
203
		}
204 2
		return $this->condition->isSatisfied( $request );
205
	}
206
207
	/**
208
	 * {@inheritDoc}
209
	 */
210 1
	public function getArguments( RequestInterface $request ) {
211 1
		return $this->getCondition()->getArguments( $request );
212
	}
213
214
	/**
215
	 * {@inheritDoc}
216
	 */
217 1
	public function handle( RequestInterface $request, $view ) {
218 1
		$arguments = array_merge( [$request, $view], $this->condition->getArguments( $request ) );
219
220 1
		return $this->getPipeline()->run( $request, $arguments );
221
	}
222
223
	/**
224
	 * @codeCoverageIgnore
225
	 * {@inheritDoc}
226
	 */
227
	public function getMiddleware() {
228
		return $this->getPipeline()->getMiddleware();
229
	}
230
231
	/**
232
	 * {@inheritDoc}
233
	 * @codeCoverageIgnore
234
	 */
235
	public function setMiddleware( $middleware ) {
236
		$this->getPipeline()->setMiddleware( $middleware );
237
	}
238
239
	/**
240
	 * @codeCoverageIgnore
241
	 * @throws Exception
242
	 * {@inheritDoc}
243
	 */
244
	public function addMiddleware( $middleware ) {
245
		$this->getPipeline()->addMiddleware( $middleware );
246
247
		return $this;
248
	}
249
250
	/**
251
	 * @codeCoverageIgnore
252
	 * {@inheritDoc}
253
	 */
254
	public function add( $middleware ) {
255
		$this->getPipeline()->add( $middleware );
256
257
		return $this;
258
	}
259
260
	/**
261
	 * @codeCoverageIgnore
262
	 * {@inheritDoc}
263
	 */
264
	public function executeMiddleware( $middleware, RequestInterface $request, Closure $next ) {
265
		return $this->getPipeline()->executeMiddleware( $middleware, $request, $next );
266
	}
267
}
268