From c3685fdbef3a136e46d36e99ac9d983776711dae Mon Sep 17 00:00:00 2001 From: kawanamiyuu Date: Wed, 8 Jul 2020 22:43:18 +0900 Subject: [PATCH] extract framework from "kawanamiyuu/htb-feed" --- composer.json | 11 +++++- src/Application.php | 47 +++++++++++++++++++++++++ src/ApplicationInterface.php | 15 ++++++++ src/ExceptionHandler.php | 29 ++++++++++++++++ src/ExceptionHandlerInterface.php | 14 ++++++++ src/FrameworkModule.php | 57 +++++++++++++++++++++++++++++++ src/MiddlewareContainer.php | 33 ++++++++++++++++++ src/RequestHandlerProvider.php | 33 ++++++++++++++++++ src/ResponseEmitter.php | 16 +++++++++ src/ResponseEmitterInterface.php | 12 +++++++ tests/FakeMiddleware.php | 18 ++++++++++ tests/FakeRequestHandler.php | 27 +++++++++++++++ tests/FrameworkModuleTest.php | 23 +++++++++++++ 13 files changed, 334 insertions(+), 1 deletion(-) create mode 100644 src/Application.php create mode 100644 src/ApplicationInterface.php create mode 100644 src/ExceptionHandler.php create mode 100644 src/ExceptionHandlerInterface.php create mode 100644 src/FrameworkModule.php create mode 100644 src/MiddlewareContainer.php create mode 100644 src/RequestHandlerProvider.php create mode 100644 src/ResponseEmitter.php create mode 100644 src/ResponseEmitterInterface.php create mode 100644 tests/FakeMiddleware.php create mode 100644 tests/FakeRequestHandler.php create mode 100644 tests/FrameworkModuleTest.php diff --git a/composer.json b/composer.json index b838dae..4ec6567 100644 --- a/composer.json +++ b/composer.json @@ -2,6 +2,7 @@ "name": "k9u/framework", "type": "library", "description": "Web Application Framework for PHP.", + "keywords": ["framework", "psr-7", "psr-15"], "license": "MIT", "authors": [ { @@ -11,7 +12,15 @@ ], "minimum-stability": "stable", "require": { - "php": "^7.4" + "php": "^7.4", + "laminas/laminas-diactoros": "^2.3", + "laminas/laminas-httphandlerrunner": "^1.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0", + "psr/http-server-handler": "^1.0", + "psr/http-server-middleware": "^1.0", + "ray/di": "^2.10", + "relay/relay": "^2.1" }, "require-dev": { "phpmd/phpmd": "^2.8", diff --git a/src/Application.php b/src/Application.php new file mode 100644 index 0000000..b4f1d70 --- /dev/null +++ b/src/Application.php @@ -0,0 +1,47 @@ +requestHandler = $requestHandler; + $this->exceptionHandler = $exceptionHandler; + $this->responseEmitter = $responseEmitter; + } + + public function __invoke(ServerRequestInterface $request): void + { + try { + $response = $this->requestHandler->handle($request); + } catch (Throwable $th) { + $response = ($this->exceptionHandler)($th, $request); + } + + ($this->responseEmitter)($response); + } +} diff --git a/src/ApplicationInterface.php b/src/ApplicationInterface.php new file mode 100644 index 0000000..d9d024f --- /dev/null +++ b/src/ApplicationInterface.php @@ -0,0 +1,15 @@ +responseFactory = $responseFactory; + } + + public function __invoke(Throwable $throwable, ServerRequestInterface $request): ResponseInterface + { + unset($request); // unused + + error_log((string) $throwable); + + return $this->responseFactory->createResponse(505); + } +} diff --git a/src/ExceptionHandlerInterface.php b/src/ExceptionHandlerInterface.php new file mode 100644 index 0000000..53293af --- /dev/null +++ b/src/ExceptionHandlerInterface.php @@ -0,0 +1,14 @@ + + */ + private array $middlewares; + + /** + * @param array $middlewares + * @param AbstractModule|null $module + */ + public function __construct(array $middlewares, AbstractModule $module = null) + { + $this->middlewares = $middlewares; + parent::__construct($module); + } + + protected function configure(): void + { + foreach ($this->middlewares as $middleware) { + $this->bind($middleware)->in(Scope::SINGLETON); + } + + $this->bind(MiddlewareContainer::class) + ->toInstance(new MiddlewareContainer($this->middlewares)); + + $this->bind(RequestHandlerInterface::class) + ->toProvider(RequestHandlerProvider::class)->in(Scope::SINGLETON); + + $this->bind(ResponseFactoryInterface::class) + ->to(ResponseFactory::class)->in(Scope::SINGLETON); + + $this->bind(ExceptionHandlerInterface::class) + ->to(ExceptionHandler::class)->in(Scope::SINGLETON); + + $this->bind(ResponseEmitterInterface::class) + ->to(ResponseEmitter::class)->in(Scope::SINGLETON); + + $this->bind(ApplicationInterface::class) + ->to(Application::class)->in(Scope::SINGLETON); + } +} diff --git a/src/MiddlewareContainer.php b/src/MiddlewareContainer.php new file mode 100644 index 0000000..7f41d07 --- /dev/null +++ b/src/MiddlewareContainer.php @@ -0,0 +1,33 @@ + + */ +class MiddlewareContainer implements IteratorAggregate +{ + /** + * @var array $middlewares + */ + private array $middlewares; + + /** + * @param array $middlewares + */ + public function __construct(array $middlewares) + { + $this->middlewares = $middlewares; + } + + public function getIterator(): Traversable + { + return new ArrayIterator($this->middlewares); + } +} diff --git a/src/RequestHandlerProvider.php b/src/RequestHandlerProvider.php new file mode 100644 index 0000000..8cc75f8 --- /dev/null +++ b/src/RequestHandlerProvider.php @@ -0,0 +1,33 @@ +middlewareContainer = $middlewareContainer; + $this->injector = $injector; + } + + public function get(): RequestHandlerInterface + { + return new Relay($this->middlewareContainer, function ($middleware) { + $instance = $this->injector->getInstance($middleware); + assert($instance instanceof MiddlewareInterface || $instance instanceof RequestHandlerInterface); + return $instance; + }); + } +} diff --git a/src/ResponseEmitter.php b/src/ResponseEmitter.php new file mode 100644 index 0000000..0ae82f8 --- /dev/null +++ b/src/ResponseEmitter.php @@ -0,0 +1,16 @@ +emit($response); + } +} diff --git a/src/ResponseEmitterInterface.php b/src/ResponseEmitterInterface.php new file mode 100644 index 0000000..b6dcbef --- /dev/null +++ b/src/ResponseEmitterInterface.php @@ -0,0 +1,12 @@ +handle($request); + } +} diff --git a/tests/FakeRequestHandler.php b/tests/FakeRequestHandler.php new file mode 100644 index 0000000..f13d82c --- /dev/null +++ b/tests/FakeRequestHandler.php @@ -0,0 +1,27 @@ +responseFactory = $responseFactory; + } + + public function handle(ServerRequestInterface $request): ResponseInterface + { + unset($request); // unused + + return $this->responseFactory->createResponse(200); + } +} diff --git a/tests/FrameworkModuleTest.php b/tests/FrameworkModuleTest.php new file mode 100644 index 0000000..ee50cb1 --- /dev/null +++ b/tests/FrameworkModuleTest.php @@ -0,0 +1,23 @@ +getInstance(ApplicationInterface::class); + + $this->assertInstanceOf(ApplicationInterface::class, $instance); + } +}