From 66e21a95bbd066cf1e0c011f1ed2b7271ccdb1bd Mon Sep 17 00:00:00 2001 From: Peter Rehm Date: Sat, 17 Jan 2015 18:51:22 +0100 Subject: [PATCH 1/4] Added chapter about the locale based on the user entity --- cookbook/session/locale_sticky_session.rst | 83 ++++++++++++++++++++++ 1 file changed, 83 insertions(+) diff --git a/cookbook/session/locale_sticky_session.rst b/cookbook/session/locale_sticky_session.rst index 2aa61eed497..90dee1954f2 100644 --- a/cookbook/session/locale_sticky_session.rst +++ b/cookbook/session/locale_sticky_session.rst @@ -106,3 +106,86 @@ method:: { $locale = $request->getLocale(); } + +Setting the locale based on the user entity +------------------------------------------- + +You might want to improve even further and want to define the locale based on +the user entity of the logged in user. However since the `LocaleListener` is called +before the `FirewallListener`, which is responsible for handling authentication and +is setting the user token into the `TokenStorage`, you have no access to the user +which is logged in. + +First lets pretend you have defined a property locale in your User Entity which you +want to be used as the locale for the given user. In order to achieve the wanted locale +configuration you can set the locale which is defined for the user to the session right +after the login. Fortunately you can hook into the login process and update your session +variable before the redirect to the first page. For this you need an event listener for the +`security.interactive_login` event. + + // src/AppBundle/EventListener/UserLocaleListener.php + namespace AppBundle\EventListener; + + use Symfony\Component\HttpFoundation\Session\Session; + use Symfony\Component\Security\Http\Event\InteractiveLoginEvent; + + /** + * Stores the locale of the user in the session after the + * login. This can be used by the LocaleListener afterwards. + */ + class UserLocaleListener + { + /** + * @var Session + */ + private $session; + public function __construct(Session $session) + { + $this->session = $session; + } + /** + * @param InteractiveLoginEvent $event + */ + public function onInteractiveLogin(InteractiveLoginEvent $event) + { + $user = $event->getAuthenticationToken()->getUser(); + $this->session->set('_locale', $user->getLocale()); + } + } + +Then register the listener: + +.. configuration-block:: + + .. code-block:: yaml + + # app/config/services.yml + services: + app.user_locale_listener: + class: AppBundle\EventListener\UserLocaleListener + tags: + - { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin } + + .. code-block:: xml + + + + + + + .. code-block:: php + + // app/config/services.php + $container + ->register('kernel.listener.your_listener_name', 'AppBundle\EventListener\UserLocaleListener') + ->addTag('kernel.event_listener', array('event' => 'security.interactive_login', 'method' => 'onInteractiveLogin')) + ; + +.. caution:: + +With this configuration you are all set for having the locale based on the user's +locale. If however the locale changes during the session it would not be updated +since with the current implementation the user locale will only be stored to the +session on login. In order to update the language immediately after a user has +changed his language you need to update the session variable after an update to +the user entity. From 6e986e188089fa8c19452e3d33c56ddf0aabf687 Mon Sep 17 00:00:00 2001 From: Peter Rehm Date: Sat, 17 Jan 2015 23:57:57 +0100 Subject: [PATCH 2/4] Updated wording of the chapter as per discussion --- cookbook/session/locale_sticky_session.rst | 35 +++++++++++++--------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/cookbook/session/locale_sticky_session.rst b/cookbook/session/locale_sticky_session.rst index 90dee1954f2..ade2a54957d 100644 --- a/cookbook/session/locale_sticky_session.rst +++ b/cookbook/session/locale_sticky_session.rst @@ -107,21 +107,23 @@ method:: $locale = $request->getLocale(); } -Setting the locale based on the user entity +Setting the Locale based on the User Entity ------------------------------------------- -You might want to improve even further and want to define the locale based on -the user entity of the logged in user. However since the `LocaleListener` is called -before the `FirewallListener`, which is responsible for handling authentication and -is setting the user token into the `TokenStorage`, you have no access to the user +You might want to improve this technique even further and define the locale based on +the user entity of the logged in user. However since the ``LocaleListener`` is called +before the ``FirewallListener``, which is responsible for handling authentication and +is setting the user token into the ``TokenStorage``, you have no access to the user which is logged in. -First lets pretend you have defined a property locale in your User Entity which you +First lets pretend you have defined a property locale in your user entity which you want to be used as the locale for the given user. In order to achieve the wanted locale configuration you can set the locale which is defined for the user to the session right after the login. Fortunately you can hook into the login process and update your session variable before the redirect to the first page. For this you need an event listener for the -`security.interactive_login` event. +``security.interactive_login`` event. + +.. code-block:: php // src/AppBundle/EventListener/UserLocaleListener.php namespace AppBundle\EventListener; @@ -139,17 +141,22 @@ variable before the redirect to the first page. For this you need an event liste * @var Session */ private $session; + public function __construct(Session $session) { $this->session = $session; } + /** * @param InteractiveLoginEvent $event */ public function onInteractiveLogin(InteractiveLoginEvent $event) { $user = $event->getAuthenticationToken()->getUser(); - $this->session->set('_locale', $user->getLocale()); + + if (null !== $user->getLocale()) { + $this->session->set('_locale', $user->getLocale()); + } } } @@ -183,9 +190,9 @@ Then register the listener: .. caution:: -With this configuration you are all set for having the locale based on the user's -locale. If however the locale changes during the session it would not be updated -since with the current implementation the user locale will only be stored to the -session on login. In order to update the language immediately after a user has -changed his language you need to update the session variable after an update to -the user entity. + With this configuration you are all set for having the locale based on the user's + locale. If however the locale changes during the session it would not be updated + since with the current implementation the user locale will only be stored to the + session on login. In order to update the language immediately after a user has + changed their language you need to update the session variable after an update to + the user entity. From 0fc72a8199371e4ec4a63b94ddaffdd34de5886c Mon Sep 17 00:00:00 2001 From: Peter Rehm Date: Wed, 21 Jan 2015 08:36:54 +0100 Subject: [PATCH 3/4] Updated as per feedback --- cookbook/session/locale_sticky_session.rst | 41 ++++++++++++++-------- 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/cookbook/session/locale_sticky_session.rst b/cookbook/session/locale_sticky_session.rst index ade2a54957d..b7e4b0d6ebc 100644 --- a/cookbook/session/locale_sticky_session.rst +++ b/cookbook/session/locale_sticky_session.rst @@ -107,20 +107,20 @@ method:: $locale = $request->getLocale(); } -Setting the Locale based on the User Entity -------------------------------------------- +Setting the Locale Based on the User's Preferences +-------------------------------------------------- You might want to improve this technique even further and define the locale based on -the user entity of the logged in user. However since the ``LocaleListener`` is called +the user entity of the logged in user. However, since the ``LocaleListener`` is called before the ``FirewallListener``, which is responsible for handling authentication and is setting the user token into the ``TokenStorage``, you have no access to the user which is logged in. -First lets pretend you have defined a property locale in your user entity which you +Let's pretend you have defined a property "locale" in your user entity which you want to be used as the locale for the given user. In order to achieve the wanted locale -configuration you can set the locale which is defined for the user to the session right -after the login. Fortunately you can hook into the login process and update your session -variable before the redirect to the first page. For this you need an event listener for the +configuration, you can set the locale which is defined for the user to the session right +after the login. Fortunately, you can hook into the login process and update the user's +session before the redirect to the first page. For this you need an event listener for the ``security.interactive_login`` event. .. code-block:: php @@ -175,24 +175,37 @@ Then register the listener: .. code-block:: xml - - - - + + + + + + + + + + + .. code-block:: php // app/config/services.php $container - ->register('kernel.listener.your_listener_name', 'AppBundle\EventListener\UserLocaleListener') + ->register('app.user_locale_listener', 'AppBundle\EventListener\UserLocaleListener') ->addTag('kernel.event_listener', array('event' => 'security.interactive_login', 'method' => 'onInteractiveLogin')) ; .. caution:: With this configuration you are all set for having the locale based on the user's - locale. If however the locale changes during the session it would not be updated + locale. If however the locale changes during the session, it would not be updated since with the current implementation the user locale will only be stored to the session on login. In order to update the language immediately after a user has - changed their language you need to update the session variable after an update to + changed their language, you need to update the session after an update to the user entity. From 1aaa4915440673f75d30b28291c4c47302b06d1a Mon Sep 17 00:00:00 2001 From: Peter Rehm Date: Sat, 24 Jan 2015 09:56:31 +0100 Subject: [PATCH 4/4] Updated as per feedback. --- cookbook/session/locale_sticky_session.rst | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/cookbook/session/locale_sticky_session.rst b/cookbook/session/locale_sticky_session.rst index b7e4b0d6ebc..44a323d6b80 100644 --- a/cookbook/session/locale_sticky_session.rst +++ b/cookbook/session/locale_sticky_session.rst @@ -121,7 +121,7 @@ want to be used as the locale for the given user. In order to achieve the wanted configuration, you can set the locale which is defined for the user to the session right after the login. Fortunately, you can hook into the login process and update the user's session before the redirect to the first page. For this you need an event listener for the -``security.interactive_login`` event. +``security.interactive_login`` event: .. code-block:: php @@ -170,12 +170,13 @@ Then register the listener: services: app.user_locale_listener: class: AppBundle\EventListener\UserLocaleListener + arguments: [@session] tags: - { name: kernel.event_listener, event: security.interactive_login, method: onInteractiveLogin } .. code-block:: xml - + + + @@ -198,8 +201,11 @@ Then register the listener: // app/config/services.php $container ->register('app.user_locale_listener', 'AppBundle\EventListener\UserLocaleListener') - ->addTag('kernel.event_listener', array('event' => 'security.interactive_login', 'method' => 'onInteractiveLogin')) - ; + ->addArgument('session') + ->addTag( + 'kernel.event_listener', + array('event' => 'security.interactive_login', 'method' => 'onInteractiveLogin' + ); .. caution::