<?php
namespace App\Controller\Security;
use FOS\UserBundle\Event\FilterUserResponseEvent;
use FOS\UserBundle\Event\FormEvent;
use FOS\UserBundle\Event\GetResponseNullableUserEvent;
use FOS\UserBundle\Event\GetResponseUserEvent;
use FOS\UserBundle\FOSUserEvents;
use FOS\UserBundle\Model\UserInterface;
use FOS\UserBundle\Util\TokenGeneratorInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use App\Service\Mailer;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use FOS\UserBundle\Controller\ResettingController as BaseResettingController;
use FOS\UserBundle\Form\Factory\FactoryInterface;
use FOS\UserBundle\Model\UserManagerInterface;
use FOS\UserBundle\Mailer\MailerInterface;
use Psr\Log\LoggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
/**
* @see https://symfony.com/doc/current/bundles/FOSUserBundle/overriding_controllers.html
* @see https://symfony.com/doc/3.4/bundles/inheritance.html
*/
class ResettingController extends AbstractController # BaseResettingController
{
/**
* @param EventDispatcherInterface $eventDispatcher
* @param FactoryInterface $formFactory
* @param UserManagerInterface $userManager
* @param TokenGeneratorInterface $tokenGenerator
* @param MailerInterface $mailer
* @param int $retryTtl
*/
private $manager;
public function __construct(UserManagerInterface $manager, EventDispatcherInterface $event, FactoryInterface $formFactory)
{
$this->manager = $manager;
$this->event = $event;
$this->formFactory = $formFactory;
}
/**
* @param Request $request
* @Route("/change-password/request", name="back_resetting_request")
*/
public function requestAction(Request $request)
{
$username = $request->get('username');
return $this->render('resetting/request.html.twig', compact('username'));
}
/**
* @param Request $request
* @Route("/change-password/send-email", name="back_resetting_send_email")
*
* @return Response
*/
public function sendEmailAction(Request $request,TokenGeneratorInterface $tokenGenerator,Mailer $mailer)
{
$username = $request->request->get('username');
/** @var UserInterface $user */
$user = $this->manager->findUserByUsernameOrEmail($username);
// $this->logger->info('user reset password ==> '.serialize($user));
if(!$user) {
return $this->redirectToRoute('back_resetting_request', compact('username'));
}
/** @var $dispatcher EventDispatcherInterface */
$dispatcher = $this->event;
/* Dispatch init event */
$event = new GetResponseNullableUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::RESETTING_SEND_EMAIL_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$ttl = $this->getParameter('fos_user.resetting.retry_ttl');
if (null !== $user && !$user->isPasswordRequestNonExpired($ttl)) {
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_REQUEST, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
if (null === $user->getConfirmationToken()) {
$user->setConfirmationToken($tokenGenerator->generateToken());
}
/* Dispatch confirm event */
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::RESETTING_SEND_EMAIL_CONFIRM, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
// send Email ressetting pwd
$mailer->sendResettingEmailMessage($user);
$user->setPasswordRequestedAt(new \DateTime());
$this->manager->updateUser($user);
/* Dispatch completed event */
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::RESETTING_SEND_EMAIL_COMPLETED, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
}
return new RedirectResponse($this->generateUrl('back_resetting_check_email', array('username' => $username)));
}
/**
* Tell the user to check his email provider.
*
* @param Request $request
* @Route("/change-password/check-email", name="back_resetting_check_email")
*
* @return Response
*/
public function checkEmailAction(Request $request)
{
$username = $request->query->get('username');
if (empty($username)) {
// the user does not come from the sendEmail action
return new RedirectResponse($this->generateUrl('back_resetting_request'));
}
return $this->render('resetting/check_email.html.twig', array(
'tokenLifetime' => ceil($this->getParameter('fos_user.resetting.retry_ttl') / 3600),
));
}
/**
* Reset user password.
*
* @param Request $request
* @param string $token
* @Route("/change-password/reset/{token}", name="back_resetting_reset")
*
* @return Response
*/
public function resetAction(Request $request, $token)
{
/** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */
$formFactory = $this->formFactory;
/** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */
$userManager = $this->manager;
/** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */
$dispatcher = $this->event;
$user = $userManager->findUserByConfirmationToken($token);
if (null === $user) {
throw new NotFoundHttpException(sprintf('The user with "confirmation token" does not exist for value "%s"', $token));
}
$event = new GetResponseUserEvent($user, $request);
$dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_INITIALIZE, $event);
if (null !== $event->getResponse()) {
return $event->getResponse();
}
$form = $formFactory->createForm();
$form->setData($user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event = new FormEvent($form, $request);
$dispatcher->dispatch(FOSUserEvents::RESETTING_RESET_SUCCESS, $event);
$userManager->updateUser($user);
if (null === $response = $event->getResponse()) {
$url = $this->generateUrl('app_login');
$response = new RedirectResponse($url);
}
$dispatcher->dispatch(
FOSUserEvents::RESETTING_RESET_COMPLETED,
new FilterUserResponseEvent($user, $request, $response)
);
return $response;
}
return $this->render('resetting/reset.html.twig', array(
'token' => $token,
'form' => $form->createView()
));
}
}