Skip to content

Commit ffb3b68

Browse files
committed
Fix issue #50
If the static route doesn't exist for the given method, try matching against dynamic ones as well. Allowed methods are now collected from both static and dynamic routes. This changes the route data format, so cache is no longer valid -- maybe include a version identifier in the cache file?
1 parent cec21d8 commit ffb3b68

File tree

3 files changed

+38
-22
lines changed

3 files changed

+38
-22
lines changed

Diff for: src/DataGenerator/RegexBasedAbstract.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ private function isStaticRoute($routeData) {
5151
private function addStaticRoute($httpMethod, $routeData, $handler) {
5252
$routeStr = $routeData[0];
5353

54-
if (isset($this->staticRoutes[$routeStr][$httpMethod])) {
54+
if (isset($this->staticRoutes[$httpMethod][$routeStr])) {
5555
throw new BadRouteException(sprintf(
5656
'Cannot register two routes matching "%s" for method "%s"',
5757
$routeStr, $httpMethod
@@ -69,7 +69,7 @@ private function addStaticRoute($httpMethod, $routeData, $handler) {
6969
}
7070
}
7171

72-
$this->staticRoutes[$routeStr][$httpMethod] = $handler;
72+
$this->staticRoutes[$httpMethod][$routeStr] = $handler;
7373
}
7474

7575
private function addVariableRoute($httpMethod, $routeData, $handler) {

Diff for: src/Dispatcher/RegexBasedAbstract.php

+14-16
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,12 @@ abstract class RegexBasedAbstract implements Dispatcher {
1111
protected abstract function dispatchVariableRoute($routeData, $uri);
1212

1313
public function dispatch($httpMethod, $uri) {
14-
if (isset($this->staticRouteMap[$uri])) {
15-
return $this->dispatchStaticRoute($httpMethod, $uri);
14+
if (isset($this->staticRouteMap[$httpMethod][$uri])) {
15+
$handler = $this->staticRouteMap[$httpMethod][$uri];
16+
return [self::FOUND, $handler, []];
17+
} else if ($httpMethod === 'HEAD' && isset($this->staticRouteMap['GET'][$uri])) {
18+
$handler = $this->staticRouteMap['GET'][$uri];
19+
return [self::FOUND, $handler, []];
1620
}
1721

1822
$varRouteData = $this->variableRouteData;
@@ -28,9 +32,15 @@ public function dispatch($httpMethod, $uri) {
2832
}
2933
}
3034

31-
// Find allowed methods for this URI by matching against all other
32-
// HTTP methods as well
35+
// Find allowed methods for this URI by matching against all other HTTP methods as well
3336
$allowedMethods = [];
37+
38+
foreach ($this->staticRouteMap as $method => $uriMap) {
39+
if ($method !== $httpMethod && isset($uriMap[$uri])) {
40+
$allowedMethods[] = $method;
41+
}
42+
}
43+
3444
foreach ($varRouteData as $method => $routeData) {
3545
if ($method === $httpMethod) {
3646
continue;
@@ -49,16 +59,4 @@ public function dispatch($httpMethod, $uri) {
4959
return [self::NOT_FOUND];
5060
}
5161
}
52-
53-
protected function dispatchStaticRoute($httpMethod, $uri) {
54-
$routes = $this->staticRouteMap[$uri];
55-
56-
if (isset($routes[$httpMethod])) {
57-
return [self::FOUND, $routes[$httpMethod], []];
58-
} elseif ($httpMethod === 'HEAD' && isset($routes['GET'])) {
59-
return [self::FOUND, $routes['GET'], []];
60-
} else {
61-
return [self::METHOD_NOT_ALLOWED, array_keys($routes)];
62-
}
63-
}
6462
}

Diff for: test/Dispatcher/DispatcherTest.php

+22-4
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ private function generateDispatcherOptions() {
3131
*/
3232
public function testFoundDispatches($method, $uri, $callback, $handler, $argDict) {
3333
$dispatcher = \FastRoute\simpleDispatcher($callback, $this->generateDispatcherOptions());
34-
list($routedStatus, $routedTo, $routedArgs) = $dispatcher->dispatch($method, $uri);
35-
$this->assertSame($dispatcher::FOUND, $routedStatus);
36-
$this->assertSame($handler, $routedTo);
37-
$this->assertSame($argDict, $routedArgs);
34+
$info = $dispatcher->dispatch($method, $uri);
35+
$this->assertSame($dispatcher::FOUND, $info[0]);
36+
$this->assertSame($handler, $info[1]);
37+
$this->assertSame($argDict, $info[2]);
3838
}
3939

4040
/**
@@ -318,6 +318,15 @@ public function provideFoundDispatchCases() {
318318
$cases[] = ['POST', '/user', $callback, 'handlerGetPost', $argDict];
319319
$cases[] = ['DELETE', '/user', $callback, 'handlerDelete', $argDict];
320320

321+
// 15 ----
322+
323+
$callback = function(RouteCollector $r) {
324+
$r->addRoute('POST', '/user.json', 'handler0');
325+
$r->addRoute('GET', '/{entity}.json', 'handler1');
326+
};
327+
328+
$cases[] = ['GET', '/user.json', $callback, 'handler1', ['entity' => 'user']];
329+
321330

322331
// x -------------------------------------------------------------------------------------->
323332

@@ -468,6 +477,15 @@ public function provideMethodNotAllowedDispatchCases() {
468477

469478
$cases[] = ['PUT', '/user', $callback, ['GET', 'POST', 'DELETE']];
470479

480+
// 5
481+
482+
$callback = function(RouteCollector $r) {
483+
$r->addRoute('POST', '/user.json', 'handler0');
484+
$r->addRoute('GET', '/{entity}.json', 'handler1');
485+
};
486+
487+
$cases[] = ['PUT', '/user.json', $callback, ['POST', 'GET']];
488+
471489
// x -------------------------------------------------------------------------------------->
472490

473491
return $cases;

0 commit comments

Comments
 (0)