I'm trying to implement registeration with FOSUserBundle. I want an admin to be able register a new user and this I've done simply by changing registration to a firewalled route (/admin/register prefix).
I created a custom registration form type and registered it as a service as instructed here: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_forms.md
I then hooked into the registration events based on this: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/controller_events.md
My listener looks like this:
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class RegistrationListener implements EventSubscriberInterface
{
private $router;
public function __construct(UrlGeneratorInterface $router)
{
$this->router = $router;
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_COMPLETED => 'onRegisterDone',
FOSUserEvents::REGISTRATION_CONFIRMED => 'onRegisterDone',
FOSUserEvents::RESETTING_RESET_COMPLETED => 'onRegisterDone',
);
}
public function onRegisterDone(FilterUserResponseEvent $event)
{
$url = $this->router->generate('admin_panel');
//$event->setResponse(new RedirectResponse($url));
}
}
The FilterUserResponseEvent does not have the setResponse method, so I'm just letting it run through. I thought that subscribing to this event would override the default FOS\UserBundle\EventListener\AuthenticationListener subscribed events and stop the user from being logged in, but the new user still gets logged in.
Is it possible to prevent the authentication, or should I just simply create a new form which would call an action to call User Manager?
Had the same problem and this worked for me.
Comment out this line in overriden Registration Controller:
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
public function registerAction(Request $request)
{
/** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->container->get('fos_user.registration.form.factory');
/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->container->get('fos_user.user_manager');
/** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->container->get('event_dispatcher');
$user = $userManager->createUser();
$user->setEnabled(true);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, new UserEvent($user, $request));
$form = $formFactory->createForm();
$form->setData($user);
if ('POST' === $request->getMethod()) {
$form->bind($request);
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->container->get('router')->generate('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
//comment below line to prevent login user after registration
//$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
}
return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.'.$this->getEngine(), array(
'form' => $form->createView(),
));
}
You can also override Registration Controller to do so. (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_controllers.md)
You just need to delete one line $this->authenticateUser($user);
and user will not be authenticated after registration.
Overriding controller for only delete this line is not a good approach. But if you cannot override right listener and hook the right moment it can be the easiest way to do your task as quickly as possible;-)
This is what I did to redirect to the admin panel. I used the REGISTRATION_SUCCESS event (which uses FormEvent instead of FilterUserResponseEvent).
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class RegistrationListener implements EventSubscriberInterface
{
private $router;
public function __construct(UrlGeneratorInterface $router)
{
$this->router = $router;
}
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
);
}
public function onRegistrationSuccess(FormEvent $event)
{
$url = $this->router->generate('admin_users');
$event->setResponse(new RedirectResponse($url));
}
}
In order to prevent the authentication I had to override the AuthenticationListener as described in https://stackoverflow.com/a/23969485/5074443. Here is my AuthenticationListener:
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\EventListener\AuthenticationListener as FOSAuthenticationListener;
class AuthenticationListener extends FOSAuthenticationListener
{
public static function getSubscribedEvents()
{
return array(
// do not authenticate after registration
// FOSUserEvents::REGISTRATION_COMPLETED => 'authenticate',
// FOSUserEvents::REGISTRATION_CONFIRMED => 'authenticate'
FOSUserEvents::RESETTING_RESET_COMPLETED => 'authenticate',
);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With