<?php
namespace App\Controller;
ini_set('memory_limit', '2G');
use App\Entity\Contact;
use App\Entity\Pcode;
use App\Entity\PcodeCategory;
use App\Entity\Users;
use App\Form\ContactType;
use Doctrine\DBAL\Driver\PDOStatement;
use Doctrine\Persistence\ManagerRegistry;
use Karser\Recaptcha3Bundle\Validator\Constraints\Recaptcha3Validator;
use Psr\Log\LoggerInterface;
use Symfony\Bridge\Twig\Mime\TemplatedEmail;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\ErrorHandler\Debug;
use Symfony\Component\ErrorHandler\ErrorHandler;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
use Symfony\Component\Mailer\MailerInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Uid\Uuid;
Debug::enable();
ErrorHandler::register();
class ContactController extends AbstractController
{
private LoggerInterface $logger;
private MailerInterface $mailer;
private ParameterBagInterface $bag;
private ManagerRegistry $managerRegistry;
/**
* @param LoggerInterface $logger
* @param MailerInterface $mailer
* @param ParameterBagInterface $bag
* @param ManagerRegistry $managerRegistry
*/
public function __construct(LoggerInterface $logger, MailerInterface $mailer, ParameterBagInterface $bag, \Doctrine\Persistence\ManagerRegistry $managerRegistry)
{
$this->logger = $logger;
$this->mailer = $mailer;
$this->bag = $bag;
$this->managerRegistry = $managerRegistry;
}
/**
* @Route("/contact", name="app_contact")
*/
public function index(Request $request, Recaptcha3Validator $recaptcha3Validator): Response
{
$mailFrom = $this->bag->get('mailFrom');
$mailTo = $this->bag->get('notificationMail');
$mailArray = explode(',', $mailTo);
$contact = new Contact();
$contact->setCreatedAt(new \DateTimeImmutable());
$contact->setIpAddress($request->getClientIp());
$contactForm = $this->createForm(ContactType::class, $contact);
$contactForm->handleRequest($request);
if ($contactForm->isSubmitted() && $contactForm->isValid()) {
$score = $recaptcha3Validator->getLastResponse()->getScore();
$contact = $contactForm->getData();
$entityManager = $this->managerRegistry->getManager();
$entityManager->persist($contact);
$entityManager->flush();
try {
//Envoyer un mail de notification au service mokanda
$notificationEmail = (new TemplatedEmail())
->from($mailFrom)
->to(...$mailArray)
->subject($contact->getSubject())
->text('Notification de l\'internaute')
->htmlTemplate('contact/sendNotificationMail.html.twig')
->context([
'contact' => $contact
]);
// Envoyer un mail de réponse à l'internaute
$email = (new TemplatedEmail())
->from($this->getParameter('contactFrom'))
->to($contact->getEmail())
->subject($contact->getSubject())
->text('vôtre sujet a été pris en compte, vous serez recontacté très bientôt')
->htmlTemplate('contact/sendmail.html.twig')
->context([
'name' => $contact->getName(),
]);
$this->mailer->send($notificationEmail);
$this->mailer->send($email);
$this->addFlash('contact_notification_success', 'votre message a été envoyé avec succès !');
return $this->redirectToRoute('app_contact');
} catch (TransportExceptionInterface $e) {
$this->logger->info('In Exception transport', [$e->getMessage()]);
$this->addFlash('contact_notification_error', 'échec d\'envoi ressayez plus tard ');
return $this->redirectToRoute('app_contact');
}
}
return $this->render('contact/index.html.twig', [
'controller_name' => 'ContactController',
'contactForm' => $contactForm->createView()
]);
}
/**
* @Route("/populate_pcode_db", name="app_contact_file")
* @throws \Throwable
*/
public function populateCities(): Response
{
// Augmentation de la durée maximale d'exécution
set_time_limit(600); // 10 minutes
// Récupération de la catégorie de ville correspondant au niveau 4
$pcodeCatVille = $this->managerRegistry->getRepository(PcodeCategory::class)->findOneBy([
'level' => 4
]);
// Ouverture du fichier en lecture
$monFichier = dirname(__DIR__) . '/fr.txt';
$file = fopen($monFichier, 'r');
// Définition de la taille du lot
$batchSize = 1000;
$count = 0;
$conn = $this->managerRegistry->getManager()->getConnection();
// Préparation de la requête d'insertion
$stmt = $conn->prepare('INSERT INTO pcode (id, label, parent_id, pcode_category_id) VALUES (?, ?, ?, ?)');
// Début de la transaction
$conn->beginTransaction();
try {
$lineNumber = 0;
$batch = [];
// Parcours du fichier ligne par ligne
while (($line = fgets($file)) !== false) {
$parts = explode("\t", trim($line));
// Récupération du code postal correspondant
$pcode = $this->managerRegistry->getRepository(Pcode::class)->findOneBy([
'ccFIPS' => $parts[0]
]);
if ($pcode) {
// Récupération du nom de la ville
$cityName = mb_strtolower($parts[2]);
// Vérification de l'existence de la ville
$existCity = $this->managerRegistry->getRepository(Pcode::class)->findOneBy([
'pcodeCategory' => $pcodeCatVille,
'label' => $cityName
]);
if (!$existCity) {
$batch[] = [
'id' => 'V' . uniqid(),
'label' => $cityName,
'parent_id' => $pcode->getId(),
'pcode_category_id' => $pcodeCatVille->getId()
];
$count++;
if ($count % $batchSize === 0) {
// Insérer le lot dans la base de données
$this->insertBatch($batch, $stmt);
// Réinitialiser le lot
$batch = [];
// Commit de la transaction
$conn->commit();
$conn->beginTransaction();
}
}
}
// Libérer la mémoire après chaque itération
unset($line, $parts, $pcode, $existCity);
}
// Insérer les lignes restantes
if (!empty($batch)) {
$this->insertBatch($batch, $stmt);
}
// Commit final de la transaction
$conn->commit();
} catch (\Throwable $e) {
// Rollback de la transaction en cas d'erreur
$conn->rollBack();
throw $e;
} finally {
// Fermeture du fichier
fclose($file);
}
return $this->render('contact/cities_file.html.twig', [
'controller_name' => 'ContactController',
]);
}
private function insertBatch(array $batch, \PDOStatement $stmt)
{
foreach ($batch as $data) {
$stmt->bindValue(1, $data['id']);
$stmt->bindValue(2, $data['label']);
$stmt->bindValue(3, $data['parent_id']);
$stmt->bindValue(4, $data['pcode_category_id']);
$stmt->execute();
}
}
private function processBatch($batch, $pcodeRepository, $pcodeCategory, $entityManager)
{
$ccFIPSList = array_column($batch, 0);
$existingPcodes = $pcodeRepository->findBy(['ccFIPS' => $ccFIPSList]);
$existingCities = $pcodeRepository->createQueryBuilder('p')
->select('p.ccFIPS, LOWER(p.label) AS label')
->andWhere('p.pcodeCategory = :category')
->andWhere('p.ccFIPS IN (:ccFIPSList)')
->setParameter('category', $pcodeCategory)
->setParameter('ccFIPSList', $ccFIPSList)
->getQuery()
->getResult();
$existingCitiesMap = array_combine(array_column($existingCities, 'ccFIPS'), array_column($existingCities, 'label'));
foreach ($batch as [$ccFIPS, $label]) {
$pcode = $existingPcodes[array_search($ccFIPS, array_column($existingPcodes, 'ccFIPS'))] ?? null;
// Vérifier si le label n'est pas vide ou null
if (empty(trim($label))) {
continue;
}
// Vérifier si le label ne contient pas d'espaces inutiles ou de caractères spéciaux
if (!preg_match('/^[a-zA-Z0-9\s]+$/', $label)) {
continue;
}
if ($pcode && !isset($existingCitiesMap[$ccFIPS][$label])) {
$ville = new Pcode();
$ville->setId("V" . uniqid());
$ville->setLabel($label);
$ville->setParent($pcode);
$ville->setPcodeCategory($pcodeCategory);
$entityManager->persist($ville);
}
}
$entityManager->flush();
$entityManager->clear();
}
/**
* @Route("/cgu-cgv", name="app_cgu_cgv")
*/
public function cgu(): Response
{
return $this->render('contact/cgu.html.twig', [
'controller_name' => 'ContactController',
'is_home' => 'true'
]);
}
/**
* @Route("/rgpd", name="app_rgpd")
*/
public function generateUuid(): Response
{
$namespaces = Uuid::NAMESPACE_OID;
$allUsers = $this->managerRegistry->getRepository(Users::class)->findAll();
foreach ($allUsers as $user) {
$user->setUID(Uuid::v3(Uuid::fromString($namespaces), $user->getMail()??uniqid()));
$this->managerRegistry->getManager()->persist($user);
}
$this->managerRegistry->getManager()->flush();
return new Response('uuid généré avec succès');
}
}