6

很多人都知道,FOS 用户包不会在用户注册时自动提供角色。最常见的解决方案是 a) 修改 User 实体构造函数以自动分配角色,或 b) 覆盖整个注册控制器。

这些解决方案似乎都不完美,我想利用 FOS 用户包提供的事件。

我已经设法捕获了我想要的事件 ( FOSUserEvents::REGISTRATION_INITIALIZE),但是我无法弄清楚如何将修改后的用户实体传递回注册表单。

我到目前为止的代码如下:

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
  }
}

事件监听器的 YML:

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

如果需要更多代码,我很乐意提供。谢谢你的帮助。

4

1 回答 1

8

答案很简单——在事件侦听器中更新事件后,您无需在注册表中获取更新User的对象。UserFOSUserEvents::REGISTRATION_INITIALIZE

让我解释。FOSUserEvents::REGISTRATION_INITIALIZE由以下人员派遣RegistrationController

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

并且,在代码中的此调度(https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Controller/RegistrationController.php#L43)之前User创建新的:

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

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

在调度期间,默认情况下 PHP call_user_func( http://php.net/manual/en/function.call-user-func.php ) 使用粘贴的事件名称(定义对象中的函数)和Event对象调用。之后,事件监听器可以修改粘贴的Event对象——尤其是事件属性。

在您的情况下,您的事件侦听器User通过以下方式修改属性:

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

因此,实际上,您无需执行任何操作即可将修改后的 User 实体传回注册表单。

于 2013-08-13T18:55:23.783 回答