symfony2 - Agregue una función predeterminada durante el registro del usuario con FOSUserBundle
symfony hash (6)
Creo que la solución @RayOnAir es la forma correcta de hacerlo. Pero no funcionará debido al manejo de roles predeterminado de FOS
para posibilitar la persistencia del rol predeterminado en la base de datos, es necesario anular el método User :: setRoles () (agréguelo a su entidad 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;
}
Probado bajo:
Versión: Symfony 2.2
Intento agregar una función predeterminada cuando un usuario se registra en mi sitio web. Utilizo FOSUserBundle y veo que cuando un usuario se registra, el campo de función está vacío en una base de datos. Comienzo con este gran paquete y no es muy fácil de entender. Entonces leo toda la documentación y no sé qué hacer.
Por ahora, creo un evento para agregar este rol dinámicamente, pero no funciona (no tengo ningún error pero mi base de datos aún está vacía) ¿Ni siquiera estoy seguro de que esta es la mejor manera de hacerlo?
Mi evento:
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);
}
}
Como ves, creo un evento simple que escuchas en REGISTRATION_SUCCESS, pero parece que nada funciona. Es mi primer intento con Eventos y servicios. Entonces, si alguien tiene un consejo, lo tomaré :)
Gracias
La forma recomendada de hacerlo como lo indica un colaborador principal de FOSUserBundle ( en el comentario aquí vinculado ) es registrar un Escuchador de eventos en el evento REGISTRATION_SUCCESS y usar $event->getForm()->getData()
para acceder al usuario y modificarlo. Siguiendo esas pautas, creé el siguiente oyente (¡que funciona!):
<?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);
}
}
Además, el servicio debe registrarse de la siguiente manera:
// src/Acme/DemoBundle/Resources/config/services.yml
services:
demo_user.registration_listener:
class: Acme/DemoBundle/EventListener/RegistrationListener
arguments: []
tags:
- { name: kernel.event_subscriber }
Tenga en cuenta que agregar una función predeterminada en la clase de usuario __construct () puede tener algunos problemas, como se indica en esta otra respuesta .
Lo que hice fue anular el constructor de la entidad:
Aquí una parte de mi Entity / User.php
public function __construct()
{
parent::__construct();
// your own logic
$this->roles = array(''ROLE_USER'');
}
Esta es la manera perezosa. Si quieres la forma correcta y mejor, mira la answer @RayOnAir
Ok, ahora está trabajando con eso:
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();
}
Cambio mi oyente y sé utilizar REGISTRATION_COMPLETED . Si alguien tiene una mejor idea para hacer eso, no lo dudes :)
Puede agregar un Suscriptor de evento a una Clase de formulario y usar el evento de formulario "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'';
}
}
Ahora la lógica para agregar el campo de función reside en su propia clase de suscriptor
<?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);
}
}
public function __construct()
{
parent::__construct();
$this->setRoles(["ROLE_WHATEVER"]);
}