FOSUserBundle 上的一个模板中的 Symfony3 登录和注册表单

Symfony3 login and register form in one template on FOSUserBundle

我需要将登录表单和注册表放在同一个页面中。我正在使用 Symfony 3.2 和 FOS 用户包。

我找到了这个:How to merge login and register form in one template on FOSUserBundle

这是我的第一个方法,但是有一个问题。在验证错误时,页面被重定向到另一个路由(只显示提交表单的模板)。问题是 SecurityController 和 RegistrationController 不知道在 Twig 中呈现两个 FOS 控制器的控制器,它们只显示表单模板。使用这种方法,我无法覆盖 fos 控制器显示的模板以显示主模板,因为这会产生无限递归。

我尝试覆盖 fos 控制器以对表单的验证错误进行重定向,但重定向导致验证消息丢失。

我也尝试将请求转发给 fos SecurityController 和 RegistrationController(像这样:http://symfony.com/doc/current/controller/forwarding.html)但是对于登录的检查操作,我得到:

RuntimeException 'You must configure the check path to be handled by the firewall using form_login in your security firewall configuration.'.

它已经配置好并且可以正常工作,但是将请求直接转发到控制器似乎会破坏它(我无法弄清楚登录检查实际上是如何进行的,因为检查方法仅 returns运行时异常)

我能想到的最后一个解决方案是在新控制器中创建两个表单,但我不知道如何手动调用 fos 用户登录检查(对于注册我可以从 RegistrationController 复制所有 registerAction ).

感谢您的宝贵时间。

好的,我终于可以让它工作了。我制作了一个新控制器,它使用 fos 控制器的输出呈现登录表单和注册表单。登录表单动作路由为login_check,注册表单动作路由与控制器的路由相同(frontend_login的值)

控制器:

/**
 * @Route("/ingresar", name="frontend_login")
 * @Method({"GET", "POST"}) 
 */
public function loginAndRegisterAction(Request $request){

    $login_response = $this->forward('FOSUserBundle:Security:login', array( $request ));
    $register_response = $this->forward('FOSUserBundle:Registration:register', array( $request ));

    return $this->render('frontend/usuario/login_register.html.twig', array(
        'login' => $login_response->getContent(),
        'register' => $register_response->getContent(),
        ));
}

在显示内容的模板中,以原始方式显示(控制器 return 表单已经在其内容中呈现为 html)

{{ login|raw }}
{{ register|raw }}

我必须重写 FosUserBundle 模板以免扩展 fosuserbundle 布局。 Resources/FOSUserBundle/layout.html.twig:

{% block fos_user_content %}{% endblock fos_user_content %}

配置security.yml表示登录路径是我们定义的控制器之一。如果出错,它将显示 frontend_login 路线。

frontend:
        pattern: ^/
        context: website
        form_login:
            provider: fos_userbundle
            login_path: frontend_login
            check_path: login_check

最后,覆盖显示表单的模板,使注册表单的动作路径为frontend_login。我这样做是因为我需要更改 html 结构,我认为将 fos_user_registration_register 路由更改为我们定义的路由应该可以解决问题。

{{ form_start(form, {'method': 'post', 'action': path('frontend_login'), 'attr': {'class': 'fos_user_registration_register', 'novalidate': 'novalidate'}}) }}
    {{ form_widget(form) }}
    <div>
        <input type="submit" value="Submit" />
    </div>
{{ form_end(form) }}