FOSUserBundle : Redirect the user after register with EventListener

后端 未结 5 1227
有刺的猬
有刺的猬 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: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.)

提交回复
热议问题