Dodawanie domyślnej roli podczas rejestracji użytkownika w FOSUserBundle

Wersja: Symfony 2.2

Próbuję dodać domyślną rolę, gdy użytkownik rejestruje się na mojej stronie. Używam FOSUserBundle i widzę, że gdy użytkownik rejestruje pole roli jest puste w bazie danych. Zaczynam od tego ogromnego pakietu i nie jest to łatwe do zrozumienia. Więc przeczytałem całą dokumentację i nie wiem, co robić.

Na razie tworzę Zdarzenie, aby dodać tę rolę dynamicznie, ale to nie działa( nie mam błędu, ale moja baza danych jest nadal pusta) nie jestem nawet sur to jest dobry sposób na to ?

Moje Wydarzenie:

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

Jak widzisz tworzę proste zdarzenie, które nasłuchuje na REGISTRATION_SUCCESS, ale nic nie działa. To moja pierwsza próba z imprezami i usługami. Więc jeśli ktoś ma radę, to ją przyjmę:)

Thanks

Author: Epok, 2013-04-14

6 answers

To co zrobiłem to nadpisanie konstruktora encji:

Tutaj kawałek mojego bytu / użytkownika.php

public function __construct()
{
    parent::__construct();
    // your own logic
    $this->roles = array('ROLE_USER');
}
To jest leniwy sposób. Jeśli chcesz mieć dobry i lepszy sposób zobacz @RayOnAir ODPOWIEDŹ
 37
Author: alvaropgl,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:59

Zalecanym sposobem na to, jak wskazuje główny współpracownik FOSUserBundle ( w komentarzu tutaj połączonym) jest zarejestrowanie słuchacza zdarzeń w zdarzeniu REGISTRATION_SUCCESS i użycie $event->getForm()->getData(), aby uzyskać dostęp do użytkownika i zmodyfikować go. Zgodnie z tymi wytycznymi stworzyłem następujący słuchacz (który działa!):

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

Ponadto usługa musi być zarejestrowana w następujący sposób:

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

Zauważ, że dodanie domyślnej roli w klasie użytkownika _ _ construct () może mieć pewne kwestie wskazane w tej drugiej odpowiedzi .

 38
Author: RayOnAir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 11:53:57

Myślę, że rozwiązanie @ RayOnAir jest dobrym sposobem na to. Ale to nie będzie działać z powodu Fos domyślnej obsługi roli

Aby możliwe było zachowanie domyślnej roli w bazie danych, należy nadpisać metodę User:: setRoles () (dodać ją do encji użytkownika):

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

Tested under:

Symfony version 2.3.6 , FOSUserBundle 2.0.x-dev

 4
Author: andrew,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-10-31 10:16:10

Możesz dodać Subskrybenta zdarzenia do klasy formularza i użyć zdarzenia formularza "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';
    }
}

Teraz logika dodawania pola roli znajduje się w jego własnej klasie Abonenta

<?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
Author: Mohamed Ben HEnda,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-04-20 14:29:05

Ok teraz działa z tym:

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

Zmieniam słuchacza i Wiem, że używam REGISTRATION_COMPLETED . Jeśli ktoś ma lepszy pomysł, nie wahaj się:)

 1
Author: Epok,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-04-13 23:25:48
public function __construct()
{
    parent::__construct();
    $this->setRoles(["ROLE_WHATEVER"]);
}
 0
Author: jelle woord,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-10-26 14:22:43