Explain Symfony's "sticky" locale event listener

664 views Asked by At

Symfony's cookbook proposes the following recipe to make the locale "sticky" during a user's session:

class LocaleListener implements EventSubscriberInterface
{
    private $defaultLocale;

    public function __construct($defaultLocale = 'en')
    {
        $this->defaultLocale = $defaultLocale;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        $request = $event->getRequest();
        if (!$request->hasPreviousSession()) {
            return;
        }

        // try to see if the locale has been set as a _locale routing parameter
        if ($locale = $request->attributes->get('_locale')) {
            $request->getSession()->set('_locale', $locale);
        } else {
            // if no explicit locale has been set on this request, use one from the session
            $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
        }
    }

    public static function getSubscribedEvents()
    {
        return array(
            // must be registered before the default Locale listener
            KernelEvents::REQUEST => array(array('onKernelRequest', 17)),
        );
    }
}

Can anybody explain the following three points:

  1. why do they return if ! $request->hasPreviousSession()?
  2. int the following if/else, why do they set the locale with $request->getSession()->set('_locale') in the if block? Why not using $request->setLocale() like in the else block?
  3. what exactly does "must be registered before the default Locale listener" mean?
1

There are 1 answers

1
Maltronic On

This event will make the _locale look like it's been submitted with the current request even though it may actually come from the session (BUT _locale might be in the request - e.g. when user changes locale - in which case updated the session object to the new value).

To answer your questions.

  1. If there is no session object, skip as event is redundant (value cannot be in the session as it doesn't exist).

  2. Sync _locale's value between session and request, favoring the request's version.

  3. As the LocaleListener event handles locale issues, the above needs to happen before that event runs. OnKernelRequest is one of the first events that gets triggered so we can be sure this is the case.