Passed
Push — master ( 00dd55...b390e5 )
by Anatoly
02:05
created

Router   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 35
dl 0
loc 129
rs 10
c 0
b 0
f 0
wmc 16

7 Methods

Rating   Name   Duplication   Size   Complexity  
A addRoutes() 0 8 2
A match() 0 31 6
A addMiddleware() 0 5 1
A getRoutes() 0 3 1
A addRoute() 0 5 1
A getMiddlewareStack() 0 3 1
A handle() 0 24 4
1
<?php declare(strict_types=1);
2
3
/**
4
 * It's free open-source software released under the MIT License.
5
 *
6
 * @author Anatoly Fenric <[email protected]>
7
 * @copyright Copyright (c) 2018, Anatoly Fenric
8
 * @license https://github.com/sunrise-php/http-router/blob/master/LICENSE
9
 * @link https://github.com/sunrise-php/http-router
10
 */
11
12
namespace Sunrise\Http\Router;
13
14
/**
15
 * Import classes
16
 */
17
use Psr\Http\Message\ResponseInterface;
18
use Psr\Http\Message\ServerRequestInterface;
19
use Psr\Http\Server\MiddlewareInterface;
20
use Sunrise\Http\Router\Exception\MethodNotAllowedException;
21
use Sunrise\Http\Router\Exception\RouteNotFoundException;
22
23
/**
24
 * Router
25
 */
26
class Router implements RouterInterface
27
{
28
29
	/**
30
	 * The router map
31
	 *
32
	 * @var RouteInterface[]
33
	 */
34
	protected $routes = [];
35
36
	/**
37
	 * The router middleware stack
38
	 *
39
	 * @var MiddlewareInterface[]
40
	 */
41
	protected $middlewareStack = [];
42
43
	/**
44
	 * {@inheritDoc}
45
	 */
46
	public function addRoute(RouteInterface $route) : RouterInterface
47
	{
48
		$this->routes[] = $route;
49
50
		return $this;
51
	}
52
53
	/**
54
	 * {@inheritDoc}
55
	 */
56
	public function addRoutes(RouteCollectionInterface $collection) : RouterInterface
57
	{
58
		foreach ($collection->getRoutes() as $route)
59
		{
60
			$this->addRoute($route);
61
		}
62
63
		return $this;
64
	}
65
66
	/**
67
	 * {@inheritDoc}
68
	 */
69
	public function addMiddleware(MiddlewareInterface $middleware) : RouterInterface
70
	{
71
		$this->middlewareStack[] = $middleware;
72
73
		return $this;
74
	}
75
76
	/**
77
	 * {@inheritDoc}
78
	 */
79
	public function getRoutes() : array
80
	{
81
		return $this->routes;
82
	}
83
84
	/**
85
	 * {@inheritDoc}
86
	 */
87
	public function getMiddlewareStack() : array
88
	{
89
		return $this->middlewareStack;
90
	}
91
92
	/**
93
	 * {@inheritDoc}
94
	 */
95
	public function match(ServerRequestInterface $request) : RouteInterface
96
	{
97
		$allowed = [];
98
99
		foreach ($this->getRoutes() as $route)
100
		{
101
			$regex = route_regex($route->getPath(), $route->getPatterns());
102
103
			if (\preg_match($regex, $request->getUri()->getPath(), $matches))
104
			{
105
				$allowed = \array_merge($allowed, $route->getMethods());
106
107
				if (\in_array($request->getMethod(), $route->getMethods()))
108
				{
109
					$attributes = \array_filter($matches, function($value, $name)
110
					{
111
						return ! ('' === $value || \is_int($name));
112
113
					}, \ARRAY_FILTER_USE_BOTH);
114
115
					return $route->withAttributes($attributes);
116
				}
117
			}
118
		}
119
120
		if (! empty($allowed))
121
		{
122
			throw new MethodNotAllowedException($request, $allowed);
123
		}
124
125
		throw new RouteNotFoundException($request);
126
	}
127
128
	/**
129
	 * {@inheritDoc}
130
	 */
131
	public function handle(ServerRequestInterface $request) : ResponseInterface
132
	{
133
		$route = $this->match($request);
134
135
		$requestHandler = new RequestHandler();
136
137
		foreach ($this->getMiddlewareStack() as $middleware)
138
		{
139
			$requestHandler->add($middleware);
140
		}
141
142
		foreach ($route->getMiddlewareStack() as $middleware)
143
		{
144
			$requestHandler->add($middleware);
145
		}
146
147
		foreach ($route->getAttributes() as $name => $value)
148
		{
149
			$request = $request->withAttribute($name, $value);
150
		}
151
152
		$request = $request->withAttribute('@route', $route->getId());
153
154
		return $requestHandler->handle($request);
155
	}
156
}
157