Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

EZP-28338: As an Editor, I want to view specific error page when reaching an http error in Admin #183

Merged
merged 4 commits into from
Dec 15, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/bundle/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,11 @@ services:
public: true
tags:
- { name: kernel.event_subscriber }

EzSystems\EzPlatformAdminUi\EventListener\AdminExceptionListener:
arguments:
$siteAccessGroups: '%ezpublish.siteaccess.groups%'
$kernelRootDir: '%kernel.root_dir%'
$kernelEnvironment: '%kernel.environment%'
tags:
- { name: kernel.event_listener, event: kernel.exception }
Binary file added src/bundle/Resources/public/img/errors/403.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/bundle/Resources/public/img/errors/404.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/bundle/Resources/public/img/errors/500.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
23 changes: 23 additions & 0 deletions src/bundle/Resources/public/scss/_error-page.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.error-page {
background: $ez-white;
text-align: center;
width: 100%;

&__image-wrapper {
margin-top: 18vh;
}

&__title,
&__messages {
max-width: 596px;
margin: 3rem auto auto;
}

&__message {
font-size: 17px;
}

&__link {
text-decoration: underline;
}
}
6 changes: 5 additions & 1 deletion src/bundle/Resources/public/scss/_general.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@ body {
height: 100%;
}

a {
transition: color .3s $ez-admin-transition;
}

.ez-main-row {
min-height: calc(100vh - 60px);
}
Expand All @@ -27,7 +31,7 @@ body {
.ez-context-menu {
padding-right: 0;
padding-left: 0;

.ez-icon {
display: block;
margin: 0 auto;
Expand Down
1 change: 1 addition & 0 deletions src/bundle/Resources/public/scss/ezplatform.scss
Original file line number Diff line number Diff line change
Expand Up @@ -43,3 +43,4 @@
@import 'alloyeditor-link-edit';
@import 'card';
@import 'pagination';
@import 'error-page';
45 changes: 45 additions & 0 deletions src/bundle/Resources/translations/messages.en.xliff
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,51 @@
<target state="new">Admin</target>
<note>key: breadcrumb.admin</note>
</trans-unit>
<trans-unit id="7cb40cbc703336ab1285e81ebf100b82b05a0e27" resname="error.page.403.actions">
<source><![CDATA[You can also go back to the <a class="error-page__link" href="%dashboard%">dashboard</a> here or <a class="error-page__link" href="%search%">search</a> for other content.]]></source>
<target state="new"><![CDATA[You can also go back to the <a class="error-page__link" href="%dashboard%">dashboard</a> here or <a class="error-page__link" href="%search%">search</a> for other content.]]></target>
<note>key: error.page.403.actions</note>
</trans-unit>
<trans-unit id="2532cb9ce6fdf46258c107f3d20888c506115ef6" resname="error.page.403.message">
<source><![CDATA[It’s an error 403. You don’t have permission to retrieve or access this page.<br/>Please contact your eZ Platform Administrator to request access to<br/>this content or modify your profile.]]></source>
<target state="new"><![CDATA[It’s an error 403. You don’t have permission to retrieve or access this page.<br/>Please contact your eZ Platform Administrator to request access to<br/>this content or modify your profile.]]></target>
<note>key: error.page.403.message</note>
</trans-unit>
<trans-unit id="b1712cfa4c13874debdcc0f1f4a3b9fa4af3c966" resname="error.page.403.title">
<source>You don’t have permission for this page. Sorry!</source>
<target state="new">You don’t have permission for this page. Sorry!</target>
<note>key: error.page.403.title</note>
</trans-unit>
<trans-unit id="638be721c063eee72e70484fe99a25b2a990bb18" resname="error.page.404.actions">
<source><![CDATA[Check the URL, in case there would be an error in there.<br/>If not, go to the <a class="error-page__link" href="%dashboard%">dashboard</a> or <a class="error-page__link" href="%search%">search</a> for specific content.]]></source>
<target state="new"><![CDATA[Check the URL, in case there would be an error in there.<br/>If not, go to the <a class="error-page__link" href="%dashboard%">dashboard</a> or <a class="error-page__link" href="%search%">search</a> for specific content.]]></target>
<note>key: error.page.404.actions</note>
</trans-unit>
<trans-unit id="7027b2adcf028b82111334763e40823cd85a52fa" resname="error.page.404.message">
<source><![CDATA[It’s an error 404. The page you requested was not found.<br/>It might have been deleted or might be temporarily unavailable.]]></source>
<target state="new"><![CDATA[It’s an error 404. The page you requested was not found.<br/>It might have been deleted or might be temporarily unavailable.]]></target>
<note>key: error.page.404.message</note>
</trans-unit>
<trans-unit id="156b8a7f797412e60bdba432064e2dade6d4a7af" resname="error.page.404.title">
<source>Something went wrong. Sorry!</source>
<target state="new">Something went wrong. Sorry!</target>
<note>key: error.page.404.title</note>
</trans-unit>
<trans-unit id="a599d59a63814826906caa9842f0b3c33db24d09" resname="error.page.default.actions">
<source><![CDATA[Please contact your eZ Platform Administrator and inform her/him about the time the error occurred, the URL in your browser window and anything related you think may have caused the error.<br/>You can also go back or try to reload the application.]]></source>
<target state="new"><![CDATA[Please contact your eZ Platform Administrator and inform her/him about the time the error occurred, the URL in your browser window and anything related you think may have caused the error.<br/>You can also go back or try to reload the application.]]></target>
<note>key: error.page.default.actions</note>
</trans-unit>
<trans-unit id="8338c190462d420926edf71e8d4cddcae710d361" resname="error.page.default.message">
<source>It's an error 500, an internal server error. The server was unable to complete your request and it's not your fault.</source>
<target state="new">It's an error 500, an internal server error. The server was unable to complete your request and it's not your fault.</target>
<note>key: error.page.default.message</note>
</trans-unit>
<trans-unit id="889ba15bcc2f87bfac9b80282f659eaeb7c175d4" resname="error.page.default.title">
<source>Something went wrong. Sorry!</source>
<target state="new">Something went wrong. Sorry!</target>
<note>key: error.page.default.title</note>
</trans-unit>
<trans-unit id="5cf420af18fd4a8d856fd30bc13aea5039369f9b" resname="form.cancel">
<source>Cancel</source>
<target state="new">Cancel</target>
Expand Down
5 changes: 0 additions & 5 deletions src/bundle/Resources/translations/section.en.xliff
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,6 @@
<target state="new">Edit</target>
<note>key: section.edit</note>
</trans-unit>
<trans-unit id="201c1849abe46fd6ea7013ec4bb1bc2630e46e0a" resname="section.form.delete">
<source>Delete</source>
<target state="new">Delete</target>
<note>key: section.form.delete</note>
</trans-unit>
<trans-unit id="bcb0a8eedc29344eb4ad95a02dd684438aae1df6" resname="section.id">
<source>ID</source>
<target state="new">ID</target>
Expand Down
16 changes: 16 additions & 0 deletions src/bundle/Resources/views/errors/403.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{% extends '@EzPlatformAdminUi/layout.html.twig' %}

{% block content %}
<div class="row align-items-stretch ez-main-row">
<div class="error-page">
<div class="error-page__image-wrapper">
<img src="{{ asset('bundles/ezplatformadminui/img/errors/403.png') }}" />
</div>
<h2 class="error-page__title">{{ 'error.page.403.title'|trans|desc('You don\’t have permission for this page. Sorry!') }}</h2>
<div class="error-page__messages">
<p class="error-page__message">{{ 'error.page.403.message'|trans|raw|desc('It\’s an error 403. You don\’t have permission to retrieve or access this page.<br/>Please contact your eZ Platform Administrator to request access to<br/>this content or modify your profile.') }}</p>
<p class="error-page__message">{{ 'error.page.403.actions'|trans({ '%dashboard%': path('ezplatform.dashboard'), '%search%': path('ezplatform.search') })|raw|desc('You can also go back to the <a class="error-page__link" href="%dashboard%">dashboard</a> here or <a class="error-page__link" href="%search%">search</a> for other content.') }}</p>
</div>
</div>
</div>
{% endblock %}
23 changes: 23 additions & 0 deletions src/bundle/Resources/views/errors/404.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{% extends '@EzPlatformAdminUi/layout.html.twig' %}

{% block navigation %}
{% if admin_ui_config.user.user is not empty %}
{{ parent() }}
{% endif %}
{% endblock %}

{% block content %}
<div class="row align-items-stretch ez-main-row">
<div class="error-page">
<div class="error-page__image-wrapper">
<img src="{{ asset('bundles/ezplatformadminui/img/errors/404.png') }}" />
</div>
<h2 class="error-page__title">{{ 'error.page.404.title'|trans|desc('Something went wrong. Sorry!') }}</h2>
<div class="error-page__messages">
<p class="error-page__message">{{ 'error.page.404.message'|trans|raw|desc('It\’s an error 404. The page you requested was not found.<br/>It might have been deleted or might be temporarily unavailable.') }}</p>
<p class="error-page__message">{{ 'error.page.404.actions'|trans({ '%dashboard%': path('ezplatform.dashboard'), '%search%': path('ezplatform.search') })|raw|desc('Check the URL, in case there would be an error in there.<br/>If not, go to the <a class="error-page__link" href="%dashboard%">dashboard</a> or <a class="error-page__link" href="%search%">search</a> for specific content.') }}
</p>
</div>
</div>
</div>
{% endblock %}
19 changes: 19 additions & 0 deletions src/bundle/Resources/views/errors/error.html.twig
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{% extends '@EzPlatformAdminUi/layout.html.twig' %}

{% block navigation %}{% endblock %}

{% block content %}
<div class="row align-items-stretch ez-main-row">
<div class="error-page">
<div class="error-page__image-wrapper">
<img src="{{ asset('bundles/ezplatformadminui/img/errors/500.png') }}" />
</div>
<h2 class="error-page__title">{{ 'error.page.default.title'|trans|desc('Something went wrong. Sorry!') }}</h2>
<div class="error-page__messages">
<p class="error-page__message">{{ 'error.page.default.message'|trans|raw|desc('It\'s an error 500, an internal server error. The server was unable to complete your request and it\'s not your fault.') }}</p>
<p class="error-page__message">{{ 'error.page.default.actions'|trans|raw|desc('Please contact your eZ Platform Administrator and inform her/him about the time the error occurred, the URL in your browser window and anything related you think may have caused the error.<br/>You can also go back or try to reload the application.') }}
</p>
</div>
</div>
<div>
{% endblock %}
138 changes: 138 additions & 0 deletions src/lib/EventListener/AdminExceptionListener.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
<?php

/**
* @copyright Copyright (C) eZ Systems AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace EzSystems\EzPlatformAdminUi\EventListener;

use eZ\Publish\Core\MVC\Symfony\SiteAccess;
use EzSystems\EzPlatformAdminUi\Notification\NotificationHandlerInterface;
use EzSystems\EzPlatformAdminUiBundle\EzPlatformAdminUiBundle;
use SplFileInfo;
use Symfony\Component\Filesystem\Filesystem;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Twig\Environment;
use Throwable;

class AdminExceptionListener
{
/** @var NotificationHandlerInterface */
protected $notificationHandler;

/** @var array */
protected $siteAccessGroups;

/** @var Environment */
protected $twig;

/** @var string */
protected $rootDir;

/** @var string */
protected $kernelEnvironment;

/**
* @param Environment $twig
* @param NotificationHandlerInterface $notificationHandler
* @param array $siteAccessGroups
* @param string $kernelRootDir
* @param string $kernelEnvironment
*/
public function __construct(
Environment $twig,
NotificationHandlerInterface $notificationHandler,
array $siteAccessGroups,
string $kernelRootDir,
string $kernelEnvironment
) {
$this->twig = $twig;
$this->notificationHandler = $notificationHandler;
$this->siteAccessGroups = $siteAccessGroups;
$this->kernelEnvironment = $kernelEnvironment;
$this->rootDir = $kernelRootDir . '/..';
}

/**
* @param GetResponseForExceptionEvent $event
*/
public function onKernelException(GetResponseForExceptionEvent $event)
{
if ($this->kernelEnvironment !== 'prod') {
return;
}

if (!$this->isAdminException($event)) {
return;
}

$response = new Response();
$exception = $event->getException();

if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}

$code = $response->getStatusCode();

$this->notificationHandler->error($this->getNotificationMessage($exception));

switch ($code) {
case 404:
$content = $this->twig->render('@EzPlatformAdminUi/errors/404.html.twig');
break;
case 403:
$content = $this->twig->render('@EzPlatformAdminUi/errors/403.html.twig');
break;
default:
$content = $this->twig->render('@EzPlatformAdminUi/errors/error.html.twig');
break;
}

$response->setContent($content);
$event->setResponse($response);
}

/**
* @param GetResponseForExceptionEvent $event
*
* @return bool
*/
private function isAdminException(GetResponseForExceptionEvent $event): bool
{
$request = $event->getRequest();

/** @var SiteAccess $siteAccess */
$siteAccess = $request->get('siteaccess', new SiteAccess());

return in_array($siteAccess->name, $this->siteAccessGroups[EzPlatformAdminUiBundle::ADMIN_GROUP_NAME]);
}

/**
* @param Throwable $exception
*
* @return string
*/
private function getNotificationMessage(Throwable $exception): string
{
if ($exception instanceof HttpExceptionInterface) {
return $exception->getMessage();
}

$file = new SplFileInfo($exception->getFile());
$line = $exception->getLine();

$relativePathname = (new Filesystem())->makePathRelative($file->getPath(), $this->rootDir) . $file->getFilename();

$message = $exception->getMessage();

return sprintf('%s [in %s:%d]', $message, $relativePathname, $line);
}
}