Reputation: 11020
I'm encountered a weird problem.
I'm working on a Symfony 2.1 project with Doctrine 2.2 and the FOSUserBundle for user management.
I added a RequestListener, since the user can change the language of the site and I want to track the last used language of the user.
So I simply added a new property to the User Entity and then want to save the new language if has changed.
So I'm doing this in the request listener:
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernel::MASTER_REQUEST != $event->getRequestType()) {
return;
}
if ($event->getRequest()->getRequestFormat() !== 'html') {
return;
}
if ($this->context->getToken()->getUser() instanceof \Foo\BarBundle\Entity\User) {
$this->request = $event->getRequest();
$this->user = $this->context->getToken()->getUser();
if ($this->user->getCustomer() instanceof \Foo\BarBundle\Entity\Customer) {
$this->customer = $this->user->getCustomer();
$permission = $this->permissionService->getPermissionSafely($this->customer);
$params = $this->request->get('_route_params');
$language = $this->getLanguage($permission['language']['languages']);
$locale = (strtolower($this->request->get('_locale')) === 'de') ? 'de_DE' : 'en_US';
if ($language !== "all" && $this->request->get('_locale') !== $language) {
$params['_locale'] = $language;
$redirect = new RedirectResponse($this->router->generate($this->request->get('_route'), $params));
$event->setResponse($redirect);
}
if ($this->user->getLastLanguage() !== $locale) {
$this->user->setLastLanguage($locale);
$this->em->flush();
}
}
}
}
private function getLanguage($language)
{
if (!isset($language['en'])) {
return 'de';
}
if (!isset($language['de'])) {
return 'en';
}
if ($language['en'] && !($language['de'])) {
return 'en';
} else if (!$language['en'] && $language['de']) {
return 'de';
}
return 'all';
}
Important is the last if
-conditional. If the current $locale
is different than the last used, I want to update the user object. So there are three possible values: de_DE
, en_US
and null
.
Now the weird behaviour comes in (and I don't know if it's a bug or what, but I'm confused):
It doesn't matter which value is stored in the database, it always gets updated to en_US
.
If a user has visit the page for the first time (value null
) and visits the site in german (value de_DE
) it gets updated to en_US
, but the profiler query says:
UPDATE `user` SET last_language = 'de_DE' WHERE id = 1
If a user has last_language = 'de_DE'
and visits the site in german (de_DE
) it gets updated to en_US
, but the query profiler says, that there wasn't a update query. Which makes sense, because the $locale
is the same like $this->user->getLastLanguage()
.
What the??
I have no idea what is going on here. Has anyone experienced a similar problem? Has this something to do with the fact, that I'm modifying the user object from the security context?
Update: The funny thing is, if I change line
$locale = (strtolower($this->request->get('_locale')) === 'de') ? 'de_DE' : 'en_US';
to
$locale = (strtolower($this->request->get('_locale')) === 'de') ? 'de_DE' : 'es_US';
it gets updated to es_US
event if $locale
holds de_DE
Upvotes: 0
Views: 832
Reputation: 52473
Your ternary if statement will always fail because the return value of
$this->request->get('_locale')
will be :
but never === 'de'. Therefore if you save $locale in your entity after calling
$locale = (strtolower($this->request->get('_locale')) === 'de') ? 'de_DE' : 'en_US';
... the next time this statement fails and puts it back to 'en_US' calling ...
$user->setLastLanguage('en_US');
... in the end. Just do a better comparison like ...
$locale = (strstr($locale,'de') !== false) ? 'de_DE' : 'en_US';
Have you tried persist before flushing:
$this->user->setLastLanguage($locale);
$this->em->flush();
should be ...
$this->user->setLastLanguage($locale);
$this->em->persist($this->user);
$this->em->flush();
... if your user is newly created and not already managed by doctrine.
Upvotes: 1