From 9ce2c0ae4c0778e6b9a0b3c0be577728b1ee7666 Mon Sep 17 00:00:00 2001 From: lubiana Date: Wed, 25 Jan 2023 22:09:06 +0100 Subject: [PATCH] move code to repository root --- composer.json | 51 + composer.lock | 1162 +++++++++++++++++ config/.gitkeep | 0 ecs.php | 18 + phpstan-baseline.neon | 0 phpstan.neon | 8 + public/favicon.ico | Bin 0 -> 15086 bytes public/index.php | 3 + rector.php | 14 + src/Bootstrap.php | 30 + src/Handler/Auchnoch.php | 15 + src/Handler/HalloDimi.php | 17 + src/Handler/Lol.php | 24 + src/Handler/Viel/.gitkeep | 0 src/Infrastructure/Event/AsListener.php | 19 + src/Infrastructure/Event/Dispatcher.php | 60 + .../Event/DispatcherFactory.php | 52 + src/Infrastructure/Event/GenericEvent.php | 8 + src/Infrastructure/Event/Listener.php | 20 + src/Infrastructure/Finder.php | 121 ++ src/Infrastructure/Route/AsHandler.php | 18 + src/Infrastructure/Route/Handler.php | 18 + src/Infrastructure/Route/HttpMethod.php | 9 + .../WebApp/Request/RequestEvent.php | 18 + .../WebApp/Route/AttributeRouteCollector.php | 20 + .../WebApp/Route/CachedResponse.php | 38 + .../WebApp/Route/CachedRouteCollector.php | 44 + .../WebApp/Route/CollectRoutes.php | 19 + .../WebApp/Route/HandlerCaller.php | 43 + .../WebApp/Route/HandlerResolver.php | 68 + src/Infrastructure/functions.php | 23 + src/Listener/LauschEvent.php | 13 + src/Listener/Lauschdoch.php | 15 + test.php | 57 + var/.gitkeep | 0 35 files changed, 2025 insertions(+) create mode 100644 composer.json create mode 100644 composer.lock create mode 100644 config/.gitkeep create mode 100644 ecs.php create mode 100644 phpstan-baseline.neon create mode 100644 phpstan.neon create mode 100644 public/favicon.ico create mode 100644 public/index.php create mode 100644 rector.php create mode 100644 src/Bootstrap.php create mode 100644 src/Handler/Auchnoch.php create mode 100644 src/Handler/HalloDimi.php create mode 100644 src/Handler/Lol.php create mode 100644 src/Handler/Viel/.gitkeep create mode 100644 src/Infrastructure/Event/AsListener.php create mode 100644 src/Infrastructure/Event/Dispatcher.php create mode 100644 src/Infrastructure/Event/DispatcherFactory.php create mode 100644 src/Infrastructure/Event/GenericEvent.php create mode 100644 src/Infrastructure/Event/Listener.php create mode 100644 src/Infrastructure/Finder.php create mode 100644 src/Infrastructure/Route/AsHandler.php create mode 100644 src/Infrastructure/Route/Handler.php create mode 100644 src/Infrastructure/Route/HttpMethod.php create mode 100644 src/Infrastructure/WebApp/Request/RequestEvent.php create mode 100644 src/Infrastructure/WebApp/Route/AttributeRouteCollector.php create mode 100644 src/Infrastructure/WebApp/Route/CachedResponse.php create mode 100644 src/Infrastructure/WebApp/Route/CachedRouteCollector.php create mode 100644 src/Infrastructure/WebApp/Route/CollectRoutes.php create mode 100644 src/Infrastructure/WebApp/Route/HandlerCaller.php create mode 100644 src/Infrastructure/WebApp/Route/HandlerResolver.php create mode 100644 src/Infrastructure/functions.php create mode 100644 src/Listener/LauschEvent.php create mode 100644 src/Listener/Lauschdoch.php create mode 100644 test.php create mode 100644 var/.gitkeep diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..6f93458 --- /dev/null +++ b/composer.json @@ -0,0 +1,51 @@ +{ + "name": "lubian/attribute-magic", + "autoload": { + "psr-4": { + "Lubian\\AttributeMagic\\": "src/" + }, + "files": [ + "src/Infrastructure/functions.php" + ] + }, + "authors": [ + { + "name": "lubiana", + "email": "lubiana123@gmail.com" + } + ], + "require": { + "php": ">=8.1", + "php-di/php-di": "^6.4", + "nikic/fast-route": "^1.3", + "symfony/http-foundation": "^6.1.7" + }, + "require-dev": { + "phpstan/phpstan": "^1.9.1", + "lubiana/code-quality": "^1.1", + "phpstan/extension-installer": "^1.2", + "phpstan/phpstan-strict-rules": "^1.4", + "thecodingmachine/phpstan-strict-rules": "^1.0" + }, + "config": { + "allow-plugins": { + "dealerdirect/phpcodesniffer-composer-installer": true, + "phpstan/extension-installer": true + } + }, + "scripts": { + "serve": [ + "Composer\\Config::disableProcessTimeout", + "php -S 0.0.0.0:1235 -t public" + ], + "phpstan": "./vendor/bin/phpstan analyze", + "baseline": "./vendor/bin/phpstan analyze --generate-baseline", + "style": "./vendor/bin/ecs", + "fix": [ + "rector process" ,"ecs --fix", "ecs --fix" + ], + "rector": "./vendor/bin/rector process" + }, + "minimum-stability": "dev", + "prefer-stable": true +} diff --git a/composer.lock b/composer.lock new file mode 100644 index 0000000..9c2dee0 --- /dev/null +++ b/composer.lock @@ -0,0 +1,1162 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "a5621f758f1624602b7368fd562c7ff2", + "packages": [ + { + "name": "laravel/serializable-closure", + "version": "v1.2.2", + "source": { + "type": "git", + "url": "https://github.com/laravel/serializable-closure.git", + "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/47afb7fae28ed29057fdca37e16a84f90cc62fae", + "reference": "47afb7fae28ed29057fdca37e16a84f90cc62fae", + "shasum": "" + }, + "require": { + "php": "^7.3|^8.0" + }, + "require-dev": { + "nesbot/carbon": "^2.61", + "pestphp/pest": "^1.21.3", + "phpstan/phpstan": "^1.8.2", + "symfony/var-dumper": "^5.4.11" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Laravel\\SerializableClosure\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Taylor Otwell", + "email": "taylor@laravel.com" + }, + { + "name": "Nuno Maduro", + "email": "nuno@laravel.com" + } + ], + "description": "Laravel Serializable Closure provides an easy and secure way to serialize closures in PHP.", + "keywords": [ + "closure", + "laravel", + "serializable" + ], + "support": { + "issues": "https://github.com/laravel/serializable-closure/issues", + "source": "https://github.com/laravel/serializable-closure" + }, + "time": "2022-09-08T13:45:54+00:00" + }, + { + "name": "nikic/fast-route", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/FastRoute.git", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/FastRoute/zipball/181d480e08d9476e61381e04a71b34dc0432e812", + "reference": "181d480e08d9476e61381e04a71b34dc0432e812", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|~5.7" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "FastRoute\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov", + "email": "nikic@php.net" + } + ], + "description": "Fast request router for PHP", + "keywords": [ + "router", + "routing" + ], + "support": { + "issues": "https://github.com/nikic/FastRoute/issues", + "source": "https://github.com/nikic/FastRoute/tree/master" + }, + "time": "2018-02-13T20:26:39+00:00" + }, + { + "name": "php-di/invoker", + "version": "2.3.3", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/Invoker.git", + "reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/Invoker/zipball/cd6d9f267d1a3474bdddf1be1da079f01b942786", + "reference": "cd6d9f267d1a3474bdddf1be1da079f01b942786", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "psr/container": "^1.0|^2.0" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "mnapoli/hard-mode": "~0.3.0", + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Invoker\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Generic and extensible callable invoker", + "homepage": "https://github.com/PHP-DI/Invoker", + "keywords": [ + "callable", + "dependency", + "dependency-injection", + "injection", + "invoke", + "invoker" + ], + "support": { + "issues": "https://github.com/PHP-DI/Invoker/issues", + "source": "https://github.com/PHP-DI/Invoker/tree/2.3.3" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + } + ], + "time": "2021-12-13T09:22:56+00:00" + }, + { + "name": "php-di/php-di", + "version": "6.4.0", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/PHP-DI.git", + "reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/PHP-DI/zipball/ae0f1b3b03d8b29dff81747063cbfd6276246cc4", + "reference": "ae0f1b3b03d8b29dff81747063cbfd6276246cc4", + "shasum": "" + }, + "require": { + "laravel/serializable-closure": "^1.0", + "php": ">=7.4.0", + "php-di/invoker": "^2.0", + "php-di/phpdoc-reader": "^2.0.1", + "psr/container": "^1.0" + }, + "provide": { + "psr/container-implementation": "^1.0" + }, + "require-dev": { + "doctrine/annotations": "~1.10", + "friendsofphp/php-cs-fixer": "^2.4", + "mnapoli/phpunit-easymock": "^1.2", + "ocramius/proxy-manager": "^2.11.2", + "phpstan/phpstan": "^0.12", + "phpunit/phpunit": "^9.5" + }, + "suggest": { + "doctrine/annotations": "Install it if you want to use annotations (version ~1.2)", + "ocramius/proxy-manager": "Install it if you want to use lazy injection (version ~2.0)" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "DI\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "The dependency injection container for humans", + "homepage": "https://php-di.org/", + "keywords": [ + "PSR-11", + "container", + "container-interop", + "dependency injection", + "di", + "ioc", + "psr11" + ], + "support": { + "issues": "https://github.com/PHP-DI/PHP-DI/issues", + "source": "https://github.com/PHP-DI/PHP-DI/tree/6.4.0" + }, + "funding": [ + { + "url": "https://github.com/mnapoli", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/php-di/php-di", + "type": "tidelift" + } + ], + "time": "2022-04-09T16:46:38+00:00" + }, + { + "name": "php-di/phpdoc-reader", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/PHP-DI/PhpDocReader.git", + "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHP-DI/PhpDocReader/zipball/66daff34cbd2627740ffec9469ffbac9f8c8185c", + "reference": "66daff34cbd2627740ffec9469ffbac9f8c8185c", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "require-dev": { + "mnapoli/hard-mode": "~0.3.0", + "phpunit/phpunit": "^8.5|^9.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "PhpDocReader\\": "src/PhpDocReader" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PhpDocReader parses @var and @param values in PHP docblocks (supports namespaced class names with the same resolution rules as PHP)", + "keywords": [ + "phpdoc", + "reflection" + ], + "support": { + "issues": "https://github.com/PHP-DI/PhpDocReader/issues", + "source": "https://github.com/PHP-DI/PhpDocReader/tree/2.2.1" + }, + "time": "2020-10-12T12:39:22+00:00" + }, + { + "name": "psr/container", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.1.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-02-25T11:15:52+00:00" + }, + { + "name": "symfony/http-foundation", + "version": "v6.1.7", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-foundation.git", + "reference": "792a1856d2b95273f0e1c3435785f1d01a60ecc6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/792a1856d2b95273f0e1c3435785f1d01a60ecc6", + "reference": "792a1856d2b95273f0e1c3435785f1d01a60ecc6", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^5.4|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" + }, + "suggest": { + "symfony/mime": "To use the file extension guesser" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Defines an object-oriented layer for the HTTP specification", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v6.1.7" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-10-12T09:44:59+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.26.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.26-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-05-24T11:49:31+00:00" + } + ], + "packages-dev": [ + { + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.7.2", + "source": { + "type": "git", + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "php-parallel-lint/php-parallel-lint": "^1.3.1", + "phpcompatibility/php-compatibility": "^9.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" + }, + "autoload": { + "psr-4": { + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + }, + { + "name": "Contributors", + "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcbf", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + }, + "time": "2022-02-04T12:51:07+00:00" + }, + { + "name": "lubiana/code-quality", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://git.php.fail/lubiana/code-quality.git", + "reference": "a99023d48440482d9da3c604442600b142ebe259" + }, + "require": { + "rector/rector": "^0.14.7", + "slevomat/coding-standard": "^8.6.2", + "symplify/easy-coding-standard": "^11.1.16" + }, + "type": "library", + "autoload": { + "psr-4": { + "Lubiana\\CodeQuality\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "time": "2022-11-04T10:18:22+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "f06dbb052ddc394e7896fcd1cfcd533f9f6ace40" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/f06dbb052ddc394e7896fcd1cfcd533f9f6ace40", + "reference": "f06dbb052ddc394e7896fcd1cfcd533f9f6ace40", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.8.0" + }, + "require-dev": { + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.2.0" + }, + "time": "2022-10-17T12:59:16+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.13.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "33aefcdab42900e36366d0feab6206e2dd68f947" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/33aefcdab42900e36366d0feab6206e2dd68f947", + "reference": "33aefcdab42900e36366d0feab6206e2dd68f947", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.13.0" + }, + "time": "2022-10-21T09:57:39+00:00" + }, + { + "name": "phpstan/phpstan", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan.git", + "reference": "a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f", + "reference": "a59c8b5bfd4a236f27efc8b5ce72c313c2b54b5f", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0" + }, + "conflict": { + "phpstan/phpstan-shim": "*" + }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.9.1" + }, + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", + "type": "tidelift" + } + ], + "time": "2022-11-04T13:35:59+00:00" + }, + { + "name": "phpstan/phpstan-strict-rules", + "version": "1.4.4", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpstan-strict-rules.git", + "reference": "23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6", + "reference": "23e5f377ee6395a1a04842d3d6ed4bd25e7b44a6", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.8.6" + }, + "require-dev": { + "nikic/php-parser": "^4.13.0", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" + }, + "type": "phpstan-extension", + "extra": { + "phpstan": { + "includes": [ + "rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Extra strict and opinionated rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-strict-rules/issues", + "source": "https://github.com/phpstan/phpstan-strict-rules/tree/1.4.4" + }, + "time": "2022-09-21T11:38:17+00:00" + }, + { + "name": "rector/rector", + "version": "0.14.7", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "3553aaba0e820083fc6d7f0dc78d8d789226a398" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/3553aaba0e820083fc6d7f0dc78d8d789226a398", + "reference": "3553aaba0e820083fc6d7f0dc78d8d789226a398", + "shasum": "" + }, + "require": { + "php": "^7.2|^8.0", + "phpstan/phpstan": "^1.9.0" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-php-parser": "*", + "rector/rector-phpoffice": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "0.14-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/0.14.7" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2022-11-04T08:48:40+00:00" + }, + { + "name": "slevomat/coding-standard", + "version": "8.6.2", + "source": { + "type": "git", + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "080f592b16f021a3a8e43d95ca8f57b87ddcf4e6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/080f592b16f021a3a8e43d95ca8f57b87ddcf4e6", + "reference": "080f592b16f021a3a8e43d95ca8f57b87ddcf4e6", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "php": "^7.2 || ^8.0", + "phpstan/phpdoc-parser": ">=1.11.0 <1.14.0", + "squizlabs/php_codesniffer": "^3.7.1" + }, + "require-dev": { + "phing/phing": "2.17.4", + "php-parallel-lint/php-parallel-lint": "1.3.2", + "phpstan/phpstan": "1.4.10|1.8.10", + "phpstan/phpstan-deprecation-rules": "1.0.0", + "phpstan/phpstan-phpunit": "1.0.0|1.1.1", + "phpstan/phpstan-strict-rules": "1.4.4", + "phpunit/phpunit": "7.5.20|8.5.21|9.5.25" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "8.x-dev" + } + }, + "autoload": { + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "keywords": [ + "dev", + "phpcs" + ], + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/8.6.2" + }, + "funding": [ + { + "url": "https://github.com/kukulich", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", + "type": "tidelift" + } + ], + "time": "2022-10-22T15:42:49+00:00" + }, + { + "name": "squizlabs/php_codesniffer", + "version": "3.7.1", + "source": { + "type": "git", + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/1359e176e9307e906dc3d890bcc9603ff6d90619", + "reference": "1359e176e9307e906dc3d890bcc9603ff6d90619", + "shasum": "" + }, + "require": { + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" + }, + "bin": [ + "bin/phpcs", + "bin/phpcbf" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Greg Sherwood", + "role": "lead" + } + ], + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", + "keywords": [ + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, + "time": "2022-06-18T07:21:10+00:00" + }, + { + "name": "symplify/easy-coding-standard", + "version": "11.1.16", + "source": { + "type": "git", + "url": "https://github.com/symplify/easy-coding-standard.git", + "reference": "32ebd57f0f47713540df8ea39134adaa9d912fae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symplify/easy-coding-standard/zipball/32ebd57f0f47713540df8ea39134adaa9d912fae", + "reference": "32ebd57f0f47713540df8ea39134adaa9d912fae", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "conflict": { + "friendsofphp/php-cs-fixer": "<3.0", + "squizlabs/php_codesniffer": "<3.6" + }, + "bin": [ + "bin/ecs" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "10.3-dev" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Prefixed scoped version of ECS package", + "support": { + "source": "https://github.com/symplify/easy-coding-standard/tree/11.1.16" + }, + "funding": [ + { + "url": "https://www.paypal.me/rectorphp", + "type": "custom" + }, + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2022-10-27T10:48:13+00:00" + }, + { + "name": "thecodingmachine/phpstan-strict-rules", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/thecodingmachine/phpstan-strict-rules.git", + "reference": "2ba8fa8b328c45f3b149c05def5bf96793c594b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thecodingmachine/phpstan-strict-rules/zipball/2ba8fa8b328c45f3b149c05def5bf96793c594b6", + "reference": "2ba8fa8b328c45f3b149c05def5bf96793c594b6", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0", + "phpstan/phpstan": "^1.0" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^7.1" + }, + "type": "phpstan-extension", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + }, + "phpstan": { + "includes": [ + "phpstan-strict-rules.neon" + ] + } + }, + "autoload": { + "psr-4": { + "TheCodingMachine\\PHPStan\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "David NĂ©grier", + "email": "d.negrier@thecodingmachine.com" + } + ], + "description": "A set of additional rules for PHPStan based on best practices followed at TheCodingMachine", + "support": { + "issues": "https://github.com/thecodingmachine/phpstan-strict-rules/issues", + "source": "https://github.com/thecodingmachine/phpstan-strict-rules/tree/v1.0.0" + }, + "time": "2021-11-08T09:10:49+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=8.1" + }, + "platform-dev": [], + "plugin-api-version": "2.3.0" +} diff --git a/config/.gitkeep b/config/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..12d6e36 --- /dev/null +++ b/ecs.php @@ -0,0 +1,18 @@ +parallel(); + $c->paths([ + __DIR__ . '/src', + __DIR__ . '/config', + __DIR__ . '/ecs.php', + __DIR__ . '/rector.php', + ]); + + $c->sets([ + LubiSetList::ECS, + ]); +}; diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon new file mode 100644 index 0000000..e69de29 diff --git a/phpstan.neon b/phpstan.neon new file mode 100644 index 0000000..20a700a --- /dev/null +++ b/phpstan.neon @@ -0,0 +1,8 @@ +includes: + - phpstan-baseline.neon + +parameters: + level: max + paths: + - src + - config \ No newline at end of file diff --git a/public/favicon.ico b/public/favicon.ico new file mode 100644 index 0000000000000000000000000000000000000000..09499b8b3b3201e0f50088e3ac42e167778d1153 GIT binary patch literal 15086 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 literal 0 HcmV?d00001 diff --git a/public/index.php b/public/index.php new file mode 100644 index 0000000..cfd3989 --- /dev/null +++ b/public/index.php @@ -0,0 +1,3 @@ +paths([__DIR__ . '/src', __DIR__ . '/config', __DIR__ . '/ecs.php', __DIR__ . '/rector.php']); + + $c->importNames(); + + $c->sets([ + LubiSetList::RECTOR, + ]); +}; diff --git a/src/Bootstrap.php b/src/Bootstrap.php new file mode 100644 index 0000000..e8d10d3 --- /dev/null +++ b/src/Bootstrap.php @@ -0,0 +1,30 @@ +addDefinitions([ + Finder::class => static fn (): Finder => new Finder(__DIR__, [], $cached), + Dispatcher::class => static fn (DispatcherFactory $f): Dispatcher => $f->getDispatcher($cached), + HandlerResolver::class => static fn (Dispatcher $d): HandlerResolver => new HandlerResolver($d, $cached), +])->build(); +$dispatcher = $container->get(Dispatcher::class); +assert($dispatcher instanceof Dispatcher); +$request = new RequestEvent(Request::createFromGlobals()); + +$dispatcher->dispatch($request); + +$request->response?->send(); +exit; diff --git a/src/Handler/Auchnoch.php b/src/Handler/Auchnoch.php new file mode 100644 index 0000000..0376c65 --- /dev/null +++ b/src/Handler/Auchnoch.php @@ -0,0 +1,15 @@ +dispatcher->dispatch($event); + echo $event->message; + } +} diff --git a/src/Handler/Viel/.gitkeep b/src/Handler/Viel/.gitkeep new file mode 100644 index 0000000..e69de29 diff --git a/src/Infrastructure/Event/AsListener.php b/src/Infrastructure/Event/AsListener.php new file mode 100644 index 0000000..4143478 --- /dev/null +++ b/src/Infrastructure/Event/AsListener.php @@ -0,0 +1,19 @@ + $priority + */ + public function __construct( + public readonly string $eventClass, + public readonly int $priority = 0, + ) { + } +} diff --git a/src/Infrastructure/Event/Dispatcher.php b/src/Infrastructure/Event/Dispatcher.php new file mode 100644 index 0000000..1a186e6 --- /dev/null +++ b/src/Infrastructure/Event/Dispatcher.php @@ -0,0 +1,60 @@ +listeners[] = $listener; + } + + /** + * @return Listener[] + */ + public function getListenerForEvent(GenericEvent $event): array + { + return arrayFilter( + $this->listeners, + static fn (Listener $l): bool => $l->eventClass === $event::class, + ); + } + + /** + * @return Listener[] + */ + public function getSortedListenerForEvent(GenericEvent $event): array + { + $filtered = $this->getListenerForEvent($event); + usort($filtered, static fn (Listener $a, Listener $b): int => $a->priority <=> $b->priority); + return $filtered; + } + + public function dispatch(GenericEvent $event): void + { + foreach ($this->getSortedListenerForEvent($event) as $listener) { + if ($event->stopped === true) { + return; + } + + $this->invoker->call( + [$listener->listenerClass, $listener->listenerMethod], + [$event], + ); + } + } +} diff --git a/src/Infrastructure/Event/DispatcherFactory.php b/src/Infrastructure/Event/DispatcherFactory.php new file mode 100644 index 0000000..195a47c --- /dev/null +++ b/src/Infrastructure/Event/DispatcherFactory.php @@ -0,0 +1,52 @@ +invoker, $this->getListeners($cached)); + } + + /** + * @return Listener[] + */ + private function getListeners(bool $cached = false): array + { + if ($cached === true && file_exists(self::CACHE_FILE)) { + $data = file_get_contents(self::CACHE_FILE); + if ($data === false) { + return []; + } + + /** @var Listener[] $listeners */ + $listeners = unserialize($data); + return $listeners; + } + + $listeners = $this->finder->getListeners(); + if ($cached === true) { + file_put_contents(self::CACHE_FILE, serialize($listeners)); + } + + return $listeners; + } +} diff --git a/src/Infrastructure/Event/GenericEvent.php b/src/Infrastructure/Event/GenericEvent.php new file mode 100644 index 0000000..60ff8af --- /dev/null +++ b/src/Infrastructure/Event/GenericEvent.php @@ -0,0 +1,8 @@ + $priority + * @param class-string $listenerClass + * @param non-empty-string $listenerMethod + */ + public function __construct( + public readonly string $eventClass, + public readonly int $priority, + public readonly string $listenerClass, + public readonly string $listenerMethod, + ) { + } +} diff --git a/src/Infrastructure/Finder.php b/src/Infrastructure/Finder.php new file mode 100644 index 0000000..a752e81 --- /dev/null +++ b/src/Infrastructure/Finder.php @@ -0,0 +1,121 @@ +populateClassnames(); + return array_map( + static fn (array $h): Listener => new Listener($h[0]->eventClass, $h[0]->priority, $h[1], $h[2]), + iterator_to_array($this->getAttributes(AsListener::class)), + ); + } + + /** + * @return Handler[] + */ + public function getHandlers(): array + { + $this->populateClassnames(); + return array_map( + static fn (array $h): Handler => new Handler($h[0]->method, $h[0]->path, $h[1], $h[2]), + iterator_to_array($this->getAttributes(AsHandler::class)), + ); + } + + private function populateClassnames(): void + { + if ($this->classNames !== []) { + return; + } + + if ($this->cached === true && file_exists(self::CACHE_FILE)) { + $data = file_get_contents(self::CACHE_FILE); + if ($data === false) { + return; + } + + /** @var class-string[] $result */ + $result = unserialize($data); + $this->classNames = $result; + return; + } + + $it = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->path)); + /** @var SplFileInfo $file */ + foreach ($it as $file) { + if (! str_ends_with((string) $file, '.php')) { + continue; + } + + $classesBeforeLoad = get_declared_classes(); + require_once (string) $file; + $classesAfterLoad = get_declared_classes(); + $this->classNames = [...$this->classNames, ...array_diff($classesAfterLoad, $classesBeforeLoad)]; + } + + if ($this->cached === true) { + file_put_contents(self::CACHE_FILE, serialize($this->classNames)); + } + } + + /** + * @template T + * @param class-string $attributeClass + * @return Iterator + */ + private function getAttributes( + string $attributeClass + ): Iterator { + foreach ($this->classNames as $class) { + $reflectionClass = new ReflectionClass($class); + foreach ($reflectionClass->getMethods() as $method) { + foreach ($method->getAttributes($attributeClass) as $attribute) { + yield [ + $attribute->newInstance(), + $class, + $method->getName(), + ]; + } + } + } + } +} diff --git a/src/Infrastructure/Route/AsHandler.php b/src/Infrastructure/Route/AsHandler.php new file mode 100644 index 0000000..7a417ca --- /dev/null +++ b/src/Infrastructure/Route/AsHandler.php @@ -0,0 +1,18 @@ +routes = $this->finder->getHandlers(); + } +} diff --git a/src/Infrastructure/WebApp/Route/CachedResponse.php b/src/Infrastructure/WebApp/Route/CachedResponse.php new file mode 100644 index 0000000..60d4a4b --- /dev/null +++ b/src/Infrastructure/WebApp/Route/CachedResponse.php @@ -0,0 +1,38 @@ +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)); + } +} diff --git a/src/Infrastructure/WebApp/Route/CachedRouteCollector.php b/src/Infrastructure/WebApp/Route/CachedRouteCollector.php new file mode 100644 index 0000000..e749258 --- /dev/null +++ b/src/Infrastructure/WebApp/Route/CachedRouteCollector.php @@ -0,0 +1,44 @@ +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), + ); + } +} diff --git a/src/Infrastructure/WebApp/Route/CollectRoutes.php b/src/Infrastructure/WebApp/Route/CollectRoutes.php new file mode 100644 index 0000000..9ed4f7b --- /dev/null +++ b/src/Infrastructure/WebApp/Route/CollectRoutes.php @@ -0,0 +1,19 @@ +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); + } +} diff --git a/src/Infrastructure/WebApp/Route/HandlerResolver.php b/src/Infrastructure/WebApp/Route/HandlerResolver.php new file mode 100644 index 0000000..d42c64a --- /dev/null +++ b/src/Infrastructure/WebApp/Route/HandlerResolver.php @@ -0,0 +1,68 @@ +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]); + } +} diff --git a/src/Infrastructure/functions.php b/src/Infrastructure/functions.php new file mode 100644 index 0000000..46b4dd7 --- /dev/null +++ b/src/Infrastructure/functions.php @@ -0,0 +1,23 @@ + $input + * @return array + */ +function arrayFilter( + array $input, + callable $callable +): array { + return array_values( + array_filter( + $input, + $callable, + ) + ); +} diff --git a/src/Listener/LauschEvent.php b/src/Listener/LauschEvent.php new file mode 100644 index 0000000..22e463a --- /dev/null +++ b/src/Listener/LauschEvent.php @@ -0,0 +1,13 @@ +message = $event->message . ' lolduuuuu'; + return $event; + } +} diff --git a/test.php b/test.php new file mode 100644 index 0000000..7a52fc2 --- /dev/null +++ b/test.php @@ -0,0 +1,57 @@ +