PHPFixing
  • Privacy Policy
  • TOS
  • Ask Question
  • Contact Us
  • Home
  • PHP
  • Programming
  • SQL Injection
  • Web3.0

Wednesday, February 16, 2022

[FIXED] Symfony 5 - Redirection after website translation based on browser language

 February 16, 2022     http-headers, php, redirect, symfony, translation     No comments   

Issue

I'm currently working on symfony 5 and I've fully translated my website in several languages. I have a button to select the language, but I would like the default language of the site to be the one of the user (of his browser more precisely). For the moment I have found a solution, but it is not optimal at all.

What I do is that in my index, I check if the user has already browsed the site before, and if not, I redirect him to a change_locale route which will take the language in question as a parameter (He enters the condition only if it's his first visit)

public function index(Request $request): Response
{
    // If this is the first visit to the site, the default language is set according to the user's browser language
    if (!$request->hasPreviousSession()) {
        return $this->redirectToRoute('change_locale', ['locale' => strtolower(str_split($_SERVER['HTTP_ACCEPT_LANGUAGE'], 2)[0])]);
    }

    return $this->render('accueil/index.html.twig');
}

Here I simply register the variable in the session to change the language. And my problem is just after this step. When the user simply clicks on the language change button on the site, he goes back to the previous page (he doesn't enter the if). However, if he comes to the site for the first time, he is redirected from the index, and when he comes to this route, he enters the condition if (!$request->hasPreviousSession()) and... That's the problem. Because if he hasn't visited anything before, I can't redirect him to the page he was visiting.

 /**
 * @Route("/change-locale/{locale}", name="change_locale")
 */
public function changeLocale($locale, Request $request)
{
    $request->getSession()->set('_locale', $locale); // Storing the requested language in the session

    // If it's the first page visited by the user
    if (!$request->headers->get('referer')) {
        return $this->redirectToRoute('index');
    }

    // Back to the previous page
    return $this->redirect($request->headers->get('referer'));
}

So I try to remove this condition from my change_locale route and find a way to add in the header of the request the attribute 'referer' which points to the previous page. I could do this in my index before doing the redirectToRoute to change_locale.


Solution

Don't use a redirect to set the locale.

Symfony's documentation on How to Work with the User’s Locale has a great suggestion: use a custom event listener instead. Also read Making the Locale “Sticky” during a User’s Session.

You can use this example from the documentation:

class LocaleSubscriber implements EventSubscriberInterface
{
    private $defaultLocale;

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

    public function onKernelRequest(RequestEvent $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 [
            // must be registered before (i.e. with a higher priority than) the default Locale listener
            KernelEvents::REQUEST => [['onKernelRequest', 20]],
        ];
    }
}

And some free advice: in the onKernelRequest method you can use HTTP_ACCEPT_LANGUAGE to see what language the user might use, but (like all other user input!) it can be unavailable or unreliable. You might want to use information from the user's IP address or other logic.



Answered By - Stephan Vierkant
  • Share This:  
  •  Facebook
  •  Twitter
  •  Stumble
  •  Digg
Newer Post Older Post Home

0 Comments:

Post a Comment

Note: Only a member of this blog may post a comment.

Total Pageviews

Featured Post

Why Learn PHP Programming

Why Learn PHP Programming A widely-used open source scripting language PHP is one of the most popular programming languages in the world. It...

Subscribe To

Posts
Atom
Posts
Comments
Atom
Comments

Copyright © PHPFixing