<?php
declare(strict_types=1);
/**
* @author Mehrez Labidi
*/
namespace App\Controller;
use Symfony\Component\RateLimiter\RateLimiterFactory;
use App\Services\ContactPubFusacqExpert as ContactPubFusacqExpertService;
use App\Form\Models\ContactPubFusacqExpert;
use App\Form\Type\ContactPubFusacqExpertType;
use App\Helper\Utils;
use App\Services\{
Mailer,
TelephoneInternational
};
use App\Form\Models\{
ContactezNous,
Publicite,
DemandeInterm
};
use App\Form\Type\{
ContactezNousType,
PubliciteType,
DemandeIntermType
};
use App\Services\ContactezNous as ContactezNousService;
use App\Services\ManagerEntity\{
PubliciteManagers,
QuestionsFrequentesManagers,
QuestionsSemaineManagers,
TemoignageManager
};
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
use Symfony\Component\HttpFoundation\{
Request,
Response
};
use App\Services\API\ClientAPI;
use App\Services\MetaTag;
use Psr\Log\LoggerInterface;
class FooterPageController extends EntityUsingController {
public const MAX_AGE = 43200; // 12heures
/**
* @var EntityManagerInterface
*/
private EntityManagerInterface $em;
/**
* @var QuestionsSemaineManagers
*/
private QuestionsSemaineManagers $qsm;
/**
* @var TemoignageManager
*/
private TemoignageManager $tm;
/**
* @var ParameterBagInterface
*/
private ParameterBagInterface $params;
/**
* @var PubliciteManagers
*/
private PubliciteManagers $publiciteManagers;
/**
* @var QuestionsFrequentesManagers
*/
private QuestionsFrequentesManagers $qfm;
/**
* @var Mailer
*/
private $mailer;
/**
* @var MetaTag
*/
private $metaTag;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @param QuestionsSemaineManagers $qsm
*/
public function __construct(
EntityManagerInterface $em,
QuestionsSemaineManagers $qsm,
TemoignageManager $tm,
QuestionsFrequentesManagers $qfm,
ParameterBagInterface $params,
PubliciteManagers $publiciteManagers,
Mailer $mailer, MetaTag $metaTag, LoggerInterface $logger
) {
$this->em = $em;
$this->qfm = $qfm;
$this->qsm = $qsm;
$this->tm = $tm;
$this->params = $params;
$this->mailer = $mailer;
$this->publiciteManagers = $publiciteManagers;
$this->metaTag = $metaTag;
$this->logger = $logger;
}
/**
* @return mixed
*/
public function publicite(Request $request, $codePays) {
$model = new Publicite();
$form = $this->createForm(PubliciteType::class, $model, [
'action' => $this->generateUrl(
$request->attributes->get('_route'),
[
'codePays' => $codePays
]
),
'method' => 'POST',
]);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$data = $form->getData();
$this->publiciteManagers->envoiMailDemandePublicite($data);
$this->addFlash('success_pub_form', "Votre message a bien été envoyé.");
} else {
$this->addFlash('error_pub_form', "L'envoi de votre message a échoué");
}
}
$metaTitle = "Publicité ciblée sur FUSACQ | Bannières & Emailing";
$metaDescription = "Boostez votre visibilité sur FUSACQ : bannières publicitaires et emailing ciblés (secteur, zone géographique) pour atteindre acquéreurs, cédants et experts.";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
return $this->render('footer_page/publicite.html.twig', [
'controller_name' => 'FooterPageController', 'form' => $form->createView(), 'metaTag' => $metaTag,
]);
}
/**
* @return Response
*/
public function quiSommeNous() {
$response = $this->render('footer_page/qui_somme_nous.html.twig',
[
'controller_name' => 'FooterPageController',
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* @return Response
*/
public function cgu() {
$response = $this->render('footer_page/cgu.html.twig',
[
'controller_name' => 'FooterPageController',
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* @return Response
*/
public function mentionsLegales() {
$response = $this->render('footer_page/mentions_legales.html.twig',
[
'controller_name' => 'FooterPageController',
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
public function charteQualiteDeposant() {
$response = $this->render('footer_page/charte_qualite_deposant.html.twig',
[
'controller_name' => 'FooterPageController'
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* @return Response
* @throws Exception
*/
public function contact(Request $request, ContactezNousService $contactezNous, RateLimiterFactory $contactFormLimiter, $codePays) {
$model = new ContactezNous();
$form = $this->createForm(ContactezNousType::class, $model, [
'action' => $this->generateUrl(
$request->attributes->get('_route'),
[
'codePays' => $codePays,
]
),
'method' => 'POST',
]);
$form->handleRequest($request);
if ($form->isSubmitted()) {
// Vérifier le rate limit avant de traiter
$limiter = $contactFormLimiter->create($request->getClientIp());
$limit = $limiter->consume(1);
// Si la limite est atteinte
if (false === $limit->isAccepted()) {
// Calculer le temps d'attente en minutes
$retryAfter = $limit->getRetryAfter();
$waitTime = ceil(($retryAfter->getTimestamp() - time()) / 60);
$this->addFlash('error', sprintf(
'Vous avez atteint la limite de %d messages par heure. Veuillez réessayer dans %d minutes.',
$limit->getLimit(),
$waitTime
));
return $this->redirectToRoute('contact', ['codePays' => $codePays]);
}
// ✅ Vérification du honeypot EN PREMIER
$honeypotWebsite = $form->get('website')->getData();
$companyWebsite = $form->get('company')->getData();
if (!empty($honeypotWebsite) || !empty($companyWebsite)) {
// Spam détecté - on arrête tout de suite
$this->logger->critical('Spam détecté via honeypot', [
'ip' => $request->getClientIp(),
'honeypot_value' => $honeypotWebsite . $companyWebsite
]);
$this->addFlash('success_contact_demande', 'Votre demande est bien envoyée');
return $this->redirectToRoute('contact', ['codePays' => $codePays]);
}
if ($form->isValid() ) {
$data = $form->getData();
$contactezNous->sendMailCreateQuestionUtilisateur($data);
$this->addFlash('success_contact_demande', 'Votre demande est bien envoyée');
} else {
$this->addFlash('error_contact_demande', "Votre demande n'est pas envoyée");
}
}
$metaTitle = "Contactez Fusacq | Experts en Cession & Acquisition d'Entreprises";
$metaDescription = "Besoin d'accompagnement pour votre projet de cession ou acquisition d'entreprise ? L'équipe Fusacq est à votre écoute. Contactez nos experts pour un accompagnement personnalisé.";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
return $this->render('footer_page/contact.html.twig', [
'controller_name' => 'FooterPageController',
'metaTag' => $metaTag,
'form' => $form->createView()
]);
}
/**
* @return Response
*/
public function presse() {
$metaTitle = "Espace Presse Fusacq | Communiqués et actualités fusions-acquisitions";
$metaDescription = "Retrouvez tous les communiqués de presse et l'actualité de Fusacq, plateforme leader des fusions-acquisitions et de la transmission d'entreprise. Contacts presse et ressources média.";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
$response = $this->render('footer_page/presse.html.twig',
[
'controller_name' => 'FooterPageController',
'metaTag' => $metaTag,
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
public function evennements(ClientAPI $api, $codePays) {
$events = $api->getEvenement();
$metaTitle = "Événements Fusacq | Agenda des rendez-vous fusions-acquisitions et reprise d'entreprise";
$metaDescription = "Découvrez tous les événements Fusacq : conférences, webinaires et rencontres dédiés aux fusions-acquisitions, cession, reprise et transmission d'entreprise. Restez informé des prochains rendez-vous.";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
$response = $this->render('footer_page/evennements.html.twig', [
"controller_name" => "FooterPageController",
'metaTag' => $metaTag,
"events" => $events
]);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
public function communiques() {
$response = $this->render('footer_page/communiques.html.twig',
[
'controller_name' => 'FooterPageController'
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* @return Response
*/
public function journalistes() {
$response = $this->render('footer_page/journalistes.html.twig',
[
'controller_name' => 'FooterPageController',
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* @return Response
*/
public function questionsFrequentes() {
$questions = $this->qfm->getAllQuestionsReponses();
return $this->render('footer_page/questions_frequentes.html.twig', [
'controller_name' => 'FooterPageController',
'questions' => $questions,
]);
}
/**
* @return Response
* @throws Exception
*/
public function questionLaSemaine() {
$questions = $this->qsm->getAllQuestionsPublique();
$metaTitle = "Les questions FUSACQ sur la reprise d'entreprise";
$metaDescription = "Les questions FUSACQ sur la reprise d'entreprise";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
return $this->render('footer_page/question_semaine.html.twig', [
'controller_name' => 'FooterPageController',
'questions' => $questions, 'metaTag' => $metaTag,
]);
}
public function getDetailsQuestion($id) {
if (!$id) {
throw $this->createNotFoundException('No Question found for id ' . $id);
}
// Incrémenter le compteur de consultations
try {
$this->qsm->incrementConsultations((int)$id);
} catch (\Exception $e) {
$this->logger->warning('Impossible d\'incrémenter le compteur de consultations', [
'question_id' => $id,
'error' => $e->getMessage(),
]);
}
$question = $this->qsm->getDetailsQuestion($id);
$metaTitle = (!empty($question[0])) ? $question[0]["question"] : "Les questions FUSACQ sur la reprise d'entreprise";
$metaDescription = (!empty($question[0])) ? $question[0]["question"] : "Les questions FUSACQ sur la reprise d'entreprise";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
return $this->render('footer_page/details_question.html.twig', [
'controller_name' => 'FooterPageController',
'question' => $question, 'metaTag' => $metaTag,
]);
}
public function getQuestionResultats(Request $request, $id) {
if (!$id) {
throw $this->createNotFoundException('No Question found for id ' . $id);
}
// Incrémenter le compteur de consultations (même si l'utilisateur répond ou non)
try {
$this->qsm->incrementConsultations((int)$id);
} catch (\Exception $e) {
$this->logger->warning('Impossible d\'incrémenter le compteur de consultations', [
'question_id' => $id,
'error' => $e->getMessage(),
]);
}
if ($request->isMethod('post')) {
$idReponse = $request->get('reponse');
if (!isset($idReponse)) {
throw $this->createNotFoundException('No reponse found for id ' . $idReponse);
}
$this->qsm->insererNouvelleReponse($idReponse);
}
$question = $this->qsm->getDetailsQuestion($id);
$resultats = $this->qsm->getSumNBReponsesByIdQuestion($id);
$metaTitle = (!empty($question[0])) ? "Résultat de la question : " . $question[0]["question"] : "Les questions FUSACQ sur la reprise d'entreprise";
$metaDescription = (!empty($question[0])) ? "Résultat de la question : " . $question[0]["question"] : "Les questions FUSACQ sur la reprise d'entreprise";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
return $this->render('footer_page/question_resultats.html.twig', [
'controller_name' => 'FooterPageController',
'question' => $question, 'resultats' => $resultats, 'metaTag' => $metaTag,
]);
}
/**
* @return Response
*/
public function temoignages() {
$tIntermediaires = $this->tm->getTemoignagesIntermediaires();
$tCedants = $this->tm->getTemoignagesCedants();
$tRepreneurs = $this->tm->getTemoignagesRepreneurs();
return $this->render('footer_page/temoignages.html.twig', [
'controller_name' => 'FooterPageController',
'tIntermediaires' => $tIntermediaires,
'tCedants' => $tCedants,
'tRepreneurs' => $tRepreneurs,
]);
}
/**
* @param $id
* @return mixed
* @throws Exception
*/
public function temoignageDetails($id) {
if (!$id) {
throw $this->createNotFoundException('No Temoignage found for id ' . $id);
}
$temoignage = $this->tm->getTemoignageDetails($id);
$previous = $this->tm->getTemoignagePrecedantMemeCategorie($id, $temoignage['profil']);
$next = $this->tm->getTemoignageSuivantMemeCategorie($id, $temoignage['profil']);
return $this->render('footer_page/temoignage_details.html.twig', [
'controller_name' => 'FooterPageController',
'temoignage' => $temoignage,
'previous' => $previous, 'next' => $next
]);
}
/**
* @return Response
*/
public function premiereVisite() {
$metaTitle = "Reprise d'entreprise, Vente d'entreprise, Transmission d'entreprise, Premiére visite sur Fusacq";
$metaDescription = "Premiére visite sur Fusacq, place de marché Reprise d'entreprise, 2000 annonces de cession d'entreprise, transmission d'entreprise, acquisition d'entreprise, vente et reprise d'entreprise";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
$response = $this->render('footer_page/premiere_visite.html.twig',
[
'controller_name' => 'FooterPageController',
'metaTag' => $metaTag,
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* @param Request $request
* @param $codePays
* @return Response
*/
public function demandeInterm(Request $request, $codePays, TelephoneInternational $telephoneInternational) {
$model = new DemandeInterm();
$form = $this->createForm(DemandeIntermType::class, $model, [
'action' => $this->generateUrl(
$request->attributes->get('_route'),
[
'codePays' => $codePays,
]
),
'method' => 'POST',
]);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$data = $form->getData();
$prenom = Utils::reformatNomPrenom($data->prenom, "prenom");
$nom = Utils::reformatNomPrenom($data->nom, "nom");
$indicatif = $data->indicatif;
$telephone = $data->telephone;
$subject = "Demande d'intermediation, question d'un utilisateur";
$telephoneInternational = $telephoneInternational->getInternationalPhone($telephone, $indicatif)['affichage'];
$varTemplate = [
'prenom' => $prenom,
'nom' => $nom,
'telephone' => $telephoneInternational,
'mail' => $data->email,
'projet_cession' => $data->projet_cession,
'annee_creation' => $data->annee_creation,
'ca' => $data->ca,
'resutltat_net' => $data->resutltat_net,
'nb_collaborateurs' => $data->nb_collaborateurs
];
$this->mailer->sendmail(
Mailer::$senderAdress['notification'],
Mailer::$receiverAdress['mail_damien'],
null,
null,
$subject,
null,
null,
'mails/templates/demande_interm.html.twig',
$varTemplate,
null
);
$this->addFlash('success_demande_interm', "la demande est envoyée avec succès");
} else {
$this->addFlash('error_demande_interm', "lenvoi de la demande a échoué");
}
}
return $this->render('footer_page/premiere_visite_vous_etes/demande_interm.html.twig', [
'controller_name' => 'FooterPageController', 'form' => $form->createView(),
]);
}
/**
* @return Response
*/
public function vousEtesInvestisseur() {
$metaTitle = "Reprise d'entreprise, Vente d'entreprise, Transmission d'entreprise, Premiére visite sur Fusacq";
$metaDescription = "Premiére visite sur Fusacq, place de marché Reprise d'entreprise, 2000 annonces de cession d'entreprise, transmission d'entreprise, acquisition d'entreprise, vente et reprise d'entreprise";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
$response = $this->render('footer_page/premiere_visite_vous_etes/vous_etes_investisseur.html.twig',
[
'controller_name' => 'FooterPageController', 'metaTag' => $metaTag,
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
public function vousEtesCedant() {
$metaTitle = "Reprise d'entreprise, Vente d'entreprise, Transmission d'entreprise, Premiére visite sur Fusacq";
$metaDescription = "Premiére visite sur Fusacq, place de marché Reprise d'entreprise, 2000 annonces de cession d'entreprise, transmission d'entreprise, acquisition d'entreprise, vente et reprise d'entreprise";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
$response = $this->render('footer_page/premiere_visite_vous_etes/vous_etes_cedant.html.twig',
[
'controller_name' => 'FooterPageController', 'metaTag' => $metaTag,
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
public function vousEtesAcquereur() {
$metaTitle = "Reprise d'entreprise, Vente d'entreprise, Transmission d'entreprise, Premiére visite sur Fusacq";
$metaDescription = "Premiére visite sur Fusacq, place de marché Reprise d'entreprise, 2000 annonces de cession d'entreprise, transmission d'entreprise, acquisition d'entreprise, vente et reprise d'entreprise";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
$response = $this->render('footer_page/premiere_visite_vous_etes/vous_etes_acquereur.html.twig',
[
'controller_name' => 'FooterPageController', 'metaTag' => $metaTag,
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
public function vousEtesExpert(Request $request, ContactPubFusacqExpertService $contactPubFusacqExpert, $codePays) {
$model = new ContactPubFusacqExpert();
$form = $this->createForm(ContactPubFusacqExpertType::class, $model, [
'action' => $this->generateUrl(
'vous_etes_expert',
[
'codePays' => $codePays,
]
),
'method' => 'POST',
]);
$form->handleRequest($request);
if ($form->isSubmitted()) {
if ($form->isValid()) {
$data = $form->getData();
$response = $contactPubFusacqExpert->sendMail($data);
if ($response) {
$this->addFlash('success', "votre message est bien envoye");
} else {
$this->addFlash('error', "l'envoi de votre message a echoue");
}
} else {
$this->addFlash('error', "l'envoi de votre message a echoue");
}
}
$metaTitle = "Reprise d'entreprise, Vente d'entreprise, Transmission d'entreprise, Premiére visite sur Fusacq";
$metaDescription = "Premiére visite sur Fusacq, place de marché Reprise d'entreprise, 2000 annonces de cession d'entreprise, transmission d'entreprise, acquisition d'entreprise, vente et reprise d'entreprise";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
$response = $this->render('footer_page/premiere_visite_vous_etes/vous_etes_expert.html.twig',
[
'controller_name' => 'FooterPageController',
'codePays' => $codePays, 'metaTag' => $metaTag,
'form' => $form->createView()
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* @return mixed
*/
public function ouvrages() {
$response = $this->render('footer_page/ouvrages.html.twig',
[
'controller_name' => 'FooterPageController',
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* @return Response
*/
public function plan() {
$response = $this->render('footer_page/plan.html.twig',
[
'controller_name' => 'FooterPageController'
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
/**
* Affiche la page de politique de confidentialité.
*
* Cette méthode génère la page de confidentialité avec les méta-informations optimisées
* pour le SEO et met en place un cache public avec une durée de validité définie.
*
* @return Response La réponse HTTP contenant la page de confidentialité rendue
* avec un cache public d'une durée de 12 heures.
*/
public function confidentialite() {
$metaTitle = "Politique de Confidentialité | Protégez vos données personnelles";
$metaDescription = "Découvrez notre politique de confidentialité transparente. Apprenez comment nous protégeons vos données personnelles, vos droits d'accès et nos engagements pour assurer la sécurité de vos informations.";
$metaTag = $this->metaTag
->setTitle($metaTitle)
->setDescription($metaDescription);
$response = $this->render('footer_page/confidentialite.html.twig',
[
'controller_name' => 'FooterPageController',
'metaTag' => $metaTag,
]
);
$response->setPublic();
$response->setMaxAge(self::MAX_AGE); // 12heures
return $response;
}
}