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 quand un utilisateur s'inscrit sur mon site. 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 avec cet énorme paquet et il n'est pas très facile à comprendre. J'ai lu toute la documentation et je ne sais pas quoi faire.
pour l'instant, je crée un événement pour ajouter ce rôle dynamiquement, mais il ne fonctionne pas (je n'ai pas d'erreur mais ma base de données est toujours vide) Je ne suis même pas sur ce est la bonne façon de le faire ?
Mon Événement:
use FOSUserBundleFOSUserEvents;
use FOSUserBundleEventFormEvent;
use SymfonyComponentDependencyInjectionContainer;
use SymfonyComponentEventDispatcherEventSubscriberInterface;
use SymfonyComponentDependencyInjectionContainerInterface;
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 les événements et les services. Donc si quelqu'un a un conseil, je vais le prendre :)
Merci
6 réponses
Ce que j'ai fait est de remplacer l'entité constructeur:
voici un morceau de mon entité/utilisateur.php
public function __construct()
{
parent::__construct();
// your own logic
$this->roles = array('ROLE_USER');
}
C'est le chemin paresseux. Si vous voulez la bonne et meilleure façon voir la @ RayOnAir réponse
la méthode recommandée pour le faire comme indiqué par un contributeur principal au FOSUserBundle (dans le commentaire ici lié) est d'enregistrer un écouteur D'événement sur L'événement REGISTRATION_SUCCESS et d'utiliser le $event->getForm()->getData()
pour accéder à l'utilisateur et de le modifier.
En suivant ces lignes directrices, j'ai créé l'auditeur 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);
}
}
de plus, 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 User __construct() peut avoir quelques problèmes, comme indiqué dans le cette autre réponse.
je pense que @RayOnAir solution est la bonne façon de le faire. Mais cela ne marchera pas à cause de FOS rôle par défaut de manipulation
pour rendre possible de persister rôle par défaut dans la base de données, un besoin de redéfinir l'Utilisateur::setRoles (), méthode (l'ajouter à votre Utilisateur de l'entité):
/**
* 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:
vous pouvez ajouter un abonné D'événement à 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);
}
}
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();
}
j'ai changer mon port d'écoute et de savoir utiliser REGISTRATION_COMPLETED. Si quelqu'un a une meilleure idée pour le faire, n'hésitez pas :)
public function __construct()
{
parent::__construct();
$this->setRoles(["ROLE_WHATEVER"]);
}