<?php
namespace Social\FrontendBundle\EventListener;
use Social\InternalBundle\Entity\LanguageSetting;
use Social\UserBundle\Entity\User;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\FinishRequestEvent;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
/**
* Class TranslateListener
*
* @package Social\FrontendBundle\EventListener
*/
class TranslateListener implements EventSubscriberInterface
{
private $tokenStorage;
private $container;
private $defaultLanguage;
/**
* TranslateListener constructor.
*
* @param TokenStorageInterface $tokenStorage
* @param ContainerInterface $container
* @param string $defaultLanguage
*/
public function __construct(
TokenStorageInterface $tokenStorage,
ContainerInterface $container,
string $defaultLanguage
) {
$this->tokenStorage = $tokenStorage;
$this->container = $container;
$this->defaultLanguage = $defaultLanguage;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
KernelEvents::REQUEST => ['onKernelRequest', 127],
KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', 0]],
];
}
/**
* @param GetResponseEvent $event
*
* @return GetResponseEvent
*/
public function onKernelRequest(GetResponseEvent $event): ?GetResponseEvent
{
$request = $event->getRequest();
if ($request->get("_route") == "social_frontend_change_locale") {
return $event;
}
if (!$request->isXmlHttpRequest()) {
$languages = $this->container->getParameter('languages');
$languages = array_column($languages, 'code');
$tokenStorage = $this->tokenStorage->getToken();
$locale = $request->getSession()->get('_locale', $this->defaultLanguage);
// Check for user locale
if ($tokenStorage instanceof TokenInterface && $tokenStorage->getUser() instanceof User) {
/** @var User $user */
$user = $this->tokenStorage->getToken()->getUser();
if ($user) {
if ($user->getLocale()) {
$locale = $user->getLocale();
} elseif ($user->hasRole(User::ROLE_USER)) {
$this->getConfiguredLanguage($request, $languages,$locale);
}
}
} elseif ($request->get("_route") == "social_user_homepage") {
$this->getConfiguredLanguage($request, $languages, $locale);
}
if (in_array($locale, $languages)) {
$this->handleLocale($event->getRequest(), $locale);
} else {
$this->handleLocale($event->getRequest(), $this->defaultLanguage);
}
return $event;
}
return $event;
}
public function getConfiguredLanguage($request, $languages, &$locale)
{
$em = $this->container->get('doctrine.orm.entity_manager');
$isFromUserLanguageActive = $em->getRepository(LanguageSetting::class)->findOneBy(['type' => LanguageSetting::TYPE_USER_BROWSER_LANGUAGE, 'active' => true]);
$isApiIpActive = $em->getRepository(LanguageSetting::class)->findOneBy(['type' => LanguageSetting::TYPE_APIIP_LANGUAGE, 'active' => true]);
$isSetStaticLanguage = $em->getRepository(LanguageSetting::class)->findOneBy(['type' => LanguageSetting::TYPE_STATIC_LANGUAGE, 'active' => true]);
if ($isFromUserLanguageActive) {
$localePreferences = explode(",",$_SERVER['HTTP_ACCEPT_LANGUAGE']);
if(is_array($localePreferences) && count($localePreferences) > 0) {
$browserLocale = $localePreferences[0];
$browserLocale = explode("-", $browserLocale);
$locale = $browserLocale[0];
}
} else {
if ($isApiIpActive) {
$apiipData = $this->container->get('social_internal.location_service')->execute($request->getClientIp());
if ($isApiIpActive->getLanguage()) {
$configuredLanguages = explode(", ", $isApiIpActive->getLanguage());
foreach ($configuredLanguages as $language) {
if (array_key_exists($language, $apiipData['languages']) && in_array($language, $languages)) {
$locale = $language;
break;
}
}
} else {
if (isset($apiipData['languages'])) {
$locale = array_key_first($apiipData['languages']);
}
}
} elseif ($isSetStaticLanguage) {
$locale = $isSetStaticLanguage->getLanguage();
}
}
}
/**
* @param FinishRequestEvent $event
* @return void
*/
public function onKernelFinishRequest(FinishRequestEvent $event)
{
if (null === $parentRequest = $this->container->get('request_stack')->getParentRequest()) {
return;
}
$this->handleLocale($parentRequest, $parentRequest->getLocale());
}
/**
* @param Request $request
* @param string $locale
* @return void
*/
private function handleLocale(Request $request, string $locale)
{
try {
$request->setLocale($locale);
$request->getSession()->set('_locale', $locale);
$this->container->get('translator')->setLocale($locale);
$this->container->get('translator')->setFallbackLocales([$locale]);
} catch (\Exception $e) {
$request->setLocale($this->defaultLanguage);
$request->getSession()->set('_locale', $this->defaultLanguage);
$this->container->get('translator')->setLocale($this->defaultLanguage);
}
}
}