<?php
/**
* Copyright (c) 2019, MND Next GmbH - www.mndnext.de
*/
namespace App\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Exception\ResourceNotFoundException;
use Symfony\Component\Routing\RouterInterface;
class LocaleListener implements EventSubscriberInterface
{
const COOKIE = 'pref_language';
const ALLOWED_LOCALE_FRONTEND = [
'de', 'en'
];
const DEFAULT_LOCALE_FRONTEND = 'de';
const ALLOWED_LOCALE_BACKEND = [
'de'
];
const DEFAULT_LOCALE_BACKEND = 'de';
private $defaultLocale;
private $allowedLocale;
private function isAllowed($locale)
{
return in_array($locale, $this->allowedLocale);
}
private function setDefault($request)
{
try {
$route = $this->router->matchRequest($request)['_route'];
} catch (ResourceNotFoundException $e) {
$route = null;
}
if ($route == 'easyadmin') {
$this->allowedLocale = self::ALLOWED_LOCALE_BACKEND;
$this->defaultLocale = self::DEFAULT_LOCALE_BACKEND;
} else {
$this->allowedLocale = self::ALLOWED_LOCALE_FRONTEND;
$this->defaultLocale = self::DEFAULT_LOCALE_FRONTEND;
}
}
public function __construct(RouterInterface $router, $defaultLocale = 'de')
{
$this->router = $router;
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(RequestEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
$this->setDefault($request);
// try to see if the locale has been set as a _locale routing parameter
$locale = $request->attributes->get('_locale');
if (!$locale && $request->isMethod('GET')) {
// try to see if the locale has been set as a locale get parameter
$locale = $request->query->get('locale');
}
// try to see if the locale has been set as a cookie
if (!$locale || !$this->isAllowed($locale)) {
$locale = $request->cookies->get(self::COOKIE);
}
if ($locale && $this->isAllowed($locale)) {
$request->getSession()->set('_locale', $locale);
$request->setLocale($locale);
} else {
// if no explicit locale has been set on this request, use one from the session
$locale = $request->getSession()->get('_locale', $this->defaultLocale);
$request->setLocale($locale);
}
$request->cookies->set(self::COOKIE, $locale);
}
public static function getSubscribedEvents()
{
return [
// must be registered before (i.e. with a higher priority than) the default Locale listener
KernelEvents::REQUEST => [['onKernelRequest', 20]],
];
}
}