diff --git a/config/app.php b/config/app.php
index ea394b8e..19118f1d 100644
--- a/config/app.php
+++ b/config/app.php
@@ -26,6 +26,7 @@ return [
\Engelsystem\Middleware\SendResponseHandler::class,
\Engelsystem\Middleware\ExceptionHandler::class,
\Engelsystem\Middleware\SetLocale::class,
+ \Engelsystem\Middleware\ErrorHandler::class,
\Engelsystem\Middleware\RouteDispatcher::class,
\Engelsystem\Middleware\RequestHandler::class,
],
diff --git a/src/Http/Response.php b/src/Http/Response.php
index 9db6fa83..d79ab98b 100644
--- a/src/Http/Response.php
+++ b/src/Http/Response.php
@@ -2,6 +2,7 @@
namespace Engelsystem\Http;
+use Engelsystem\Renderer\Renderer;
use Psr\Http\Message\ResponseInterface;
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
@@ -9,6 +10,25 @@ class Response extends SymfonyResponse implements ResponseInterface
{
use MessageTrait;
+ /** @var Renderer */
+ protected $view;
+
+ /**
+ * @param string $content
+ * @param int $status
+ * @param array $headers
+ * @param Renderer $view
+ */
+ public function __construct(
+ $content = '',
+ int $status = 200,
+ array $headers = array(),
+ Renderer $view = null
+ ) {
+ $this->view = $view;
+ parent::__construct($content, $status, $headers);
+ }
+
/**
* Return an instance with the specified status code and, optionally, reason phrase.
*
@@ -72,4 +92,25 @@ class Response extends SymfonyResponse implements ResponseInterface
return $new;
}
+
+ /**
+ * Return an instance with the rendered content.
+ *
+ * THis method retains the immutability of the message and returns
+ * an instance with the updated status and headers
+ *
+ * @param string $view
+ * @param array $data
+ * @param int $status
+ * @param string[]|string[][] $headers
+ * @return Response
+ */
+ public function withView($view, $data = [], $status = 200, $headers = [])
+ {
+ if (!$this->view instanceof Renderer) {
+ throw new \InvalidArgumentException('Renderer not defined');
+ }
+
+ return $this->create($this->view->render($view, $data), $status, $headers);
+ }
}
diff --git a/src/Middleware/ErrorHandler.php b/src/Middleware/ErrorHandler.php
new file mode 100644
index 00000000..a7c4cfe6
--- /dev/null
+++ b/src/Middleware/ErrorHandler.php
@@ -0,0 +1,80 @@
+loader = $loader;
+ }
+
+ /**
+ * Handles any error messages
+ *
+ * Should be added at the beginning
+ *
+ * @param ServerRequestInterface $request
+ * @param RequestHandlerInterface $handler
+ * @return ResponseInterface
+ */
+ public function process(
+ ServerRequestInterface $request,
+ RequestHandlerInterface $handler
+ ): ResponseInterface {
+ $response = $handler->handle($request);
+
+ $statusCode = $response->getStatusCode();
+ if ($statusCode < 400 || !$response instanceof Response) {
+ return $response;
+ }
+
+ $view = $this->selectView($statusCode);
+
+ return $response->withView(
+ $this->viewPrefix . $view,
+ [
+ 'status' => $statusCode,
+ 'content' => $response->getContent(),
+ ],
+ $statusCode,
+ $response->getHeaders()
+ );
+ }
+
+ /**
+ * Select a view based on the given status code
+ *
+ * @param int $statusCode
+ * @return string
+ */
+ protected function selectView(int $statusCode): string
+ {
+ $hundreds = intdiv($statusCode, 100);
+
+ $viewsList = [$statusCode, $hundreds, $hundreds * 100];
+ foreach ($viewsList as $view) {
+ if ($this->loader->exists($this->viewPrefix . $view)) {
+ return $view;
+ }
+ }
+
+ return 'default';
+ }
+}
diff --git a/src/Middleware/LegacyMiddleware.php b/src/Middleware/LegacyMiddleware.php
index bf849611..78132815 100644
--- a/src/Middleware/LegacyMiddleware.php
+++ b/src/Middleware/LegacyMiddleware.php
@@ -83,7 +83,7 @@ class LegacyMiddleware implements MiddlewareInterface
}
if (empty($title) and empty($content)) {
- $page = '404';
+ $page = 404;
$title = _('Page not found');
$content = _('This page could not be found or you don\'t have permission to view it. You probably have to sign in or register in order to gain access!');
}
@@ -277,10 +277,8 @@ class LegacyMiddleware implements MiddlewareInterface
$parameters['meetings'] = 1;
}
- $status = 200;
- if ($page == '404') {
- $status = 404;
- $content = info($content, true);
+ if (!empty($page) && is_int($page)) {
+ return response($content, (int)$page);
}
return response(view('layouts/app', [
@@ -290,6 +288,6 @@ class LegacyMiddleware implements MiddlewareInterface
'content' => msg() . $content,
'header_toolbar' => header_toolbar(),
'event_info' => EventConfig_info($event_config) . '
'
- ]), $status);
+ ]), 200);
}
}
diff --git a/src/Renderer/RendererServiceProvider.php b/src/Renderer/RendererServiceProvider.php
index 3e8d69bc..2e41837b 100644
--- a/src/Renderer/RendererServiceProvider.php
+++ b/src/Renderer/RendererServiceProvider.php
@@ -24,12 +24,14 @@ class RendererServiceProvider extends ServiceProvider
protected function registerRenderer()
{
$renderer = $this->app->make(Renderer::class);
+ $this->app->instance(Renderer::class, $renderer);
$this->app->instance('renderer', $renderer);
}
protected function registerHtmlEngine()
{
$htmlEngine = $this->app->make(HtmlEngine::class);
+ $this->app->instance(HtmlEngine::class, $htmlEngine);
$this->app->instance('renderer.htmlEngine', $htmlEngine);
$this->app->tag('renderer.htmlEngine', ['renderer.engine']);
}
diff --git a/templates/errors/default.twig b/templates/errors/default.twig
new file mode 100644
index 00000000..a04afc4e
--- /dev/null
+++ b/templates/errors/default.twig
@@ -0,0 +1,7 @@
+{% extends "layouts/app.twig" %}
+
+{% block title %}Error {{ status }}{% endblock %}
+
+{% block content %}
+