FOSUserBundle : Redirect the user after register with EventListener

后端 未结 5 1225
有刺的猬
有刺的猬 2020-12-03 08:07

I want to redirect the user to another form just after registration, before he could access to anything on my website (like in https://github.com/FriendsOfSymfony/FOSUserBun

相关标签:
5条回答
  • 2020-12-03 08:48

    To accomplish what you want, you should use FOSUserEvents::REGISTRATION_CONFIRM instead of FOSUserEvents::REGISTRATION_CONFIRMED.

    You then have to rewrite rewrite your class RegistrationConfirmedListener like:

    class RegistrationConfirmListener implements EventSubscriberInterface
    {
        private $router;
    
        public function __construct(UrlGeneratorInterface $router)
        {
            $this->router = $router;
        }
    
        /**
         * {@inheritDoc}
         */
        public static function getSubscribedEvents()
        {
            return array(
                    FOSUserEvents::REGISTRATION_CONFIRM => 'onRegistrationConfirm'
            );
        }
    
        public function onRegistrationConfirm(GetResponseUserEvent $event)
        {
            $url = $this->router->generate('rsWelcomeBundle_check_full_register');
    
            $event->setResponse(new RedirectResponse($url));
        }
    }
    

    And your service.yml:

    services:
        rs_user.registration_complet:
            class: rs\UserBundle\EventListener\RegistrationConfirmListener
            arguments: [@router]
            tags:
                - { name: kernel.event_subscriber }
    

    REGISTRATION_CONFIRM receives a FOS\UserBundle\Event\GetResponseUserEvent instance as you can see here: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/FOSUserEvents.php

    It allows you to modify the response that will be sent: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Event/GetResponseUserEvent.php

    0 讨论(0)
  • 2020-12-03 08:58
    "friendsofsymfony/user-bundle": "2.0.x-dev",
    

    Not sure why the accepted answer works for you as REGISTRATION_CONFIRM happens after the token is confirmed.

    In case you want to perform an action, redirect to another page with some additional form after the FOS registerAction I would suggest the following way.

    This is the code that is performed on registerAction once the submitted form is valid by FOS:

    FOS\UserBundle\Controller\RegistrationController

            if ($form->isValid()) {
                $event = new FormEvent($form, $request);
                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
    
                $userManager->updateUser($user);
    
                if (null === $response = $event->getResponse()) {
                    $url = $this->generateUrl('fos_user_registration_confirmed');
                    $response = new RedirectResponse($url);
                }
    
                $dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
    
                return $response;
            }
    

    As you can see the first possible return happens after FOSUserEvents::REGISTRATION_SUCCESS event in case the response is null which in my case doesn't as I have configured a mailer to send a confirmation token and FOS is using an listener that listens to this FOSUserEvents::REGISTRATION_SUCCESS event and after sending an email it sets a redirect response.

    FOS\UserBundle\EventListener\EmailConfirmationListener

    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return array(
            FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
        );
    }
    
    /**
     * @param FormEvent $event
     */
    public function onRegistrationSuccess(FormEvent $event)
    {
        /** @var $user \FOS\UserBundle\Model\UserInterface */
        $user = $event->getForm()->getData();
    
        $user->setEnabled(false);
        if (null === $user->getConfirmationToken()) {
            $user->setConfirmationToken($this->tokenGenerator->generateToken());
        }
    
        $this->mailer->sendConfirmationEmailMessage($user);
    
        $this->session->set('fos_user_send_confirmation_email/email', $user->getEmail());
    
        $url = $this->router->generate('fos_user_registration_check_email');
        $event->setResponse(new RedirectResponse($url));
    }
    

    Okay I understand! So how do I redirect to another page?

    I would suggest to overwrite checkEmailAction as most likely you don't want to overwrite the listener that sends an email as that's part of your workflow.

    Simply:

    TB\UserBundle\Controller\RegistrationController

    /**
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function checkEmailAction()
    {
        /** @var UserManager $userManager */
        $userManager = $this->get('fos_user.user_manager');
        /** @var string $email */
        $email = $this->get('session')->get('fos_user_send_confirmation_email/email');
    
        $user = $userManager->findUserByEmail($email);
    
        return $this->redirect($this->generateUrl('wall', ['username' => $user->getUsername()]));
    }
    

    As you can see instead of rendering FOS's check_email template I decided to redirect user to his new profile.

    Docs how to overwrite an controller: https://symfony.com/doc/master/bundles/FOSUserBundle/overriding_controllers.html (basically define a parent for your bundle and create a file in the directory with the same name as FOS does.)

    0 讨论(0)
  • 2020-12-03 09:01

    Route redirection can also be used:

    fos_user_registration_confirmed:
        path: /register/confirmed
        defaults:
            _controller: FrameworkBundle:Redirect:redirect
            route: redirection_route
            permanent: true
    
    0 讨论(0)
  • 2020-12-03 09:08

    If you're not using a confirmation email, you can redirect the user right after submiting the registration form this way :

    class RegistrationConfirmationSubscriber implements EventSubscriberInterface
    {
        /** @var Router */
        private $router;
    
        public function __construct(Router $router)
        {
            $this->router = $router;
        }
    
        public static function getSubscribedEvents()
        {
            return [FOSUserEvents::REGISTRATION_COMPLETED => 'onRegistrationConfirm'];
        }
    
        public function onRegistrationConfirm(FilterUserResponseEvent $event)
        {
            /** @var RedirectResponse $response */
            $response = $event->getResponse();
            $response->setTargetUrl($this->router->generate('home_route'));
        }
    }
    

    The subscriber declaration stay the same :

    registration_confirmation_subscriber:
        class: AppBundle\Subscriber\RegistrationConfirmationSubscriber
        arguments:
            - "@router"
        tags:
            - { name: kernel.event_subscriber }
    
    0 讨论(0)
  • 2020-12-03 09:09

    For a quick solution: you can also override the route. Let's say you want to redirect to your homepage you can do something like this:

     /**
     * @Route("/", name="index")
     * @Route("/", name="fos_user_registration_confirmed")
     * @Template(":Default:index.html.twig")
     */
    public function indexAction()
    {
    
    0 讨论(0)
提交回复
热议问题