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
			
			
This commit is contained in:
		| @@ -10,7 +10,7 @@ class Kernel extends BaseKernel | ||||
| { | ||||
|     protected function dependencies(ContainerInterface $container): void | ||||
|     { | ||||
|         $this->addRoutes($container, [ | ||||
|         $this->addControllers($container, [ | ||||
|             BaseController::class, | ||||
|         ]); | ||||
|     } | ||||
|   | ||||
| @@ -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, | ||||
|     ) | ||||
|     { | ||||
|     } | ||||
|   | ||||
| @@ -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); | ||||
|     } | ||||
| } | ||||
							
								
								
									
										31
									
								
								src/Http/RouteConfig.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/Http/RouteConfig.php
									
									
									
									
									
										Normal file
									
								
							| @@ -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; | ||||
|     } | ||||
| } | ||||
							
								
								
									
										16
									
								
								src/Http/RouteNotFoundException.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/Http/RouteNotFoundException.php
									
									
									
									
									
										Normal file
									
								
							| @@ -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() | ||||
|         )); | ||||
|     } | ||||
| } | ||||
| @@ -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; | ||||
|     } | ||||
| } | ||||
| @@ -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 | ||||
|   | ||||
		Reference in New Issue
	
	Block a user