Compare commits
62 commits
f98fc5078d
...
23d37db8f6
Author | SHA1 | Date | |
---|---|---|---|
|
23d37db8f6 | ||
28491fd4ea | |||
4910317c38 | |||
f23b073377 | |||
|
70d16b7659 | ||
911c0ff4b5 | |||
2872d932b6 | |||
|
45b5b746f6 | ||
0733c8456d | |||
|
5ccbc66134 | ||
|
03952677f6 | ||
|
ea7d5eff68 | ||
|
14db5b36e6 | ||
|
b638a0124f | ||
|
a7f60358eb | ||
|
4ca96eafb9 | ||
|
8d8306ef42 | ||
|
1bbde50fc3 | ||
|
919d84173e | ||
|
ea854064b3 | ||
|
36ea1f111f | ||
|
b665352669 | ||
|
4e8953ba46 | ||
|
e7c1df5eb1 | ||
|
90ce46d9d1 | ||
|
c769aa5fe4 | ||
|
cf25187eef | ||
|
0b7f70541f | ||
|
b43ce75c42 | ||
|
912dddb6fb | ||
|
c4acc2c358 | ||
|
b85c91b3d0 | ||
|
32eba79853 | ||
|
2eeb093f8e | ||
|
9228c09d60 | ||
|
ff7e416c57 | ||
|
66c8dc14ce | ||
|
766b4c2d87 | ||
|
2a4660a732 | ||
|
f5f216e0e8 | ||
|
f1453b0c2f | ||
|
f1796b2ea1 | ||
|
0ecf1160d5 | ||
|
d2fe65734e | ||
|
56cf5fec2e | ||
|
668dd79d07 | ||
|
fc554efd13 | ||
|
3e6e8c70b8 | ||
|
c4ae79cd69 | ||
|
dbb98b1eac | ||
|
a06f01d598 | ||
|
f21b18d8ac | ||
|
0687c75d0a | ||
|
1e97d89a5a | ||
|
c86dad5c6c | ||
|
2679849cc4 | ||
|
fcaf69c2ad | ||
|
63dc61769d | ||
|
d03ecc5b93 | ||
|
d98ff5b363 | ||
|
bb77a21fb8 | ||
|
e7ab312d84 |
25 changed files with 1422 additions and 1436 deletions
32
.forgejo/workflows/push.yml
Normal file
32
.forgejo/workflows/push.yml
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
on: [push]
|
||||||
|
jobs:
|
||||||
|
ls:
|
||||||
|
runs-on: docker
|
||||||
|
container:
|
||||||
|
image: git.php.fail/lubiana/container/php:8.3.0-node-20231212
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Get Composer Cache Directory
|
||||||
|
id: composer-cache
|
||||||
|
run: |
|
||||||
|
echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
id: restore-cache
|
||||||
|
with:
|
||||||
|
path: ${{ steps.composer-cache.outputs.dir }}
|
||||||
|
key: composer-cache
|
||||||
|
- run: composer install
|
||||||
|
- run: composer fix
|
||||||
|
- name: GIT commit and push all changed files
|
||||||
|
env:
|
||||||
|
CI_COMMIT_MESSAGE: Continuous Integration Fixes
|
||||||
|
CI_COMMIT_AUTHOR: Continuous Integration
|
||||||
|
run: |
|
||||||
|
if [[ -n "$(git status -s)" ]]; then
|
||||||
|
git config --global user.name "${{ env.CI_COMMIT_AUTHOR }}"
|
||||||
|
git config --global user.email "gitbot@users.noreply.php.fail"
|
||||||
|
git commit -am "${{ env.CI_COMMIT_MESSAGE }}"
|
||||||
|
git push
|
||||||
|
fi
|
||||||
|
|
||||||
|
|
|
@ -15,20 +15,20 @@
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"php": ">=8.2",
|
"php": ">=8.3",
|
||||||
"ext-apcu": "*",
|
"ext-apcu": "*",
|
||||||
"php-di/php-di": "^7.0.1",
|
"php-di/php-di": "^7.0.6",
|
||||||
"nikic/fast-route": "^1.3",
|
"nikic/fast-route": "^1.3",
|
||||||
"symfony/http-foundation": "^6.2.5",
|
"symfony/http-foundation": "^7.0"
|
||||||
"vimeo/psalm": "^5.6"
|
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"phpstan/phpstan": "^1.9.14",
|
"phpstan/phpstan": "^1.10.46",
|
||||||
"lubiana/code-quality": "^1.1.5",
|
"lubiana/code-quality": "^1.2",
|
||||||
"phpstan/extension-installer": "^1.2",
|
"phpstan/extension-installer": "^1.3.1",
|
||||||
"phpstan/phpstan-strict-rules": "^1.4.5",
|
"phpstan/phpstan-strict-rules": "^1.5.2",
|
||||||
"thecodingmachine/phpstan-strict-rules": "^1.0",
|
"thecodingmachine/phpstan-strict-rules": "^1.0",
|
||||||
"pmjones/php-styler": "0.x-dev"
|
"pmjones/php-styler": "^0.14.0",
|
||||||
|
"vimeo/psalm": "^5.16"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"allow-plugins": {
|
"allow-plugins": {
|
||||||
|
@ -51,7 +51,7 @@
|
||||||
],
|
],
|
||||||
"style": "./vendor/bin/ecs",
|
"style": "./vendor/bin/ecs",
|
||||||
"fix": [
|
"fix": [
|
||||||
"rector process" ,"ecs --fix", "ecs --fix"
|
"rector process", "php-styler apply" ,"ecs --fix", "ecs --fix"
|
||||||
],
|
],
|
||||||
"rector": "./vendor/bin/rector process"
|
"rector": "./vendor/bin/rector process"
|
||||||
},
|
},
|
||||||
|
|
2689
composer.lock
generated
2689
composer.lock
generated
File diff suppressed because it is too large
Load diff
|
@ -4,7 +4,7 @@ use PhpStyler\Files;
|
||||||
use PhpStyler\Styler;
|
use PhpStyler\Styler;
|
||||||
|
|
||||||
return new Config(
|
return new Config(
|
||||||
files: new Files(__DIR__ . '/src'),
|
|
||||||
styler: new Styler(),
|
styler: new Styler(),
|
||||||
|
files: new Files(__DIR__ . '/src'),
|
||||||
cache: __DIR__ . '/.php-styler.cache',
|
cache: __DIR__ . '/.php-styler.cache',
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,13 +1,8 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<files psalm-version="5.6.0@e784128902dfe01d489c4123d69918a9f3c1eac5">
|
<files psalm-version="5.16.0@2897ba636551a8cb61601cc26f6ccfbba6c36591">
|
||||||
<file src="src/Infrastructure/Finder.php">
|
<file src="src/Infrastructure/Finder.php">
|
||||||
<UnresolvableInclude>
|
<UnresolvableInclude>
|
||||||
<code>require_once (string) $file</code>
|
<code>require_once (string) $file</code>
|
||||||
</UnresolvableInclude>
|
</UnresolvableInclude>
|
||||||
</file>
|
</file>
|
||||||
<file src="src/Infrastructure/functions.php">
|
|
||||||
<MixedArgumentTypeCoercion>
|
|
||||||
<code>$callable</code>
|
|
||||||
</MixedArgumentTypeCoercion>
|
|
||||||
</file>
|
|
||||||
</files>
|
</files>
|
||||||
|
|
|
@ -6,7 +6,7 @@ use DI\ContainerBuilder;
|
||||||
use Lubian\AttributeMagic\Infrastructure\Event\Dispatcher;
|
use Lubian\AttributeMagic\Infrastructure\Event\Dispatcher;
|
||||||
use Lubian\AttributeMagic\Infrastructure\Event\DispatcherFactory;
|
use Lubian\AttributeMagic\Infrastructure\Event\DispatcherFactory;
|
||||||
use Lubian\AttributeMagic\Infrastructure\Finder;
|
use Lubian\AttributeMagic\Infrastructure\Finder;
|
||||||
use Lubian\AttributeMagic\Infrastructure\WebApp\Request\RequestEvent;
|
use Lubian\AttributeMagic\Infrastructure\HttpKernel;
|
||||||
use Lubian\AttributeMagic\Infrastructure\WebApp\Route\HandlerResolver;
|
use Lubian\AttributeMagic\Infrastructure\WebApp\Route\HandlerResolver;
|
||||||
use Symfony\Component\HttpFoundation\Request;
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
|
||||||
|
@ -14,18 +14,17 @@ use function assert;
|
||||||
|
|
||||||
require_once __DIR__ . '/../vendor/autoload.php';
|
require_once __DIR__ . '/../vendor/autoload.php';
|
||||||
$cached = false;
|
$cached = false;
|
||||||
$container = (new ContainerBuilder)->addDefinitions(
|
$container = (new ContainerBuilder())->addDefinitions(
|
||||||
[
|
[
|
||||||
Finder::class => static fn (): Finder => new Finder(__DIR__, [], $cached),
|
Finder::class => static fn(): Finder => new Finder(__DIR__, [], $cached),
|
||||||
Dispatcher::class => static fn (DispatcherFactory $f): Dispatcher
|
Dispatcher::class => static fn(DispatcherFactory $f): Dispatcher
|
||||||
=> $f->getDispatcher($cached),
|
=> $f->getDispatcher($cached),
|
||||||
HandlerResolver::class => static fn (Dispatcher $d): HandlerResolver
|
HandlerResolver::class => static fn(Dispatcher $d): HandlerResolver
|
||||||
=> new HandlerResolver($d, $cached),
|
=> new HandlerResolver($d, $cached),
|
||||||
],
|
],
|
||||||
)->build();
|
)->build();
|
||||||
$dispatcher = $container->get(Dispatcher::class);
|
$kernel = $container->get(HttpKernel::class);
|
||||||
assert($dispatcher instanceof Dispatcher);
|
assert($kernel instanceof HttpKernel);
|
||||||
$request = new RequestEvent(Request::createFromGlobals());
|
$response = $kernel->handle(Request::createFromGlobals());
|
||||||
$dispatcher->dispatch($request);
|
$response->send();
|
||||||
$request->response?->send();
|
|
||||||
exit();
|
exit();
|
||||||
|
|
|
@ -9,6 +9,11 @@ use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
final class HalloDimi
|
final class HalloDimi
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* Returns a JSON response with the message "Hallo Dimi".
|
||||||
|
*
|
||||||
|
* @return Response The JSON response.
|
||||||
|
*/
|
||||||
#[AsHandler(HttpMethod::GET, '/dimi')]
|
#[AsHandler(HttpMethod::GET, '/dimi')]
|
||||||
public function hallo(): Response
|
public function hallo(): Response
|
||||||
{
|
{
|
||||||
|
|
|
@ -11,8 +11,7 @@ final readonly class Lol
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private Dispatcher $dispatcher
|
private Dispatcher $dispatcher
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
#[AsHandler(HttpMethod::GET, '/')]
|
#[AsHandler(HttpMethod::GET, '/')]
|
||||||
public function lol(): void
|
public function lol(): void
|
||||||
|
|
|
@ -14,6 +14,5 @@ final readonly class AsListener
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public string $eventClass,
|
public string $eventClass,
|
||||||
public int $priority = 0
|
public int $priority = 0
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,8 +15,7 @@ final class Dispatcher
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private readonly InvokerInterface $invoker,
|
private readonly InvokerInterface $invoker,
|
||||||
private array $listeners = [],
|
private array $listeners = [],
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
public function addListener(Listener $listener): void
|
public function addListener(Listener $listener): void
|
||||||
{
|
{
|
||||||
|
@ -30,7 +29,7 @@ final class Dispatcher
|
||||||
{
|
{
|
||||||
return arrayFilter(
|
return arrayFilter(
|
||||||
$this->listeners,
|
$this->listeners,
|
||||||
static fn (Listener $l): bool => $l->eventClass === $event::class,
|
static fn(Listener $l): bool => $l->eventClass === $event::class,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -42,7 +41,7 @@ final class Dispatcher
|
||||||
$filtered = $this->getListenerForEvent($event);
|
$filtered = $this->getListenerForEvent($event);
|
||||||
usort(
|
usort(
|
||||||
$filtered,
|
$filtered,
|
||||||
static fn (Listener $a, Listener $b): int => $a->priority <=> $b->priority,
|
static fn(Listener $a, Listener $b): int => $a->priority <=> $b->priority,
|
||||||
);
|
);
|
||||||
return $filtered;
|
return $filtered;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,8 +18,7 @@ final readonly class DispatcherFactory
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private Finder $finder,
|
private Finder $finder,
|
||||||
private InvokerInterface $invoker,
|
private InvokerInterface $invoker,
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
public function getDispatcher(bool $cached = false): Dispatcher
|
public function getDispatcher(bool $cached = false): Dispatcher
|
||||||
{
|
{
|
||||||
|
|
|
@ -15,6 +15,5 @@ final readonly class Listener
|
||||||
public int $priority,
|
public int $priority,
|
||||||
public string $listenerClass,
|
public string $listenerClass,
|
||||||
public string $listenerMethod,
|
public string $listenerMethod,
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,7 @@ final class Finder
|
||||||
private readonly string $path,
|
private readonly string $path,
|
||||||
private array $classNames = [],
|
private array $classNames = [],
|
||||||
private readonly bool $cached = false,
|
private readonly bool $cached = false,
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Listener[]
|
* @return Listener[]
|
||||||
|
@ -44,7 +43,7 @@ final class Finder
|
||||||
{
|
{
|
||||||
$this->populateClassnames();
|
$this->populateClassnames();
|
||||||
return array_map(
|
return array_map(
|
||||||
static fn (array $h): Listener
|
static fn(array $h): Listener
|
||||||
=> new Listener($h[0]->eventClass, $h[0]->priority, $h[1], $h[2]),
|
=> new Listener($h[0]->eventClass, $h[0]->priority, $h[1], $h[2]),
|
||||||
iterator_to_array($this->getAttributes(AsListener::class)),
|
iterator_to_array($this->getAttributes(AsListener::class)),
|
||||||
);
|
);
|
||||||
|
@ -57,7 +56,7 @@ final class Finder
|
||||||
{
|
{
|
||||||
$this->populateClassnames();
|
$this->populateClassnames();
|
||||||
return array_map(
|
return array_map(
|
||||||
static fn (array $h): Handler
|
static fn(array $h): Handler
|
||||||
=> new Handler($h[0]->method, $h[0]->path, $h[1], $h[2]),
|
=> new Handler($h[0]->method, $h[0]->path, $h[1], $h[2]),
|
||||||
iterator_to_array($this->getAttributes(AsHandler::class)),
|
iterator_to_array($this->getAttributes(AsHandler::class)),
|
||||||
);
|
);
|
||||||
|
@ -72,6 +71,7 @@ final class Finder
|
||||||
if ($this->cached === true && file_exists(self::CACHE_FILE)) {
|
if ($this->cached === true && file_exists(self::CACHE_FILE)) {
|
||||||
$data = file_get_contents(self::CACHE_FILE);
|
$data = file_get_contents(self::CACHE_FILE);
|
||||||
|
|
||||||
|
/** test */
|
||||||
if ($data === false) {
|
if ($data === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
23
src/Infrastructure/HttpKernel.php
Normal file
23
src/Infrastructure/HttpKernel.php
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
<?php declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Lubian\AttributeMagic\Infrastructure;
|
||||||
|
|
||||||
|
use Exception;
|
||||||
|
use Lubian\AttributeMagic\Infrastructure\Event\Dispatcher;
|
||||||
|
use Lubian\AttributeMagic\Infrastructure\WebApp\Request\RequestEvent;
|
||||||
|
use Symfony\Component\HttpFoundation\Request;
|
||||||
|
use Symfony\Component\HttpFoundation\Response;
|
||||||
|
|
||||||
|
class HttpKernel
|
||||||
|
{
|
||||||
|
public function __construct(
|
||||||
|
private readonly Dispatcher $dispatcher
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public function handle(Request $request): Response
|
||||||
|
{
|
||||||
|
$requestEvent = new RequestEvent($request);
|
||||||
|
$this->dispatcher->dispatch($requestEvent);
|
||||||
|
return $requestEvent->response ?? throw new Exception('errror');
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,6 +13,5 @@ final readonly class AsHandler
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public HttpMethod $method,
|
public HttpMethod $method,
|
||||||
public string $path
|
public string $path
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,5 @@ final readonly class Handler
|
||||||
public string $path,
|
public string $path,
|
||||||
public string $handlerClass,
|
public string $handlerClass,
|
||||||
public string $handlerMethod,
|
public string $handlerMethod,
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,5 @@ final class RequestEvent extends GenericEvent
|
||||||
public Request $request,
|
public Request $request,
|
||||||
public Response|null $response = null,
|
public Response|null $response = null,
|
||||||
public Handler|null $handler = null,
|
public Handler|null $handler = null,
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,8 +9,7 @@ final readonly class AttributeRouteCollector
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private Finder $finder
|
private Finder $finder
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
#[AsListener(CollectRoutes::class)]
|
#[AsListener(CollectRoutes::class)]
|
||||||
public function collect(CollectRoutes $event): void
|
public function collect(CollectRoutes $event): void
|
||||||
|
|
|
@ -32,7 +32,6 @@ final class CachedResponse
|
||||||
/** @var Response|null $response */
|
/** @var Response|null $response */
|
||||||
$response = unserialize($serialized);
|
$response = unserialize($serialized);
|
||||||
$event->response = $response;
|
$event->response = $response;
|
||||||
|
|
||||||
$event->stopped = true;
|
$event->stopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -29,7 +29,6 @@ final class CachedRouteCollector
|
||||||
/** @var Handler[] $routes */
|
/** @var Handler[] $routes */
|
||||||
$routes = unserialize(file_get_contents(self::ROUTES_DIR));
|
$routes = unserialize(file_get_contents(self::ROUTES_DIR));
|
||||||
$event->routes = $routes;
|
$event->routes = $routes;
|
||||||
|
|
||||||
$event->stopped = true;
|
$event->stopped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,5 @@ final class CollectRoutes extends GenericEvent
|
||||||
|
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public readonly bool $cached = false
|
public readonly bool $cached = false
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,7 @@ final readonly class HandlerCaller
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private InvokerInterface $invoker
|
private InvokerInterface $invoker
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
#[AsListener(RequestEvent::class, -50)]
|
#[AsListener(RequestEvent::class, -50)]
|
||||||
public function callHandler(RequestEvent $event): void
|
public function callHandler(RequestEvent $event): void
|
||||||
|
|
|
@ -21,8 +21,7 @@ final readonly class HandlerResolver
|
||||||
public function __construct(
|
public function __construct(
|
||||||
private Dispatcher $dispatcher,
|
private Dispatcher $dispatcher,
|
||||||
private bool $cached = false,
|
private bool $cached = false,
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
|
|
||||||
#[AsListener(RequestEvent::class, -90)]
|
#[AsListener(RequestEvent::class, -90)]
|
||||||
public function resolveHandler(RequestEvent $event): void
|
public function resolveHandler(RequestEvent $event): void
|
||||||
|
|
|
@ -7,9 +7,9 @@ use function array_values;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @template T
|
* @template T
|
||||||
* @param array<T> $input
|
* @param T[] $input
|
||||||
* @param callable(mixed, mixed=):scalar $callable
|
* @param callable(T):bool $callable
|
||||||
* @return array<int, T>
|
* @return T[]
|
||||||
*/
|
*/
|
||||||
function arrayFilter(array $input, callable $callable): array
|
function arrayFilter(array $input, callable $callable): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -8,6 +8,5 @@ final class LauschEvent extends GenericEvent
|
||||||
{
|
{
|
||||||
public function __construct(
|
public function __construct(
|
||||||
public string $message
|
public string $message
|
||||||
) {
|
) {}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue