-
Notifications
You must be signed in to change notification settings - Fork 448
/
Copy pathRegexBasedAbstract.php
123 lines (99 loc) · 3.88 KB
/
RegexBasedAbstract.php
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
121
122
123
<?php
declare(strict_types=1);
namespace FastRoute\Dispatcher;
use FastRoute\DataGenerator;
use FastRoute\Dispatcher;
use FastRoute\Dispatcher\Result\Matched;
use FastRoute\Dispatcher\Result\MethodNotAllowed;
use FastRoute\Dispatcher\Result\NotMatched;
/**
* @internal
*
* @phpstan-import-type StaticRoutes from DataGenerator
* @phpstan-import-type DynamicRouteChunk from DataGenerator
* @phpstan-import-type DynamicRouteChunks from DataGenerator
* @phpstan-import-type DynamicRoutes from DataGenerator
* @phpstan-import-type RouteData from DataGenerator
*/
abstract class RegexBasedAbstract implements Dispatcher
{
/** @var StaticRoutes */
protected array $staticRouteMap = [];
/** @var DynamicRoutes */
protected array $variableRouteData = [];
/** @param RouteData $data */
public function __construct(array $data)
{
[$this->staticRouteMap, $this->variableRouteData] = $data;
}
/** @param DynamicRouteChunks $routeData */
abstract protected function dispatchVariableRoute(array $routeData, string $uri): ?Matched;
public function dispatch(string $httpMethod, string $uri): Matched|NotMatched|MethodNotAllowed
{
if (isset($this->staticRouteMap[$httpMethod][$uri])) {
$result = new Matched();
$result->handler = $this->staticRouteMap[$httpMethod][$uri][0];
$result->extraParameters = $this->staticRouteMap[$httpMethod][$uri][1];
return $result;
}
if (isset($this->variableRouteData[$httpMethod])) {
$result = $this->dispatchVariableRoute($this->variableRouteData[$httpMethod], $uri);
if ($result !== null) {
return $result;
}
}
// For HEAD requests, attempt fallback to GET
if ($httpMethod === 'HEAD') {
if (isset($this->staticRouteMap['GET'][$uri])) {
$result = new Matched();
$result->handler = $this->staticRouteMap['GET'][$uri][0];
$result->extraParameters = $this->staticRouteMap['GET'][$uri][1];
return $result;
}
if (isset($this->variableRouteData['GET'])) {
$result = $this->dispatchVariableRoute($this->variableRouteData['GET'], $uri);
if ($result !== null) {
return $result;
}
}
}
// If nothing else matches, try fallback routes
if (isset($this->staticRouteMap['*'][$uri])) {
$result = new Matched();
$result->handler = $this->staticRouteMap['*'][$uri][0];
$result->extraParameters = $this->staticRouteMap['*'][$uri][1];
return $result;
}
if (isset($this->variableRouteData['*'])) {
$result = $this->dispatchVariableRoute($this->variableRouteData['*'], $uri);
if ($result !== null) {
return $result;
}
}
// Find allowed methods for this URI by matching against all other HTTP methods as well
$allowedMethods = [];
foreach ($this->staticRouteMap as $method => $uriMap) {
if ($method === $httpMethod || ! isset($uriMap[$uri])) {
continue;
}
$allowedMethods[] = $method;
}
foreach ($this->variableRouteData as $method => $routeData) {
if ($method === $httpMethod) {
continue;
}
$result = $this->dispatchVariableRoute($routeData, $uri);
if ($result === null) {
continue;
}
$allowedMethods[] = $method;
}
// If there are no allowed methods the route simply does not exist
if ($allowedMethods !== []) {
$result = new MethodNotAllowed();
$result->allowedMethods = $allowedMethods;
return $result;
}
return new NotMatched();
}
}