Symfony 3:FOSSUserBundle 得到一个 JsonResponse 而不是重定向

Symfony 3: FOSSUserBundle get a JsonResponse Instead of redirecting

在我的 Symnfony3 项目中,我注意到在注册过程中会生成一些事件,我可以在其中覆盖响应。例如。而不是呈现默认的树枝模板并重定向到 return 带有 successMessage 的 JsonResponse。

因此我做了以下事件订阅者:

namespace AppBundle\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use AppBundle\Constants\AjaxJsonResponseConstants;
use Symfony\Component\HttpFoundation\JsonResponse;
use FOS\UserBundle\Event\FilterUserResponseEvent;

class UserRegistrationResponseChanger implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        $subscribedEvents=[
//              FOSUserEvents::REGISTRATION_INITIALIZE=>[],
                FOSUserEvents::REGISTRATION_COMPLETED=>[],
                FOSUserEvents::REGISTRATION_SUCCESS=>["setJsonResponseOnSuccess",-1],
                FOSUserEvents::REGISTRATION_FAILURE=>["setJsonResponseOnFailure",-1],
//              FOSUserEvents::REGISTRATION_CONFIRM=>[],
//              FOSUserEvents::REGISTRATION_CONFIRMED=>[]
        ];
    }

    public function setJsonResponseOnSuccess(FormEvent $formEvent)
    {
        $response=['status'=>AjaxJsonResponseConstants::AJAX_ACTION_SUCCESS,'message'=>"User Sucessfully Registered please check your mail."];
        $response=new JsonResponse($response);
        $formEvent->setResponse($response);

        return $response;
    }

    public function setJsonResponseOnFailure(FormEvent $formEvent)
    {
        $response=['status'=>AjaxJsonResponseConstants::AJAX_ACTION_FAIL,'message'=>"You cannot register please try again later"];
        $response=new JsonResponse($response);
        $formEvent->setResponse($response);

        return $response;
    }
}

也在我的 services.yml 上添加了以下内容:

 app.user_register.subscriber:
  class: AppBundle\EventSubscriber\UserRegistrationResponseChanger
  tags:
   - { name: app.user_register.subscriber }

和命令

为了覆盖响应将如何获得 returned 但不知何故它无法这样做并重定向到默认页面。我试图通过 ajax 调用而不是呈现注册页面和重定向来执行注册。

您应该执行以下步骤:

首先,当您定义事件订阅者时,您应该使用 kernel.event_subscriber 而不是 app.user_register.subscriber,因此您的订阅者将被定义为:

 app.user_register.subscriber:
  class: AppBundle\EventSubscriber\UserRegistrationResponseChanger
  tags:
   - { name: kernel.event_subscriber }

services.yml.

此外 getSubscribedEvents 必须 return 监听器数组。另外 FOSUserEvents::REGISTRATION_COMPLETED 必须 有一个监听器,即使它没有实现,如果你不想要一个监听器,只需评论之类的。

最后你的监听器应该这样实现:

namespace AppBundle\EventSubscriber;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use AppBundle\Constants\AjaxJsonResponseConstants;
use Symfony\Component\HttpFoundation\JsonResponse;
use FOS\UserBundle\Event\FilterUserResponseEvent;

class UserRegistrationResponseChanger implements EventSubscriberInterface
{
    public static function getSubscribedEvents()
    {
        $subscribedEvents=[
//              FOSUserEvents::REGISTRATION_INITIALIZE=>[],
//              FOSUserEvents::REGISTRATION_COMPLETED=>[],
                FOSUserEvents::REGISTRATION_SUCCESS=>["setJsonResponseOnSuccess",-1],
                FOSUserEvents::REGISTRATION_FAILURE=>["setJsonResponseOnFailure",-1],
//              FOSUserEvents::REGISTRATION_CONFIRM=>[],
//              FOSUserEvents::REGISTRATION_CONFIRMED=>[]
        ];

        return $subscribedEvents;
    }

    public function setJsonResponseOnSuccess(FormEvent $formEvent)
    {
        $response=['status'=>AjaxJsonResponseConstants::AJAX_ACTION_SUCCESS,'message'=>"User Sucessfully Registered please check your mail."];
        $response=new JsonResponse($response);
        $formEvent->setResponse($response);

        return $response;
    }

    public function setJsonResponseOnFailure(FormEvent $formEvent)
    {
        $response=['status'=>AjaxJsonResponseConstants::AJAX_ACTION_FAIL,'message'=>"You cannot register please try again later"];
        $response=new JsonResponse($response);
        $formEvent->setResponse($response);

        return $response;
    }
}

您应该在注册确认后优先处理 REGISTRATION_SUCCESS 事件(FOSUserBundle 中的默认行为),请参阅 http://symfony.com/doc/master/bundles/FOSUserBundle/controller_events.html#registration-success-listener-with-enabled-confirmation-at-the-same-time

服务定义需要这样:

#app/config/services.yml
app.security_registration_success:
    class: Path\To\Your\EventListener\RegistrationSuccessListener
    tags:
        - { name: kernel.event_subscriber }

注册成功监听示例:

<?php

declare(strict_types=1);

namespace Path\To\Your\EventListener;

use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\FOSUserEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\JsonResponse;

class RegistrationSuccessListener implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [FOSUserEvents::REGISTRATION_SUCCESS => [['onRegistrationSuccess', -10]]];
    }

    public function onRegistrationSuccess(FormEvent $event): void
    {
        $event->setResponse(new JsonResponse());
    }
}