From 3d2dccb72aff372b8a0afddf06c74a5caa0b58d7 Mon Sep 17 00:00:00 2001 From: fadrian06 Date: Mon, 3 Jun 2024 13:09:21 -0400 Subject: [PATCH 1/6] Started draft of route compact syntax --- flight/Flight.php | 54 ++++++++++ .../FlightRouteCompactSyntaxTest.php | 101 ++++++++++++++++++ tests/groupcompactsyntax/PostsController.php | 34 ++++++ tests/groupcompactsyntax/TodosController.php | 14 +++ tests/groupcompactsyntax/UsersController.php | 14 +++ 5 files changed, 217 insertions(+) create mode 100644 tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php create mode 100644 tests/groupcompactsyntax/PostsController.php create mode 100644 tests/groupcompactsyntax/TodosController.php create mode 100644 tests/groupcompactsyntax/UsersController.php diff --git a/flight/Flight.php b/flight/Flight.php index 207d44b3..020e5460 100644 --- a/flight/Flight.php +++ b/flight/Flight.php @@ -121,6 +121,60 @@ public static function __callStatic(string $name, array $params) return self::app()->{$name}(...$params); } + /** + * Create a resource controller customizing the methods names mapping. + * + * @param class-string $controllerClass + * @param array $methods + */ + public static function resource( + string $pattern, + string $controllerClass, + array $methods = [] + ): void { + $defaultMapping = [ + 'GET /' => 'index', + 'GET /@id/' => 'show', + 'GET /create/' => 'create', + 'POST /' => 'store', + 'GET /@id/edit/' => 'edit', + 'PUT /@id/' => 'update', + 'DELETE /@id/' => 'destroy' + ]; + + if ($methods !== []) { + static::group( + $pattern, + function () use ($controllerClass, $methods): void { + foreach ($methods as $methodPattern => $controllerMethod) { + static::route( + $methodPattern, + [$controllerClass, $controllerMethod] + ); + } + } + ); + } else { + static::group( + $pattern, + function () use ($defaultMapping, $controllerClass): void { + foreach ($defaultMapping as $methodPattern => $controllerMethod) { + $class = new ReflectionClass($controllerClass); + + if ($class->hasMethod($controllerMethod) === false) { + continue; + } + + static::route( + $methodPattern, + [$controllerClass, $controllerMethod] + ); + } + } + ); + } + } + /** @return Engine Application instance */ public static function app(): Engine { diff --git a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php new file mode 100644 index 00000000..3e522a2b --- /dev/null +++ b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php @@ -0,0 +1,101 @@ +clear(); + } + + public function testCanMapMethodsWithVerboseSyntax(): void + { + Flight::route('GET /users', [UsersController::class, 'list']); + Flight::route('POST /users', [UsersController::class, 'handleRegister']); + + $routes = Flight::router()->getRoutes(); + + $this->assertCount(2, $routes); + + $this->assertSame('/users', $routes[0]->pattern); + $this->assertSame([UsersController::class, 'list'], $routes[0]->callback); + $this->assertSame('GET', $routes[0]->methods[0]); + + $this->assertSame('/users', $routes[1]->pattern); + $this->assertSame([UsersController::class, 'handleRegister'], $routes[1]->callback); + $this->assertSame('POST', $routes[1]->methods[0]); + } + + public function testCanMapSomeMethods(): void + { + Flight::resource('/users', UsersController::class, [ + 'GET /' => 'list', + 'POST /' => 'handleRegister' + ]); + + $routes = Flight::router()->getRoutes(); + + $this->assertCount(2, $routes); + + $this->assertSame('/users/', $routes[0]->pattern); + $this->assertSame('GET', $routes[0]->methods[0]); + $this->assertSame([UsersController::class, 'list'], $routes[0]->callback); + + $this->assertSame('/users/', $routes[1]->pattern); + $this->assertSame('POST', $routes[1]->methods[0]); + $this->assertSame([UsersController::class, 'handleRegister'], $routes[1]->callback); + } + + public function testCanMapDefaultMethods(): void + { + Flight::resource('/posts', PostsController::class); + + $routes = Flight::router()->getRoutes(); + + $this->assertCount(7, $routes); + + $this->assertSame('/posts/', $routes[0]->pattern); + $this->assertSame('GET', $routes[0]->methods[0]); + $this->assertSame([PostsController::class, 'index'], $routes[0]->callback); + + $this->assertSame('/posts/@id/', $routes[1]->pattern); + $this->assertSame('GET', $routes[1]->methods[0]); + $this->assertSame([PostsController::class, 'show'], $routes[1]->callback); + + $this->assertSame('/posts/create/', $routes[2]->pattern); + $this->assertSame('GET', $routes[2]->methods[0]); + $this->assertSame([PostsController::class, 'create'], $routes[2]->callback); + + $this->assertSame('/posts/', $routes[3]->pattern); + $this->assertSame('POST', $routes[3]->methods[0]); + $this->assertSame([PostsController::class, 'store'], $routes[3]->callback); + + $this->assertSame('/posts/@id/edit/', $routes[4]->pattern); + $this->assertSame('GET', $routes[4]->methods[0]); + $this->assertSame([PostsController::class, 'edit'], $routes[4]->callback); + + $this->assertSame('/posts/@id/', $routes[5]->pattern); + $this->assertSame('PUT', $routes[5]->methods[0]); + $this->assertSame([PostsController::class, 'update'], $routes[5]->callback); + + $this->assertSame('/posts/@id/', $routes[6]->pattern); + $this->assertSame('DELETE', $routes[6]->methods[0]); + $this->assertSame([PostsController::class, 'destroy'], $routes[6]->callback); + } + + public function testCanMapExistingMethods(): void + { + Flight::resource('/todos', TodosController::class); + + $routes = Flight::router()->getRoutes(); + + $this->assertCount(2, $routes); + } +} diff --git a/tests/groupcompactsyntax/PostsController.php b/tests/groupcompactsyntax/PostsController.php new file mode 100644 index 00000000..ac2c4975 --- /dev/null +++ b/tests/groupcompactsyntax/PostsController.php @@ -0,0 +1,34 @@ + Date: Mon, 3 Jun 2024 20:02:13 -0600 Subject: [PATCH 2/6] Moved the function over and fleshed it out --- flight/Engine.php | 75 ++++++++++++++++++++++++++++++++++++++++++++++- flight/Flight.php | 56 ++--------------------------------- 2 files changed, 76 insertions(+), 55 deletions(-) diff --git a/flight/Engine.php b/flight/Engine.php index a1378a61..2c06adc4 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -42,6 +42,8 @@ * Routes a PATCH URL to a callback function. * @method Route delete(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') * Routes a DELETE URL to a callback function. + * @method void resource(string $pattern, string $controllerClass, array $methods = []) + * Adds standardized RESTful routes for a controller. * @method Router router() Gets router * @method string getUrl(string $alias) Gets a url from an alias * @@ -76,7 +78,7 @@ class Engine private const MAPPABLE_METHODS = [ 'start', 'stop', 'route', 'halt', 'error', 'notFound', 'render', 'redirect', 'etag', 'lastModified', 'json', 'jsonHalt', 'jsonp', - 'post', 'put', 'patch', 'delete', 'group', 'getUrl' + 'post', 'put', 'patch', 'delete', 'group', 'getUrl', 'resource' ]; /** @var array Stored variables. */ @@ -727,6 +729,77 @@ public function _delete(string $pattern, $callback, bool $pass_route = false, st return $this->router()->map('DELETE ' . $pattern, $callback, $pass_route, $route_alias); } + /** + * Create a resource controller customizing the methods names mapping. + * + * @param class-string $controllerClass + * @param array $options + */ + public function _resource( + string $pattern, + string $controllerClass, + array $options = [] + ): void { + // $defaultMapping = [ + // 'GET ' => 'index', + // 'GET /create' => 'create', + // 'POST ' => 'store', + // 'GET /@id' => 'show', + // 'GET /@id/edit' => 'edit', + // 'PUT /@id' => 'update', + // 'DELETE /@id' => 'destroy' + // ]; + + $defaultMapping = [ + 'index' => 'GET ', + 'create' => 'GET /create', + 'store' => 'POST ', + 'show' => 'GET /@id', + 'edit' => 'GET /@id/edit', + 'update' => 'PUT /@id', + 'destroy' =>'DELETE /@id' + ]; + + // Create a custom alias base + $aliasBase = trim(basename($pattern), '/'); + if(isset($options['alias_base']) === true) { + $aliasBase = $options['alias_base']; + } + + // Only use these controller methods + if(isset($options['only']) === true) { + $only = $options['only']; + $defaultMapping = array_filter($defaultMapping, function($key) use ($only) { + return in_array($key, $only, true) === true; + }, ARRAY_FILTER_USE_KEY); + + // Exclude these controller methods + } else if(isset($options['except']) === true) { + $except = $options['except']; + $defaultMapping = array_filter($defaultMapping, function($key) use ($except) { + return in_array($key, $except, true) === false; + }, ARRAY_FILTER_USE_KEY); + } + + // Add group middleware + $middleware = []; + if(isset($options['middleware']) === true) { + $middleware = $options['middleware']; + } + + $this->group( + $pattern, + function (Router $router) use ($controllerClass, $defaultMapping, $aliasBase): void { + foreach ($defaultMapping as $controllerMethod => $methodPattern) { + $router->map( + $methodPattern, + $controllerClass.'->'.$controllerMethod + )->setAlias($aliasBase.'.'.$controllerMethod); + } + } + , $middleware); + } + /** * Stops processing and returns a given response. * diff --git a/flight/Flight.php b/flight/Flight.php index 020e5460..70e8bddf 100644 --- a/flight/Flight.php +++ b/flight/Flight.php @@ -42,6 +42,8 @@ * Routes a PATCH URL to a callback function. * @method static Route delete(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') * Routes a DELETE URL to a callback function. + * @method void resource(string $pattern, string $controllerClass, array $methods = []) + * Adds standardized RESTful routes for a controller. * @method static Router router() Returns Router instance. * @method static string getUrl(string $alias, array $params = []) Gets a url from an alias * @@ -121,60 +123,6 @@ public static function __callStatic(string $name, array $params) return self::app()->{$name}(...$params); } - /** - * Create a resource controller customizing the methods names mapping. - * - * @param class-string $controllerClass - * @param array $methods - */ - public static function resource( - string $pattern, - string $controllerClass, - array $methods = [] - ): void { - $defaultMapping = [ - 'GET /' => 'index', - 'GET /@id/' => 'show', - 'GET /create/' => 'create', - 'POST /' => 'store', - 'GET /@id/edit/' => 'edit', - 'PUT /@id/' => 'update', - 'DELETE /@id/' => 'destroy' - ]; - - if ($methods !== []) { - static::group( - $pattern, - function () use ($controllerClass, $methods): void { - foreach ($methods as $methodPattern => $controllerMethod) { - static::route( - $methodPattern, - [$controllerClass, $controllerMethod] - ); - } - } - ); - } else { - static::group( - $pattern, - function () use ($defaultMapping, $controllerClass): void { - foreach ($defaultMapping as $methodPattern => $controllerMethod) { - $class = new ReflectionClass($controllerClass); - - if ($class->hasMethod($controllerMethod) === false) { - continue; - } - - static::route( - $methodPattern, - [$controllerClass, $controllerMethod] - ); - } - } - ); - } - } - /** @return Engine Application instance */ public static function app(): Engine { From a12d4740065a36a1b14afebf762e5489f1fe1c5d Mon Sep 17 00:00:00 2001 From: n0nag0n Date: Mon, 3 Jun 2024 20:03:02 -0600 Subject: [PATCH 3/6] beautify --- flight/Engine.php | 91 ++++++++++---------- flight/Flight.php | 2 +- tests/FlightTest.php | 3 +- tests/groupcompactsyntax/UsersController.php | 6 +- 4 files changed, 52 insertions(+), 50 deletions(-) diff --git a/flight/Engine.php b/flight/Engine.php index 2c06adc4..8572b69d 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -42,7 +42,7 @@ * Routes a PATCH URL to a callback function. * @method Route delete(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') * Routes a DELETE URL to a callback function. - * @method void resource(string $pattern, string $controllerClass, array $methods = []) + * @method void resource(string $pattern, string $controllerClass, array $methods = []) * Adds standardized RESTful routes for a controller. * @method Router router() Gets router * @method string getUrl(string $alias) Gets a url from an alias @@ -729,7 +729,7 @@ public function _delete(string $pattern, $callback, bool $pass_route = false, st return $this->router()->map('DELETE ' . $pattern, $callback, $pass_route, $route_alias); } - /** + /** * Create a resource controller customizing the methods names mapping. * * @param class-string $controllerClass @@ -748,56 +748,57 @@ public function _resource( // 'GET /@id/edit' => 'edit', // 'PUT /@id' => 'update', // 'DELETE /@id' => 'destroy' - // ]; + // ]; - $defaultMapping = [ + $defaultMapping = [ 'index' => 'GET ', 'create' => 'GET /create', 'store' => 'POST ', 'show' => 'GET /@id', 'edit' => 'GET /@id/edit', 'update' => 'PUT /@id', - 'destroy' =>'DELETE /@id' - ]; - - // Create a custom alias base - $aliasBase = trim(basename($pattern), '/'); - if(isset($options['alias_base']) === true) { - $aliasBase = $options['alias_base']; - } - - // Only use these controller methods - if(isset($options['only']) === true) { - $only = $options['only']; - $defaultMapping = array_filter($defaultMapping, function($key) use ($only) { - return in_array($key, $only, true) === true; - }, ARRAY_FILTER_USE_KEY); - - // Exclude these controller methods - } else if(isset($options['except']) === true) { - $except = $options['except']; - $defaultMapping = array_filter($defaultMapping, function($key) use ($except) { - return in_array($key, $except, true) === false; - }, ARRAY_FILTER_USE_KEY); - } - - // Add group middleware - $middleware = []; - if(isset($options['middleware']) === true) { - $middleware = $options['middleware']; - } - - $this->group( - $pattern, - function (Router $router) use ($controllerClass, $defaultMapping, $aliasBase): void { - foreach ($defaultMapping as $controllerMethod => $methodPattern) { - $router->map( - $methodPattern, - $controllerClass.'->'.$controllerMethod - )->setAlias($aliasBase.'.'.$controllerMethod); - } - } - , $middleware); + 'destroy' => 'DELETE /@id' + ]; + + // Create a custom alias base + $aliasBase = trim(basename($pattern), '/'); + if (isset($options['alias_base']) === true) { + $aliasBase = $options['alias_base']; + } + + // Only use these controller methods + if (isset($options['only']) === true) { + $only = $options['only']; + $defaultMapping = array_filter($defaultMapping, function ($key) use ($only) { + return in_array($key, $only, true) === true; + }, ARRAY_FILTER_USE_KEY); + + // Exclude these controller methods + } elseif (isset($options['except']) === true) { + $except = $options['except']; + $defaultMapping = array_filter($defaultMapping, function ($key) use ($except) { + return in_array($key, $except, true) === false; + }, ARRAY_FILTER_USE_KEY); + } + + // Add group middleware + $middleware = []; + if (isset($options['middleware']) === true) { + $middleware = $options['middleware']; + } + + $this->group( + $pattern, + function (Router $router) use ($controllerClass, $defaultMapping, $aliasBase): void { + foreach ($defaultMapping as $controllerMethod => $methodPattern) { + $router->map( + $methodPattern, + $controllerClass . '->' . $controllerMethod + )->setAlias($aliasBase . '.' . $controllerMethod); + } + }, + $middleware + ); } /** diff --git a/flight/Flight.php b/flight/Flight.php index 70e8bddf..4942b258 100644 --- a/flight/Flight.php +++ b/flight/Flight.php @@ -42,7 +42,7 @@ * Routes a PATCH URL to a callback function. * @method static Route delete(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') * Routes a DELETE URL to a callback function. - * @method void resource(string $pattern, string $controllerClass, array $methods = []) + * @method void resource(string $pattern, string $controllerClass, array $methods = []) * Adds standardized RESTful routes for a controller. * @method static Router router() Returns Router instance. * @method static string getUrl(string $alias, array $params = []) Gets a url from an alias diff --git a/tests/FlightTest.php b/tests/FlightTest.php index 5d196d6f..cf0c9f01 100644 --- a/tests/FlightTest.php +++ b/tests/FlightTest.php @@ -361,8 +361,7 @@ public function testDoesNotPreserveVarsWhenFlagIsDisabled( string $output, array $renderParams, string $regexp - ): void - { + ): void { Flight::view()->preserveVars = false; $this->expectOutputString($output); diff --git a/tests/groupcompactsyntax/UsersController.php b/tests/groupcompactsyntax/UsersController.php index 184c102d..90e1b68f 100644 --- a/tests/groupcompactsyntax/UsersController.php +++ b/tests/groupcompactsyntax/UsersController.php @@ -2,13 +2,15 @@ namespace tests\groupcompactsyntax; -final class UsersController { +final class UsersController +{ public function list(): void { echo __METHOD__; } - public function handleRegister(): void { + public function handleRegister(): void + { echo __METHOD__; } } From edcd1ad092dd0511222dc3cadc5fa8b031d3d9c7 Mon Sep 17 00:00:00 2001 From: n0nag0n Date: Fri, 27 Sep 2024 23:26:49 -0600 Subject: [PATCH 4/6] got unit tests up and running --- flight/Engine.php | 60 +--------- flight/Flight.php | 2 +- flight/net/Router.php | 65 ++++++++++- .../FlightRouteCompactSyntaxTest.php | 107 ++++++++++++------ tests/groupcompactsyntax/UsersController.php | 4 +- 5 files changed, 141 insertions(+), 97 deletions(-) diff --git a/flight/Engine.php b/flight/Engine.php index 8572b69d..83f0c1b3 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -740,65 +740,7 @@ public function _resource( string $controllerClass, array $options = [] ): void { - // $defaultMapping = [ - // 'GET ' => 'index', - // 'GET /create' => 'create', - // 'POST ' => 'store', - // 'GET /@id' => 'show', - // 'GET /@id/edit' => 'edit', - // 'PUT /@id' => 'update', - // 'DELETE /@id' => 'destroy' - // ]; - - $defaultMapping = [ - 'index' => 'GET ', - 'create' => 'GET /create', - 'store' => 'POST ', - 'show' => 'GET /@id', - 'edit' => 'GET /@id/edit', - 'update' => 'PUT /@id', - 'destroy' => 'DELETE /@id' - ]; - - // Create a custom alias base - $aliasBase = trim(basename($pattern), '/'); - if (isset($options['alias_base']) === true) { - $aliasBase = $options['alias_base']; - } - - // Only use these controller methods - if (isset($options['only']) === true) { - $only = $options['only']; - $defaultMapping = array_filter($defaultMapping, function ($key) use ($only) { - return in_array($key, $only, true) === true; - }, ARRAY_FILTER_USE_KEY); - - // Exclude these controller methods - } elseif (isset($options['except']) === true) { - $except = $options['except']; - $defaultMapping = array_filter($defaultMapping, function ($key) use ($except) { - return in_array($key, $except, true) === false; - }, ARRAY_FILTER_USE_KEY); - } - - // Add group middleware - $middleware = []; - if (isset($options['middleware']) === true) { - $middleware = $options['middleware']; - } - - $this->group( - $pattern, - function (Router $router) use ($controllerClass, $defaultMapping, $aliasBase): void { - foreach ($defaultMapping as $controllerMethod => $methodPattern) { - $router->map( - $methodPattern, - $controllerClass . '->' . $controllerMethod - )->setAlias($aliasBase . '.' . $controllerMethod); - } - }, - $middleware - ); + $this->router()->mapResource($pattern, $controllerClass, $options); } /** diff --git a/flight/Flight.php b/flight/Flight.php index 4942b258..287d43a9 100644 --- a/flight/Flight.php +++ b/flight/Flight.php @@ -42,7 +42,7 @@ * Routes a PATCH URL to a callback function. * @method static Route delete(string $pattern, callable|string $callback, bool $pass_route = false, string $alias = '') * Routes a DELETE URL to a callback function. - * @method void resource(string $pattern, string $controllerClass, array $methods = []) + * @method static void resource(string $pattern, string $controllerClass, array $methods = []) * Adds standardized RESTful routes for a controller. * @method static Router router() Returns Router instance. * @method static string getUrl(string $alias, array $params = []) Gets a url from an alias diff --git a/flight/net/Router.php b/flight/net/Router.php index a43b5baf..f80fab60 100644 --- a/flight/net/Router.php +++ b/flight/net/Router.php @@ -87,7 +87,7 @@ public function clear(): void public function map(string $pattern, $callback, bool $pass_route = false, string $route_alias = ''): Route { - // This means that the route ies defined in a group, but the defined route is the base + // This means that the route is 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() {}); @@ -276,6 +276,69 @@ public function getUrlByAlias(string $alias, array $params = []): string throw new Exception($exception_message); } + /** + * Create a resource controller customizing the methods names mapping. + * + * @param class-string $controllerClass + * @param array $options + */ + public function mapResource( + string $pattern, + string $controllerClass, + array $options = [] + ): void { + + $defaultMapping = [ + 'index' => 'GET ', + 'create' => 'GET /create', + 'store' => 'POST ', + 'show' => 'GET /@id', + 'edit' => 'GET /@id/edit', + 'update' => 'PUT /@id', + 'destroy' => 'DELETE /@id' + ]; + + // Create a custom alias base + $aliasBase = trim(basename($pattern), '/'); + if (isset($options['alias_base']) === true) { + $aliasBase = $options['alias_base']; + } + + // Only use these controller methods + if (isset($options['only']) === true) { + $only = $options['only']; + $defaultMapping = array_filter($defaultMapping, function ($key) use ($only) { + return in_array($key, $only, true) === true; + }, ARRAY_FILTER_USE_KEY); + + // Exclude these controller methods + } elseif (isset($options['except']) === true) { + $except = $options['except']; + $defaultMapping = array_filter($defaultMapping, function ($key) use ($except) { + return in_array($key, $except, true) === false; + }, ARRAY_FILTER_USE_KEY); + } + + // Add group middleware + $middleware = []; + if (isset($options['middleware']) === true) { + $middleware = $options['middleware']; + } + + $this->group( + $pattern, + function (Router $router) use ($controllerClass, $defaultMapping, $aliasBase): void { + foreach ($defaultMapping as $controllerMethod => $methodPattern) { + $router->map( + $methodPattern, + [ $controllerClass, $controllerMethod ] + )->setAlias($aliasBase . '.' . $controllerMethod); + } + }, + $middleware + ); + } + /** * Rewinds the current route index. */ diff --git a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php index 3e522a2b..719946d6 100644 --- a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php +++ b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php @@ -17,85 +17,124 @@ public function setUp(): void public function testCanMapMethodsWithVerboseSyntax(): void { - Flight::route('GET /users', [UsersController::class, 'list']); - Flight::route('POST /users', [UsersController::class, 'handleRegister']); + Flight::route('GET /users', [UsersController::class, 'index']); + Flight::route('DELETE /users/@id', [UsersController::class, 'destroy']); $routes = Flight::router()->getRoutes(); $this->assertCount(2, $routes); $this->assertSame('/users', $routes[0]->pattern); - $this->assertSame([UsersController::class, 'list'], $routes[0]->callback); + $this->assertSame([UsersController::class, 'index'], $routes[0]->callback); $this->assertSame('GET', $routes[0]->methods[0]); - $this->assertSame('/users', $routes[1]->pattern); - $this->assertSame([UsersController::class, 'handleRegister'], $routes[1]->callback); - $this->assertSame('POST', $routes[1]->methods[0]); + $this->assertSame('/users/@id', $routes[1]->pattern); + $this->assertSame([UsersController::class, 'destroy'], $routes[1]->callback); + $this->assertSame('DELETE', $routes[1]->methods[0]); } - public function testCanMapSomeMethods(): void + public function testOptionsOnly(): void { Flight::resource('/users', UsersController::class, [ - 'GET /' => 'list', - 'POST /' => 'handleRegister' + 'only' => [ 'index', 'destroy' ] ]); $routes = Flight::router()->getRoutes(); $this->assertCount(2, $routes); - $this->assertSame('/users/', $routes[0]->pattern); + $this->assertSame('/users', $routes[0]->pattern); $this->assertSame('GET', $routes[0]->methods[0]); - $this->assertSame([UsersController::class, 'list'], $routes[0]->callback); + $this->assertSame([UsersController::class, 'index'], $routes[0]->callback); - $this->assertSame('/users/', $routes[1]->pattern); - $this->assertSame('POST', $routes[1]->methods[0]); - $this->assertSame([UsersController::class, 'handleRegister'], $routes[1]->callback); + $this->assertSame('/users/@id', $routes[1]->pattern); + $this->assertSame('DELETE', $routes[1]->methods[0]); + $this->assertSame([UsersController::class, 'destroy'], $routes[1]->callback); } - public function testCanMapDefaultMethods(): void + public function testDefaultMethods(): void { Flight::resource('/posts', PostsController::class); $routes = Flight::router()->getRoutes(); - $this->assertCount(7, $routes); - $this->assertSame('/posts/', $routes[0]->pattern); + $this->assertSame('/posts', $routes[0]->pattern); $this->assertSame('GET', $routes[0]->methods[0]); $this->assertSame([PostsController::class, 'index'], $routes[0]->callback); - - $this->assertSame('/posts/@id/', $routes[1]->pattern); + $this->assertSame('posts.index', $routes[0]->alias); + + $this->assertSame('/posts/create', $routes[1]->pattern); $this->assertSame('GET', $routes[1]->methods[0]); - $this->assertSame([PostsController::class, 'show'], $routes[1]->callback); - - $this->assertSame('/posts/create/', $routes[2]->pattern); - $this->assertSame('GET', $routes[2]->methods[0]); - $this->assertSame([PostsController::class, 'create'], $routes[2]->callback); - - $this->assertSame('/posts/', $routes[3]->pattern); - $this->assertSame('POST', $routes[3]->methods[0]); - $this->assertSame([PostsController::class, 'store'], $routes[3]->callback); - - $this->assertSame('/posts/@id/edit/', $routes[4]->pattern); + $this->assertSame([PostsController::class, 'create'], $routes[1]->callback); + $this->assertSame('posts.create', $routes[1]->alias); + + $this->assertSame('/posts', $routes[2]->pattern); + $this->assertSame('POST', $routes[2]->methods[0]); + $this->assertSame([PostsController::class, 'store'], $routes[2]->callback); + $this->assertSame('posts.store', $routes[2]->alias); + + $this->assertSame('/posts/@id', $routes[3]->pattern); + $this->assertSame('GET', $routes[3]->methods[0]); + $this->assertSame([PostsController::class, 'show'], $routes[3]->callback); + $this->assertSame('posts.show', $routes[3]->alias); + + $this->assertSame('/posts/@id/edit', $routes[4]->pattern); $this->assertSame('GET', $routes[4]->methods[0]); $this->assertSame([PostsController::class, 'edit'], $routes[4]->callback); + $this->assertSame('posts.edit', $routes[4]->alias); - $this->assertSame('/posts/@id/', $routes[5]->pattern); + $this->assertSame('/posts/@id', $routes[5]->pattern); $this->assertSame('PUT', $routes[5]->methods[0]); $this->assertSame([PostsController::class, 'update'], $routes[5]->callback); + $this->assertSame('posts.update', $routes[5]->alias); - $this->assertSame('/posts/@id/', $routes[6]->pattern); + $this->assertSame('/posts/@id', $routes[6]->pattern); $this->assertSame('DELETE', $routes[6]->methods[0]); $this->assertSame([PostsController::class, 'destroy'], $routes[6]->callback); + $this->assertSame('posts.destroy', $routes[6]->alias); } - public function testCanMapExistingMethods(): void + public function testOptionsExcept(): void { - Flight::resource('/todos', TodosController::class); + Flight::resource('/todos', TodosController::class, [ + 'except' => [ 'create', 'store', 'update', 'destroy', 'edit' ] + ]); $routes = Flight::router()->getRoutes(); $this->assertCount(2, $routes); + + $this->assertSame('/todos', $routes[0]->pattern); + $this->assertSame('GET', $routes[0]->methods[0]); + $this->assertSame([TodosController::class, 'index'], $routes[0]->callback); + + $this->assertSame('/todos/@id', $routes[1]->pattern); + $this->assertSame('GET', $routes[1]->methods[0]); + $this->assertSame([TodosController::class, 'show'], $routes[1]->callback); } + + public function testOptionsMiddlewareAndAliasBase(): void + { + Flight::resource('/todos', TodosController::class, [ + 'middleware' => [ 'auth' ], + 'alias_base' => 'nothanks' + ]); + + $routes = Flight::router()->getRoutes(); + + $this->assertCount(7, $routes); + + $this->assertSame('/todos', $routes[0]->pattern); + $this->assertSame('GET', $routes[0]->methods[0]); + $this->assertSame([TodosController::class, 'index'], $routes[0]->callback); + $this->assertSame('auth', $routes[0]->middleware[0]); + $this->assertSame('nothanks.index', $routes[0]->alias); + + $this->assertSame('/todos/create', $routes[1]->pattern); + $this->assertSame('GET', $routes[1]->methods[0]); + $this->assertSame([TodosController::class, 'create'], $routes[1]->callback); + $this->assertSame('auth', $routes[1]->middleware[0]); + $this->assertSame('nothanks.create', $routes[1]->alias); + } } diff --git a/tests/groupcompactsyntax/UsersController.php b/tests/groupcompactsyntax/UsersController.php index 90e1b68f..2727ac6e 100644 --- a/tests/groupcompactsyntax/UsersController.php +++ b/tests/groupcompactsyntax/UsersController.php @@ -4,12 +4,12 @@ final class UsersController { - public function list(): void + public function index(): void { echo __METHOD__; } - public function handleRegister(): void + public function destroy(): void { echo __METHOD__; } From a788c8a6081b07ff1299fc52160dfc0d68c9ad78 Mon Sep 17 00:00:00 2001 From: n0nag0n Date: Fri, 27 Sep 2024 23:35:20 -0600 Subject: [PATCH 5/6] prettify --- flight/Engine.php | 4 +- flight/net/Router.php | 6 +- .../FlightRouteCompactSyntaxTest.php | 78 ++++++++++--------- tests/groupcompactsyntax/PostsController.php | 2 + tests/groupcompactsyntax/TodosController.php | 2 + tests/groupcompactsyntax/UsersController.php | 2 + 6 files changed, 51 insertions(+), 43 deletions(-) diff --git a/flight/Engine.php b/flight/Engine.php index 83f0c1b3..12352290 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -733,14 +733,14 @@ public function _delete(string $pattern, $callback, bool $pass_route = false, st * Create a resource controller customizing the methods names mapping. * * @param class-string $controllerClass - * @param array $options + * @param array> $options */ public function _resource( string $pattern, string $controllerClass, array $options = [] ): void { - $this->router()->mapResource($pattern, $controllerClass, $options); + $this->router()->mapResource($pattern, $controllerClass, $options); } /** diff --git a/flight/net/Router.php b/flight/net/Router.php index f80fab60..50275ac0 100644 --- a/flight/net/Router.php +++ b/flight/net/Router.php @@ -276,13 +276,13 @@ public function getUrlByAlias(string $alias, array $params = []): string throw new Exception($exception_message); } - /** + /** * Create a resource controller customizing the methods names mapping. * * @param class-string $controllerClass - * @param array $options + * @param array> $options */ - public function mapResource( + public function mapResource( string $pattern, string $controllerClass, array $options = [] diff --git a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php index 719946d6..1f438bb8 100644 --- a/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php +++ b/tests/groupcompactsyntax/FlightRouteCompactSyntaxTest.php @@ -1,5 +1,7 @@ [ 'index', 'destroy' ] + 'only' => [ 'index', 'destroy' ] ]); $routes = Flight::router()->getRoutes(); @@ -62,79 +64,79 @@ public function testDefaultMethods(): void $this->assertSame('/posts', $routes[0]->pattern); $this->assertSame('GET', $routes[0]->methods[0]); $this->assertSame([PostsController::class, 'index'], $routes[0]->callback); - $this->assertSame('posts.index', $routes[0]->alias); - + $this->assertSame('posts.index', $routes[0]->alias); + $this->assertSame('/posts/create', $routes[1]->pattern); $this->assertSame('GET', $routes[1]->methods[0]); $this->assertSame([PostsController::class, 'create'], $routes[1]->callback); - $this->assertSame('posts.create', $routes[1]->alias); - + $this->assertSame('posts.create', $routes[1]->alias); + $this->assertSame('/posts', $routes[2]->pattern); $this->assertSame('POST', $routes[2]->methods[0]); $this->assertSame([PostsController::class, 'store'], $routes[2]->callback); - $this->assertSame('posts.store', $routes[2]->alias); - + $this->assertSame('posts.store', $routes[2]->alias); + $this->assertSame('/posts/@id', $routes[3]->pattern); $this->assertSame('GET', $routes[3]->methods[0]); $this->assertSame([PostsController::class, 'show'], $routes[3]->callback); - $this->assertSame('posts.show', $routes[3]->alias); + $this->assertSame('posts.show', $routes[3]->alias); $this->assertSame('/posts/@id/edit', $routes[4]->pattern); $this->assertSame('GET', $routes[4]->methods[0]); $this->assertSame([PostsController::class, 'edit'], $routes[4]->callback); - $this->assertSame('posts.edit', $routes[4]->alias); + $this->assertSame('posts.edit', $routes[4]->alias); $this->assertSame('/posts/@id', $routes[5]->pattern); $this->assertSame('PUT', $routes[5]->methods[0]); $this->assertSame([PostsController::class, 'update'], $routes[5]->callback); - $this->assertSame('posts.update', $routes[5]->alias); + $this->assertSame('posts.update', $routes[5]->alias); $this->assertSame('/posts/@id', $routes[6]->pattern); $this->assertSame('DELETE', $routes[6]->methods[0]); $this->assertSame([PostsController::class, 'destroy'], $routes[6]->callback); - $this->assertSame('posts.destroy', $routes[6]->alias); + $this->assertSame('posts.destroy', $routes[6]->alias); } public function testOptionsExcept(): void { Flight::resource('/todos', TodosController::class, [ - 'except' => [ 'create', 'store', 'update', 'destroy', 'edit' ] - ]); + 'except' => [ 'create', 'store', 'update', 'destroy', 'edit' ] + ]); $routes = Flight::router()->getRoutes(); $this->assertCount(2, $routes); - $this->assertSame('/todos', $routes[0]->pattern); + $this->assertSame('/todos', $routes[0]->pattern); $this->assertSame('GET', $routes[0]->methods[0]); $this->assertSame([TodosController::class, 'index'], $routes[0]->callback); - $this->assertSame('/todos/@id', $routes[1]->pattern); + $this->assertSame('/todos/@id', $routes[1]->pattern); $this->assertSame('GET', $routes[1]->methods[0]); $this->assertSame([TodosController::class, 'show'], $routes[1]->callback); } - public function testOptionsMiddlewareAndAliasBase(): void - { - Flight::resource('/todos', TodosController::class, [ - 'middleware' => [ 'auth' ], - 'alias_base' => 'nothanks' - ]); - - $routes = Flight::router()->getRoutes(); - - $this->assertCount(7, $routes); - - $this->assertSame('/todos', $routes[0]->pattern); - $this->assertSame('GET', $routes[0]->methods[0]); - $this->assertSame([TodosController::class, 'index'], $routes[0]->callback); - $this->assertSame('auth', $routes[0]->middleware[0]); - $this->assertSame('nothanks.index', $routes[0]->alias); - - $this->assertSame('/todos/create', $routes[1]->pattern); - $this->assertSame('GET', $routes[1]->methods[0]); - $this->assertSame([TodosController::class, 'create'], $routes[1]->callback); - $this->assertSame('auth', $routes[1]->middleware[0]); - $this->assertSame('nothanks.create', $routes[1]->alias); - } + public function testOptionsMiddlewareAndAliasBase(): void + { + Flight::resource('/todos', TodosController::class, [ + 'middleware' => [ 'auth' ], + 'alias_base' => 'nothanks' + ]); + + $routes = Flight::router()->getRoutes(); + + $this->assertCount(7, $routes); + + $this->assertSame('/todos', $routes[0]->pattern); + $this->assertSame('GET', $routes[0]->methods[0]); + $this->assertSame([TodosController::class, 'index'], $routes[0]->callback); + $this->assertSame('auth', $routes[0]->middleware[0]); + $this->assertSame('nothanks.index', $routes[0]->alias); + + $this->assertSame('/todos/create', $routes[1]->pattern); + $this->assertSame('GET', $routes[1]->methods[0]); + $this->assertSame([TodosController::class, 'create'], $routes[1]->callback); + $this->assertSame('auth', $routes[1]->middleware[0]); + $this->assertSame('nothanks.create', $routes[1]->alias); + } } diff --git a/tests/groupcompactsyntax/PostsController.php b/tests/groupcompactsyntax/PostsController.php index ac2c4975..bae82422 100644 --- a/tests/groupcompactsyntax/PostsController.php +++ b/tests/groupcompactsyntax/PostsController.php @@ -1,5 +1,7 @@ Date: Fri, 27 Sep 2024 23:41:45 -0600 Subject: [PATCH 6/6] fix bad resolve --- flight/Engine.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/flight/Engine.php b/flight/Engine.php index df06a8cd..d52f4988 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -600,11 +600,7 @@ public function _start(): void */ public function _error(Throwable $e): void { - $msg = sprintf( - - - - HTML + $msg = sprintf(<<500 Internal Server Error

%s (%s)

%s