Подтвердить что ты не робот

Добавить роль по умолчанию во время регистрации пользователя с помощью 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, но, похоже, ничего не работает. Это моя первая попытка с событиями и услугами. Так что если у кого-то есть совет, я его приму :)

4b9b3361

Ответ 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"]);
}