diff options
Diffstat (limited to 'src/Middleware/RouteDispatcher.php')
-rw-r--r-- | src/Middleware/RouteDispatcher.php | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/Middleware/RouteDispatcher.php b/src/Middleware/RouteDispatcher.php new file mode 100644 index 00000000..f14faea8 --- /dev/null +++ b/src/Middleware/RouteDispatcher.php @@ -0,0 +1,75 @@ +<?php + +namespace Engelsystem\Middleware; + +use FastRoute\Dispatcher as FastRouteDispatcher; +use Psr\Http\Message\ResponseInterface; +use Psr\Http\Message\ServerRequestInterface; +use Psr\Http\Server\MiddlewareInterface; +use Psr\Http\Server\RequestHandlerInterface; + +class RouteDispatcher implements MiddlewareInterface +{ + /** @var FastRouteDispatcher */ + protected $dispatcher; + + /** @var ResponseInterface */ + protected $response; + + /** @var MiddlewareInterface|null */ + protected $notFound; + + /** + * @param FastRouteDispatcher $dispatcher + * @param ResponseInterface $response Default response + * @param MiddlewareInterface|null $notFound Handles any requests if the route can't be found + */ + public function __construct( + FastRouteDispatcher $dispatcher, + ResponseInterface $response, + MiddlewareInterface $notFound = null + ) { + $this->dispatcher = $dispatcher; + $this->response = $response; + $this->notFound = $notFound; + } + + /** + * Process an incoming server request and return a response, optionally delegating + * response creation to a handler. + * + * @param ServerRequestInterface $request + * @param RequestHandlerInterface $handler + * @return ResponseInterface + */ + public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface + { + $route = $this->dispatcher->dispatch($request->getMethod(), urldecode($request->getUri()->getPath())); + + $status = $route[0]; + if ($status == FastRouteDispatcher::NOT_FOUND) { + if ($this->notFound instanceof MiddlewareInterface) { + return $this->notFound->process($request, $handler); + } + + return $this->response->withStatus(404); + } + + if ($status == FastRouteDispatcher::METHOD_NOT_ALLOWED) { + $methods = $route[1]; + return $this->response + ->withStatus(405) + ->withHeader('Allow', implode(', ', $methods)); + } + + $routeHandler = $route[1]; + $request = $request->withAttribute('route-request-handler', $routeHandler); + + $vars = $route[2]; + foreach ($vars as $name => $value) { + $request = $request->withAttribute($name, $value); + } + + return $handler->handle($request); + } +} |