Symfony: Set language based on user’s setting

Symfony: Set language based on user’s setting

When using localization in a web application it might be useful to store user’s language in database so that every time they log in to the application they get the interface in the language they are used to. Let’s see how to do that in Symfony.

First install and configure these bundles using their respective configuration:

Once we have all these bundles properly set up, we are able to switch between interface languages and we have localized login forms. The only remaining part is to redirect the user to correct language version once they log in.

Step 1: Add locale attribute to user entity

Find your user entity and add a locale attribute. Implement getLocale() function. It might also be a good idea to make the value configurable in user profile form.

Step 2: Implement AuthenticationSuccessHandler

The handler will be called when user successfully logs in to the application. It will check user’s locale and redirect to proper language version. Please note that ‘dashboard’ is name of the route we want to redirect the user to.

namespace AppBundle\Authentication;

use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Routing\RouterInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;

class AfterLoginRedirection implements AuthenticationSuccessHandlerInterface {

    const DEFAULT_LOCALE = 'en';

    /** @var RouterInterface */
    private $router;

    /**
     * AfterLoginRedirection constructor.
     *
     * @param RouterInterface $router
     */
    public function __construct(RouterInterface $router) {
        $this->router = $router;
    }

    public function onAuthenticationSuccess(Request $request, TokenInterface $token) {
        $response = new RedirectResponse($this->router->generate('fos_user_security_login'));

        if ($token->isAuthenticated()) {
            $locale = self::DEFAULT_LOCALE;
            $user = $token->getUser();

            if ($request->getLocale()) {
                $locale = $request->getLocale();
            }

            if ($user->getLocale()) {
                $locale = $user->getLocale();
            }

            $response = new RedirectResponse($this->router->generate('dashboard', array(
                        '_locale' => $locale
            )));
        }

        return $response;
    }
}

Step 3: Activate the handler

Configure service:

services:
    app.authentication.login.redirect:
        class: AppBundle\Authentication\AfterLoginRedirection
        arguments: ['@router']

Configure FOSUserBundle to use the service:

security:
    firewalls:
        main:
            pattern: ^/
            form_login:
                provider: fos_userbundle
                login_path: fos_user_security_login
                check_path: fos_user_security_check
                success_handler: app.authentication.login.redirect
                csrf_token_generator: security.csrf.token_manager
            logout:       true
            anonymous:    true

And that’s it. Now users are redirected to the correct language version.

3 thoughts on “Symfony: Set language based on user’s setting

  1. Is there a way to make the confirmation mail sent to the user, translated on the user’s prefered language parameter saved in the registration form?

    1. I’m using the following workflow:

      1. User reads information on public website. They read it in a language they understand. (They use a language switch which sets their locale).
      2. They go to registration form, fill it out and submit.
      3. When creating a new User entity, I store current locale.
      4. FOSUserBundle generates confirmation email. At this time locale is set to user’s preferred one so the confirmation email can be translated in the same way as any other web page. I use Twig templates as described here and {% trans %} blocks in the template.
      3. The email is sent in user’s locale.

Leave a Reply

Your email address will not be published. Required fields are marked *