Implement commands
This commit is contained in:
parent
1ee5c1c992
commit
f8d1c66934
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);
|
|
||||||
}
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user