2013-06-11 6 views
5

Я пытаюсь реализовать регистрацию с помощью FOSUserBundle. Я хочу, чтобы администратор мог зарегистрировать нового пользователя, и это я сделал просто, изменив регистрацию на брандмауэр-маршрут (префикс/admin/register).Регистрация пользователя с помощью FOSUserBundle без регистрации пользователя в

Я создал пользовательский тип формы регистрации и зарегистрировал его в качестве службы, как указано здесь: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_forms.md

Затем я подключил в регистрационные мероприятия, основанные на этом: https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/controller_events.md

Мой слушатель выглядит следующим образом:

use FOS\UserBundle\FOSUserEvents; 
use FOS\UserBundle\Event\FilterUserResponseEvent; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 


class RegistrationListener implements EventSubscriberInterface 
{ 
    private $router; 

    public function __construct(UrlGeneratorInterface $router) 
    { 
     $this->router = $router; 
    } 

    /** 
    * {@inheritDoc} 
    */ 
    public static function getSubscribedEvents() 
    { 
     return array(
      FOSUserEvents::REGISTRATION_COMPLETED => 'onRegisterDone', 
      FOSUserEvents::REGISTRATION_CONFIRMED => 'onRegisterDone', 
      FOSUserEvents::RESETTING_RESET_COMPLETED => 'onRegisterDone', 
     ); 
    } 

    public function onRegisterDone(FilterUserResponseEvent $event) 
    { 
     $url = $this->router->generate('admin_panel'); 

     //$event->setResponse(new RedirectResponse($url)); 
    } 
} 

У фильтра FilterUserResponseEvent нет метода setResponse, поэтому я просто позволяю ему работать. Я думал, что подписка на это событие переопределит подписанные по умолчанию FOS \ UserBundle \ EventListener \ AuthenticationListener события и не позволит пользователю войти в систему, но новый пользователь все равно войдет в систему.

Возможно ли предотвратить аутентификацию, или просто я должен просто создать новую форму, которая вызовет действие для вызова User Manager?

+1

Простую форму (с повторным использованием существующего типа формы регистрации), который просто использует диспетчер пользователей. –

+0

Я пошел с этим пока. Возможно, в какой-то момент я столкнусь с тем, как отключить функциональность по умолчанию. – juuga

ответ

2

Вы также можете переопределить регистрационный контроллер. (https://github.com/FriendsOfSymfony/FOSUserBundle/blob/master/Resources/doc/overriding_controllers.md)

Вам просто нужно удалить одну строку $this->authenticateUser($user);, и пользователь не будет аутентифицирован после регистрации.

Переопределение контроллера только для удаления этой строки не является хорошим подходом. Но если вы не можете переопределить права слушателя и зацепить правильный момент, это может быть самым простым способом выполнить вашу задачу как можно быстрее ;-)

+0

Да, я думал, что это может быть решение, но я не думал, что это будет устойчивый вариант, когда я буду развертывать где-то еще и перезагрузить пакет вместе с композитором. – juuga

5

Если бы такая же проблема и это сработало для меня.

Закомментируйте эта линия в перекрываться регистрации контроллера:

$ dispatcher-> отправка (FOSUserEvents :: REGISTRATION_COMPLETED, новый FilterUserResponseEvent ($ пользователю, $ запрос, $ ответ));

public function registerAction(Request $request) 
{ 
    /** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */ 
    $formFactory = $this->container->get('fos_user.registration.form.factory'); 
    /** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */ 
    $userManager = $this->container->get('fos_user.user_manager'); 
    /** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */ 
    $dispatcher = $this->container->get('event_dispatcher'); 

    $user = $userManager->createUser(); 
    $user->setEnabled(true); 

    $dispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, new UserEvent($user, $request)); 

    $form = $formFactory->createForm(); 
    $form->setData($user); 

    if ('POST' === $request->getMethod()) { 
     $form->bind($request); 

     if ($form->isValid()) { 
      $event = new FormEvent($form, $request); 
      $dispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event); 

      $userManager->updateUser($user); 

      if (null === $response = $event->getResponse()) { 
       $url = $this->container->get('router')->generate('fos_user_registration_confirmed'); 
       $response = new RedirectResponse($url); 
      } 

      //comment below line to prevent login user after registration 
      //$dispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response)); 

      return $response; 
     } 
    } 

    return $this->container->get('templating')->renderResponse('FOSUserBundle:Registration:register.html.'.$this->getEngine(), array(
      'form' => $form->createView(), 
    )); 
} 
+0

Спасибо за обмен. Я уже пошла по-другому, но если я перейду к этой проблеме, я сделаю это так. Посмотрев на ответы здесь, я на самом деле заметил, что я неправильно понял ответ Майкла в первый раз. – juuga

+0

это решение работает для меня –

0

Вот более чистую версии без overrideing всего контроллера:

Да, я знаю, что инъекционное весь контейнер является плохой практикой, но это было быстрым решением. : b

class RegistrationListener implements EventSubscriberInterface 
{ 

protected $container; 

public function __construct(ContainerInterface $container) 
{ 
    $this->container = $container; 
} 

    public static function getSubscribedEvents() 
    { 
     return array(
      FOSUserEvents::REGISTRATION_CONFIRMED => ['onRegistrationConfirm', 999], 
     ); 
    } 

    public function onRegistrationConfirm(FilterUserResponseEvent $filterUserResponseEvent){ 
     $user = $filterUserResponseEvent->getUser(); 
     $user_manager = $this->container->get('fos_user.user_manager'); 
$user->setEnabled(false); 
     $user->setLocked(true); 
     $user_manager->updateUser($user); 

    } 


} 
2

Это то, что я сделал для перенаправления на панель администратора. Я использовал событие REGISTRATION_SUCCESS (которое использует FormEvent вместо FilterUserResponseEvent).

use FOS\UserBundle\FOSUserEvents; 
use FOS\UserBundle\Event\FormEvent; 
use Symfony\Component\EventDispatcher\EventSubscriberInterface; 
use Symfony\Component\HttpFoundation\RedirectResponse; 
use Symfony\Component\Routing\Generator\UrlGeneratorInterface; 


class RegistrationListener implements EventSubscriberInterface 
{ 
    private $router; 

    public function __construct(UrlGeneratorInterface $router) 
    { 
     $this->router = $router; 
    } 

    public static function getSubscribedEvents() 
    { 
     return array(
      FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess', 
     ); 
    } 

    public function onRegistrationSuccess(FormEvent $event) 
    { 
     $url = $this->router->generate('admin_users'); 
     $event->setResponse(new RedirectResponse($url)); 
    } 
} 

В целях предотвращения аутентификации мне пришлось переопределить AuthenticationListener, как описано в https://stackoverflow.com/a/23969485/5074443. Вот мой AuthenticationListener:

use FOS\UserBundle\FOSUserEvents; 
use FOS\UserBundle\EventListener\AuthenticationListener as FOSAuthenticationListener; 

class AuthenticationListener extends FOSAuthenticationListener 
{ 
    public static function getSubscribedEvents() 
    { 
     return array(
      // do not authenticate after registration 
      // FOSUserEvents::REGISTRATION_COMPLETED => 'authenticate', 
      // FOSUserEvents::REGISTRATION_CONFIRMED => 'authenticate' 
      FOSUserEvents::RESETTING_RESET_COMPLETED => 'authenticate', 
     ); 
    } 
} 
Смежные вопросы