menu
Symfony 4 - Mot de passe oublié

Symfony 4 - Mot de passe oublié

Créons un reset password pour notre projet Symfony 4 pour nos utilisateurs étourdis :)

<?php
// AuthenticationController.php

use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\HttpFoundation\Session\Session;
use App\Form\ResetType;
use App\Form\EmailResetType;
use App\Form\RegistrationType;
use App\Entity\User;
use Mailgun\Mailgun;

public function resetPassword(Request $request)
    {
        $entityManager = $this->getDoctrine()->getManager();
        $form = $this->createForm(EmailResetType::class);

        $form->handleRequest($request);
        if ($form->isSubmitted() && $form->isValid()) {
            $user = $entityManager->getRepository(User::class)->findOneByEmail($form->getData()['email']);
            if ($user !== null) {
                $token = uniqid();
                $user->setResetPassword($token);
                $entityManager->persist($user);
                $entityManager->flush();

                $mgClient   = new Mailgun($this->getParameter('mailgun_api_key'));
                $domain     = $this->getParameter('mailgun_domain');
                $mailFrom   = $this->getParameter('mail_mail_from');
                $nameFrom   = $this->getParameter('mail_name_from');
                $mailTo = $user->getEmail();
                $result = $mgClient->sendMessage($domain, array(
                    'from' => "$nameFrom <$mailFrom>",
                    'to' => "<$mailTo>",
                    'subject' => 'Mot de passe oublié ?',
                    'html' => $this->renderView('emails/reset-password.html.twig', array('token' => $token))
                ));

                return $this->render('authentication/reset-password-confirmation.html.twig');
            }
        }

        return $this->render('authentication/reset-password.html.twig', array(
            'form' => $form->createView(),
        ));
    }

    public function resetPasswordToken(Request $request, UserPasswordEncoderInterface $encoder)
    {
        $token = $request->query->get('token');
        if ($token !== null) {
            $entityManager = $this->getDoctrine()->getManager();
            $user = $entityManager->getRepository(User::class)->findOneByResetPassword($token);
            if ($user !== null) {
                $form = $this->createForm(ResetType::class, $user);

                $form->handleRequest($request);
                if ($form->isSubmitted() && $form->isValid()) {
                    $plainPassword = $form->getData()->getPlainPassword();
                    $encoded = $encoder->encodePassword($user, $plainPassword);
                    $user->setPassword($encoded);
                    $entityManager->persist($user);
                    $entityManager->flush();

                    //add flash

                    return $this->redirectToRoute('login');
                }

                return $this->render('authentication/reset-password-token.html.twig', array(
                    'form' => $form->createView(),
                ));       
            }
        }
    }

// EmailResetType.php

namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;

use App\Entity\User;

class EmailResetType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email')
        ;
    }
    
    /**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => null,
        ));
    }
}

// EmailType.php
namespace App\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;

use App\Entity\Email;

class EmailType extends AbstractType
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('email')
            ->add('submit', SubmitType::class)
        ;
    }/**
     * {@inheritdoc}
     */
    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => Email::class
        ));
    }
}

// User.php
    /**
     * @ORM\Column(type="string", length=255, nullable=true)
     */
    private $resetPassword;

    public function getResetPassword(): ?string
    {
        return $this->resetPassword;
    }

    public function setResetPassword(string $resetPassword): self
    {
        $this->resetPassword = $resetPassword;

        return $this;
    }