Issues (3)

src/Router.php (1 issue)

Labels
Severity
1
<?php
2
3
/**
4
 * This file is part of the miBadger package.
5
 *
6
 * @author Michael Webbers <[email protected]>
7
 * @license http://opensource.org/licenses/Apache-2.0 Apache v2 License
8
 */
9
10
namespace miBadger\Router;
11
12
use miBadger\Http\ServerRequest;
13
use miBadger\Http\ServerResponse;
14
use miBadger\Http\ServerResponseException;
15
16
/**
17
 * The router class.
18
 *
19
 * @since 1.0.0
20
 */
21
class Router implements \IteratorAggregate
22
{
23
	/** @var string The base path. */
24
	private $basePath;
25
26
	/** @var array The routes. */
27
	private $routes;
28
29
	/**
30
	 * Construct a Router object with the given routers.
31
	 *
32
	 * @param string $basePath = ''
33
	 */
34 20
	public function __construct($basePath = '')
35
	{
36 20
		$this->basePath = $basePath;
37 20
		$this->routes = [];
38 20
	}
39
40
	/**
41
	 * Returns the base path.
42
	 *
43
	 * @return string the base path.
44
	 */
45 2
	public function getBasePath()
46
	{
47 2
		return $this->basePath;
48
	}
49
50
	/**
51
	 * Set the base path.
52
	 *
53
	 * @param string $basePath
54
	 * @return $this
55
	 */
56 2
	public function setBasePath($basePath)
57
	{
58 2
		$this->basePath = $basePath;
59
60 2
		return $this;
61
	}
62
63
	/**
64
	 * {@inheritdoc}
65
	 */
66 1
	public function getIterator()
67
	{
68 1
		return new \RecursiveArrayIterator($this->routes);
69
	}
70
71
	/**
72
	 * Returns the number of key-value mappings in the router map.
73
	 *
74
	 * @return int the number of key-value mappings in the router map.
75
	 */
76 1
	public function count()
77
	{
78 1
		$result = 0;
79
80 1
		foreach ($this->routes as $routes) {
81 1
			$result += count($routes);
82
		}
83
84 1
		return $result;
85
	}
86
87
	/**
88
	 * Returns true if the router map contains no key-value mappings.
89
	 *
90
	 * @return bool true if the router map contains no key-value mappings.
91
	 */
92 2
	public function isEmpty()
93
	{
94 2
		return empty($this->routes);
95
	}
96
97
	/**
98
	 * Returns true if the router map contains a mapping for the specified method & route.
99
	 *
100
	 * @param string $method
101
	 * @param string $route
102
	 * @return bool true if the static route map contains a mapping for the specified method & route.
103
	 */
104 2
	public function contains($method, $route)
105
	{
106 2
		return $this->get($method, $route) !== null;
107
	}
108
109
	/**
110
	 * Returns true if the router map maps one or more routes to the specified callable.
111
	 *
112
	 * @param callable $callable
113
	 * @return bool true if the router map maps one or more routes to the specified callable.
114
	 */
115 1
	public function containsCallable(callable $callable)
116
	{
117 1
		foreach ($this->routes as $method) {
118 1
			foreach ($method as $entry)
119
			{
120 1
				if ($entry->callable === $callable) {
121 1
					return true;
122
				}
123
			}
124
		}
125
126 1
		return false;
127
	}
128
129
	/**
130
	 * Returns the callable to which the specified route is mapped, or null if the router map contains no mapping for the route.
131
	 *
132
	 * @param string $method
133
	 * @param string $route
134
	 * @return callable the callable to which the specified route is mapped, or null if the router map contains no mapping for the route.
135
	 */
136 5
	public function get($method, $route)
137
	{
138 5
		if (!array_key_exists($method, $this->routes)) {
139 2
			return null;
140
		}
141
142 4
		$pattern = $this->createPattern($route);
143
144 4
		if (array_key_exists($pattern, $this->routes[$method])) {
145 4
			return $this->routes[$method][$pattern]->callable;
146
		}
147
148 2
		return null;
149
	}
150
151
	/**
152
	 * Associates the specified callable with the specified method & route in the route map.
153
	 *
154
	 * @param string|array $methods
155
	 * @param string $route
156
	 * @param callable $callable
157
	 * @return $this
158
	 */
159 20
	public function set($methods, $route, callable $callable)
160
	{
161 20
		if (is_string($methods)) {
162 2
			$methods = [$methods];
163
		}
164
165 20
		foreach ($methods as $method) {
166 20
			$this->add($method, $route, $callable);
167
		}
168
169 20
		return $this;
170
	}
171
172
	/**
173
	 * Adds a method & route to the to the route map.
174
	 *
175
	 * @param string $method
176
	 * @param string $route
177
	 * @param callable $callable
178
	 */
179 20
	protected function add(string $method, string $route, callable $callable)
180
	{
181 20
		$pattern = $this->createPattern($route);
182
183
		$entry = (object)[
184 20
			'route' => $route,
185 20
			'pattern' => $pattern,
186 20
			'callable' => $callable
187
		];
188
189 20
		if (!array_key_exists($method, $this->routes)) {
190 20
			$this->routes[$method] = [];
191
		}
192
193 20
		$this->routes[$method][$pattern] = $entry;
194 20
	}
195
196
	/**
197
	 * Creates a regex-enabled pattern from the route
198
	 *
199
	 * @param string $route
200
	 * @return string the pattern string.
201
	 */
202 20
	protected function createPattern(string $route)
203
	{
204 20
		return '|^' . preg_replace('|\{[^\}]+\}|', '([^\/]+)', $route) . '$|';
205
	}
206
207
	/**
208
	 * Removes the mapping for the specified route from the router map if present.
209
	 *
210
	 * @param string $method
211
	 * @param string $route
212
	 * @return null
213
	 */
214 3
	public function remove($method, $route)
215
	{
216 3
		if (!array_key_exists($method, $this->routes)) {
217 1
			return;
218
		}
219
220 3
		$pattern = $this->createPattern($route);
221
222 3
		if (array_key_exists($pattern, $this->routes[$method])) {
223 3
			unset($this->routes[$method][$pattern]);
224
		}
225
226 3
		if (count($this->routes[$method]) == 0) {
227 3
			unset($this->routes[$method]);
228
		}
229 3
	}
230
231
	/**
232
	 * Removes all of the mappings from the router map.
233
	 *
234
	 * @return null
235
	 */
236 1
	public function clear()
237
	{
238 1
		$this->routes = [];
239 1
	}
240
241
	/**
242
	 * Returns the result of the given route's callable.
243
	 *
244
	 * @param string|null $method = new ServerRequest()->getMethod()
245
	 * @param string|null $route = new ServerRequest()->getUri()->getPath()
246
	 * @return mixed the result of the given route's callable.
247
	 * @throws ServerResponseException
248
	 */
249 8
	public function resolve($method = null, $route = null)
250
	{
251 8
		$serverRequest = new ServerRequest();
252
253 8
		if ($method === null) {
254 1
			$method = $serverRequest->getMethod();
255
		}
256
257 8
		if ($route === null) {
258 1
			$route = $serverRequest->getUri()->getPath();
259
		}
260
261 8
		if ($this->basePath !== '' && strpos($route, $this->basePath, 0) === 0) {
262 1
			$route = mb_substr($route, strlen($this->basePath));
263
		}
264
265 8
		return $this->callCallable($this->getCallable($method, $route));
266
	}
267
268
	/**
269
	 * Returns the callable to which the specied method and route are mapped.
270
	 *
271
	 * @param string $method
272
	 * @param string $route
273
	 * @return array the callable to which the specied method and route are mapped and the route matches.
274
	 * @throws ServerResponseException
275
	 */
276 8
	protected function getCallable($method, $route)
277
	{
278 8
		if (!array_key_exists($method, $this->routes)) {
279 1
			throw new ServerResponseException(new ServerResponse(404));
280
		}
281
282 7
		foreach ($this->routes[$method] as $entry) {
283 7
			if (preg_match($entry->pattern, $route, $matches) > 0) {
284 6
				array_shift($matches);
285 7
				return [$entry->callable, $matches];
286
			}
287
		}
288
289 1
		throw new ServerResponseException(new ServerResponse(404));
290
	}
291
292
	/**
293
	 * Returns the result of the callable.
294
	 *
295
	 * @param array the callable and the route matches.
0 ignored issues
show
The type miBadger\Router\the was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
296
	 * @return mixed the result the callable.
297
	 */
298 6
	protected function callCallable($callable)
299
	{
300 6
		return call_user_func_array($callable[0], $callable[1]);
301
	}
302
}
303