From da43a39de5808eb5173b848de197afc57c944239 Mon Sep 17 00:00:00 2001 From: Lonnie Ezell Date: Tue, 2 Oct 2018 22:34:46 -0500 Subject: [PATCH] Ensure current HTTP verb routes are matched prior to any * matched routes. Fixes #1240 --- system/Router/RouteCollection.php | 19 +++++++++++++++++- tests/system/Router/RouterTest.php | 31 ++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/system/Router/RouteCollection.php b/system/Router/RouteCollection.php index ec0b121659db..02ed4ac5efc4 100644 --- a/system/Router/RouteCollection.php +++ b/system/Router/RouteCollection.php @@ -518,7 +518,9 @@ public function getRoutes($verb = null): array if (isset($this->routes[$verb])) { - $collection = array_merge($this->routes['*'], $this->routes[$verb]); + // Keep current verb's routes at the beginning so they're matched + // before any of the generic, "add" routes. + $collection = array_merge($this->routes[$verb], $this->routes['*']); foreach ($collection as $r) { @@ -558,6 +560,21 @@ public function getHTTPVerb(): string //-------------------------------------------------------------------- + /** + * Sets the current HTTP verb. + * Used primarily for testing. + * + * @param string $verb + * + * @return $this + */ + public function setHTTPVerb(string $verb) + { + $this->HTTPVerb = $verb; + + return $this; + } + /** * A shortcut method to add a number of routes at a single time. * It does not allow any options to be set on the route, or to diff --git a/tests/system/Router/RouterTest.php b/tests/system/Router/RouterTest.php index b1e7fde0298d..2d01192fc1f7 100644 --- a/tests/system/Router/RouterTest.php +++ b/tests/system/Router/RouterTest.php @@ -270,4 +270,35 @@ public function testRouteWorksWithFilters() } //-------------------------------------------------------------------- + + /** + * @see https://github.com/bcit-ci/CodeIgniter4/issues/1240 + */ + public function testMatchesCorrectlyWithMixedVerbs() + { + $this->collection->setHTTPVerb('get'); + + $this->collection->add('/', 'Home::index'); + $this->collection->get('news', 'News::index'); + $this->collection->get('news/(:segment)', 'News::view/$1'); + $this->collection->add('(:any)', 'Pages::view/$1'); + + $router = new Router($this->collection); + + $router->handle('/'); + $this->assertEquals('\Home', $router->controllerName()); + $this->assertEquals('index', $router->methodName()); + + $router->handle('news'); + $this->assertEquals('\News', $router->controllerName()); + $this->assertEquals('index', $router->methodName()); + + $router->handle('news/daily'); + $this->assertEquals('\News', $router->controllerName()); + $this->assertEquals('view', $router->methodName()); + + $router->handle('about'); + $this->assertEquals('\Pages', $router->controllerName()); + $this->assertEquals('view', $router->methodName()); + } }