<?php
namespace App\EventListener;
use App\Entity\Redirection;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ExceptionEvent;
use Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Routing\Router;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\VarDumper\VarDumper;
class RequestListener implements EventSubscriberInterface
{
private $em;
private $router;
public function __construct(RouterInterface $router, EntityManagerInterface $em)
{
$this->router = $router;
$this->em = $em;
}
public static function getSubscribedEvents(): array
{
return [
ExceptionEvent::class => 'onException',
RequestEvent::class => 'onRequest',
];
}
public function onException(RequestEvent $event)
{
if ($event->getRequest()->getRequestUri()) {
if ($event->getThrowable() instanceof NotFoundHttpException) {
$code = "404";
} else {
$code = "500";
}
$redirections = $this->em->getRepository("App:Redirection")->findBy(['path' => $event->getRequest()->getRequestUri(), 'deletedAt' => null]);
if (count($redirections) <= 0) {
$redirection = new Redirection();
$redirection->setPath($event->getRequest()->getRequestUri());
$redirection->setCode($code);
$this->em->persist($redirection);
$this->em->flush();
} else {
$target = null;
foreach ($redirections as $redirection) {
if ($redirection->getTarget()) {
$target = $redirection->getTarget();
}
}
if ($target !== null) {
$response = new RedirectResponse($redirection->getTarget(), Response::HTTP_MOVED_PERMANENTLY);
$event->setResponse($response);
}
}
}
}
public function onRequest(RequestEvent $event)
{
// do not redirect if the request is for an API endpoint or the admin panel
if (str_starts_with($event->getRequest()->getRequestUri(), '/api') || str_starts_with($event->getRequest()->getRequestUri(), '/admin')) {
return;
}
if ($event->isMainRequest()) {
$session = $event->getRequest()->getSession();
if($event->getRequest()->get('selected_locale')){
$session->set('selected_locale', $event->getRequest()->get('selected_locale'));
}
$browserLocale = $event->getRequest()->getPreferredLanguage(array('en', 'fr'));
if (!$session->has('selected_locale') && $event->getRequest()->getLocale() != $browserLocale) {
$route = $this->router->match($event->getRequest()->getPathInfo());
if(array_key_exists('_route', $route)){
$attributes = $route;
unset($attributes['_route']);
unset($attributes['_controller']);
$attributes['_locale'] = $browserLocale;
$response = new RedirectResponse($this->router->generate($route["_route"], $attributes));
$event->getRequest()->setLocale($browserLocale);
$event->setResponse($response);
}
}
}
}
}