@@ -106,3 +106,112 @@ method::
106106 {
107107 $locale = $request->getLocale();
108108 }
109+
110+ Setting the Locale Based on the User's Preferences
111+ --------------------------------------------------
112+
113+ You might want to improve this technique even further and define the locale based on
114+ the user entity of the logged in user. However, since the ``LocaleListener `` is called
115+ before the ``FirewallListener ``, which is responsible for handling authentication and
116+ is setting the user token into the ``TokenStorage ``, you have no access to the user
117+ which is logged in.
118+
119+ Let's pretend you have defined a property "locale" in your user entity which you
120+ want to be used as the locale for the given user. In order to achieve the wanted locale
121+ configuration, you can set the locale which is defined for the user to the session right
122+ after the login. Fortunately, you can hook into the login process and update the user's
123+ session before the redirect to the first page. For this you need an event listener for the
124+ ``security.interactive_login `` event:
125+
126+ .. code-block :: php
127+
128+ // src/AppBundle/EventListener/UserLocaleListener.php
129+ namespace AppBundle\EventListener;
130+
131+ use Symfony\Component\HttpFoundation\Session\Session;
132+ use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
133+
134+ /**
135+ * Stores the locale of the user in the session after the
136+ * login. This can be used by the LocaleListener afterwards.
137+ */
138+ class UserLocaleListener
139+ {
140+ /**
141+ * @var Session
142+ */
143+ private $session;
144+
145+ public function __construct(Session $session)
146+ {
147+ $this->session = $session;
148+ }
149+
150+ /**
151+ * @param InteractiveLoginEvent $event
152+ */
153+ public function onInteractiveLogin(InteractiveLoginEvent $event)
154+ {
155+ $user = $event->getAuthenticationToken()->getUser();
156+
157+ if (null !== $user->getLocale()) {
158+ $this->session->set('_locale', $user->getLocale());
159+ }
160+ }
161+ }
162+
163+ Then register the listener:
164+
165+ .. configuration-block ::
166+
167+ .. code-block :: yaml
168+
169+ # app/config/services.yml
170+ services :
171+ app.user_locale_listener :
172+ class : AppBundle\EventListener\UserLocaleListener
173+ arguments : [@session]
174+ tags :
175+ - { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin }
176+
177+ .. code-block :: xml
178+
179+ <!-- app/config/services.xml -->
180+ <?xml version =" 1.0" encoding =" UTF-8" ?>
181+ <container xmlns =" http://symfony.com/schema/dic/services"
182+ xmlns : xsi =" http://www.w3.org/2001/XMLSchema-instance"
183+ xsi : schemaLocation =" http://symfony.com/schema/dic/services
184+ http://symfony.com/schema/dic/services/services-1.0.xsd" >
185+
186+ <services >
187+ <service id =" app.user_locale_listener"
188+ class =" AppBundle\EventListener\UserLocaleListener" >
189+
190+ <argument type =" service" id =" session" />
191+
192+ <tag name =" kernel.event_listener"
193+ event =" security.interactive_login"
194+ method =" onInteractiveLogin" />
195+ </service >
196+ </services >
197+ </container >
198+
199+ .. code-block :: php
200+
201+ // app/config/services.php
202+ $container
203+ ->register('app.user_locale_listener', 'AppBundle\EventListener\UserLocaleListener')
204+ ->addArgument('session')
205+ ->addTag(
206+ 'kernel.event_listener',
207+ array('event' => 'security.interactive_login', 'method' => 'onInteractiveLogin'
208+ );
209+
210+ .. caution ::
211+
212+ With this configuration you are all set for having the locale based on the user's
213+ locale. If however the locale changes during the session, it would not be updated
214+ since with the current implementation the user locale will only be stored to the
215+ session on login. In order to update the language immediately after a user has
216+ changed their language, you need to update the session after an update to
217+ the user entity.
0 commit comments