В этом документе сказано (из того, что я могу сказать) изменить метод getSubscribedEvents()
, чтобы иметь более низкий приоритет -10. После включения подтверждения по электронной почте в config.yml
письмо отправляется и, насколько это касается, работает, но оно не будет перенаправлено на страницу /register/check-email
. Слушатель для сброса пароля перенаправляет на правильную страницу, но это не так.
Registration success listener with enabled confirmation at the same time
------------------------------------------------------------------------
When you have registration confirmation and you want to hook up to
``FOSUserEvents::REGISTRATION_SUCCESS`` event you will have to prioritize this listener to be called
before ``FOS\UserBundle\EventListener\EmailConfirmationListener::onRegistrationSuccess``::
public static function getSubscribedEvents()
{
return [
FOSUserEvents::REGISTRATION_SUCCESS => [
['onRegistrationSuccess', -10],
],
];
}
If you don't do it, ``EmailConfirmationListener`` will be called earlier and you will be redirected to
``fos_user_registration_check_email`` route.
Возможно, это относится к приоритету других слушателей, но я не уверен. Я предположил, что они хотели изменить приоритет в emailConfirmationListener.php
. Глядя на _profiler
, /register/check-email
не запрашивается в любое время. Вместо этого он перенаправляет на account/listings
, который затем перенаправляет на страницу входа.
EmailConfirmationListener.php
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\EventListener;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Mailer\MailerInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
class EmailConfirmationListener implements EventSubscriberInterface
{
private $mailer;
private $tokenGenerator;
private $router;
private $session;
/**
* EmailConfirmationListener constructor.
*
* @param MailerInterface $mailer
* @param TokenGeneratorInterface $tokenGenerator
* @param UrlGeneratorInterface $router
* @param SessionInterface $session
*/
public function __construct(MailerInterface $mailer, TokenGeneratorInterface $tokenGenerator, UrlGeneratorInterface $router, SessionInterface $session)
{
$this->mailer = $mailer;
$this->tokenGenerator = $tokenGenerator;
$this->router = $router;
$this->session = $session;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
// return array(
// FOSUserEvents::REGISTRATION_SUCCESS => 'onRegistrationSuccess',
// );
return [
FOSUserEvents::REGISTRATION_SUCCESS => [
['onRegistrationSuccess', -10],
],
];
}
/**
* @param FormEvent $event
*/
public function onRegistrationSuccess(FormEvent $event)
{
/** @var $user \FOS\UserBundle\Model\UserInterface */
$user = $event->getForm()->getData();
$user->setEnabled(false);
if (null === $user->getConfirmationToken()) {
$user->setConfirmationToken($this->tokenGenerator->generateToken());
}
$this->mailer->sendConfirmationEmailMessage($user);
$this->session->set('fos_user_send_confirmation_email/email', $user->getEmail());
$url = $this->router->generate('fos_user_registration_check_email');
$event->setResponse(new RedirectResponse($url));
}
}
RegistrationController.php
<?php
/*
* This file is part of the FOSUserBundle package.
*
* (c) FriendsOfSymfony <http://friendsofsymfony.github.com/>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace FOS\UserBundle\Controller;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Exception\AccessDeniedException;
/**
* Controller managing the registration.
*
* @author Thibault Duplessis <thibault.duplessis@gmail.com>
* @author Christophe Coevoet <stof@notk.org>
*/
class RegistrationController extends Controller
{
private $eventDispatcher;
private $formFactory;
private $userManager;
private $tokenStorage;
public function __construct(EventDispatcherInterface $eventDispatcher, FactoryInterface $formFactory, UserManagerInterface $userManager, TokenStorageInterface $tokenStorage)
{
$this->eventDispatcher = $eventDispatcher;
$this->formFactory = $formFactory;
$this->userManager = $userManager;
$this->tokenStorage = $tokenStorage;
}
/**
* @param Request $request
*
* @return Response
*/
public function registerAction(Request $request)
{
$user = $this->userManager->createUser();
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $this->formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_SUCCESS, $event);
$this->userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_COMPLETED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
$event = new FormEvent($form, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_FAILURE, $event);
if (null !== $response = $event->getResponse()) {
return $response;
}
}
return $this->render('@FOSUser/Registration/register.html.twig', array(
'form' => $form->createView(),
));
}
/**
* Tell the user to check their email provider.
*/
public function checkEmailAction(Request $request)
{
$email = $request->getSession()->get('fos_user_send_confirmation_email/email');
if (empty($email)) {
return new RedirectResponse($this->generateUrl('fos_user_registration_register'));
}
$request->getSession()->remove('fos_user_send_confirmation_email/email');
$user = $this->userManager->findUserByEmail($email);
if (null === $user) {
return new RedirectResponse($this->container->get('router')->generate('fos_user_security_login'));
}
return $this->render('@FOSUser/Registration/check_email.html.twig', array(
'user' => $user,
));
}
/**
* Receive the confirmation token from user email provider, login the user.
*
* @param Request $request
* @param string $token
*
* @return Response
*/
public function confirmAction(Request $request, $token)
{
$userManager = $this->userManager;
$user = $userManager->findUserByConfirmationToken($token);
if (null === $user) {
throw new NotFoundHttpException(sprintf('The user with confirmation token "%s" does not exist', $token));
}
$user->setConfirmationToken(null);
$user->setEnabled(true);
$event = new GetResponseUserEvent($user, $request);
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_CONFIRM, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('fos_user_registration_confirmed');
$response = new RedirectResponse($url);
}
$this->eventDispatcher->dispatch(FOSUserEvents::REGISTRATION_CONFIRMED, new FilterUserResponseEvent($user, $request, $response));
return $response;
}
/**
* Tell the user his account is now confirmed.
*/
public function confirmedAction(Request $request)
{
$user = $this->getUser();
if (!is_object($user) || !$user instanceof UserInterface) {
throw new AccessDeniedException('This user does not have access to this section.');
}
return $this->render('@FOSUser/Registration/confirmed.html.twig', array(
'user' => $user,
'targetUrl' => $this->getTargetUrlFromSession($request->getSession()),
));
}
/**
* @return string|null
*/
private function getTargetUrlFromSession(SessionInterface $session)
{
$key = sprintf('_security.%s.target_path', $this->tokenStorage->getToken()->getProviderKey());
if ($session->has($key)) {
return $session->get($key);
}
return null;
}
}