Я пытаюсь установить локаль на основе настроек текущего пользователя, которые хранятся в БД.
Поэтому у нашего класса User есть getPreferredLanguage, который возвращает идентификатор локали ('en', 'fr_FR' и т. Д.).
Я рассмотрел следующий подход:
К сожалению, это не работает. Когда вызывается метод onRequestEvent службы «locale» слушателя, контекст безопасности не имеет токена. Похоже, что прослушиватель контекста вызывается на очень поздней стадии (с приоритетом 0), и невозможно сказать, что мой «локальный» прослушиватель запускается до контекста безопасности.
Кто-нибудь знает, как исправить этот подход или предложить другой?
Вы можете быть заинтересованы в слушателе локали, который я опубликовал в этом ответе: обнаружение локализации Symfony2: не считая _locale в сеансе
Изменить: если пользователь меняет свой язык в профиле, это не проблема. Вы можете подключиться к событию успеха редактирования профиля, если вы используете FOSUserBundle (мастер). В противном случае в вашем контроллере профиля, если вы используете самодельную систему. Вот пример для FOSUserBundle:
<?php namespace Acme\UserBundle\EventListener; use FOS\UserBundle\Event\FormEvent; use FOS\UserBundle\FOSUserEvents; use Symfony\Component\EventDispatcher\EventSubscriberInterface; class ChangeLanguageListener implements EventSubscriberInterface { public static function getSubscribedEvents() { return array( FOSUserEvents::PROFILE_EDIT_SUCCESS => 'onProfileEditSuccess', ); } public function onProfileEditSuccess(FormEvent $event) { $request = $event->getRequest(); $session = $request->getSession(); $form = $event->getForm(); $user = $form->getData(); $lang = $user->getLanguage(); $session->set('_locale', $lang); $request->setLocale($lang); } }
и в services.yml
services: acme.change_language: class: Acme\UserBundle\EventListener\ChangeLanguageListener tags: - { name: kernel.event_subscriber }
для нескольких сеансов в нескольких браузерах нет проблем, так как каждый новый сеанс требует нового входа. Хм, хорошо, не после изменения языка, так как обновляется только текущий сеанс. Но вы можете изменить LanguageListener для поддержки этого.
И случай, если администратор меняет язык, должен быть незначителен.