-
Notifications
You must be signed in to change notification settings - Fork 145
Expand file tree
/
Copy pathRouter.php
More file actions
120 lines (97 loc) · 3.37 KB
/
Copy pathRouter.php
File metadata and controls
120 lines (97 loc) · 3.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
<?php
namespace PHPCensor\Http;
use PHPCensor\Application;
use PHPCensor\Common\Exception\InvalidArgumentException;
use Symfony\Component\HttpFoundation\Request;
/**
* @package PHP Censor
* @subpackage Application
*
* @author Dan Cryer <dan@block8.co.uk>
* @author Dmitry Khomutov <poisoncorpsee@gmail.com>
*/
class Router
{
protected Request $request;
protected Application $application;
protected array $routes = [
['route' => '/:controller/:action', 'callback' => null, 'defaults' => []]
];
public function __construct(Application $application, Request $request)
{
$this->application = $application;
$this->request = $request;
}
public function clearRoutes()
{
$this->routes = [];
}
/**
* @param string $route Route definition
* @param array $options
* @param callable $callback
*
* @throws InvalidArgumentException
*/
public function register($route, $options = [], $callback = null)
{
if (!\is_callable($callback)) {
throw new InvalidArgumentException('$callback must be callable.');
}
\array_unshift($this->routes, ['route' => $route, 'callback' => $callback, 'defaults' => $options]);
}
public function dispatch()
{
foreach ($this->routes as $route) {
$pathParts = $this->request->getPathInfo();
$pathParts = \array_values(\array_filter(\explode('/', $pathParts)));
$thisController = null;
$thisAction = null;
if (\array_key_exists('controller', $route['defaults'])) {
$thisController = $route['defaults']['controller'];
}
if (\array_key_exists('action', $route['defaults'])) {
$thisAction = $route['defaults']['action'];
}
$routeParts = \array_filter(\explode('/', $route['route']));
$routeMatches = true;
while (\count($routeParts)) {
$routePart = \array_shift($routeParts);
$pathPart = \array_shift($pathParts);
switch ($routePart) {
case ':controller':
$thisController = !\is_null($pathPart) ? $pathPart : $thisController;
break;
case ':action':
$thisAction = !\is_null($pathPart) ? $pathPart : $thisAction;
break;
default:
if ($routePart !== $pathPart) {
$routeMatches = false;
}
}
if (!$routeMatches || !\count($pathParts)) {
break;
}
}
foreach ($pathParts as &$pathPart) {
if (\is_numeric($pathPart)) {
$pathPart = (int)$pathPart;
}
}
unset($pathPart);
if ($routeMatches) {
$route = [
'controller' => $thisController,
'action' => $thisAction,
'args' => $pathParts,
'callback' => $route['callback']
];
if ($this->application->isValidRoute($route)) {
return $route;
}
}
}
return null;
}
}