<?php
namespace App\Utils\Listeners;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Routing\Matcher\UrlMatcher;
use Symfony\Component\Routing\Matcher\UrlMatcherInterface;
use Symfony\Component\Routing\RequestContext;
use Symfony\Component\HttpKernel\Event\RequestEvent;
class LocaleListener implements EventSubscriberInterface
{
/**
* @var routeCollection \Symfony\Component\Routing\RouteCollection
*/
private $routeCollection;
/**
* @var urlMatcher \Symfony\Component\Routing\Matcher\UrlMatcher;
*/
private $urlMatcher;
private $oldUrl;
private $newUrl;
private $languages;
private $defaultLanguage;
public function __construct(RouterInterface $router, UrlMatcherInterface $urlMatcher)
{
$this->routeCollection = $router->getRouteCollection();
$this->languages = ["en","ar"];
$this->defaultLanguage = "en";
$context = new RequestContext("/");
$this->urlMatcher = $urlMatcher;
}
public function onKernelRequest(RequestEvent $event)
{
//GOAL:
// Redirect all incoming requests to their /locale/route equivalent when exists.
// Do nothing if it already has /locale/ in the route to prevent redirect loops
// Do nothing if the route requested has no locale param
$request = $event->getRequest();
$this->newUrl = $request->getPathInfo();
$this->oldUrl = $request->headers->get('referer');
$locale = $this->checkLanguage();
if ($locale === null) {
return;
}
$request->setLocale($locale);
$pathLocale = "/".$locale.$this->newUrl;
//We have to catch the ResourceNotFoundException
try {
//Try to match the path with the local prefix
$this->urlMatcher->match($pathLocale);
$event->setResponse(new RedirectResponse($pathLocale));
} catch (\Symfony\Component\Routing\Exception\ResourceNotFoundException $e) {
} catch (\Symfony\Component\Routing\Exception\MethodNotAllowedException $e) {
}
}
private function checkLanguage()
{
foreach ($this->languages as $language) {
if (preg_match_all("/\/$language\//", $this->newUrl)) {
return null;
}
if (preg_match_all("/\/$language\//", $this->oldUrl)) {
return $language;
}
}
return $this->defaultLanguage;
}
public static function getSubscribedEvents()
{
return array(
// must be registered before the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
);
}
}