web-dev-qa-db-fra.com

Ajouter un rôle par défaut lors de l'enregistrement de l'utilisateur avec FOSUserBundle

Version: Symfony 2.2

J'essaie d'ajouter un rôle par défaut lorsqu'un utilisateur s'enregistre sur mon site Web. J'utilise FOSUserBundle et je vois que lorsqu'un utilisateur enregistre le champ de rôle est vide dans une base de données ..__ Je commence par cet énorme paquet et ce n'est pas très facile à comprendre. J'ai donc lu toute la documentation et je ne sais pas quoi faire.

Pour le moment, je crée un événement pour ajouter ce rôle de manière dynamique, mais cela ne fonctionne pas (je n'ai aucune erreur, mais ma base de données est toujours vide).

Mon événement:

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

Comme vous le voyez, je crée un événement simple qui écoute sur REGISTRATION_SUCCESS, mais rien ne semble fonctionner. C'est mon premier essai avec des événements et des services. Donc si quelqu'un a un conseil, je le prendrai :)

Merci

26
Epok

Ce que j'ai fait est de remplacer le constructeur d'entité:

Voici un morceau de mon Entity/User.php

public function __construct()
{
    parent::__construct();
    // your own logic
    $this->roles = array('ROLE_USER');
}

C'est la manière paresseuse. Si vous voulez le bon et le meilleur moyen, voyez le @RayOnAir answer

37
alvaropgl

La méthode recommandée pour le faire, indiquée par un contributeur principal de FOSUserBundle ( dans le commentaire lié ici ), consiste à enregistrer un écouteur d'événement sur l'événement REGISTRATION_SUCCESS et à utiliser la fonction $event->getForm()->getData() pour accéder à l'utilisateur et le modifier ..__ En suivant ces instructions, j'ai créé le programme d'écoute suivant (qui fonctionne!):

<?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);
    }
}

En outre, le service doit être enregistré comme suit:

// src/Acme/DemoBundle/Resources/config/services.yml
services:
    demo_user.registration_listener:
        class: Acme\DemoBundle\EventListener\RegistrationListener
        arguments: []
        tags:
            - { name: kernel.event_subscriber }

Notez que l'ajout d'un rôle par défaut dans la classe d'utilisateurs __construct () peut poser certains problèmes, comme indiqué dans cette autre réponse .

39
RayOnAir

Je pense que la solution @RayOnAir est un bon moyen de le faire. Mais cela ne fonctionnera pas à cause de gestion du rôle par défaut de FOS

pour rendre possible le maintien du rôle par défaut dans la base de données, il est nécessaire de remplacer la méthode User :: setRoles () (ajoutez-la à votre entité User):

/**
 * 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;
}

Testé sous:

Version Symfony 2.3.6 , FOSUserBundle 2.0.x-dev

4
andrew

Vous pouvez ajouter un abonné aux événements à une classe de formulaire et utiliser l'événement de formulaire "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';
    }
}

Maintenant, la logique pour ajouter le champ de rôle réside dans sa propre classe d'abonné

<?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);
    }
}
2
Mohamed Ben HEnda

Ok maintenant ça marche avec ça:

 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();
}

Je change mon auditeur et je sais utiliser REGISTRATION_COMPLETED. Si quelqu'un a une meilleure idée de le faire, n'hésitez pas :)

1
Epok
public function __construct()
{
    parent::__construct();
    $this->setRoles(["ROLE_WHATEVER"]);
}
0
jelle woord