<?php
namespace App\EventSubscriber;
use GeoIp2\Database\Reader;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class LocaleSubscriber implements EventSubscriberInterface
{
private $availableLocales;
private $defaultLocale;
/** @var Reader */
private $geoip;
/**
* LocaleSubscriber constructor.
*/
public function __construct(ParameterBagInterface $parameterBag, Reader $geoip)
{
$this->availableLocales = explode('|', $parameterBag->get('available_locales'));
$this->defaultLocale = $parameterBag->get('default_locale');
$this->geoip = $geoip;
}
public static function getSubscribedEvents()
{
return [
KernelEvents::REQUEST => [['onKernelRequest', 20]]
];
}
public function onKernelRequest(RequestEvent $event) {
$request = $event->getRequest();
if (!$event->isMainRequest()) {
return null;
}
$locale = null;
// get from url
$uriLocale = $this->getLocaleFromUri($request);
$locale = $uriLocale ?? null;
// get from ip
$ipLocale = $this->getLocaleFromIp($request);
$locale = $ipLocale ?? null;
// get default locale
$locale = $locale ?? $this->defaultLocale;
$request->setLocale($locale);
}
private function getLocaleFromUri(Request $request) {
$uri = $request->getRequestUri();
$uriParts = explode('/', $uri);
$localePart = null;
if (count($uriParts) > 1) {
$localePart = $uriParts[1];
}
$availableLocales = $this->availableLocales;
if (!in_array($localePart, $availableLocales)) {
return null;
}
return $localePart;
}
private function getLocaleFromIp(Request $request) {
$ip = $request->getClientIp();
// return null if localhost
if (in_array($ip, ['::1', '127.0.0.1'])) {
return null;
}
$availableLocales = $this->availableLocales;
try {
$country = $this->geoip->country($ip);
$countryIso = strtolower($country->country->isoCode);
if (!in_array($countryIso, $availableLocales)) {
return null;
}
return $countryIso;
} catch (\Exception $e) {
return null;
}
}
}