Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 291 Vote(s) - 3.53 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Symfony2 wrong locale detection?

#1
Following Symfony2 guide about [translation][1] i found that inferred locale from http headers (stored in `$this->get('session')->getLocale()`) is wrong (sent **it**, inferred **en**):

> Host localhost User-Agent Mozilla/5.0 (Windows NT 6.1; WOW64;
> rv:7.0.1) Gecko/20100101 Firefox/7.0.1
> Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
> Accept-Language it-it,it;q=0.8,en-us;q=0.5,en;q=0.3

Is this a normal behaviour? Or should i set something in order to get localization working out of the box?

[1]:

[To see links please register here]

Reply

#2
I looked more thoroughly onto the code today, because I was experiencing the same problem as you, and it appears that the language comes from `Session::getLocale()`. But Symfony2 never calls `Session::setLocale()`, and sets the `locale` member of the `Session` object. A google search for "symfony2 session setlocale" leads to [this § of the documentation][1]


[1]:

[To see links please register here]


So I ended up putting this line on top of the controller I was working on, and it worked :

$this->getRequest()->getSession()->setLocale(
$this->getRequest()->getPreferredLanguage());

Now I guess this is not acceptable, because you're not going to add this on top of each and every controller. Plus, this should not be done for every request, it should only be done for the first one, when the user has no session yet. If anyone knows how to do this feel free to edit this answer.
Reply

#3
I wrote a LocaleListener which is not redirecting you to a locale-specific url, it does however set the locale settings for you ;)

Code in the services.yml

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

and the actual listener:

class LocaleListener
{
protected $container;
protected $availableLocales;

public function __construct(\Symfony\Component\DependencyInjection\Container $container, $availableLocales) {
$this->container = $container;
$this->availableLocales = $availableLocales;
}

public function onKernelRequest(GetResponseEvent $e) {
$req = $e->getRequest();
$locale = $req->getPreferredLanguage($this->availableLocales);
$session = $this->container->get('session');
$session->setLocale($locale);
}
}
Reply

#4
You can register listener like follow:


use Symfony\Component\DependencyInjection\ContainerInterface;

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

class LocaleListener
{
private $container;
private $defaultLocale;

public function __construct(ContainerInterface $container, $defaultLocale = 'nl')
{
$this->container = $container;
$this->defaultLocale = $defaultLocale;
}

public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
return;
}

if (!$this->container->has('session')) {
return;
}

$session = $this->container->get('session');
$session->setLocale($this->defaultLocale);
}
}

([gist][1])

Just after framework session setup stage:

<service id="my.event_listener.locale_listener" class="MyBundle\MyEventListener\LocaleListener">
<tag name="kernel.event_listener" event="kernel.request" method="onKernelRequest" priority="100" />
<argument type="service" id="service_container" />
</service>

([gist][2])


[1]:

[To see links please register here]

[2]:

[To see links please register here]

Reply

#5
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.
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through