diff --git a/flight/Engine.php b/flight/Engine.php index 58b0859..398061e 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -64,6 +64,7 @@ use flight\net\Route; * @method void etag(string $id, ('strong'|'weak') $type = 'strong') Handles ETag HTTP caching. * @method void lastModified(int $time) Handles last modified HTTP caching. */ +// phpcs:ignoreFile PSR2.Methods.MethodDeclaration.Underscore class Engine { /** @var array Stored variables. */ diff --git a/flight/core/Dispatcher.php b/flight/core/Dispatcher.php index d91b4b2..9fd8d1e 100644 --- a/flight/core/Dispatcher.php +++ b/flight/core/Dispatcher.php @@ -78,7 +78,7 @@ class Dispatcher * Assigns a callback to an event. * * @param string $name Event name - * @param Closure(): (void|mixed) $callback Callback function + * @param Closure(): (void|mixed)|callable $callback Callback function * * @return $this */ diff --git a/flight/net/Router.php b/flight/net/Router.php index 5d067ad..895b337 100644 --- a/flight/net/Router.php +++ b/flight/net/Router.php @@ -46,6 +46,13 @@ class Router */ protected array $group_middlewares = []; + /** + * Allowed HTTP methods + * + * @var array + */ + protected array $allowed_methods = ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']; + /** * Gets mapped routes. * @@ -74,7 +81,19 @@ class Router */ public function map(string $pattern, callable $callback, bool $pass_route = false, string $route_alias = ''): Route { - $url = trim($pattern); + + // This means that the route ies defined in a group, but the defined route is the base + // url path. Note the '' in route() + // Ex: Flight::group('/api', function() { + // Flight::route('', function() {}); + // } + // Keep the space so that it can execute the below code normally + if ($this->group_prefix !== '') { + $url = ltrim($pattern); + } else { + $url = trim($pattern); + } + $methods = ['*']; if (false !== strpos($url, ' ')) { @@ -83,7 +102,12 @@ class Router $methods = explode('|', $method); } - $route = new Route($this->group_prefix . $url, $callback, $methods, $pass_route, $route_alias); + // And this finishes it off. + if ($this->group_prefix !== '') { + $url = rtrim($this->group_prefix . $url); + } + + $route = new Route($url, $callback, $methods, $pass_route, $route_alias); // to handle group middleware foreach ($this->group_middlewares as $gm) { diff --git a/tests/RouterTest.php b/tests/RouterTest.php index f67759f..1b52ae1 100644 --- a/tests/RouterTest.php +++ b/tests/RouterTest.php @@ -459,6 +459,41 @@ class RouterTest extends TestCase $this->check('123'); } + public function testGroupRouteWithEmptyMapPath() + { + $this->router->group('/user', function (Router $router) { + $router->map('', function () { + echo "I'm a little teapot"; + }); + }); + $this->request->url = '/user'; + $this->check('I\'m a little teapot'); + } + + public function testGroupRouteWithEmptyGetPath() + { + $this->router->group('/user', function (Router $router) { + $router->get('', function () { + echo "I'm a little teapot"; + }); + }); + $this->request->url = '/user'; + $this->request->method = 'GET'; + $this->check('I\'m a little teapot'); + } + + public function testGroupRouteWithEmptyMultipleMethodsPath() + { + $this->router->group('/user', function (Router $router) { + $router->map('GET|POST ', function () { + echo "I'm a little teapot"; + }); + }); + $this->request->url = '/user'; + $this->request->method = 'GET'; + $this->check('I\'m a little teapot'); + } + public function testGroupRoutesMultiParams() { $this->router->group('/user', function (Router $router) {