Symfony2 wrong locale detection?

后端 未结 4 1695
鱼传尺愫
鱼传尺愫 2020-12-15 10:20

Following Symfony2 guide about translation i found that inferred locale from http headers (stored in $this->get(\'session\')->getLocale()) is wrong (sent

4条回答
  •  暗喜
    暗喜 (楼主)
    2020-12-15 10:58

    per HTTP-Standard you should be using a different URL for each translated version of the page. What remains is a simple action that will infer the best-to-use locale from the request and redirect to the corresponding page:

    /**
     * @Route("/")
     */
    public function localeRedirectAction() {
        /* @var $request \Symfony\Component\HttpFoundation\Request */
        /* @var $session \Symfony\Component\HttpFoundation\Session */
        $req = $this->getRequest();
        $session = $this->get('session');
    
        $session->setLocale($req->getPreferredLanguage(array('de', 'en')));
    
        return $this->redirect($this->generateUrl('home'));
    }
    

    if you need to do this for any page, you'll basically need to do the same, but within a Listener for the kernel.request-Event. In order to be reliably called after the route-matcher did it's work you should set the priority of the listener to a value < 0:

    # services.yml
    services:
      my_locale_listener:
        class: Namespace\LocaleListener
        tags: [{ name: kernel.event_listener, event: kernel.request, method: onKernelRequest, priority: -255 }]
        arguments: [ @service_container, [ 'en', 'fr', 'de', 'es', 'it' ] ]
    

    the listener would then look like this:

    class LocaleListener {
        public function __construct($container, $availableLocales) {
            $this->container = $container;
            $this->availableLocales = $availableLocales;
        }
    
        public function onKernelRequest(GetResponseEvent $e) {
            $req = $e->getRequest();
            $locale = $req->getPreferredLanguage($this->availableLocales);
    
            // generate a new URL from the current route-name and -params, overwriting
            // the current locale
            $routeName = $req->attributes->get('_route');
            $routeParams = array_merge($req->attributes->all(), array('_locale' => $locale));
            $localizedUrl = $this->container->get('router')->generateUrl($routeName, $routeParams);
    
            $e->setResponse(new RedirectResponse($localizedUrl));
        }
    }
    

    P.S. i'm not entirely confident that this code actually works, but it should give a basic idea on how this could be done.

提交回复
热议问题