mirror of
https://github.com/shlinkio/shlink.git
synced 2024-11-25 02:10:18 -06:00
Merge pull request #915 from acelaya-forks/feature/remove-plates
Feature/remove plates
This commit is contained in:
commit
74108a19e5
@ -9,7 +9,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com), and this
|
||||
* [#869](https://github.com/shlinkio/shlink/issues/869) Added support for Mercure Hub 0.10.
|
||||
|
||||
### Changed
|
||||
* *Nothing*
|
||||
* [#912](https://github.com/shlinkio/shlink/issues/912) Changed error templates to be plain html files, removing the dependency on `league/plates` package.
|
||||
|
||||
### Deprecated
|
||||
* *Nothing*
|
||||
|
@ -38,7 +38,6 @@
|
||||
"mezzio/mezzio": "^3.2",
|
||||
"mezzio/mezzio-fastroute": "^3.0",
|
||||
"mezzio/mezzio-helpers": "^5.3",
|
||||
"mezzio/mezzio-platesrenderer": "^2.1",
|
||||
"mezzio/mezzio-problem-details": "^1.1",
|
||||
"mezzio/mezzio-swoole": "^2.6.4",
|
||||
"monolog/monolog": "^2.0",
|
||||
|
@ -1,17 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
|
||||
'templates' => [
|
||||
'extension' => 'phtml',
|
||||
],
|
||||
|
||||
'plates' => [
|
||||
'extensions' => [
|
||||
// extension service names or instances
|
||||
],
|
||||
],
|
||||
|
||||
];
|
@ -15,7 +15,6 @@ return (new ConfigAggregator\ConfigAggregator([
|
||||
Mezzio\ConfigProvider::class,
|
||||
Mezzio\Router\ConfigProvider::class,
|
||||
Mezzio\Router\FastRouteRouter\ConfigProvider::class,
|
||||
Mezzio\Plates\ConfigProvider::class,
|
||||
Mezzio\Swoole\ConfigProvider::class,
|
||||
ProblemDetails\ConfigProvider::class,
|
||||
Diactoros\ConfigProvider::class,
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\CLI;
|
||||
|
||||
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shlinkio\Shlink\CLI\ConfigProvider;
|
||||
|
||||
@ -21,7 +22,9 @@ class ConfigProviderTest extends TestCase
|
||||
{
|
||||
$config = ($this->configProvider)();
|
||||
|
||||
self::assertCount(3, $config);
|
||||
self::assertArrayHasKey('cli', $config);
|
||||
self::assertArrayHasKey('dependencies', $config);
|
||||
self::assertArrayHasKey(ConfigAbstractFactory::class, $config);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ declare(strict_types=1);
|
||||
namespace Shlinkio\Shlink\Core;
|
||||
|
||||
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
|
||||
use Mezzio\Template\TemplateRendererInterface;
|
||||
use Laminas\ServiceManager\Factory\InvokableFactory;
|
||||
use Psr\EventDispatcher\EventDispatcherInterface;
|
||||
use Shlinkio\Shlink\Core\ErrorHandler;
|
||||
use Shlinkio\Shlink\Core\Options\NotFoundRedirectOptions;
|
||||
@ -16,7 +16,7 @@ return [
|
||||
'dependencies' => [
|
||||
'factories' => [
|
||||
ErrorHandler\NotFoundRedirectHandler::class => ConfigAbstractFactory::class,
|
||||
ErrorHandler\NotFoundTemplateHandler::class => ConfigAbstractFactory::class,
|
||||
ErrorHandler\NotFoundTemplateHandler::class => InvokableFactory::class,
|
||||
|
||||
Options\AppOptions::class => ConfigAbstractFactory::class,
|
||||
Options\DeleteShortUrlsOptions::class => ConfigAbstractFactory::class,
|
||||
@ -60,7 +60,6 @@ return [
|
||||
Util\RedirectResponseHelper::class,
|
||||
'config.router.base_path',
|
||||
],
|
||||
ErrorHandler\NotFoundTemplateHandler::class => [TemplateRendererInterface::class],
|
||||
|
||||
Options\AppOptions::class => ['config.app_options'],
|
||||
Options\DeleteShortUrlsOptions::class => ['config.delete_short_urls'],
|
||||
|
@ -1,14 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
|
||||
'mezzio' => [
|
||||
'error_handler' => [
|
||||
'template_404' => 'ShlinkCore::error/404',
|
||||
'template_error' => 'ShlinkCore::error/error',
|
||||
],
|
||||
],
|
||||
|
||||
];
|
@ -1,13 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
return [
|
||||
|
||||
'templates' => [
|
||||
'paths' => [
|
||||
'ShlinkCore' => __DIR__ . '/../templates',
|
||||
],
|
||||
],
|
||||
|
||||
];
|
@ -4,40 +4,37 @@ declare(strict_types=1);
|
||||
|
||||
namespace Shlinkio\Shlink\Core\ErrorHandler;
|
||||
|
||||
use Closure;
|
||||
use Fig\Http\Message\StatusCodeInterface;
|
||||
use InvalidArgumentException;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Mezzio\Router\RouteResult;
|
||||
use Mezzio\Template\TemplateRendererInterface;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\RequestHandlerInterface;
|
||||
|
||||
use function file_get_contents;
|
||||
use function sprintf;
|
||||
|
||||
class NotFoundTemplateHandler implements RequestHandlerInterface
|
||||
{
|
||||
public const NOT_FOUND_TEMPLATE = 'ShlinkCore::error/404';
|
||||
public const INVALID_SHORT_CODE_TEMPLATE = 'ShlinkCore::invalid-short-code';
|
||||
private const TEMPLATES_BASE_DIR = __DIR__ . '/../../templates';
|
||||
public const NOT_FOUND_TEMPLATE = '404.html';
|
||||
public const INVALID_SHORT_CODE_TEMPLATE = 'invalid-short-code.html';
|
||||
private Closure $readFile;
|
||||
|
||||
private TemplateRendererInterface $renderer;
|
||||
|
||||
public function __construct(TemplateRendererInterface $renderer)
|
||||
public function __construct(?callable $readFile = null)
|
||||
{
|
||||
$this->renderer = $renderer;
|
||||
$this->readFile = $readFile ? Closure::fromCallable($readFile) : fn (string $file) => file_get_contents($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dispatch the next available middleware and return the response.
|
||||
*
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function handle(ServerRequestInterface $request): ResponseInterface
|
||||
{
|
||||
/** @var RouteResult $routeResult */
|
||||
$routeResult = $request->getAttribute(RouteResult::class, RouteResult::fromRouteFailure(null));
|
||||
$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);
|
||||
$templateContent = ($this->readFile)(sprintf('%s/%s', self::TEMPLATES_BASE_DIR, $template));
|
||||
return new Response\HtmlResponse($templateContent, $status);
|
||||
}
|
||||
}
|
||||
|
27
module/Core/templates/404.html
Normal file
27
module/Core/templates/404.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Not Found | Shlink</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<style>
|
||||
html, body {height: 100%}
|
||||
.app {height: 100vh; display: flex; align-items: center; justify-content: center; flex-flow: column;}
|
||||
p {margin-bottom: 20px;}
|
||||
body {text-align: center;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<main class="container">
|
||||
<h1>404</h1>
|
||||
<hr>
|
||||
<h3>Page not found.</h3>
|
||||
<p>The page you requested could not be found.</p>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,19 +0,0 @@
|
||||
<?php $this->layout('ShlinkCore::layout/default') ?>
|
||||
|
||||
<?php $this->start('title') ?>
|
||||
Not Found
|
||||
<?php $this->end() ?>
|
||||
|
||||
<?php $this->start('stylesheets') ?>
|
||||
<style>
|
||||
p {margin-bottom: 20px;}
|
||||
body {text-align: center;}
|
||||
</style>
|
||||
<?php $this->end() ?>
|
||||
|
||||
<?php $this->start('main') ?>
|
||||
<h1>404</h1>
|
||||
<hr>
|
||||
<h3>Page not found.</h3>
|
||||
<p>The page you requested could not be found.</p>
|
||||
<?php $this->end() ?>
|
@ -1,25 +0,0 @@
|
||||
<?php $this->layout('ShlinkCore::layout/default') ?>
|
||||
|
||||
<?php $this->start('title') ?>
|
||||
<?= $this->e($status . ' ' . $reason) ?>
|
||||
<?php $this->end() ?>
|
||||
|
||||
<?php $this->start('stylesheets') ?>
|
||||
<style>
|
||||
p {margin-bottom: 20px;}
|
||||
body {text-align: center;}
|
||||
</style>
|
||||
<?php $this->end() ?>
|
||||
|
||||
<?php $this->start('main') ?>
|
||||
<h1>Oops!</h1>
|
||||
<hr>
|
||||
|
||||
<?php if ($status !== 404): ?>
|
||||
<p><?= sprintf('We encountered a %s %s error.', $status, $reason) ?></p>
|
||||
<?php else: ?>
|
||||
<p>'This short URL doesn't seem to be valid.</p>
|
||||
<p>'Make sure you included all the characters, with no extra punctuation.</p>
|
||||
<?php endif; ?>
|
||||
<?php $this->end() ?>
|
||||
|
27
module/Core/templates/invalid-short-code.html
Normal file
27
module/Core/templates/invalid-short-code.html
Normal file
@ -0,0 +1,27 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title>Invalid Short URL | Shlink</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<style>
|
||||
html, body {height: 100%}
|
||||
.app {height: 100vh; display: flex; align-items: center; justify-content: center; flex-flow: column;}
|
||||
p {margin-bottom: 20px;}
|
||||
body {text-align: center;}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<main class="container">
|
||||
<h1>Oops!</h1>
|
||||
<hr>
|
||||
<p>This short URL doesn't seem to be valid.</p>
|
||||
<p>Make sure you included all the characters, with no extra punctuation.</p>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -1,19 +0,0 @@
|
||||
<?php $this->layout('ShlinkCore::layout/default') ?>
|
||||
|
||||
<?php $this->start('title') ?>
|
||||
Invalid Short URL
|
||||
<?php $this->end() ?>
|
||||
|
||||
<?php $this->start('stylesheets') ?>
|
||||
<style>
|
||||
p {margin-bottom: 20px;}
|
||||
body {text-align: center;}
|
||||
</style>
|
||||
<?php $this->end() ?>
|
||||
|
||||
<?php $this->start('main') ?>
|
||||
<h1>Oops!</h1>
|
||||
<hr>
|
||||
<p>This short URL doesn't seem to be valid.</p>
|
||||
<p>Make sure you included all the characters, with no extra punctuation.</p>
|
||||
<?php $this->end() ?>
|
@ -1,23 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<title><?= $this->section('title', '') ?> | Shlink</title>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css">
|
||||
<link rel="shortcut icon" href="/favicon.ico">
|
||||
<style>
|
||||
html, body {height: 100%}
|
||||
.app {height: 100vh; display: flex; align-items: center; justify-content: center; flex-flow: column;}
|
||||
</style>
|
||||
<?= $this->section('stylesheets', '') ?>
|
||||
</head>
|
||||
<body>
|
||||
<div class="app">
|
||||
<main class="container">
|
||||
<?= $this->section('main', '') ?>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Core;
|
||||
|
||||
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shlinkio\Shlink\Core\ConfigProvider;
|
||||
|
||||
@ -19,11 +20,13 @@ class ConfigProviderTest extends TestCase
|
||||
/** @test */
|
||||
public function properConfigIsReturned(): void
|
||||
{
|
||||
$config = $this->configProvider->__invoke();
|
||||
$config = ($this->configProvider)();
|
||||
|
||||
self::assertCount(5, $config);
|
||||
self::assertArrayHasKey('routes', $config);
|
||||
self::assertArrayHasKey('dependencies', $config);
|
||||
self::assertArrayHasKey('templates', $config);
|
||||
self::assertArrayHasKey('mezzio', $config);
|
||||
self::assertArrayHasKey('entity_manager', $config);
|
||||
self::assertArrayHasKey('events', $config);
|
||||
self::assertArrayHasKey(ConfigAbstractFactory::class, $config);
|
||||
}
|
||||
}
|
||||
|
@ -4,29 +4,30 @@ declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Core\ErrorHandler;
|
||||
|
||||
use Closure;
|
||||
use Laminas\Diactoros\Response;
|
||||
use Laminas\Diactoros\ServerRequestFactory;
|
||||
use Mezzio\Router\Route;
|
||||
use Mezzio\Router\RouteResult;
|
||||
use Mezzio\Template\TemplateRendererInterface;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Prophecy\PhpUnit\ProphecyTrait;
|
||||
use Prophecy\Prophecy\ObjectProphecy;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use Psr\Http\Server\MiddlewareInterface;
|
||||
use Shlinkio\Shlink\Core\ErrorHandler\NotFoundTemplateHandler;
|
||||
|
||||
class NotFoundTemplateHandlerTest extends TestCase
|
||||
{
|
||||
use ProphecyTrait;
|
||||
|
||||
private NotFoundTemplateHandler $handler;
|
||||
private ObjectProphecy $renderer;
|
||||
private Closure $readFile;
|
||||
private bool $readFileCalled;
|
||||
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->renderer = $this->prophesize(TemplateRendererInterface::class);
|
||||
$this->handler = new NotFoundTemplateHandler($this->renderer->reveal());
|
||||
$this->readFileCalled = false;
|
||||
$this->readFile = function (string $fileName): string {
|
||||
$this->readFileCalled = true;
|
||||
return $fileName;
|
||||
};
|
||||
$this->handler = new NotFoundTemplateHandler($this->readFile);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,13 +36,11 @@ class NotFoundTemplateHandlerTest extends TestCase
|
||||
*/
|
||||
public function properErrorTemplateIsRendered(ServerRequestInterface $request, string $expectedTemplate): void
|
||||
{
|
||||
$request = $request->withHeader('Accept', 'text/html');
|
||||
$render = $this->renderer->render($expectedTemplate)->willReturn('');
|
||||
|
||||
$resp = $this->handler->handle($request);
|
||||
$resp = $this->handler->handle($request->withHeader('Accept', 'text/html'));
|
||||
|
||||
self::assertInstanceOf(Response\HtmlResponse::class, $resp);
|
||||
$render->shouldHaveBeenCalledOnce();
|
||||
self::assertStringContainsString($expectedTemplate, (string) $resp->getBody());
|
||||
self::assertTrue($this->readFileCalled);
|
||||
}
|
||||
|
||||
public function provideTemplates(): iterable
|
||||
|
@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace ShlinkioTest\Shlink\Rest;
|
||||
|
||||
use Laminas\ServiceManager\AbstractFactory\ConfigAbstractFactory;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Shlinkio\Shlink\Rest\ConfigProvider;
|
||||
|
||||
@ -21,8 +22,12 @@ class ConfigProviderTest extends TestCase
|
||||
{
|
||||
$config = ($this->configProvider)();
|
||||
|
||||
self::assertCount(5, $config);
|
||||
self::assertArrayHasKey('routes', $config);
|
||||
self::assertArrayHasKey('dependencies', $config);
|
||||
self::assertArrayHasKey('auth', $config);
|
||||
self::assertArrayHasKey('entity_manager', $config);
|
||||
self::assertArrayHasKey(ConfigAbstractFactory::class, $config);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user