Search code examples
phpsymfonysessionmultilingual

User select languague and save locale for all session


I'm working in page with multiple languages. I have a buttons in a twig homepage to switch between languages. I'm trying to set locale like this when user click a button to select language:

public function indexLangAction(Request $request, $lang)
{
$session = $this->get('session');
if ($session->has("_locale") && $lang !== $session->get("_locale")) {
    $session->set("_locale", $lang);
    return new RedirectResponse('/' . $lang);
}

return $this->render('default/index.html.twig', [
    'base_dir' => realpath($this-
>getParameter('kernel.project_dir')).DIRECTORY_SEPARATOR,
]);
}

But when I go to another page in same session, the language back to default.

How can I save _locale in all user session?

How is the best way to set _locale? And how can I call to controller from twig? When user click button to change language, how can I call to controller?

privacy_lang:
path:     /{_locale}/privacy
defaults: { _controller: AppBundle:Documents:privacy }
requirements:
        _locale: en|es|ca

And this is link in twig that call route privacy_lang:

<a class="privacy enllac-lower" href="{{ path('privacy_lang') }}">Política de privacidad</a>

Solution

  • Using the listener. Create a service first:

    AppBundle\EventListener\LocaleListener:
        tags:
            - { name: kernel.event_subscriber }
    

    LocaleListener.php:

    namespace AppBundle\EventListener;
    
    use Symfony\Component\HttpKernel\Event\GetResponseEvent;
    use Symfony\Component\HttpKernel\KernelEvents;
    use Symfony\Component\EventDispatcher\EventSubscriberInterface;
    
    class LocaleListener implements EventSubscriberInterface {
    private $defaultLocale;
    
    public function __construct($defaultLocale = 'en')
    {
        $this->defaultLocale = $defaultLocale;
    }
    
    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
    
        if ($locale = $request->attributes->get('_locale')) {
            $request->getSession()->set('_locale', $locale);
        } else {
            $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
        }
    }
    
    public static function getSubscribedEvents()
    {
        return [KernelEvents::REQUEST => array(array('onKernelRequest', 15))];
    }
    
    }
    

    Change Language Controller:

    $request->getSession()->set('_locale', 'fr');