<?php
declare(strict_types=1);
namespace App\Controller\Security;
use App\Entity\Security\User;
use App\Form\Security\ChangePasswordFormType;
use App\Form\Security\ResetPasswordRequestFormType;
use App\Service\Mailer\Mailer;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use SymfonyCasts\Bundle\ResetPassword\Controller\ResetPasswordControllerTrait;
use SymfonyCasts\Bundle\ResetPassword\Exception\ResetPasswordExceptionInterface;
use SymfonyCasts\Bundle\ResetPassword\ResetPasswordHelperInterface;
class ResetPasswordController extends AbstractController
{
use ResetPasswordControllerTrait;
public function __construct(
private ResetPasswordHelperInterface $resetPasswordHelper,
private EntityManagerInterface $entityManager,
private Mailer $mailer,
private UrlGeneratorInterface $urlGenerator,
) {
}
public function request(Request $request): Response
{
$form = $this->createForm(ResetPasswordRequestFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
return $this->processSendingPasswordResetEmail(
$form->get('email')->getData(),
);
}
return $this->render('Security/Emails/request.html.twig', [
'requestForm' => $form->createView(),
]);
}
public function checkEmail(): Response
{
if (null === ($resetToken = $this->getTokenObjectFromSession())) {
$resetToken = $this->resetPasswordHelper->generateFakeResetToken();
}
return $this->render('Security/ResetPassword/check_email.html.twig', [
'resetToken' => $resetToken,
]);
}
public function reset(Request $request, UserPasswordHasherInterface $userPasswordHasher, TranslatorInterface $translator, string $token = null): Response
{
if (null !== $token) {
$this->storeTokenInSession($token);
return $this->redirectToRoute('foxorders_security_reset_password_reset');
}
$token = $this->getTokenFromSession();
if (null === $token) {
throw $this->createNotFoundException($translator->trans('app.app.global.user.password.reset.messages.token_not_found'));
}
try {
$user = $this->resetPasswordHelper->validateTokenAndFetchUser($token);
} catch (ResetPasswordExceptionInterface $e) {
$this->addFlash('reset_password_error', sprintf(
'%s - %s',
$translator->trans(ResetPasswordExceptionInterface::MESSAGE_PROBLEM_VALIDATE, [], 'ResetPasswordBundle'),
$translator->trans($e->getReason(), [], 'ResetPasswordBundle')
));
return $this->redirectToRoute('foxorders_security_reset_password_request');
}
$form = $this->createForm(ChangePasswordFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted()) {
$this->resetPasswordHelper->removeResetRequest($token);
$encodedPassword = $userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
);
$user->setPassword($encodedPassword);
$this->entityManager->flush();
$this->cleanSessionAfterReset();
return $this->redirectToRoute('foxorders_dashboard');
}
return $this->render('Security/ResetPassword/reset.html.twig', [
'resetForm' => $form->createView(),
]);
}
private function processSendingPasswordResetEmail(string $emailFormData): RedirectResponse
{
$user = $this->entityManager->getRepository(User::class)->findOneBy([
'email' => $emailFormData,
]);
if (!$user) {
return $this->redirectToRoute('foxorders_security_reset_password_check_email');
}
try {
$resetToken = $this->resetPasswordHelper->generateResetToken($user);
$url = $this->urlGenerator->generate('foxorders_security_reset_password_reset', ['token' => $resetToken->getToken()], UrlGeneratorInterface::ABSOLUTE_URL);
$this->mailer->sendResetPasswordMail($user, compact('url'));
$this->setTokenObjectInSession($resetToken);
} catch (ResetPasswordExceptionInterface $e) {
return $this->redirectToRoute('foxorders_security_reset_password_check_email');
}
return $this->redirectToRoute('foxorders_security_reset_password_check_email');
}
}