Split NotFoundHandler into two different middlewares

This commit is contained in:
Alejandro Celaya
2019-11-23 10:25:12 +01:00
parent 89e373f775
commit 1bafe54a75
6 changed files with 125 additions and 86 deletions

View File

@@ -4,67 +4,38 @@ declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ErrorHandler;
use Fig\Http\Message\StatusCodeInterface;
use InvalidArgumentException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Message\UriInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Shlinkio\Shlink\Core\Action\RedirectAction;
use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions;
use Zend\Diactoros\Response;
use Zend\Expressive\Router\RouteResult;
use Zend\Expressive\Template\TemplateRendererInterface;
use function array_shift;
use function explode;
use function rtrim;
class NotFoundHandler implements RequestHandlerInterface
class NotFoundRedirectHandler implements MiddlewareInterface
{
public const NOT_FOUND_TEMPLATE = 'ShlinkCore::error/404';
public const INVALID_SHORT_CODE_TEMPLATE = 'ShlinkCore::invalid-short-code';
/** @var TemplateRendererInterface */
private $renderer;
/** @var NotFoundRedirectOptions */
private $redirectOptions;
/** @var string */
private $shlinkBasePath;
public function __construct(
TemplateRendererInterface $renderer,
NotFoundRedirectOptions $redirectOptions,
string $shlinkBasePath
) {
$this->renderer = $renderer;
public function __construct(NotFoundRedirectOptions $redirectOptions, string $shlinkBasePath)
{
$this->redirectOptions = $redirectOptions;
$this->shlinkBasePath = $shlinkBasePath;
}
/**
* Dispatch the next available middleware and return the response.
*
* @param ServerRequestInterface $request
*
* @return ResponseInterface
* @throws InvalidArgumentException
*/
public function handle(ServerRequestInterface $request): ResponseInterface
public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
{
/** @var RouteResult $routeResult */
$routeResult = $request->getAttribute(RouteResult::class, RouteResult::fromRouteFailure(null));
$redirectResponse = $this->createRedirectResponse($routeResult, $request->getUri());
if ($redirectResponse !== null) {
return $redirectResponse;
}
$accepts = explode(',', $request->getHeaderLine('Accept'));
$accept = array_shift($accepts);
$status = StatusCodeInterface::STATUS_NOT_FOUND;
$template = $routeResult->isFailure() ? self::NOT_FOUND_TEMPLATE : self::INVALID_SHORT_CODE_TEMPLATE;
return new Response\HtmlResponse($this->renderer->render($template), $status);
return $redirectResponse ?? $handler->handle($request);
}
private function createRedirectResponse(RouteResult $routeResult, UriInterface $uri): ?ResponseInterface

View File

@@ -0,0 +1,46 @@
<?php
declare(strict_types=1);
namespace Shlinkio\Shlink\Core\ErrorHandler;
use Fig\Http\Message\StatusCodeInterface;
use InvalidArgumentException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\RequestHandlerInterface;
use Zend\Diactoros\Response;
use Zend\Expressive\Router\RouteResult;
use Zend\Expressive\Template\TemplateRendererInterface;
class NotFoundTemplateHandler implements RequestHandlerInterface
{
public const NOT_FOUND_TEMPLATE = 'ShlinkCore::error/404';
public const INVALID_SHORT_CODE_TEMPLATE = 'ShlinkCore::invalid-short-code';
/** @var TemplateRendererInterface */
private $renderer;
public function __construct(TemplateRendererInterface $renderer)
{
$this->renderer = $renderer;
}
/**
* Dispatch the next available middleware and return the response.
*
* @param ServerRequestInterface $request
*
* @return ResponseInterface
* @throws InvalidArgumentException
*/
public function handle(ServerRequestInterface $request): ResponseInterface
{
/** @var RouteResult $routeResult */
$routeResult = $request->getAttribute(RouteResult::class, RouteResult::fromRouteFailure(null));
$status = StatusCodeInterface::STATUS_NOT_FOUND;
$template = $routeResult->isFailure() ? self::NOT_FOUND_TEMPLATE : self::INVALID_SHORT_CODE_TEMPLATE;
return new Response\HtmlResponse($this->renderer->render($template), $status);
}
}