<?php
namespace AppBundle\EventListener;
use Pimcore\Http\Request\Resolver\PimcoreContextResolver;
use Pimcore\Model\Document;
use Pimcore\Templating\Renderer\ActionRenderer;
use Pimcore\Bundle\CoreBundle\EventListener\Traits\PimcoreContextAwareTrait;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\KernelEvents;
class ResponseExceptionListener
{
use PimcoreContextAwareTrait;
/**
* @var ActionRenderer
*/
protected $actionRenderer;
/**
* @var Document\Service
*/
protected $documentService;
/**
* @param ActionRenderer $actionRenderer
* @param Document\Service $documentService
* @param array $pimcoreConfig
*/
public function __construct(
ActionRenderer $actionRenderer,
Document\Service $documentService,
array $pimcoreConfig
) {
$this->actionRenderer = $actionRenderer;
$this->documentService = $documentService;
$this->pimcoreConfig = $pimcoreConfig;
}
/**
* @param ExceptionEvent $event
*
* @throws \Exception
*/
public function onKernelException(ExceptionEvent $event)
{
// $exception = $event->getException();
// // handle ResponseException (can be used from any context)
// if ($exception instanceof ResponseException) {
// $event->setResponse($exception->getResponse());
// return;
// }
// $request = $event->getRequest();
// if ($this->matchesPimcoreContext($request, PimcoreContextResolver::CONTEXT_DEFAULT)) {
// $this->handleErrorPage($event);
// }
}
/**
* @param ExceptionEvent $event
*
* @throws \Exception
*/
protected function handleErrorPage(ExceptionEvent $event)
{
if (\Pimcore::inDebugMode()) {
return;
}
$exception = $event->getThrowable();
$request = $event->getRequest();
if (\Pimcore\Model\Site::isSiteRequest()) {
// We expect all requests to be site requests as all the content is part of a site
$site = \Pimcore\Model\Site::getCurrentSite();
$siteDocument = $site->getRootDocument();
if ($siteDocument) {
// The nearest document of the request is use to extract the language from the path
$internalPath = $siteDocument->getRealFullPath() . $request->getPathInfo();
$nearestDocument = $this->documentService->getNearestDocumentByPath($internalPath);
if ($nearestDocument) {
// Now we search for the error document based on the locale and status code
// (this is the structure of the corporate website and mylorch)
$exceptionStatusCode = 500;
if (method_exists( $exception, 'getStatusCode') ) {
$exceptionStatusCode = $exception->getStatusCode();
}
$requestLocale = $nearestDocument->getProperty('language') ?? 'en'; // Use en as fallback
$searchErrorDocument = $siteDocument->getRealFullPath() . '/' . $requestLocale . '/meta/' . $exceptionStatusCode;
$errorDocument = Document::getByPath($searchErrorDocument);
if (!$errorDocument) {
// Search again without the locale whitch matches the structure of the microsites
$searchErrorDocument = $siteDocument->getRealFullPath() . '/meta/' . $exceptionStatusCode;
$errorDocument = Document::getByPath($searchErrorDocument);
}
if ($errorDocument) {
try {
// Try to render the localized error document
$response = $this->actionRenderer->render($errorDocument);
} catch (\Exception $e) {
// we are even not able to render the error page, so we send the client a unicorn
if ($e) {
$response = 'Page not found (' . $e->getMessage() . ') 🦄';
} else {
$response = 'Page not found 🦄';
}
}
$headers = [];
if ($exception instanceof HttpExceptionInterface) {
$statusCode = $exceptionStatusCode;
$headers = $exception->getHeaders();
}
$event->setResponse(new Response($response, $statusCode, $headers));
}
}
}
}
}
}