<?php
namespace App\Controller\Front\LandingPage;
use App\Entity\Prospect;
use App\Form\ProspectStepType;
use App\Form\ProspectType;
use App\Form\StoreChoiceType;
use App\Repository\BlogPostRepository;
use App\Repository\FreelancerRepository;
use App\Repository\HearingBrandRepository;
use App\Service\ProspectService;
use Doctrine\ORM\EntityManager;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Exception\ORMException;
use Doctrine\ORM\OptimisticLockException;
use Psr\Log\LoggerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\Routing\Annotation\Route;
class LandingPageController extends AbstractProspectCreationController
{
// array contains LP path ['url' => 'template_path']
protected array $lpTemplatePaths = [
'solution-acouphene' => 'front_v4/mca/landing_page/prospect/index_acq_acouphene.html.twig',
'demande-de-bilan-1' => 'front_v4/mca/landing_page/prospect/index_acq_seo.html.twig',
'mon-bilan-auditif' => 'front_v4/mca/landing_page/prospect/index_acq_seo.html.twig',
'demande-de-bilan-2' => 'front_v4/mca/landing_page/prospect/index_acq_seo.html.twig',
'demande-de-bilan-3' => 'front_v4/mca/landing_page/prospect/index_acq_seo.html.twig',
'demande-de-bilan-4' => 'front_v4/mca/landing_page/prospect/index_acq_seo.html.twig',
'eml_acq_wstep' => 'front_v4/mca/landing_page/prospect/index_acq_seo.html.twig',
'mon-essai-gratuit' => 'front_v4/mca/landing_page/prospect/index_free_try.html.twig',
'demande-de-bilan-auditif-depistage' => 'front_v4/mca/landing_page/prospect/acq_native/index_acq_native_1.html.twig',
'demande-de-bilan-auditif-depistage-conversation' => 'front_v4/mca/landing_page/prospect/acq_native/index_acq_native_2.html.twig',
'demande-de-bilan-auditif-depistage-son-television' => 'front_v4/mca/landing_page/prospect/acq_native/index_acq_native_3.html.twig',
'demande-de-bilan-auditif-depistage-environnement-bruyant' => 'front_v4/mca/landing_page/prospect/acq_native/index_acq_native_4.html.twig',
'appareils-totalement-rembourses' => 'front_v4/mca/landing_page/prospect/index_free_hearing_aid.html.twig',
'sante-pour-tous' => 'front_v4/mca/landing_page/prospect/index_acq_campaign_sms.html.twig',
];
/**
* Méthode appelée lorsqu'un prospect valide le form d'une lp
*
* @Route("/success/{id}", name="lp_form_success")
*
* @param BlogPostRepository $blogPostRepository
* @param Prospect $prospect
* @param string $origin // route d'où est émise la requete
* @return Response
*/
public function landingPageSuccess(BlogPostRepository $blogPostRepository, Prospect $prospect, string $origin = "default"): Response
{
$pos = $prospect->getProspectsOnStore()->last();
$store = $pos->getStore();
return $this->render("front_v4/mca/landing_page/prospect/form_success.html.twig", [
'store' => $store,
'prospect' => $prospect,
'pos_id' => empty($pos) ? null : $pos->getId(),
'origin' => $origin . '-success',
'blogPosts' => $blogPostRepository->getLastedArticle(),
'is_freelancer' => $store->getAdministrator()->isFreelancer()
]);
}
/**
* @param Request $request
* @param EntityManager $entityManager
* @param LoggerInterface $logger
* @param HearingBrandRepository $hearingBrandRepository
* @param FreelancerRepository $freelancerRepository
* @return Response
* @throws OptimisticLockException
* @throws ORMException
*/
public function landingPageShow(Request $request, EntityManagerInterface $entityManager, LoggerInterface $logger, HearingBrandRepository $hearingBrandRepository, FreelancerRepository $freelancerRepository): Response
{
// with url get path of template
$pathInfo = $request->getPathInfo();
$templatePath = $this->lpTemplatePaths[ltrim($pathInfo, '/')];
if (empty($templatePath)) {
throw $this->createNotFoundException();
}
$logger->info('get prospect from landing page path : ' . $pathInfo);
$prospect = new Prospect();
$this->prefiledProspectWithGetParam($request, $prospect);
$prospectForm = $this->createForm(ProspectType::class, $prospect);
$prospectForm->handleRequest($request);
if ($prospectForm->isSubmitted() && $prospectForm->isValid()) {
$this->get("security.csrf.token_manager")->refreshToken("prospect_token");
// already TYPE_CHECKUP on landing page
$prospect->setRequest(Prospect::TYPE_CHECKUP);
// create a prospect or redirect to a specific page if duplicate has been found
$redirection = $this->createProspectOrRedirect($prospect);
// apply redirection if one is returned
if (!is_null($redirection)) {
return $redirection;
}
$entityManager->flush();
// redirect to success page
return $this->redirectToSuccessPage($prospect, $pathInfo);
}
return $this->render($templatePath, [
'formProspect' => $prospectForm->createView(),
'hearingBrands' => $hearingBrandRepository->findBy(['presentable' => true]),
'freelancers' => $freelancerRepository->getOnlyWithLogo(),
]);
}
/**
* @Route("/demande-de-bilan-auditif-gratuit", name="index_acquisition_step", methods={"GET", "POST"})
* @param Request $request
* @param LoggerInterface $logger
* @param EntityManagerInterface $entityManager
* @return Response
*/
public function landingPageStepShow(Request $request, LoggerInterface $logger, EntityManagerInterface $entityManager): Response
{
$logger->info('get prospect from landing page path : indexAcquisitionStep');
$prospect = new Prospect();
$this->prefiledProspectWithGetParam($request, $prospect);
$prospectForm = $this->createForm(ProspectStepType::class, $prospect);
$prospectForm->handleRequest($request);
if ($prospectForm->isSubmitted() && $prospectForm->isValid()) {
$this->get("security.csrf.token_manager")->refreshToken("prospect_token");
// already TYPE_CHECKUP on landing page
$prospect->setRequest(Prospect::TYPE_CHECKUP);
// patch for Google API postal code
if (empty($prospect->getPostalcode())) {
$logger->info('Google APi can\'t get postalcode');
$prospect->setPostalcode('00000');
}
// create a prospect or redirect to a specific page if duplicate has been found
$redirection = $this->createProspectOrRedirect($prospect);
// apply redirection if one is returned
if (!is_null($redirection)) {
return $redirection;
}
$entityManager->flush();
// redirect to success page
return $this->redirectToSuccessPage($prospect, 'index_acquisition_step');
}
return $this->render('front_v4/mca/landing_page/prospect/index_acq_step.html.twig', [
'formProspect' => $prospectForm->createView()
]);
}
/**
* Hearing Test redirect to another LP (test scoring hearing online)
* @Route("/test-auditif", name="index_hearing_test", methods={"GET", "POST"})
* @param LoggerInterface $logger
* @return Response
*/
public function indexHearingTest(LoggerInterface $logger): Response
{
$logger->info('Landing page path : indexHearingTest');
return $this->render('front_v4/mca/landing_page/prospect/index_hearing_test.html.twig');
}
/**
* LP with choice store from user
* @Route("/trouver-votre-centre-auditif", name="index_lp_choice", methods={"GET", "POST"})
* @param Request $request
* @param LoggerInterface $logger
* @param HearingBrandRepository $hearingBrandRepository
* @param FreelancerRepository $freelancerRepository
* @param SessionInterface $session
* @return Response
*/
public function landingPageStoreChoice(
Request $request,
LoggerInterface $logger,
HearingBrandRepository $hearingBrandRepository,
FreelancerRepository $freelancerRepository,
SessionInterface $session
): Response
{
$logger->info('get prospect from LP Store Choice path : indexLpChoicePrefill');
$prospect = new Prospect();
$this->prefiledProspectWithGetParam($request, $prospect);
$prospectForm = $this->createForm(ProspectType::class, $prospect);
$prospectForm->handleRequest($request);
if ($prospectForm->isSubmitted() && $prospectForm->isValid()) {
$this->get("security.csrf.token_manager")->refreshToken("prospect_token");
// already TYPE_CHECKUP on landing page
$prospect->setRequest(Prospect::TYPE_CHECKUP);
// patch for Google API postal code
if (empty($prospect->getPostalcode())) {
$logger->info('Google APi can\'t get postalcode');
$prospect->setPostalcode('00000');
}
// store prospect date in session (persist after choosing store)
$session->set('prospect_data', $prospect);
// Store choice redirection
return $this->redirectToRoute('store_choice');
}
return $this->render('front_v4/mca/landing_page/prospect/index_acq_seo.html.twig', [
'formProspect' => $prospectForm->createView(),
'hearingBrands' => $hearingBrandRepository->findBy(['presentable' => true]),
'freelancers' => $freelancerRepository->getOnlyWithLogo(),
]);
}
/**
* Store Choice
* @Route("/store-choice", name="store_choice", methods={"GET", "POST"})
*/
public function storeChoice(
Request $request,
LoggerInterface $logger,
EntityManagerInterface $entityManager,
HearingBrandRepository $hearingBrandRepository,
FreelancerRepository $freelancerRepository,
ProspectService $prospectService,
SessionInterface $session
): Response
{
$logger->info('Store choice for prospect data.');
// get prospect data form session
$prospect = $session->get('prospect_data');
if (!$prospect) {
throw $this->createNotFoundException('No prospect data found in session.');
}
$searchResultStores = $prospectService->pickStoresBelongingToADifferentAdmin($prospect, 5);
if (empty($searchResultStores)) {
$logger->info('No stores available for the given prospect.');
return $this->render('front_v4/mca/landing_page/prospect/index_store_choice.html.twig', [
'noStoreAvailable' => true,
'searchResultStores' => $searchResultStores,
'prospect' => $prospect,
'hearingBrands' => $hearingBrandRepository->findBy(['presentable' => true]),
'freelancers' => $freelancerRepository->getOnlyWithLogo(),
]);
}
$storeForm = $this->createForm(StoreChoiceType::class, null, ['stores' => $searchResultStores]);
$storeForm->handleRequest($request);
if ($storeForm->isSubmitted() && $storeForm->isValid()) {
$selectedStore = $storeForm->get('store')->getData();
// create a prospect or redirect to a specific page if duplicate has been found
$redirection = $this->createProspectOrRedirect($prospect, $selectedStore->getStore());
// apply redirection if one is returned
if (!is_null($redirection)) {
return $redirection;
}
$entityManager->flush();
// redirect to success page
return $this->redirectToSuccessPage($prospect, 'index_acquisition_step');
}
// return a page with store list
return $this->render('front_v4/mca/landing_page/prospect/index_store_choice.html.twig', [
'storeForm' => $storeForm->createView(),
'searchResultStores' => $searchResultStores,
'prospect' => $prospect,
'hearingBrands' => $hearingBrandRepository->findBy(['presentable' => true]),
'freelancers' => $freelancerRepository->getOnlyWithLogo(),
]);
}
}