<?php
namespace Hitso\Bundle\CommonBundle\EventListener;
use Doctrine\Common\Collections\Criteria;
use Hitso\Bundle\CommonBundle\Helper\Templating\TemplatingHelperInterface;
use Hitso\Bundle\RoutingBundle\Entity\Redirect;
use Hitso\Bundle\RoutingBundle\Manager\RedirectManager;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\HttpKernel\KernelInterface;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Contracts\Translation\TranslatorInterface;
/**
* Class ExceptionSubscriber
*
* @package Hitso\Bundle\CommonBundle\EventListener
*/
class ExceptionSubscriber implements EventSubscriberInterface
{
/**
* @var KernelInterface
*/
protected $kernel;
/**
* @var RedirectManager
*/
private $redirectManager;
/**
* @var TemplatingHelperInterface
*/
protected $templatingHelper;
/**
* @var TranslatorInterface
*/
protected $translator;
/**
* ExceptionSubscriber constructor.
*
* @param KernelInterface $kernel
* @param TemplatingHelperInterface $templatingHelper
*/
public function __construct(
KernelInterface $kernel,
RedirectManager $redirectManager,
TemplatingHelperInterface $templatingHelper,
TranslatorInterface $translator
) {
$this->kernel = $kernel;
$this->redirectManager = $redirectManager;
$this->templatingHelper = $templatingHelper;
$this->translator = $translator;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::EXCEPTION => ['onKernelException', 0],
];
}
public function onKernelException(GetResponseForExceptionEvent $event)
{
$exception = $event->getException();
$request = $event->getRequest();
if ($exception instanceof HttpExceptionInterface || $exception instanceof ResourceNotFoundException) {
$redirect = $this->getRedirect($request);
if ($redirect instanceof Redirect) {
$response = new RedirectResponse($redirect->getTarget(), $redirect->getStatus());
} else {
$response = $this->getNotFoundResponse($request, $exception);
}
$event->setResponse($response);
}
if ($exception->getCode() == 500) {
$response = $this->getErrorResponse($exception);
$event->setResponse($response);
}
}
private function getNotFoundResponse(Request $request, $exception): Response
{
$this->translator->setLocale($request->getLocale());
$content = $this->templatingHelper->render('HitsoCommonBundle:Front/Exception:404.html.twig', [
'message' => $exception->getMessage(),
'code' => $exception->getStatusCode(),
'exception' => $exception,
]);
$response = new Response();
$response->setContent($content);
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getStatusCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
return $response;
}
private function getErrorResponse($exception): Response
{
$content = $this->templatingHelper->render('HitsoCommonBundle:Front/Exception:500.html.twig', [
'message' => $exception->getMessage(),
'code' => $exception->getCode(),
'exception' => $exception,
]);
$response = new Response();
$response->setContent($content);
if ($exception instanceof HttpExceptionInterface) {
$response->setStatusCode($exception->getCode());
$response->headers->replace($exception->getHeaders());
} else {
$response->setStatusCode(Response::HTTP_INTERNAL_SERVER_ERROR);
}
return $response;
}
private function getRedirect(Request $request): ?Redirect
{
$path = $request->getPathInfo();
$criteria = new Criteria();
$criteria->andWhere($criteria->expr()->eq('source', $path));
$collection = $this->redirectManager->getCollection($criteria);
if ($collection->count()) {
return $collection->first();
}
return null;
}
}