move code to repository root

This commit is contained in:
lubiana 2023-01-25 22:09:06 +01:00
parent 47e227257c
commit 9ce2c0ae4c
No known key found for this signature in database
35 changed files with 2025 additions and 0 deletions

View file

@ -0,0 +1,20 @@
<?php declare(strict_types=1);
namespace Lubian\AttributeMagic\Infrastructure\WebApp\Route;
use Lubian\AttributeMagic\Infrastructure\Event\AsListener;
use Lubian\AttributeMagic\Infrastructure\Finder;
final class AttributeRouteCollector
{
public function __construct(
private readonly Finder $finder
) {
}
#[AsListener(CollectRoutes::class)]
public function collect(CollectRoutes $event): void
{
$event->routes = $this->finder->getHandlers();
}
}

View file

@ -0,0 +1,38 @@
<?php declare(strict_types=1);
namespace Lubian\AttributeMagic\Infrastructure\WebApp\Route;
use Lubian\AttributeMagic\Infrastructure\Event\AsListener;
use Lubian\AttributeMagic\Infrastructure\WebApp\Request\RequestEvent;
use Symfony\Component\HttpFoundation\Response;
use function apcu_add;
use function md5;
use function serialize;
use function unserialize;
final class CachedResponse
{
#[AsListener(RequestEvent::class, -99)]
public function cachedResponse(RequestEvent $event): void
{
$response = new Response('lol');
$serialized = serialize($response);
/** @var Response|null $response */
$response = unserialize($serialized);
$event->response = $response;
$event->stopped = true;
}
#[AsListener(RequestEvent::class, 99)]
public function doCache(RequestEvent $event): void
{
if ($event->response === null) {
return;
}
$path = md5($event->request->getPathInfo());
apcu_add($path, serialize($event->response));
}
}

View file

@ -0,0 +1,44 @@
<?php declare(strict_types=1);
namespace Lubian\AttributeMagic\Infrastructure\WebApp\Route;
use Lubian\AttributeMagic\Infrastructure\Event\AsListener;
use function file_exists;
use function file_get_contents;
use function file_put_contents;
use function serialize;
use function unserialize;
final class CachedRouteCollector
{
public const ROUTES_DIR = __DIR__ . '/../../../../var/routesCache';
#[AsListener(CollectRoutes::class, -10)]
public function getCached(CollectRoutes $event): void
{
if ($event->cached === false) {
return;
}
if (! file_exists(self::ROUTES_DIR)) {
return;
}
$event->routes = unserialize(file_get_contents(self::ROUTES_DIR)); //@phpstan-ignore-line
$event->stopped = true;
}
#[AsListener(CollectRoutes::class, 10)]
public function setCached(CollectRoutes $event): void
{
if ($event->cached === false) {
return;
}
file_put_contents(
self::ROUTES_DIR,
serialize($event->routes),
);
}
}

View file

@ -0,0 +1,19 @@
<?php declare(strict_types=1);
namespace Lubian\AttributeMagic\Infrastructure\WebApp\Route;
use Lubian\AttributeMagic\Infrastructure\Event\GenericEvent;
use Lubian\AttributeMagic\Infrastructure\Route\Handler;
final class CollectRoutes extends GenericEvent
{
/**
* @var Handler[]
*/
public array $routes = [];
public function __construct(
public readonly bool $cached = false,
) {
}
}

View file

@ -0,0 +1,43 @@
<?php declare(strict_types=1);
namespace Lubian\AttributeMagic\Infrastructure\WebApp\Route;
use Invoker\InvokerInterface;
use Lubian\AttributeMagic\Infrastructure\Event\AsListener;
use Lubian\AttributeMagic\Infrastructure\WebApp\Request\RequestEvent;
use Symfony\Component\HttpFoundation\Response;
use function ob_get_clean;
use function ob_start;
final class HandlerCaller
{
public function __construct(
private readonly InvokerInterface $invoker
) {
}
#[AsListener(RequestEvent::class, -50)]
public function callHandler(RequestEvent $event): void
{
if ($event->handler === null) {
$event->stopped = true;
$event->response = new Response('not resolved', 500);
return;
}
ob_start();
$response = $this->invoker->call(
[$event->handler->handlerClass, $event->handler->handlerMethod],
$event->request->attributes->all()
);
$output = (string) ob_get_clean();
if ($response instanceof Response) {
$event->response = $response;
return;
}
$event->response = new Response($output, 200);
}
}

View file

@ -0,0 +1,68 @@
<?php declare(strict_types=1);
namespace Lubian\AttributeMagic\Infrastructure\WebApp\Route;
use FastRoute\RouteCollector;
use Lubian\AttributeMagic\Infrastructure\Event\AsListener;
use Lubian\AttributeMagic\Infrastructure\Event\Dispatcher;
use Lubian\AttributeMagic\Infrastructure\Route\Handler;
use Lubian\AttributeMagic\Infrastructure\Route\HttpMethod;
use Lubian\AttributeMagic\Infrastructure\WebApp\Request\RequestEvent;
use Symfony\Component\HttpFoundation\Response;
use function FastRoute\cachedDispatcher;
final class HandlerResolver
{
public function __construct(
private readonly Dispatcher $dispatcher,
private readonly bool $cached = false,
) {
}
#[AsListener(RequestEvent::class, -90)]
public function resolveHandler(RequestEvent $event): void
{
$routesEvent = new CollectRoutes($this->cached);
$this->dispatcher->dispatch($routesEvent);
$dispatcher = $this->dispatcher;
$routeDispatcher = cachedDispatcher(static function (RouteCollector $r) use (
$dispatcher,
$routesEvent
): void {
$dispatcher->dispatch($routesEvent);
foreach ($routesEvent->routes as $h) {
$r->addRoute($h->method->value, $h->path, [$h->handlerClass, $h->handlerMethod]);
}
}, [
'cacheFile' => __DIR__ . '/../../../../var/route.cache',
'cacheDisabled' => ! $this->cached,
]);
$routeInfo = $routeDispatcher->dispatch(
$event->request->getMethod(),
$event->request->getPathInfo(),
);
if ($routeInfo[0] === \FastRoute\Dispatcher::NOT_FOUND) {
$event->response = new Response('Not Found', 404);
$event->stopped = true;
return;
}
if ($routeInfo[0] === \FastRoute\Dispatcher::METHOD_NOT_ALLOWED) {
$event->response = new Response('Not Allowed', 403);
$event->stopped = true;
return;
}
$event->handler = new Handler(
HttpMethod::from($event->request->getMethod()),
$event->request->getPathInfo(),
...$routeInfo[1],
);
$event->request->attributes->add($routeInfo[2]);
}
}