Добавить роль по умолчанию во время регистрации пользователя с помощью FOSUserBundle
Версия: Symfony 2.2
Я пытаюсь добавить роль по умолчанию, когда пользователь регистрируется на моем сайте. Я использую FOSUserBundle и вижу, что при регистрации пользователя поле роли в базе данных становится пустым.
Я начинаю с этой огромной связки, и это не очень легко понять. Поэтому я прочитал всю документацию и не знаю, что делать.
Сейчас я создаю событие, чтобы динамически добавлять эту роль, но оно не работает (у меня нет ошибки, но моя база данных все еще пуста). Я даже не уверен, что это хороший способ сделать это?
Мое событие:
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\DependencyInjection\Container;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class AddDefaultRoleListener implements EventSubscriberInterface {
private $container;
public function __construct(Container $container)
{
$this->container = $container;
}
/**
* {@inheritDoc}
*/
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'onAddDefaultRoleSuccess',
);
}
public function onAddDefaultRoleSuccess(FormEvent $event)
{
$doctrine = $this->container->get('doctrine');
$em = $doctrine->getManager();
$user = $event->getForm()->getData();
$user->addRole('ROLE_USER');
//$user->setRoles(array('ROLE_USER'));
$em->persist($user);
}
}
Как видите, я создаю простое событие, которое прослушивает REGISTRATION_SUCCESS, но, похоже, ничего не работает. Это моя первая попытка с событиями и услугами. Так что если у кого-то есть совет, я его приму :)
Ответы
Ответ 1
То, что я сделал, переопределяет конструктор сущности:
Здесь часть моего Entity/User.php
public function __construct()
{
parent::__construct();
// your own logic
$this->roles = array('ROLE_USER');
}
Это ленивый путь. Если вам нужен правильный и лучший способ увидеть ответ @RayOnAir
Ответ 2
Рекомендуемый способ сделать это, как указано основным вкладчиком FOSUserBundle (в приведенном здесь комментарии) - зарегистрировать событие Слушатель события REGISTRATION_SUCCESS и используйте $event->getForm()->getData()
для доступа к пользователю и его изменения.
Следуя этим рекомендациям, я создал следующий слушатель (который работает!):
<?php
// src/Acme/DemoBundle/EventListener/RegistrationListener.php
namespace Acme\DemoBundle\EventListener;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Event\FormEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Listener responsible for adding the default user role at registration
*/
class RegistrationListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(
FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
);
}
public function onRegistrationSuccess(FormEvent $event)
{
$rolesArr = array('ROLE_USER');
/** @var $user \FOS\UserBundle\Model\UserInterface */
$user = $event->getForm()->getData();
$user->setRoles($rolesArr);
}
}
Кроме того, услугу необходимо зарегистрировать следующим образом:
// src/Acme/DemoBundle/Resources/config/services.yml
services:
demo_user.registration_listener:
class: Acme\DemoBundle\EventListener\RegistrationListener
arguments: []
tags:
- { name: kernel.event_subscriber }
Обратите внимание, что добавление роли по умолчанию в классе User __construct() может иметь некоторые проблемы, указанные в этом другом ответе.
Ответ 3
Я думаю, что решение @RayOnAir - это правильный способ сделать это. Но это не сработает из-за Обработка роли по умолчанию FOS
чтобы можно было сохранить роль по умолчанию в базе данных, необходимо переопределить метод User:: setRoles() (добавить его в свой объект пользователя):
/**
* Overriding Fos User class due to impossible to set default role ROLE_USER
* @see User at line 138
* @link https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Model/User.php#L138
* {@inheritdoc}
*/
public function addRole($role)
{
$role = strtoupper($role);
if (!in_array($role, $this->roles, true)) {
$this->roles[] = $role;
}
return $this;
}
Протестировано под:
Версия Symfony 2.3.6,
FOSUserBundle 2.0.x-dev
Ответ 4
Вы можете добавить подписчика на событие в класс формы и использовать событие формы "formEvents :: POST_SUBMIT"
<?php
//src/yourNS/UserBundle/Form/Type/RegistrationFormType.php
use Symfony\Component\Form\FormBuilderInterface;
use FOS\UserBundle\Form\Type\RegistrationFormType as BaseType;
use yourNS\UserBundle\Form\EventListener\AddRoleFieldSubscriber;
class RegistrationFormType extends BaseType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
parent::buildForm($builder, $options);
// add your custom field
$builder->add('firstName')
->add('lastName')
->add('address')
//...
//...
->add('phone');
$builder->addEventSubscriber(new AddRoleFieldSubscriber());
}
public function getName()
{
return 'yourNS_user_registration';
}
}
Теперь логика добавления поля роли находится в его собственном классе подписчика
<?php
//src/yourNS/UserBundle/Form/EventListener/AddRoleFieldSubscriber.php
namespace yourNS\UserBundle\Form\EventListener;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class AddRoleFieldSubscriber implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return array(FormEvents::POST_SUBMIT => 'setRole');
}
public function setRole(FormEvent $event)
{
$aRoles = array('ROLE_USER');
/** @var $user \FOS\UserBundle\Model\UserInterface */
$user = $event->getForm()->getData();
$user->setRoles($aRoles);
}
}
Ответ 5
Теперь он работает с этим:
public function onAddDefaultRoleSuccess(FilterUserResponseEvent $event)
{
$doctrine = $this->container->get('doctrine');
$em = $doctrine->getManager();
$user = $event->getUser();
$user->addRole('ROLE_BLOGGER');
$em->persist($user);
$em->flush();
}
Я меняю своего слушателя и знаю, что использую REGISTRATION_COMPLETED. Если кто-то лучше это сделает, не стесняйтесь:)
Ответ 6
public function __construct()
{
parent::__construct();
$this->setRoles(["ROLE_WHATEVER"]);
}