Passed
Push — master ( 8efdc7...e83a93 )
by Atanas
01:32
created

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