<?php
namespace App\Controller;
use App\Entity\User;
use App\Entity\Customer;
use App\Form\RegistrationFormType;
use App\Repository\UserRepository;
use Symfony\Component\Mime\Address;
use App\Repository\CustomerRepository;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Repository\Variables\UserTypeRepository;
use SymfonyCasts\Bundle\VerifyEmail\VerifyEmailHelperInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
#[Route('/register')]
class RegistrationController extends AbstractController
{
public function __construct(private VerifyEmailHelperInterface $verifyEmailHelper, private MailerInterface $mailer)
{
}
#[Route('/', name: 'customer_register')]
public function register(Request $request, UserPasswordHasherInterface $passwordHasher): Response
{
if ($this->isGranted('IS_AUTHENTICATED')) {
$this->addFlash('warning', 'Vous êtes déja connecté');
return $this->redirectToRoute('app_login');
}
$customer = new Customer();
$form = $this->createForm(RegistrationFormType::class, $customer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var Customer $customer */
$customer = $form->getData();
/** @var string $password */
$password = $form->get('plainPassword')->getData();
$hashedPassword = $passwordHasher->hashPassword($customer, $password);
$customer->setPassword($hashedPassword);
$session = $request->getSession();
$session->set('customer', $customer);
return $this->redirectToRoute('customer_civility');
}
return $this->render('registration/register.html.twig', [
'form' => $form->createView(),
]);
}
#[Route('/customer/civility', name: 'customer_civility')]
public function civility(Request $request): Response
{
$session = $request->getSession();
$customer = $session->get('customer');
if (!$customer) {
return $this->redirectToRoute('customer_register');
}
$form = $this->createForm(RegistrationFormType::class, $customer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$customer = $form->getData();
$session->set('customer', $customer);
return $this->redirectToRoute('customer_address');
}
return $this->render('registration/civility.html.twig', [
'form' => $form->createView(),
]);
}
#[Route('/customer/address', name: 'customer_address')]
public function address(Request $request, UserTypeRepository $userTypeRepository, CustomerRepository $customerRepository): Response
{
$session = $request->getSession();
/** @var ?Customer $customer */
$customer = $session->get('customer');
if (!$customer) {
return $this->redirectToRoute('customer_register');
}
$customer->removeAllAddress();
$form = $this->createForm(RegistrationFormType::class, $customer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var Customer $customer */
$customer = $form->getData();
$userType = $userTypeRepository->findOneByName("Client particulier");
$customer->setUserType($userType);
$customerRepository->add($customer, true);
$session->set('customer', $customer);
return $this->redirectToRoute('customer_know', ['id' => $customer->getId()]);
}
return $this->render('registration/address.html.twig', [
'form' => $form->createView(),
]);
}
#[Route('/customer/know/{id}', name: 'customer_know')]
public function know(Request $request, ManagerRegistry $doctrine, Customer $customer): Response
{
$entityManager = $doctrine->getManager();
$form = $this->createForm(RegistrationFormType::class, $customer);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var Customer $customer */
$customer = $form->getData();
/** @var string $know */
$know = $form->get('know')->getData();
if ('Autre' == $know) {
/** @var string $other */
$other = $form->get('other')->getData();
$know = '' != $other ? $other : $know;
$customer->setKnow($know);
}
$entityManager->flush();
return $this->redirectToRoute('app_confirmation', ['id' => $customer->getId()]);
}
return $this->render('registration/know.html.twig', [
'form' => $form->createView(),
'id' => $customer->getId(),
]);
}
/**
* @Route("/verify", name="registration_confirmation_route")
*/
public function verifyUserEmail(Request $request, UserRepository $userRepository, EntityManagerInterface $entityManager): Response
{
$id = $request->get('id');
if (null === $id) {
return $this->redirectToRoute('customer_register');
}
$user = $userRepository->find($id);
if (null === $user) {
return $this->redirectToRoute('customer_register');
}
// Do not get the User's Id or Email Address from the Request object
try {
$this->verifyEmailHelper->validateEmailConfirmation($request->getUri(), (string) $user->getId(), $user->getEmail());
} catch (VerifyEmailExceptionInterface $e) {
$this->addFlash('verify_email_error', $e->getReason());
return $this->redirectToRoute('customer_register');
}
// Mark your user as verified. e.g. switch a User::verified property to true
$user->setIsVerified(true);
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', 'Votre email a bien été vérifié');
return $this->redirectToRoute('app_login');
}
/**
* @Route("/confirmation/{id}", name="app_confirmation")
*
* @throws TransportExceptionInterface
*/
public function confirmationConfirm(User $user): Response
{
$userConfirm = $user->isVerified();
if (true === $userConfirm) {
return $this->redirectToRoute('app_login');
}
$signatureComponents = $this->verifyEmailHelper->generateSignature(
'registration_confirmation_route',
(string) $user->getId(),
$user->getEmail(),
['id' => $user->getId()] // add the user's id as an extra query param
);
$email = new TemplatedEmail();
$email->from(new Address('contact@nibuco.fr', 'Livraison Nibuco'));
$email->to($user->getEmail());
$email->subject('Confirmez votre email');
$email->htmlTemplate('registration/confirmation_email.html.twig');
$email->context(['expiresAtMessageKey' => '1 heure', 'signedUrl' => $signatureComponents->getSignedUrl()]);
$this->mailer->send($email);
return $this->render('registration/check_registration.html.twig', [
'confirm' => 'confirm',
'user' => $user,
]);
}
}