a854480ff1
6 Commits
Author | SHA1 | Message | Date | |
---|---|---|---|---|
a854480ff1 |
Implement basic version of route matching
Make RouteConfig more readable diff --git a/app/Kernel.php b/app/Kernel.php index 4425355..a365d39 100644 --- a/app/Kernel.php +++ b/app/Kernel.php @@ -10,7 +10,7 @@ class Kernel extends BaseKernel { protected function dependencies(ContainerInterface $container): void { - $this->addRoutes($container, [ + $this->addControllers($container, [ BaseController::class, ]); } diff --git a/src/Attribute/Route.php b/src/Attribute/Route.php index 6bbd272..7129654 100644 --- a/src/Attribute/Route.php +++ b/src/Attribute/Route.php @@ -2,13 +2,15 @@ namespace Ardent\Undercurrent\Attribute; +use Ardent\Undercurrent\Http\MethodEnum; use Attribute; #[Attribute] class Route { public function __construct( - public string $path, + public string $path, + public ?MethodEnum $method = null, ) { } diff --git a/src/Http/GenericRouter.php b/src/Http/GenericRouter.php index fa1bc6a..73ce8f1 100644 --- a/src/Http/GenericRouter.php +++ b/src/Http/GenericRouter.php @@ -11,15 +11,21 @@ class GenericRouter implements RouterInterface { public function __construct( private readonly ContainerInterface $container, - private readonly RouterConfig $config, + private readonly RouterConfig $config, ) { } public function dispatch(RequestInterface $request): ResponseInterface { - $controller = $this->container->get(BaseController::class); - $method = 'helloWorld'; - return $controller->$method(); + foreach ($this->config->getRoutes() as $route) { + if ($route->getRoute()->path === $request->getUri()) { + $controller = $this->container->get($route->getController()); + $method = $route->getMethod(); + return $controller->$method(); + } + } + + throw new RouteNotFoundException($request); } } \ No newline at end of file diff --git a/src/Http/RouteConfig.php b/src/Http/RouteConfig.php new file mode 100644 index 0000000..00c2cb0 --- /dev/null +++ b/src/Http/RouteConfig.php @@ -0,0 +1,31 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +use Ardent\Undercurrent\Attribute\Route; + +class RouteConfig +{ + public function __construct( + private readonly Route $route, + private readonly string $controller, + private readonly string $method + ) + { + } + + public function getRoute(): Route + { + return $this->route; + } + + public function getController(): string + { + return $this->controller; + } + + public function getMethod(): string + { + return $this->method; + } +} \ No newline at end of file diff --git a/src/Http/RouteNotFoundException.php b/src/Http/RouteNotFoundException.php new file mode 100644 index 0000000..081c625 --- /dev/null +++ b/src/Http/RouteNotFoundException.php @@ -0,0 +1,16 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +use Exception; + +class RouteNotFoundException extends Exception +{ + public function __construct(RequestInterface $request) + { + parent::__construct(sprintf( + 'No controller found for uri: %s', + $request->getUri() + )); + } +} \ No newline at end of file diff --git a/src/Http/RouterConfig.php b/src/Http/RouterConfig.php index 60e5af7..eec5cde 100644 --- a/src/Http/RouterConfig.php +++ b/src/Http/RouterConfig.php @@ -2,16 +2,45 @@ namespace Ardent\Undercurrent\Http; +use Ardent\Undercurrent\Attribute\Route; +use ReflectionAttribute; +use ReflectionClass; + class RouterConfig { - public function __construct( - private readonly array $controllers = [], - ) + /** + * @var array<RouteConfig> + */ + private array $routes = []; + + public function addController(string $controller): self { + $reflectionClass = new ReflectionClass($controller); + + foreach ($reflectionClass->getMethods() as $method) { + $attributes = $method->getAttributes(Route::class, ReflectionAttribute::IS_INSTANCEOF); + + if (count($attributes) === 0) { + continue; + } + + $route = $attributes[0]->newInstance(); + + $this->routes[] = new RouteConfig( + $route, + $controller, + $method->getName(), + ); + } + + return $this; } - public function getControllers(): array + /** + * @return array<RouteConfig> + */ + public function getRoutes(): array { - return $this->controllers; + return $this->routes; } } \ No newline at end of file diff --git a/src/Kernel/BaseKernel.php b/src/Kernel/BaseKernel.php index 149aa8b..7122dcc 100644 --- a/src/Kernel/BaseKernel.php +++ b/src/Kernel/BaseKernel.php @@ -38,13 +38,16 @@ class BaseKernel echo $router->dispatch($request)->getBody(); } - protected function addRoutes(ContainerInterface $container, array $routes): void + protected function addControllers(ContainerInterface $container, array $controllers): void { - foreach ($routes as $route) { - $container->add($route); + $config = new RouterConfig(); + + foreach ($controllers as $controller) { + $container->add($controller); + $config->addController($controller); } - $container->add(RouterConfig::class, fn() => new RouterConfig($routes)); + $container->add(RouterConfig::class, fn() => $config); } protected function dependencies(ContainerInterface $container): void |
|||
96e833fb4b |
Move route config to app
diff --git a/app/Kernel.php b/app/Kernel.php index 0e8e047..4425355 100644 --- a/app/Kernel.php +++ b/app/Kernel.php @@ -2,8 +2,16 @@ namespace App; +use App\Controller\BaseController; +use Ardent\Undercurrent\Container\ContainerInterface; use Ardent\Undercurrent\Kernel\BaseKernel; class Kernel extends BaseKernel { + protected function dependencies(ContainerInterface $container): void + { + $this->addRoutes($container, [ + BaseController::class, + ]); + } } \ No newline at end of file diff --git a/src/Http/RouterConfig.php b/src/Http/RouterConfig.php index ad856d6..60e5af7 100644 --- a/src/Http/RouterConfig.php +++ b/src/Http/RouterConfig.php @@ -4,7 +4,6 @@ namespace Ardent\Undercurrent\Http; class RouterConfig { - public function __construct( private readonly array $controllers = [], ) diff --git a/src/Kernel/BaseKernel.php b/src/Kernel/BaseKernel.php index a6732f4..149aa8b 100644 --- a/src/Kernel/BaseKernel.php +++ b/src/Kernel/BaseKernel.php @@ -2,7 +2,6 @@ namespace Ardent\Undercurrent\Kernel; -use App\Controller\BaseController; use Ardent\Undercurrent\Container\ContainerInterface; use Ardent\Undercurrent\Container\GenericContainer; use Ardent\Undercurrent\Http\GenericRequest; @@ -20,12 +19,9 @@ class BaseKernel ->alias(RouterInterface::class, GenericRouter::class) ->alias(ContainerInterface::class, GenericContainer::class) ->add(GenericContainer::class, fn($container) => $container) - ->add(GenericRouter::class) - ->add(BaseController::class); + ->add(GenericRouter::class); - $container->add(RouterConfig::class, fn() => new RouterConfig([ - BaseController::class, - ])); + $this->dependencies($container); $this->render($container); } @@ -41,4 +37,17 @@ class BaseKernel $router = $container->get(RouterInterface::class); echo $router->dispatch($request)->getBody(); } + + protected function addRoutes(ContainerInterface $container, array $routes): void + { + foreach ($routes as $route) { + $container->add($route); + } + + $container->add(RouterConfig::class, fn() => new RouterConfig($routes)); + } + + protected function dependencies(ContainerInterface $container): void + { + } } \ No newline at end of file |
|||
a55d1c3c2e |
Properly implement the router with config and interfaces
Expand the container with aliases and argument autowiring |
|||
e9a636554f |
Add response and request objects and interfaces
diff --git a/README.md b/README.md index 4b64da1..c860957 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,7 @@ Todos: - [ ] Collect routes properly - [ ] Process routes correctly +- [ ] Add request and response objects diff --git a/app/Controller/BaseController.php b/app/Controller/BaseController.php index aa0a79b..7df9387 100644 --- a/app/Controller/BaseController.php +++ b/app/Controller/BaseController.php @@ -3,12 +3,14 @@ namespace App\Controller; use Ardent\Undercurrent\Attribute\Route; +use Ardent\Undercurrent\Http\GenericResponse; +use Ardent\Undercurrent\Http\ResponseInterface; class BaseController { #[Route('/hello')] - public function HelloWorld(): string + public function HelloWorld(): ResponseInterface { - return 'Hello, World!'; + return new GenericResponse('Hello World!'); } } \ No newline at end of file diff --git a/src/Http/GenericRequest.php b/src/Http/GenericRequest.php new file mode 100644 index 0000000..c758a40 --- /dev/null +++ b/src/Http/GenericRequest.php @@ -0,0 +1,30 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +class GenericRequest implements RequestInterface +{ + + public function __construct( + private readonly MethodEnum $method, + private readonly string $uri, + private readonly array $body, + ) + { + } + + public function getMethod(): MethodEnum + { + return $this->method; + } + + public function getUri(): string + { + return $this->uri; + } + + public function getBody(): array + { + return $this->body; + } +} \ No newline at end of file diff --git a/src/Http/GenericResponse.php b/src/Http/GenericResponse.php new file mode 100644 index 0000000..d80d350 --- /dev/null +++ b/src/Http/GenericResponse.php @@ -0,0 +1,23 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +class GenericResponse implements ResponseInterface +{ + public function __construct( + private readonly string $body, + private readonly StatusEnum $status = StatusEnum::OK, + ) + { + } + + public function getStatus(): StatusEnum + { + return $this->status; + } + + public function getBody(): string + { + return $this->body; + } +} \ No newline at end of file diff --git a/src/Controller/GenericRouter.php b/src/Http/GenericRouter.php similarity index 89% rename from src/Controller/GenericRouter.php rename to src/Http/GenericRouter.php index 28f75b1..0332ce5 100644 --- a/src/Controller/GenericRouter.php +++ b/src/Http/GenericRouter.php @@ -1,6 +1,6 @@ <?php -namespace Ardent\Undercurrent\Controller; +namespace Ardent\Undercurrent\Http; use App\Controller\BaseController; use Ardent\Undercurrent\Attribute\Route; diff --git a/src/Http/MethodEnum.php b/src/Http/MethodEnum.php new file mode 100644 index 0000000..76948c9 --- /dev/null +++ b/src/Http/MethodEnum.php @@ -0,0 +1,16 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +enum MethodEnum: string +{ + case GET = 'GET'; + case POST = 'POST'; +// case PUT = 'PUT'; +// case PATCH = 'PATCH'; +// case DELETE = 'DELETE'; +// case HEAD = 'HEAD'; +// case OPTIONS = 'OPTIONS'; +// case TRACE = 'TRACE'; +// case CONNECT = 'CONNECT'; +} diff --git a/src/Http/RequestInterface.php b/src/Http/RequestInterface.php new file mode 100644 index 0000000..0f564b8 --- /dev/null +++ b/src/Http/RequestInterface.php @@ -0,0 +1,12 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +interface RequestInterface +{ + public function getMethod(): MethodEnum; + + public function getUri(): string; + + public function getBody(): array; +} \ No newline at end of file diff --git a/src/Http/ResponseInterface.php b/src/Http/ResponseInterface.php new file mode 100644 index 0000000..abdc290 --- /dev/null +++ b/src/Http/ResponseInterface.php @@ -0,0 +1,10 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +interface ResponseInterface +{ + public function getStatus(): StatusEnum; + + public function getBody(): string; +} \ No newline at end of file diff --git a/src/Http/RouterInterface.php b/src/Http/RouterInterface.php new file mode 100644 index 0000000..186baac --- /dev/null +++ b/src/Http/RouterInterface.php @@ -0,0 +1,8 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +interface RouterInterface +{ + public function dispatch(RequestInterface $request): ResponseInterface; +} \ No newline at end of file diff --git a/src/Http/StatusEnum.php b/src/Http/StatusEnum.php new file mode 100644 index 0000000..6dce100 --- /dev/null +++ b/src/Http/StatusEnum.php @@ -0,0 +1,10 @@ +<?php + +namespace Ardent\Undercurrent\Http; + +enum StatusEnum: int +{ + case OK = 200; + case FORBIDDEN = 403; + case NOT_FOUND = 404; +} diff --git a/src/Kernel/BaseKernel.php b/src/Kernel/BaseKernel.php index 6bc8ed5..05ecf06 100644 --- a/src/Kernel/BaseKernel.php +++ b/src/Kernel/BaseKernel.php @@ -4,11 +4,12 @@ namespace Ardent\Undercurrent\Kernel; use App\Controller\BaseController; use Ardent\Undercurrent\Container\GenericContainer; -use Ardent\Undercurrent\Controller\GenericRouter; +use Ardent\Undercurrent\Http\GenericRouter; +use Ardent\Undercurrent\Http\ResponseInterface; class BaseKernel { - public function __invoke() + public function __invoke(): void { $container = new GenericContainer(); $container->add(GenericRouter::class); @@ -23,6 +24,6 @@ class BaseKernel $route = $router->getRoute($_SERVER['REQUEST_URI']); $controller = $container->get($route['controller']); $method = $route['method']; - echo $controller->$method(); + echo $controller->$method()->getBody(); } } \ No newline at end of file |
|||
68ccd37f07 | Move public to make it compatible with symfony nginx files | |||
503d8c524a | First working version with non working routes |