Add doctrine and seperate out the renderer

This commit is contained in:
Tim 2023-08-16 14:28:06 +02:00
parent 56e8caa26c
commit 59200be680
11 changed files with 2158 additions and 54 deletions

View File

@ -2,6 +2,7 @@
namespace App\Controller; namespace App\Controller;
use App\Entity\Book;
use App\View\RouteView; use App\View\RouteView;
use Ardent\Undercurrent\Attribute\Route; use Ardent\Undercurrent\Attribute\Route;
use Ardent\Undercurrent\Http\GenericResponse; use Ardent\Undercurrent\Http\GenericResponse;
@ -10,6 +11,7 @@ use Ardent\Undercurrent\Http\RouterConfig;
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;
use Doctrine\ORM\EntityManager;
class HelloWorldController class HelloWorldController
{ {
@ -48,4 +50,13 @@ class HelloWorldController
{ {
return new GenericResponse("Hello $name!"); return new GenericResponse("Hello $name!");
} }
#[Route('/db')]
public function db(EntityManager $em): ResponseInterface
{
$repo = $em->getRepository(Book::class);
dump($repo->findAll());
return new GenericResponse("DB stuff");
}
} }

13
app/Entity/Book.php Normal file
View File

@ -0,0 +1,13 @@
<?php
namespace App\Entity;
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
#[ORM\Table(name: 'book')]
class Book
{
#[ORM\Id, ORM\Column, ORM\GeneratedValue]
private int $id;
}

10
app/bin.php Normal file
View File

@ -0,0 +1,10 @@
<?php
use App\Kernel;
use Ardent\Undercurrent\Config\AppConfig;
require_once dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new Kernel(new AppConfig(__DIR__ . '/../app'));
$container = $kernel->setup();

View File

@ -5,5 +5,12 @@ namespace App;
use Ardent\Undercurrent\Config\GenericConfig; use Ardent\Undercurrent\Config\GenericConfig;
return new GenericConfig([ return new GenericConfig([
'key' => 'value', 'dev' => true,
'orm' => [
'driver' => 'pdo_mysql',
'host' => 'localhost',
'user' => 'root',
'password' => 'password',
'db' => 'db',
],
]); ]);

View File

@ -3,7 +3,9 @@
"description": "A tiny no nonsense php framework", "description": "A tiny no nonsense php framework",
"type": "library", "type": "library",
"require": { "require": {
"php": "^8.1" "php": "^8.1",
"doctrine/orm": "^2.16",
"symfony/cache": "^6.3"
}, },
"autoload": { "autoload": {
"psr-4": { "psr-4": {

2027
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -7,8 +7,13 @@ ini_set('display_startup_errors', 1);
error_reporting(E_ALL); error_reporting(E_ALL);
use App\Kernel; use App\Kernel;
use Ardent\Undercurrent\Config\AppConfig;
use Ardent\Undercurrent\Http\Renderer;
require_once dirname(__DIR__) . '/vendor/autoload.php'; require_once dirname(__DIR__) . '/vendor/autoload.php';
$kernel = new Kernel(__DIR__ . '/../app'); $kernel = new Kernel(new AppConfig(__DIR__ . '/../app'));
$kernel->run(); $container = $kernel->setup();
$renderer = new Renderer($container);
$renderer->render();

View File

@ -6,7 +6,8 @@ class AppConfig
{ {
public function __construct( public function __construct(
private readonly string $rootPath, private readonly string $rootPath,
private readonly string $templatePath, private readonly string $templatePath = '/Template',
private readonly string $entityPath = '/Entity',
) )
{ {
} }
@ -20,4 +21,9 @@ class AppConfig
{ {
return $this->getRootPath() . $this->templatePath; return $this->getRootPath() . $this->templatePath;
} }
public function getEntityPath(): string
{
return $this->getRootPath() . $this->entityPath;
}
} }

View File

@ -12,6 +12,14 @@ class GenericConfig
public function get(string $key): mixed public function get(string $key): mixed
{ {
return $this->config[$key]; $keys = explode('.', $key);
$value = $this->config;
foreach ($keys as $key) {
if (!isset($value[$key])) {
throw new \InvalidArgumentException("Key '$key' not found in config");
}
$value = $value[$key];
}
return $value;
} }
} }

49
src/Http/Renderer.php Normal file
View File

@ -0,0 +1,49 @@
<?php
namespace Ardent\Undercurrent\Http;
use Ardent\Undercurrent\Container\ContainerInterface;
use Ardent\Undercurrent\Logger\LogContainer;
class Renderer
{
public function __construct(
private readonly ContainerInterface $container,
)
{
}
public function render(): void
{
$request = new GenericRequest(
MethodEnum::from($_SERVER['REQUEST_METHOD']),
$_SERVER['REQUEST_URI'],
$_REQUEST,
);
$router = $this->container->get(RouterInterface::class);
$log = $this->container->get(LogContainer::class);
try {
$response = $router->dispatch($request);
} catch (\Throwable $e) {
$response = new GenericResponse(
$e->getMessage(),
StatusEnum::NOT_FOUND
);
//$response = $container->get(RouterConfig::class)->getExceptionRoute()->getController()::exception($e);
}
http_response_code($response->getStatus()->value);
foreach ($response->getHeaders() as $header) {
header($header);
}
echo $response->getBody();
echo '<pre>Log:<br>';
foreach ($log->getLogs() as $log) {
echo sprintf('%s<br>', $log);
}
echo '</pre>';
}
}

View File

@ -6,82 +6,54 @@ use Ardent\Undercurrent\Config\AppConfig;
use Ardent\Undercurrent\Config\GenericConfig; use Ardent\Undercurrent\Config\GenericConfig;
use Ardent\Undercurrent\Container\ContainerInterface; use Ardent\Undercurrent\Container\ContainerInterface;
use Ardent\Undercurrent\Container\GenericContainer; use Ardent\Undercurrent\Container\GenericContainer;
use Ardent\Undercurrent\Http\GenericRequest;
use Ardent\Undercurrent\Http\GenericResponse;
use Ardent\Undercurrent\Http\GenericRouter; use Ardent\Undercurrent\Http\GenericRouter;
use Ardent\Undercurrent\Http\MethodEnum;
use Ardent\Undercurrent\Http\RouterConfig; use Ardent\Undercurrent\Http\RouterConfig;
use Ardent\Undercurrent\Http\RouterInterface; use Ardent\Undercurrent\Http\RouterInterface;
use Ardent\Undercurrent\Http\StatusEnum;
use Ardent\Undercurrent\Logger\LogContainer; use Ardent\Undercurrent\Logger\LogContainer;
use Ardent\Undercurrent\Logger\LoggerInterface; use Ardent\Undercurrent\Logger\LoggerInterface;
use Ardent\Undercurrent\View\ViewHelper; use Ardent\Undercurrent\View\ViewHelper;
use Doctrine\DBAL\DriverManager;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\ORMSetup;
class BaseKernel class BaseKernel
{ {
public function __construct( public function __construct(
private readonly string $rootDirectory, private readonly AppConfig $appConfig,
) )
{ {
} }
public function run(): void public function setup(): ContainerInterface
{ {
$appConfig = new AppConfig($this->rootDirectory, '/Template');
$container = (new GenericContainer()); $container = (new GenericContainer());
$container $container
->alias(RouterInterface::class, GenericRouter::class) ->alias(RouterInterface::class, GenericRouter::class)
->alias(ContainerInterface::class, GenericContainer::class) ->alias(ContainerInterface::class, GenericContainer::class)
->alias(LoggerInterface::class, LogContainer::class) ->alias(LoggerInterface::class, LogContainer::class)
->add(GenericContainer::class, fn($container) => $container) ->add(GenericContainer::class, fn($container) => $container)
->add(AppConfig::class, fn() => $appConfig) ->add(AppConfig::class, fn() => $this->appConfig)
->add(GenericRouter::class) ->add(GenericRouter::class)
->add(ViewHelper::class) ->add(ViewHelper::class)
->add(EntityManager::class, function (ContainerInterface $container) {
$config = $container->get(GenericConfig::class);
$paths = [$container->get(AppConfig::class)->getEntityPath()];
$ormConfig = ORMSetup::createAttributeMetadataConfiguration($paths, $config->get('dev'));
$connection = DriverManager::getConnection($config->get('orm'), $ormConfig);
return new EntityManager($connection, $ormConfig);
})
->add(LogContainer::class); ->add(LogContainer::class);
// App related dependencies // App related dependencies
$this->dependencies($container); $this->dependencies($container);
$configPath = $this->rootDirectory . '/config.php'; $configPath = $this->appConfig->getRootPath() . '/config.php';
if (file_exists($configPath)) { if (file_exists($configPath)) {
$container->add(GenericConfig::class, fn() => include $configPath); $container->add(GenericConfig::class, fn() => include $configPath);
} }
$this->render($container); return $container;
}
private function render(GenericContainer $container): void
{
$request = new GenericRequest(
MethodEnum::from($_SERVER['REQUEST_METHOD']),
$_SERVER['REQUEST_URI'],
$_REQUEST,
);
$router = $container->get(RouterInterface::class);
$log = $container->get(LogContainer::class);
try {
$response = $router->dispatch($request);
} catch (\Throwable $e) {
$response = new GenericResponse(
$e->getMessage(),
StatusEnum::NOT_FOUND
);
//$response = $container->get(RouterConfig::class)->getExceptionRoute()->getController()::exception($e);
}
http_response_code($response->getStatus()->value);
foreach ($response->getHeaders() as $header) {
header($header);
}
echo $response->getBody();
echo '<pre>Log:<br>';
foreach ($log->getLogs() as $log) {
echo sprintf('%s<br>', $log);
}
echo '</pre>';
} }
protected function addControllers(ContainerInterface $container, array $controllers): void protected function addControllers(ContainerInterface $container, array $controllers): void