使用FosUserBundle重定向登录后,Symfony会忽略用户的语言环境

时间:2019-01-08 19:05:19

标签: php symfony redirect login fosuserbundle

用户登录后,我希望他被重定向到使用语言环境作为参数/{_locale}/admin/schedule/list的给定URL。如果我使用FosUserBundles的登录路径作为返回URL(无语言环境),则该站点将正确翻译。

我在做什么错了?

security.yaml:

firewalls:
    main:
        pattern: ^/
        user_checker: security.user_checker
        form_login:
            provider: fos_userbundle
            csrf_token_generator: security.csrf.token_manager
            always_use_default_target_path: false
            default_target_path: scheduler_list

routes.yaml:

    scheduler_list: #If I use scheduler_list, it isn't working...
      path:
        en: /admin/{_locale}/list
        nl: /admin/{_locale}/lijst
      defaults: { _controller: App\Controller\ScheduleController:list }
      methods: [GET]

       some_page: #But 'some_page' is working because it doesn't contain 'user-locale'.
          path: /some-other-url-without-locale
          defaults: { _controller: App\Controller\SomeController:function }
          methods: [GET]

我还添加了两个EventSubscribers,LocaleSubscriber使用户会话期间的语言环境变得“粘稠”,以及UserLocaleSubscriber,以便在登录后从用户获取用户语言环境。

LocaleSubscriber.php:

class LocaleSubscriber implements EventSubscriberInterface
{
    /** @var string */
    private $defaultLocale;

    /**
     * LocaleSubscriber constructor.
     * @param string $defaultLocale
     */
    public function __construct($defaultLocale = 'en')
    {
        $this->defaultLocale = $defaultLocale;
    }

    /**
     * @param GetResponseEvent $event
     */
    public function onKernelRequest(GetResponseEvent $event): void
    {
        $request = $event->getRequest();
        if (!$request->hasPreviousSession()) {
            return;
        }

        if ($locale = $request->attributes->get('_locale')) {
            $request->getSession()->set('_locale', $locale);
        } else {
            $request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
        }
    }

    /**
     * @return array
     */
    public static function getSubscribedEvents(): array
    {
        return ['kernel.request' => [['onKernelRequest', 20]]];
    }
}

UserLocaleSubscriber.php:

class UserLocaleSubscriber implements EventSubscriberInterface
{
    /** @var SessionInterface */
    private $session;

    /**
     * UserLocaleSubscriber constructor.
     * @param SessionInterface $session
     */
    public function __construct(SessionInterface $session)
    {
        $this->session = $session;
    }

    /**
     * @param InteractiveLoginEvent $event
     */
    public function onInteractiveLogin(InteractiveLoginEvent $event): void
    {
        $user = $event->getAuthenticationToken()->getUser();
        if (null !== $user->getLocale()) {
            $this->session->set('_locale', $user->getLocale());
        }
    }

    /**
     * @return array
     */
    public static function getSubscribedEvents(): array
    {
        return ['security.interactive_login' => 'onInteractiveLogin'];
    }
}

替代: 作为替代方案,我尝试与success_handler合作,但没有成功:

security.yaml:

firewalls:
    main:
        pattern: ^/
        user_checker: security.user_checker
        form_login:
            provider: fos_userbundle
            csrf_token_generator: security.csrf.token_manager
            success_handler: App\EventSubscriber\RedirectLocaleHandler

App \ EventSubscriber \ RedirectLocaleHandler:onAuthenticationSuccess:

public function onAuthenticationSuccess(Request $request, TokenInterface $token)
{
    $user = $token->getUser();
    if ($user instanceof User) {
        return new RedirectResponse($this->router->generate('scheduler_list', ['_locale' => $user->getLocale()]));
    }
}

以某种方式$this->router->generate无法覆盖_locale,因此$user->getLocale()被忽略并使用默认语言环境。

提前感谢所有建议。为了简化此操作,请链接到the project source code on Github

0 个答案:

没有答案