<?php
namespace App\Controller;
use Datetime;
use App\Entity\User;
use App\Entity\Notification;
use Psr\Log\LoggerInterface;
use App\Service\EmailService;
use App\Security\EmailVerifier;
use App\Form\RegistrationFormType;
use App\Repository\UserRepository;
use Symfony\Component\Mime\Address;
use App\Service\UserWordpressService;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Contracts\HttpClient\HttpClientInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use SymfonyCasts\Bundle\VerifyEmail\Exception\VerifyEmailExceptionInterface;
class RegistrationController extends AbstractController
{
private $logger;
private $httpClient;
private $emailService;
private $wordpressService;
private EmailVerifier $emailVerifier;
public function __construct(UserWordpressService $wordpressService, EmailService $emailService, LoggerInterface $logger, EmailVerifier $emailVerifier, HttpClientInterface $httpClient)
{
$this->logger = $logger;
$this->httpClient = $httpClient;
$this->emailService = $emailService;
$this->emailVerifier = $emailVerifier;
$this->wordpressService = $wordpressService;
}
#[Route('/register', name: 'app_register')]
public function register(Request $request, JWTTokenManagerInterface $JWTTokenManager, UserPasswordHasherInterface $userPasswordHasher, EntityManagerInterface $entityManager): Response
{
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
if($form->has('seoPlugin') && $form->get('seoPlugin')->getData() === null ) {
//dump("seoPlugin par défaut mis");
$user->setSeoPlugin('yoastseo');
}
try {
//dump($form);
// encode le plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
//dump("Ici1");
$user->setRoles(['ROLE_USER']);
$creationDate = new Datetime('now');
$user->setCreationDate($creationDate);
if ($form->has('wordpressPassword') && $form->get('wordpressPassword')->getData() !== null ) {
$user->setWordpressPassword($this->wordpressService->encryptPassword($user->getWordpressPassword()));
}
$user->setMemberOptionAutoPublish(false);
$user->setAutoPublish(false);
$customerKey = $JWTTokenManager->create($user);
$user->setCustomerKey($customerKey);
$user->setNumberOfTestArticle(3);
if($form->get('phoneNumber')->getData() === "null" ) {
// Gestion des erreurs
$this->addFlash('danger', 'Erreur : Numéro de téléphone invalide.');
return $this->redirectToRoute('app_register');
}
//dump("Ici");
if (preg_match('/^\+\d+/', $form->get('phoneNumber')->getData())) {
$phoneNumber = $user->setPhoneNumber($form->get('phoneNumber')->getData());
}
else {
throw new \InvalidArgumentException("Le numéro de téléphone doit inclure un préfixe international.");
}
//dump("Ici2");
try {
$entityManager->persist($user);
$entityManager->flush();
} catch (Exception $e) {
$this->addFlash("danger" . $e->getMessage());
}
//dump("Ici3");
// A faire après la vérification d'email dans la prod
$jsonData = [
'authentication_key' => $_ENV['AUTHENTICATION_KEY'],
'idcustomer' => $user->getId(),
'customerkey' => $user->getCustomerKey(),
'customerlastname' => $user->getLastname(),
'customerfirstname' => $user->getFirstname(),
'customeremail' => $user->getEmail(),
'customerphonenumber' => $user->getPhoneNumber(),
'customersubjects' => "",
'companyname' => $user->getCompanyName(),
'siteurl' => $user->getWordpressUrl(),
'publishinguser' => $user->getWordpressUsername(),
'publishinguserkey' => $user->getWordpressPassword() !== null ? $this->wordpressService->decryptPassword($user->getWordpressPassword()) : null,
'seoplugin' => $user->getSeoPlugin(),
'autopublish' => $user->isAutoPublish() == true ? 1 : 0
];
//dump("Ici4");
//dump($jsonData);
try {
// Envoyer les données à l'API externe
$response = $this->httpClient->request('POST', 'https://www.groupe-saven.fr/api.cpe/newcustomer.php',
[
'json' => $jsonData
]);
$statusCode = $response->getStatusCode();
//dump($response);
$content = $response->getContent(false);
$data = json_decode($content, true);
//dump($statusCode);
//dump($data);
//dump($response);
if ($statusCode !== 200) {
// Lancer une exception avec le contenu de la réponse si le code de statut n'est pas 200
throw new \Exception("Erreur HTTP $statusCode: " . $content);
}
if ($data['status'] === 'success') {
//dump($data['id']);
$user->setPbnId($data['id']);
try {
$tokenVerif = uniqid(md5($user->getEmail()), true) . bin2hex(random_bytes(5));
$user->setTempToken($tokenVerif);
$entityManager->persist($user);
$entityManager->flush();
// Je cree la notification pour l'historique d'activité
$notification = new Notification();
$creationDate = new Datetime('now');
$notification->setDateCreated($creationDate);
$notification->setTitle('Création du compte');
$notification->setUser($user);
$notification->setDetail('Vous avez créé votre compte');
$entityManager->persist($notification);
$entityManager->flush();
} catch (Exception $e) {
$this->logger->error('Erreur : '. $e->getMessage());
}
}
} catch (Exception $e) {
//dump($response);
$this->logger->error("danger" . $e->getMessage());
}
//
// generate a signed url and email it to the user
//dump('envoie de mail');
$to = $user->getEmail();
// Sujet de l'e-mail
$subject = "Vérification d'adresse mail";
$signedUrl = $this->generateUrl('app_verify_email',['token' => $tokenVerif], UrlGeneratorInterface::ABSOLUTE_URL, [
'scheme' => 'https'
]);
$profilUrl = $this->generateUrl('app_profile', [], UrlGeneratorInterface::ABSOLUTE_URL, [
'scheme' => 'https'
]);
// Message
$message = "<h4>Bonjour! Veuillez confirmer votre adresse mail s'il vous plaît!</h4>
<p>
Confirmer votre adresse mail en appuyant sur le lien ci dessous: <br><br>
<a href=".$signedUrl.">Confirmer mon adresse mail</a>.
<p>
Vous trouverez votre clé pour l'utilisation de l'api dans votre profil : <br> $profilUrl
</p>
</p>
<p>
Bien à vous!
</p>";
//dump($to);
//dump($subject);
//dump($message);
if($this->emailService->sendMail($to, $subject, $message) == 'succeed') {
$this->addFlash('success', 'Un email de confirmation vous a été envoyé dans votre boite mail '.$user->getEmail().', veuillez confirmer votre adresse afin de pouvoir vous connecter');
}
else {
throw new \Exception("Erreur d'envoie de mail");
}
//
return $this->redirectToRoute('app_login');
} catch (\InvalidArgumentException $e) {
// Ajouter une erreur au champ du formulaire
$this->addFlash('danger', $e->getMessage());
} catch (\Exception $e) {
//dump($e->getCode());
// Vérifiez si l'exception implémente HttpExceptionInterface
if ($e->getCode() == 400) {
$statusCode = $e->getCode();
$message = $e->getMessage();
}
elseif ($e instanceof ClientException) {
// Cas d'erreur côté client, comme une exception `BadRequestHttpException`
$statusCode = $e->getStatusCode();
$message = $e->getMessage();
} else {
if($e->getCode() == 0) {
$statusCode = Response::HTTP_INTERNAL_SERVER_ERROR;
$message = $e->getMessage();
}
else {
// Cas d'erreur côté serveur
$statusCode = Response::HTTP_INTERNAL_SERVER_ERROR;
$message = 'Une erreur interne du serveur s\'est produite.';
}
}
// Gestion des erreurs
$this->addFlash('danger', 'Erreur : '. $message);
return $this->redirectToRoute('app_register');
}
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
]);
}
#[Route('/verify/email', name: 'app_verify_email')]
public function verifyUserEmail(Request $request, UserRepository $userRepository, TranslatorInterface $translator, EntityManagerInterface $entityManager): Response
{
// Je vérifie la présence du token dans l'url
if($request->get('token')) {
// Je cherche la correspondance avec un User par token
$user = $userRepository->findOneByTempToken($request->get('token'));
// Si je ne trouve pas de correspondance
if(empty($user)) {
return new JsonResponse('Votre lien a expiré, veuillez nous contacter par mail à l\'adresse : contact@leadplanet.fr', Response::HTTP_BAD_REQUEST);
}
// Si j'en trouve
else {
$user->setIsVerified(true);
$user->setTempToken(null);
//dump($user);
$entityManager->persist($user);
$entityManager->flush();
$this->addFlash('success', 'Votre adresse mail a bien été vérifiée, vous pouvez vous connecter');
// Je cree la notification pour l'historique d'activité
$notification = new Notification();
$creationDate = new Datetime('now');
$notification->setDateCreated($creationDate);
$notification->setTitle('Vérification du compte');
$notification->setUser($user);
$notification->setDetail('Vous avez vérifié votre compte');
$entityManager->persist($notification);
$entityManager->flush();
return $this->redirectToRoute('app_login');
}
}
return $this->redirectToRoute('app_register');
}
// Route de renvoie d'email de confirmation
#[Route('/resend/verify/email', name: 'resend_verification_email')]
public function sendVerifUserMail(Request $request, UserRepository $userRepository, TranslatorInterface $translator, EntityManagerInterface $entityManager): Response
{
// Je vérifie la présence du token dans l'url
if($request->get('email')) {
// Je cherche la correspondance avec un User par token
$user = $userRepository->findOneByEmail($request->get('email'));
// Si je ne trouve pas de correspondance
if(empty($user)) {
return new JsonResponse('Aucun utilisateur n\'est lié à cette email');
}
elseif($user->isVerified()) {
$this->addFlash('danger', 'Utilisateur déjà vérifié');
return $this->redirectToRoute('app_login');
}
// Si j'en trouve
else {
//dump('Renvoie de mail');
$to = $user->getEmail();
// Sujet de l'e-mail
$subject = "Vérification d'adresse mail";
if($user->getTempToken()) {
$tokenVerif = $user->getTempToken();
}
else {
$tokenVerif = uniqid(md5($user->getEmail()), true) . bin2hex(random_bytes(5));
$user->setTempToken($tokenVerif);
$entityManager->persist($user);
$entityManager->flush();
}
$signedUrl = $this->generateUrl('app_verify_email',['token' => $tokenVerif], UrlGeneratorInterface::ABSOLUTE_URL, [
'scheme' => 'https'
]);
$profilUrl = $this->generateUrl('app_profile', [], UrlGeneratorInterface::ABSOLUTE_URL, [
'scheme' => 'https'
]);
// Message
$message = "<h4>Bonjour! Veuillez confirmer votre adresse mail s'il vous plaît!</h4>
<p>
Confirmer votre adresse mail en appuyant sur le lien ci dessous: <br><br>
<a href=".$signedUrl.">Confirmer mon adresse mail</a>.
<p>
Vous trouverez votre clé pour l'utilisation de l'api dans votre profil une fois ce dernier vérifié: <br> $profilUrl
</p>
</p>
<p>
Bien à vous!
</p>";
//dump($to);
//dump($subject);
//dump($message);
if($this->emailService->sendMail($to, $subject, $message) == 'succeed') {
$this->addFlash('success', 'Un email de confirmation vous a été envoyé dans votre boite mail '.$user->getEmail().', veuillez confirmer votre adresse afin de pouvoir vous connecter');
}
else {
throw new \Exception("Erreur d'envoie de mail");
}
}
return $this->redirectToRoute('app_login');
}
return $this->render('security/resend_verification_mail.html.twig');
}
}