Implement commands
This commit is contained in:
		
							
								
								
									
										17
									
								
								app/Console/TestCommand.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								app/Console/TestCommand.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,17 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace App\Console; | ||||||
|  |  | ||||||
|  |  | ||||||
|  | use Ardent\Undercurrent\Attribute\Command; | ||||||
|  | use Ardent\Undercurrent\Console\BaseCommand; | ||||||
|  | use Ardent\Undercurrent\Console\Output; | ||||||
|  |  | ||||||
|  | #[Command('app:test')] | ||||||
|  | class TestCommand extends BaseCommand | ||||||
|  | { | ||||||
|  |     protected function run(Output $output): void | ||||||
|  |     { | ||||||
|  |         $output->printLine('Hello, command!'); | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -7,7 +7,7 @@ use App\View\RouteView; | |||||||
| use Ardent\Undercurrent\Attribute\Route; | use Ardent\Undercurrent\Attribute\Route; | ||||||
| use Ardent\Undercurrent\Http\GenericResponse; | use Ardent\Undercurrent\Http\GenericResponse; | ||||||
| use Ardent\Undercurrent\Http\ResponseInterface; | use Ardent\Undercurrent\Http\ResponseInterface; | ||||||
| use Ardent\Undercurrent\Http\RouterConfig; | use Ardent\Undercurrent\Http\RoutesConfig; | ||||||
| use Ardent\Undercurrent\Http\StatusEnum; | use Ardent\Undercurrent\Http\StatusEnum; | ||||||
| use Ardent\Undercurrent\View\BaseView; | use Ardent\Undercurrent\View\BaseView; | ||||||
| use Ardent\Undercurrent\View\ViewInterface; | use Ardent\Undercurrent\View\ViewInterface; | ||||||
| @@ -40,7 +40,7 @@ class HelloWorldController | |||||||
|     } |     } | ||||||
|  |  | ||||||
|     #[Route('/routes')] |     #[Route('/routes')] | ||||||
|     public function routes(RouterConfig $config): ViewInterface |     public function routes(RoutesConfig $config): ViewInterface | ||||||
|     { |     { | ||||||
|         return new RouteView($config); |         return new RouteView($config); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -10,4 +10,22 @@ class Book | |||||||
| { | { | ||||||
|     #[ORM\Id, ORM\Column, ORM\GeneratedValue] |     #[ORM\Id, ORM\Column, ORM\GeneratedValue] | ||||||
|     private int $id; |     private int $id; | ||||||
|  |  | ||||||
|  |     #[ORM\Column] | ||||||
|  |     private string $title; | ||||||
|  |  | ||||||
|  |     public function getId(): int | ||||||
|  |     { | ||||||
|  |         return $this->id; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function getTitle(): string | ||||||
|  |     { | ||||||
|  |         return $this->title; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function setTitle(string $title): void | ||||||
|  |     { | ||||||
|  |         $this->title = $title; | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -2,16 +2,23 @@ | |||||||
|  |  | ||||||
| namespace App; | namespace App; | ||||||
|  |  | ||||||
|  | use App\Console\TestCommand; | ||||||
| use App\Controller\HelloWorldController; | use App\Controller\HelloWorldController; | ||||||
|  | use Ardent\Undercurrent\Console\CommandsConfig; | ||||||
| use Ardent\Undercurrent\Container\ContainerInterface; | use Ardent\Undercurrent\Container\ContainerInterface; | ||||||
|  | use Ardent\Undercurrent\Http\RoutesConfig; | ||||||
| use Ardent\Undercurrent\Kernel\BaseKernel; | use Ardent\Undercurrent\Kernel\BaseKernel; | ||||||
|  |  | ||||||
| class Kernel extends BaseKernel | class Kernel extends BaseKernel | ||||||
| { | { | ||||||
|     protected function dependencies(ContainerInterface $container): void |     protected function dependencies(ContainerInterface $container): void | ||||||
|     { |     { | ||||||
|         $this->addControllers($container, [ |         $routes = new RoutesConfig(); | ||||||
|             HelloWorldController::class, |         $routes->add(HelloWorldController::class); | ||||||
|         ]); |         $this->addControllers($container, $routes); | ||||||
|  |  | ||||||
|  |         $commands = new CommandsConfig(); | ||||||
|  |         $commands->add(TestCommand::class); | ||||||
|  |         $this->addCommands($container, $commands); | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -2,12 +2,12 @@ | |||||||
|  |  | ||||||
| namespace App\View; | namespace App\View; | ||||||
|  |  | ||||||
| use Ardent\Undercurrent\Http\RouterConfig; | use Ardent\Undercurrent\Http\RoutesConfig; | ||||||
| use Ardent\Undercurrent\View\BaseView; | use Ardent\Undercurrent\View\BaseView; | ||||||
|  |  | ||||||
| class RouteView extends BaseView | class RouteView extends BaseView | ||||||
| { | { | ||||||
|     public function __construct(protected readonly RouterConfig $routes) |     public function __construct(protected readonly RoutesConfig $routes) | ||||||
|     { |     { | ||||||
|         parent::__construct('/routes.php', extends: '/base'); |         parent::__construct('/routes.php', extends: '/base'); | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -3,9 +3,12 @@ | |||||||
|  |  | ||||||
| use App\Kernel; | use App\Kernel; | ||||||
| use Ardent\Undercurrent\Config\AppConfig; | use Ardent\Undercurrent\Config\AppConfig; | ||||||
|  | use Ardent\Undercurrent\Console\Console; | ||||||
|  |  | ||||||
| require_once dirname(__DIR__) . '/vendor/autoload.php'; | require_once dirname(__DIR__) . '/vendor/autoload.php'; | ||||||
|  |  | ||||||
| $kernel = new Kernel(new AppConfig(__DIR__ . '/../app')); | $kernel = new Kernel(new AppConfig(__DIR__ . '/../app')); | ||||||
| $container = $kernel->setup(); | $container = $kernel->setup(); | ||||||
|  |  | ||||||
|  | $console = new Console($container); | ||||||
|  | $console->run(); | ||||||
| @@ -8,7 +8,7 @@ error_reporting(E_ALL); | |||||||
|  |  | ||||||
| use App\Kernel; | use App\Kernel; | ||||||
| use Ardent\Undercurrent\Config\AppConfig; | use Ardent\Undercurrent\Config\AppConfig; | ||||||
| use Ardent\Undercurrent\Kernel\Renderer; | use Ardent\Undercurrent\Http\Renderer; | ||||||
|  |  | ||||||
| require_once dirname(__DIR__) . '/vendor/autoload.php'; | require_once dirname(__DIR__) . '/vendor/autoload.php'; | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								src/Attribute/Command.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								src/Attribute/Command.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,15 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace Ardent\Undercurrent\Attribute; | ||||||
|  |  | ||||||
|  | use Attribute; | ||||||
|  |  | ||||||
|  | #[Attribute] | ||||||
|  | class Command | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         public string $signature, | ||||||
|  |     ) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										13
									
								
								src/Console/BaseCommand.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								src/Console/BaseCommand.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,13 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace Ardent\Undercurrent\Console; | ||||||
|  |  | ||||||
|  | abstract class BaseCommand | ||||||
|  | { | ||||||
|  |     public function execute(Output $output): void | ||||||
|  |     { | ||||||
|  |         $this->run($output); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     abstract protected function run(Output $output): void; | ||||||
|  | } | ||||||
							
								
								
									
										40
									
								
								src/Console/CommandsConfig.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/Console/CommandsConfig.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,40 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace Ardent\Undercurrent\Console; | ||||||
|  |  | ||||||
|  | use Ardent\Undercurrent\Attribute\Command; | ||||||
|  | use ReflectionAttribute; | ||||||
|  | use ReflectionClass; | ||||||
|  |  | ||||||
|  | class CommandsConfig | ||||||
|  | { | ||||||
|  |     private array $commands = []; | ||||||
|  |  | ||||||
|  |     public function add(string $commandClass): self | ||||||
|  |     { | ||||||
|  |         $reflectionClass = new ReflectionClass($commandClass); | ||||||
|  |  | ||||||
|  |         $attributes = $reflectionClass->getAttributes(Command::class, ReflectionAttribute::IS_INSTANCEOF); | ||||||
|  |  | ||||||
|  |         if (count($attributes) === 0) { | ||||||
|  |             return $this; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $command = $attributes[0]->newInstance(); | ||||||
|  |  | ||||||
|  |         $this->commands[] = [ | ||||||
|  |             $command, | ||||||
|  |             $commandClass, | ||||||
|  |         ]; | ||||||
|  |  | ||||||
|  |         return $this; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     /** | ||||||
|  |      * @return array<array{Command, string}> | ||||||
|  |      */ | ||||||
|  |     public function getCommands(): array | ||||||
|  |     { | ||||||
|  |         return $this->commands; | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										39
									
								
								src/Console/Console.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								src/Console/Console.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace Ardent\Undercurrent\Console; | ||||||
|  |  | ||||||
|  | use Ardent\Undercurrent\Container\ContainerInterface; | ||||||
|  |  | ||||||
|  | class Console | ||||||
|  | { | ||||||
|  |     public function __construct( | ||||||
|  |         private readonly ContainerInterface $container, | ||||||
|  |     ) | ||||||
|  |     { | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     public function run(): void | ||||||
|  |     { | ||||||
|  |         $argv = $_SERVER['argv']; | ||||||
|  |         $command = $argv[1] ?? ''; | ||||||
|  |  | ||||||
|  |         $output = new Output(); | ||||||
|  |  | ||||||
|  |         if (empty($command)) { | ||||||
|  |             $output->printLine('No command defined'); | ||||||
|  |             return; | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $config = $this->container->get(CommandsConfig::class); | ||||||
|  |  | ||||||
|  |         foreach ($config->getCommands() as [$commandConfig, $commandClass]) { | ||||||
|  |             if ($commandConfig->signature === $command) { | ||||||
|  |                 $commandInstance = $this->container->get($commandClass); | ||||||
|  |                 $commandInstance->execute($output); | ||||||
|  |                 return; | ||||||
|  |             } | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $output->printLine(sprintf('Command not found: "%s"', $command)); | ||||||
|  |     } | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								src/Console/Output.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								src/Console/Output.php
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,11 @@ | |||||||
|  | <?php | ||||||
|  |  | ||||||
|  | namespace Ardent\Undercurrent\Console; | ||||||
|  |  | ||||||
|  | class Output | ||||||
|  | { | ||||||
|  |     public function printLine(string $line): void | ||||||
|  |     { | ||||||
|  |         echo $line . PHP_EOL; | ||||||
|  |     } | ||||||
|  | } | ||||||
| @@ -13,7 +13,7 @@ class GenericRouter implements RouterInterface | |||||||
|     public function __construct( |     public function __construct( | ||||||
|         private readonly ContainerInterface $container, |         private readonly ContainerInterface $container, | ||||||
|         private readonly LoggerInterface    $logger, |         private readonly LoggerInterface    $logger, | ||||||
|         private readonly RouterConfig       $config, |         private readonly RoutesConfig       $config, | ||||||
|     ) |     ) | ||||||
|     { |     { | ||||||
|     } |     } | ||||||
|   | |||||||
| @@ -1,13 +1,8 @@ | |||||||
| <?php | <?php | ||||||
| 
 | 
 | ||||||
| namespace Ardent\Undercurrent\Kernel; | namespace Ardent\Undercurrent\Http; | ||||||
| 
 | 
 | ||||||
| use Ardent\Undercurrent\Container\ContainerInterface; | use Ardent\Undercurrent\Container\ContainerInterface; | ||||||
| use Ardent\Undercurrent\Http\GenericRequest; |  | ||||||
| use Ardent\Undercurrent\Http\GenericResponse; |  | ||||||
| use Ardent\Undercurrent\Http\MethodEnum; |  | ||||||
| use Ardent\Undercurrent\Http\RouterInterface; |  | ||||||
| use Ardent\Undercurrent\Http\StatusEnum; |  | ||||||
| use Ardent\Undercurrent\Logger\LogContainer; | use Ardent\Undercurrent\Logger\LogContainer; | ||||||
| 
 | 
 | ||||||
| class Renderer | class Renderer | ||||||
| @@ -34,7 +29,7 @@ class Renderer | |||||||
|                 $e->getMessage(), |                 $e->getMessage(), | ||||||
|                 StatusEnum::NOT_FOUND |                 StatusEnum::NOT_FOUND | ||||||
|             ); |             ); | ||||||
|             //$response = $container->get(RouterConfig::class)->getExceptionRoute()->getController()::exception($e);
 |             //$response = $container->get(RoutesConfig::class)->getExceptionRoute()->getController()::exception($e);
 | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         http_response_code($response->getStatus()->value); |         http_response_code($response->getStatus()->value); | ||||||
| @@ -6,16 +6,19 @@ use Ardent\Undercurrent\Attribute\Route; | |||||||
| use ReflectionAttribute; | use ReflectionAttribute; | ||||||
| use ReflectionClass; | use ReflectionClass; | ||||||
| 
 | 
 | ||||||
| class RouterConfig | class RoutesConfig | ||||||
| { | { | ||||||
|     /** |     /** | ||||||
|      * @var array<RouteConfig> |      * @var array<RouteConfig> | ||||||
|      */ |      */ | ||||||
|     private array $routes = []; |     private array $routes = []; | ||||||
| 
 | 
 | ||||||
|     public function addController(string $controller): self |     private array $controllers = []; | ||||||
|  | 
 | ||||||
|  |     public function add(string $controllerClass): self | ||||||
|     { |     { | ||||||
|         $reflectionClass = new ReflectionClass($controller); |         $this->controllers[] = $controllerClass; | ||||||
|  |         $reflectionClass = new ReflectionClass($controllerClass); | ||||||
| 
 | 
 | ||||||
|         foreach ($reflectionClass->getMethods() as $method) { |         foreach ($reflectionClass->getMethods() as $method) { | ||||||
|             $attributes = $method->getAttributes(Route::class, ReflectionAttribute::IS_INSTANCEOF); |             $attributes = $method->getAttributes(Route::class, ReflectionAttribute::IS_INSTANCEOF); | ||||||
| @@ -28,7 +31,7 @@ class RouterConfig | |||||||
| 
 | 
 | ||||||
|             $this->routes[] = new RouteConfig( |             $this->routes[] = new RouteConfig( | ||||||
|                 $route, |                 $route, | ||||||
|                 $controller, |                 $controllerClass, | ||||||
|                 $method->getName(), |                 $method->getName(), | ||||||
|             ); |             ); | ||||||
|         } |         } | ||||||
| @@ -43,4 +46,9 @@ class RouterConfig | |||||||
|     { |     { | ||||||
|         return $this->routes; |         return $this->routes; | ||||||
|     } |     } | ||||||
|  | 
 | ||||||
|  |     public function getControllers(): array | ||||||
|  |     { | ||||||
|  |         return $this->controllers; | ||||||
|  |     } | ||||||
| } | } | ||||||
| @@ -4,10 +4,11 @@ namespace Ardent\Undercurrent\Kernel; | |||||||
|  |  | ||||||
| use Ardent\Undercurrent\Config\AppConfig; | use Ardent\Undercurrent\Config\AppConfig; | ||||||
| use Ardent\Undercurrent\Config\GenericConfig; | use Ardent\Undercurrent\Config\GenericConfig; | ||||||
|  | use Ardent\Undercurrent\Console\CommandsConfig; | ||||||
| use Ardent\Undercurrent\Container\ContainerInterface; | use Ardent\Undercurrent\Container\ContainerInterface; | ||||||
| use Ardent\Undercurrent\Container\GenericContainer; | use Ardent\Undercurrent\Container\GenericContainer; | ||||||
| use Ardent\Undercurrent\Http\GenericRouter; | use Ardent\Undercurrent\Http\GenericRouter; | ||||||
| use Ardent\Undercurrent\Http\RouterConfig; | use Ardent\Undercurrent\Http\RoutesConfig; | ||||||
| use Ardent\Undercurrent\Http\RouterInterface; | use Ardent\Undercurrent\Http\RouterInterface; | ||||||
| use Ardent\Undercurrent\Logger\LogContainer; | use Ardent\Undercurrent\Logger\LogContainer; | ||||||
| use Ardent\Undercurrent\Logger\LoggerInterface; | use Ardent\Undercurrent\Logger\LoggerInterface; | ||||||
| @@ -56,16 +57,22 @@ class BaseKernel | |||||||
|         return $container; |         return $container; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected function addControllers(ContainerInterface $container, array $controllers): void |     protected function addControllers(ContainerInterface $container, RoutesConfig $routes): void | ||||||
|     { |     { | ||||||
|         $config = new RouterConfig(); |         foreach ($routes->getControllers() as $controller) { | ||||||
|  |  | ||||||
|         foreach ($controllers as $controller) { |  | ||||||
|             $container->add($controller); |             $container->add($controller); | ||||||
|             $config->addController($controller); |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         $container->add(RouterConfig::class, fn() => $config); |         $container->add(RoutesConfig::class, fn() => $routes); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     protected function addCommands(ContainerInterface $container, CommandsConfig $commands): void | ||||||
|  |     { | ||||||
|  |         foreach ($commands->getCommands() as [$commandConfig, $commandClass]) { | ||||||
|  |             $container->add($commandClass); | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         $container->add(CommandsConfig::class, fn() => $commands); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|     protected function dependencies(ContainerInterface $container): void |     protected function dependencies(ContainerInterface $container): void | ||||||
|   | |||||||
| @@ -1,21 +0,0 @@ | |||||||
| <?php |  | ||||||
|  |  | ||||||
| namespace Ardent\Undercurrent\Kernel; |  | ||||||
|  |  | ||||||
| use Ardent\Undercurrent\Container\ContainerInterface; |  | ||||||
|  |  | ||||||
| class Console |  | ||||||
| { |  | ||||||
|     public function __construct( |  | ||||||
|         private readonly ContainerInterface $container, |  | ||||||
|     ) |  | ||||||
|     { |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|     public function run(): void |  | ||||||
|     { |  | ||||||
|         $argv = $_SERVER['argv']; |  | ||||||
|  |  | ||||||
|         dump($argv); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
		Reference in New Issue
	
	Block a user