<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\PasswordResetRequestFormType;
use App\Form\PasswordResetFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mime\Address;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Uid\Uuid;
class PasswordResetController extends AbstractController {
private $entityManager;
private $mailer;
private $passwordEncoder;
public function __construct(EntityManagerInterface $entityManager, MailerInterface $mailer, UserPasswordEncoderInterface $passwordEncoder) {
$this->entityManager = $entityManager;
$this->mailer = $mailer;
$this->passwordEncoder = $passwordEncoder;
}
/**
* @Route("/recuperar-pass", name="app_forgot_password")
*/
public function request(Request $request): Response {
// Crear el formulario para solicitar el restablecimiento de contraseña
$form = $this->createForm(PasswordResetRequestFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Obtener el email del formulario
$email = $form->get('email')->getData();
// Buscar el usuario por su email
$user = $this->entityManager->getRepository(User::class)->findOneBy(['email' => $email]);
if ($user) {
// Generar un token de restablecimiento
$resetToken = Uuid::v4();
$user->setResetToken($resetToken);
$user->setResetTokenExpiresAt(new \DateTime('+1 hour'));
// Guardar el token y la fecha de expiración en la base de datos
$this->entityManager->flush();
// Enviar el email de restablecimiento
$email = (new TemplatedEmail())
->from(new Address('contacto@urba-loca.es', 'UrbaLoca'))
->to($user->getEmail())
->subject('UrbaLoca - Solicitud de restablecimiento de contraseña')
->htmlTemplate('emails/reset_password.html.twig')
->context([
'resetToken' => $resetToken,
]);
$this->mailer->send($email);
// Añadir un mensaje flash para informar al usuario
$this->addFlash('success', 'Se ha enviado un email con instrucciones para restablecer tu contraseña.');
// Redirigir al usuario a la página de inicio de sesión
return $this->redirectToRoute('app_login');
}
// Añadir un mensaje flash en caso de que no se encuentre el usuario
$this->addFlash('error', 'No se encontró ningún usuario con ese correo electrónico.');
}
// Renderizar la vista del formulario de solicitud
return $this->render('password_reset/request.html.twig', [
'requestForm' => $form->createView(),
]);
}
/**
* @Route("/restablecer-pass/{token}", name="app_reset_password")
*/
public function reset(Request $request, string $token): Response {
// Buscar el usuario por su token de restablecimiento
$user = $this->entityManager->getRepository(User::class)->findOneBy(['resetToken' => $token]);
// Verificar si el token es válido o ha expirado
if (!$user || $user->getResetTokenExpiresAt() < new \DateTime()) {
// Añadir un mensaje flash en caso de token inválido o expirado
$this->addFlash('error', 'Token de restablecimiento inválido o expirado.');
// Redirigir al usuario a la página de solicitud de restablecimiento
return $this->redirectToRoute('app_forgot_password');
}
// Crear el formulario para restablecer la contraseña
$form = $this->createForm(PasswordResetFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// Obtener la nueva contraseña del formulario
$plainPassword = $form->get('plainPassword')->getData();
// Codificar la nueva contraseña
$encodedPassword = $this->passwordEncoder->encodePassword($user, $plainPassword);
$user->setPassword($encodedPassword);
// Limpiar el token y la fecha de expiración
$user->setResetToken(null);
$user->setResetTokenExpiresAt(null);
// Guardar la nueva contraseña en la base de datos
$this->entityManager->flush();
// Añadir un mensaje flash para informar al usuario
$this->addFlash('success', 'Tu contraseña ha sido restablecida con éxito.');
// Redirigir al usuario a la página de inicio de sesión
return $this->redirectToRoute('app_login');
}
// Renderizar la vista del formulario de restablecimiento
return $this->render('password_reset/reset.html.twig', [
'resetForm' => $form->createView(),
'token' => $token,
]);
}
}