<?php
namespace App\Security;
use App\Entity\User;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Event\LogoutEvent;
/**
* Symfony's session logout listener invalidates the session (wiping the
* "_locale" the user picked) before dispatching LogoutEvent to subscribers
* like this one.
*
* $token is still the authenticated one here (LogoutListener clears
* TokenStorage only after dispatching the event), but the request's own
* locale is not - LocaleListener runs at a lower kernel.request priority
* than the security firewall, so it hasn't executed yet for this request
* and Request::getLocale() is still just the untouched framework default.
* Re-derive the effective locale from the token directly, mirroring
* LocaleListener's own authenticated-user resolution, so the locale the
* user was actually browsing in survives into the anonymous session.
*/
class LocalePreservingLogoutHandler implements EventSubscriberInterface
{
public static function getSubscribedEvents(): array
{
return [LogoutEvent::class => 'onLogout'];
}
public function onLogout(LogoutEvent $logoutEvent): void
{
$token = $logoutEvent->getToken();
if (!$token) {
return;
}
$request = $logoutEvent->getRequest();
$request->getSession()->set('_locale', $this->resolveLocale($token, $request));
}
private function resolveLocale(TokenInterface $token, Request $request): string
{
$user = $token->getUser();
if (!$user instanceof User) {
return $request->getSession()->get('_locale', $request->getLocale());
}
if (!$company = $user->getCompany()) {
return $request->getSession()->get('_locale', $request->getLocale());
}
return $company->getLanguage();
}
}