<?php
namespace AWCmsBundle\EventListener;
use AWCmsBundle\Exception\AuthFailException;
use AWCmsBundle\Manager\RedirectionManager;
use AWCmsBundle\Manager\SiteManager;
use AWCmsBundle\Manager\SlugManager;
use AWCmsBundle\Service\SiteByHostNameProvider;
use AWCmsBundle\Service\SiteProvider;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
use Symfony\Contracts\Translation\TranslatorInterface;
class ExceptionListener implements EventSubscriberInterface
{
/**
* @var RedirectionManager
*/
private RedirectionManager $redirectionManager;
/**
* @var SiteManager
*/
private SiteManager $siteManager;
/**
* @var SlugManager
*/
private SlugManager $slugManager;
/**
* @var SessionInterface
*/
private SessionInterface $session;
/**
* @var TranslatorInterface
*/
private TranslatorInterface $translator;
/**
* @var RouterInterface
*/
private RouterInterface $router;
private SiteByHostNameProvider $siteByHostNameProvider;
public function __construct(
RedirectionManager $redirectionManager,
SiteManager $siteManager,
SlugManager $slugManager,
SessionInterface $session,
TranslatorInterface $translator,
RouterInterface $router,
SiteByHostNameProvider $siteByHostNameProvider
)
{
$this->redirectionManager = $redirectionManager;
$this->siteManager = $siteManager;
$this->slugManager = $slugManager;
$this->session = $session;
$this->translator = $translator;
$this->router = $router;
$this->siteByHostNameProvider = $siteByHostNameProvider;
}
public static function getSubscribedEvents(): array
{
return [
KernelEvents::EXCEPTION => ['onKernelException', 2],
];
}
public function onKernelException(ExceptionEvent $event): void
{
$exception = $event->getThrowable();
if($exception instanceof AuthFailException){
$route = ($this->isAdmin($event->getRequest()))
? 'user_security_admin_login'
: 'user_security_login';
$this->sendError($event, $exception->getMessage(), 400, $route);
}
if($exception instanceof AccessDeniedException){
$route = ($this->isAdmin($event->getRequest()))
? 'user_security_admin_login'
: 'user_security_login';
$this->sendError($event, $exception->getMessage(), 403, $route);
}
if ($exception instanceof NotFoundHttpException) {
$this->notFoundHandler($event);
}
}
public function sendError(ExceptionEvent $event, $message, $status = null, $redirectToRoute = null){
if($this->isApi($event->getRequest())){
$event->setResponse(new JsonResponse(['message' => $message], $status));
}
else{
$this->session->getFlashBag()->add('notice_error', $message);
if ($redirectToRoute){
$response = new RedirectResponse($this->router->generate($redirectToRoute));
$event->setResponse($response);
}
}
}
public function notFoundHandler(ExceptionEvent $event){
$request = $event->getRequest();
if(
!$this->isDebugBar($event->getRequest())
and !$this->isResource($event->getRequest())
and !$this->isApi($event->getRequest())
and !$this->isAdmin($event->getRequest())) {
// Checking if their is redirection for this uri
$redirection = $this->redirectionManager->getRedirectionFromUrl($request->getRequestUri());
$site = $this->siteManager->getSite() ?: $this->siteByHostNameProvider->get($event);
if ($redirection
and $url = $this->redirectionManager->getTargetUrl($redirection)
and $url != $request->getRequestUri()) {
$response = new RedirectResponse($url, $redirection->getStatus());
$event->setResponse($response);
}
// Render 404 cms site content page when response has 404 status code, not in admin panel
elseif ($site
and !$this->isAdmin($request)
and $page = $site->getRedirectPageOn404()) {
$response = new Response($this->slugManager->forwardSlug($page->getSlugEntity(), $request)->getContent(), 404);
$event->setResponse($response);
}
}
}
private function isApi(Request $request)
{
if (!empty(preg_match("#^/api/#i", $request->getRequestUri(), $matches))) {
return true;
}
return false;
}
private function isAdmin(Request $request)
{
if (!empty(preg_match("#^/admin/#i", $request->getRequestUri(), $matches))) {
return true;
}
return false;
}
private function isDebugBar(Request $request)
{
if (!empty(preg_match("#^/_wdt/#i", $request->getRequestUri(), $matches))) {
return true;
}
return false;
}
private function isResource(Request $request)
{
if (!empty(preg_match("#^/bundles/#i", $request->getRequestUri(), $matches))) {
return true;
}
return false;
}
}