<?php 
 
/* 
 * This file is part of the Symfony package. 
 * 
 * (c) Fabien Potencier <fabien@symfony.com> 
 * 
 * For the full copyright and license information, please view the LICENSE 
 * file that was distributed with this source code. 
 */ 
 
namespace Symfony\Component\HttpKernel\EventListener; 
 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\RequestStack; 
use Symfony\Component\HttpKernel\Event\FinishRequestEvent; 
use Symfony\Component\HttpKernel\Event\GetResponseEvent; 
use Symfony\Component\HttpKernel\Event\KernelEvent; 
use Symfony\Component\HttpKernel\KernelEvents; 
use Symfony\Component\Routing\RequestContextAwareInterface; 
 
/** 
 * Initializes the locale based on the current request. 
 * 
 * @author Fabien Potencier <fabien@symfony.com> 
 * 
 * @final since Symfony 4.3 
 */ 
class LocaleListener implements EventSubscriberInterface 
{ 
    private $router; 
    private $defaultLocale; 
    private $requestStack; 
 
    public function __construct(RequestStack $requestStack, string $defaultLocale = 'en', RequestContextAwareInterface $router = null) 
    { 
        $this->defaultLocale = $defaultLocale; 
        $this->requestStack = $requestStack; 
        $this->router = $router; 
    } 
 
    public function setDefaultLocale(KernelEvent $event) 
    { 
        $event->getRequest()->setDefaultLocale($this->defaultLocale); 
    } 
 
    public function onKernelRequest(GetResponseEvent $event) 
    { 
        $request = $event->getRequest(); 
 
        $this->setLocale($request); 
        $this->setRouterContext($request); 
    } 
 
    public function onKernelFinishRequest(FinishRequestEvent $event) 
    { 
        if (null !== $parentRequest = $this->requestStack->getParentRequest()) { 
            $this->setRouterContext($parentRequest); 
        } 
    } 
 
    private function setLocale(Request $request) 
    { 
        if ($locale = $request->attributes->get('_locale')) { 
            $request->setLocale($locale); 
        } 
    } 
 
    private function setRouterContext(Request $request) 
    { 
        if (null !== $this->router) { 
            $this->router->getContext()->setParameter('_locale', $request->getLocale()); 
        } 
    } 
 
    public static function getSubscribedEvents() 
    { 
        return [ 
            KernelEvents::REQUEST => [ 
                ['setDefaultLocale', 100], 
                // must be registered after the Router to have access to the _locale 
                ['onKernelRequest', 16], 
            ], 
            KernelEvents::FINISH_REQUEST => [['onKernelFinishRequest', 0]], 
        ]; 
    } 
}