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
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
"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:
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.
/**
* @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));
}
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:
/**
* @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.)
Route redirection can also be used:
fos_user_registration_confirmed:
path: /register/confirmed
defaults:
_controller: FrameworkBundle:Redirect:redirect
route: redirection_route
permanent: true
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 }
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()
{