diff --git a/flight/Engine.php b/flight/Engine.php index a1378a6..2c06adc 100644 --- a/flight/Engine.php +++ b/flight/Engine.php @@ -42,6 +42,8 @@ use flight\net\Route; * 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 @@ class Engine 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 020e546..70e8bdd 100644 --- a/flight/Flight.php +++ b/flight/Flight.php @@ -42,6 +42,8 @@ require_once __DIR__ . '/autoload.php'; * 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 @@ class Flight 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 {