summaryrefslogtreecommitdiff
path: root/src/Middleware/Dispatcher.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/Middleware/Dispatcher.php')
-rw-r--r--src/Middleware/Dispatcher.php110
1 files changed, 110 insertions, 0 deletions
diff --git a/src/Middleware/Dispatcher.php b/src/Middleware/Dispatcher.php
new file mode 100644
index 00000000..f2a5b5d5
--- /dev/null
+++ b/src/Middleware/Dispatcher.php
@@ -0,0 +1,110 @@
+<?php
+
+namespace Engelsystem\Middleware;
+
+use Engelsystem\Application;
+use InvalidArgumentException;
+use LogicException;
+use Psr\Http\Message\ResponseInterface;
+use Psr\Http\Message\ServerRequestInterface;
+use Psr\Http\Server\MiddlewareInterface;
+use Psr\Http\Server\RequestHandlerInterface;
+
+class Dispatcher implements MiddlewareInterface, RequestHandlerInterface
+{
+ /** @var MiddlewareInterface[]|string[] */
+ protected $stack;
+
+ /** @var Application */
+ protected $container;
+
+ /** @var RequestHandlerInterface */
+ protected $next;
+
+ /**
+ * @param MiddlewareInterface[]|string[] $stack
+ * @param Application|null $container
+ */
+ public function __construct($stack = [], Application $container = null)
+ {
+ $this->stack = $stack;
+ $this->container = $container;
+ }
+
+ /**
+ * Process an incoming server request and return a response, optionally delegating
+ * response creation to a handler.
+ *
+ * Could be used to group middleware
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ * @return ResponseInterface
+ */
+ public function process(
+ ServerRequestInterface $request,
+ RequestHandlerInterface $handler
+ ): ResponseInterface {
+ $this->next = $handler;
+
+ return $this->handle($request);
+ }
+
+ /**
+ * Handle the request and return a response.
+ *
+ * It calls all configured middleware and handles their response
+ *
+ * @param ServerRequestInterface $request
+ * @return ResponseInterface
+ */
+ public function handle(ServerRequestInterface $request): ResponseInterface
+ {
+ $middleware = array_shift($this->stack);
+
+ if (!$middleware) {
+ if ($this->next) {
+ return $this->next->handle($request);
+ }
+
+ throw new LogicException('Middleware queue is empty');
+ }
+
+ if (is_string($middleware)) {
+ $middleware = $this->resolveMiddleware($middleware);
+ }
+
+ if (!$middleware instanceof MiddlewareInterface) {
+ throw new InvalidArgumentException('Middleware is no instance of ' . MiddlewareInterface::class);
+ }
+
+ return $middleware->process($request, $this);
+ }
+
+ /**
+ * Resolve the middleware with the container
+ *
+ * @param string $middleware
+ * @return MiddlewareInterface
+ */
+ protected function resolveMiddleware($middleware)
+ {
+ if (!$this->container instanceof Application) {
+ throw new InvalidArgumentException('Unable to resolve middleware ' . $middleware);
+ }
+
+ if ($this->container->has($middleware)) {
+ return $this->container->get($middleware);
+ }
+
+ return $this->container->make($middleware);
+ }
+
+ /**
+ * @param Application $container
+ */
+ public function setContainer(Application $container)
+ {
+ $this->container = $container;
+ }
+}