<?php
namespace App\Controller\Transporteur;
use App\Entity\{Transporteur, User};
use App\Form\{TransporteurType, ResendConfirmationType};
use App\Service\{AccessClientService, AddressInfoService};
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use DateTime;
use Symfony\Component\Mime\Email;
use Symfony\Component\Mime\Address;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
class RegisterController extends AbstractController
{
private $tokenStorage;
private $session;
public function __construct(
TokenStorageInterface $tokenStorage,
SessionInterface $session
) {
$this->tokenStorage = $tokenStorage;
$this->session = $session;
}
/**
* @Route("/professional/register", name="app_transporteur_register")
*/
public function register(
AccessClientService $accessClientService,
AddressInfoService $addressInfoService,
Request $request,
EntityManagerInterface $entityManager,
UserPasswordEncoderInterface $passwordEncoder,
MailerInterface $mailer
): Response
{
$accessClientService->handleAccessControl();
$user = new User();
$transporteur = new Transporteur();
$originalEmail = $user->getEmail();
$form = $this->createForm(TransporteurType::class, $transporteur);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$civility = $form->get('user')->get('civility')->getData();
$lastname = $form->get('user')->get('lastname')->getData();
$firstname = $form->get('user')->get('firstname')->getData();
$email = $form->get('user')->get('email')->getData();
$plainPassword = $form->get('user')->get('password')->getData();
$address = $form->get('address')->getData();
$posteZip = $form->get('postalCode')->getData();
$ville = $form->get('city')->getData();
$department = $form->get('department')->getData();
$pays = $form->get('country')->getData();
$lon = $form->get('longitude')->getData();
$lat = $form->get('latitude')->getData();
$agreeTerms = $form->get('agreeTerms')->getData();
$user->setCivility($civility);
$user->setLastname($lastname);
$user->setFirstname($firstname);
$user->setEmail($email);
$user->setRoles(['ROLE_TRANSPORTEUR']);
$encodedPassword = $passwordEncoder->encodePassword($user, $plainPassword);
$user->setPassword($encodedPassword);
$user->setStatus(User::PENDING_CONFIRMATION);
$user->setCreatedAtValue();
$user->preUpdate();
$addressInfo = $addressInfoService->getAddressInfo($address);
if ($addressInfo !== null) {
$postalCode = $addressInfo['postal_code'];
$city = $addressInfo['city'];
$areaAdministrative = $addressInfo['department'];
$country = $addressInfo['country'];
$longitude = $addressInfo['longitude'];
$latitude = $addressInfo['latitude'];
} else {
$postalCode = null;
$city = null;
$department = null;
$country = null;
$longitude = null;
$latitude = null;
}
if ($postalCode !== null && $posteZip !== $postalCode) {
$transporteur->setPostalCode($postalCode);
}
if ($city !== null && $ville !== $city) {
$transporteur->setCity($city);
}
if ($areaAdministrative !== null && $department !== $areaAdministrative) {
$transporteur->setDepartment($department);
}
if ($country !== null && $pays->getPays() !== $country) {
$transporteur->setCountry($pays);
}
if ($lon === null && $longitude !== null) {
$transporteur->setLongitude($longitude);
}
if ($lat === null && $latitude !== null) {
$transporteur->setLatitude($latitude);
}
$transporteur->setUser($user);
$token = $transporteur->getConfirmationToken();
$transporteur->setConfirmationToken($token);
$parisTimeZone = new \DateTimeZone('Europe/Paris');
$confirmationTokenCreatedAt = new \DateTime('now', $parisTimeZone);
$transporteur->setConfirmationTokenCreatedAt($confirmationTokenCreatedAt);
$transporteur->setAgreeTerms($agreeTerms);
$entityManager->persist($user);
$entityManager->persist($transporteur);
$entityManager->flush();
$email = (new Email())
->from(new Address('no-reply@resoh.fr', 'Ryvup.com'))
->to($user->getEmail())
->subject('Confirmation de compte')
->html($this->renderView('emails/confirmation_email.html.twig', [
'user' => $user,
'confirmationUrl' => $this->generateUrl('app_transporteur_confirm_account', [
'confirmationToken' => $transporteur->getConfirmationToken()
],
UrlGeneratorInterface::ABSOLUTE_URL),
]));
$mailer->send($email);
$this->addFlash('success', 'Succès ! Nous avons envoyé un lien de confirmation de votre compte à votre adresse e-mail : '. $user->getEmail().'. ');
return $this->redirectToRoute('app_front_login');
}
return $this->render('transporteur/register/inscription.html.twig', [
'transporteur' => $transporteur,
'form' => $form->createView()
]);
}
/**
* @Route("/professional/resend-confirmation/{expirationToken}", name="app_resend_confirmation_link")
*/
public function resendConfirmation(AccessClientService $accessClientService, Request $request, $expirationToken, EntityManagerInterface $entityManager, MailerInterface $mailer): Response
{
$accessClientService->handleAccessControl();
$transporteurRepository = $entityManager->getRepository(Transporteur::class);
$transporteur = $transporteurRepository->findOneBy(['expirationToken' => $expirationToken]);
if (!$transporteur) {
throw new NotFoundHttpException('Votre compte professionnel est introuvable.');
}
$form = $this->createForm(ResendConfirmationType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->get('email')->getData();
$userRepository = $entityManager->getRepository(User::class);
$user = $userRepository->findOneBy(['email' => $email]);
if (!$user) {
$this->addFlash('danger', 'Attention ! Aucun utilisateur trouvé avec cette adresse e-mail : ' . $email . '.');
} else if ($user && $user->getTransporteur() && $user->getTransporteur()->getExpirationToken()) {
$length = 20;
$alpha = "0123456789azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN-_";
$newToken = substr(str_shuffle(str_repeat($alpha, $length)), 0, $length);
$transporteur = $user->getTransporteur();
$transporteur->setConfirmationToken($newToken);
$parisTimeZone = new \DateTimeZone('Europe/Paris');
$confirmationTokenCreatedAt = new \DateTime('now', $parisTimeZone);
$transporteur->setConfirmationTokenCreatedAt($confirmationTokenCreatedAt);
$transporteur->setExpirationToken(null);
$entityManager->persist($transporteur);
$entityManager->flush();
$confirmationUrl = $this->generateUrl('app_transporteur_confirm_account', [
'confirmationToken' => $newToken
], UrlGeneratorInterface::ABSOLUTE_URL);
$email = (new Email())
->from(new Address('no-reply@resoh.fr', 'Ryvup.com'))
->to($user->getEmail())
->subject('Nouveau lien de confirmation de compte')
->html($this->renderView('emails/new_confirmation_email.html.twig', [
'user' => $user,
'confirmationUrl' => $confirmationUrl,
]));
$mailer->send($email);
$this->addFlash('success', 'Succès ! Un nouveau lien de confirmation a été envoyé à votre adresse e-mail : '. $user->getEmail() .'.');
} else {
$this->addFlash('danger', 'Attention ! Aucun compte professionnel trouvé avec cette adresse e-mail : ' . $email . '.');
}
}
return $this->render('transporteur/register/renvoi_confirmation.html.twig', [
'form' => $form->createView(),
]);
}
/**
* @Route("/professional/confirm-account/{confirmationToken}", name="app_transporteur_confirm_account")
*/
public function confirmAccount(AccessClientService $accessClientService, Request $request, $confirmationToken, EntityManagerInterface $entityManager): Response
{
$accessClientService->handleAccessControl();
$transporteurRepository = $entityManager->getRepository(Transporteur::class);
$transporteur = $transporteurRepository->findOneBy(['confirmationToken' => $confirmationToken]);
if (!$transporteur) {
throw new NotFoundHttpException('Votre compte professionnel est introuvable pour ce jeton.');
}
$user = $transporteur->getUser();
$parisTimezone = new \DateTimeZone('Europe/Paris');
$tokenCreatedAt = $transporteur->getConfirmationTokenCreatedAt();
$expirationTime = new \DateTime('-24 hours', $parisTimezone);
if ($tokenCreatedAt < $expirationTime) {
$length = 30;
$alpha = "0123456789azertyuiopqsdfghjklmwxcvbnAZERTYUIOPQSDFGHJKLMWXCVBN-_";
$expirationToken = substr(str_shuffle(str_repeat($alpha, $length)), 0, $length);
$transporteur->setConfirmationToken(null);
$transporteur->setConfirmationTokenCreatedAt(null);
$transporteur->setExpirationToken($expirationToken);
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($transporteur);
$entityManager->flush();
$this->addFlash('info', 'Info ! Votre lien de confirmation a expiré. Renvoyer un nouveau lien à votre adresse email.');
return $this->redirectToRoute('app_resend_confirmation_link', ['expirationToken' => $expirationToken]);
}
$transporteur->setConfirmationToken(null);
$transporteur->setConfirmationTokenCreatedAt(null);
$user->setStatus(User::AWAITING_DOCUMENTS);
$entityManager->persist($transporteur);
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', 'Succès ! Votre compte est confirmé mais en attente de validation des pièces justificative.');
return $this->redirectToRoute('app_front_login');
}
}