Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Modifying User entity when registering using FOS User Bundle and Symfony2

As many people know, the FOS User Bundle doesn't provide roles automatically when a user registers. The most common solution is to either a) modify the User entity constructor to automatically assign a role, or b) override the entire registration controller.

Neither of these solutions seems perfect, and I want to make use of the Events that the FOS user bundle provides.

I have managed to capture the event I want (FOSUserEvents::REGISTRATION_INITIALIZE), but I am having trouble figuring out how to pass the modified User entity back to the registration form.

The code I have so far is as follows:

namespace HCLabs\UserBundle\EventListener;

use FOS\UserBundle\FOSUserEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use FOS\UserBundle\Event\UserEvent;
use FOS\UserBundle\Model\UserInterface;

class AutoRoleAssignmentListener implements EventSubscriberInterface
{
  public static function getSubscribedEvents()
  {
    return [ FOSUserEvents::REGISTRATION_INITIALIZE => 'onRegistrationInitialise' ];
  }

  public function onRegistrationInitialise( UserEvent $event )
  {
    $user = $event->getUser();
    $user->addRole( 'ROLE_USER' );

    // what do
  }
}

The YML for the event listener:

services:
    hc_labs_user.reg_init:
        class: HCLabs\UserBundle\EventListener\AutoRoleAssignmentListener
        tags:
            - { name: kernel.event_subscriber }

If more code is needed I'm happy to provide it. Thanks for your help.

like image 974
jrdn Avatar asked Aug 13 '13 15:08

jrdn


1 Answers

Answer is very simple - you have to do nothing to get updated User object in registration form after updated User in event listener for FOSUserEvents::REGISTRATION_INITIALIZE event.

Let me explain. FOSUserEvents::REGISTRATION_INITIALIZE is dispatched in RegistrationController by:

$dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, new UserEvent($user, $request));

And, before this dispatch in code (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Controller/RegistrationController.php#L43) new User is created:

    $user = $userManager->createUser();
    $user->setEnabled(true);

    $dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, new UserEvent($user, $request));

During dispatching, by default PHP call_user_func (http://php.net/manual/en/function.call-user-func.php ) is called with pasted event name (function in defined object) and Event object. After that, event listener has possibility to modify pasted Event object - particularly event property.

In your case, your event listener modify User property via:

$user = $event->getUser();
$user->addRole( 'ROLE_USER' );

So in fact, you have to do nothing to pass the modified User entity back to the registration form.

like image 92
NHG Avatar answered Nov 01 '22 15:11

NHG