src/Controller/PageController.php line 22

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\FormPageInterface;
  4. use App\Entity\Lead;
  5. use App\Entity\PageInterface;
  6. use App\Form\LeadType;
  7. use App\Message\FacebookPageViewConversionMessage;
  8. use App\Repository\LeadRepository;
  9. use App\Repository\PageRepository;
  10. use App\Service\SiteManager;
  11. use App\Service\CookieConsentCookieManager;
  12. use Doctrine\Persistence\ManagerRegistry;
  13. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  14. use Symfony\Component\HttpFoundation\Request;
  15. use Symfony\Component\HttpFoundation\RequestStack;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\Messenger\MessageBusInterface;
  18. use Symfony\Component\Routing\Annotation\Route;
  19. class PageController extends AbstractController
  20. {
  21.     private const UPLOAD_DIR 'uploads';
  22.     protected SiteManager $siteManager;
  23.     protected Request $request;
  24.     public function __construct(SiteManager $siteManagerRequestStack $requestStack) {
  25.         $this->siteManager $siteManager;
  26.         $this->request $requestStack->getCurrentRequest();
  27.     }
  28.     public function __invoke(PageInterface $contentDocumentManagerRegistry $doctrinePageRepository $pageRepositoryLeadRepository $leadRepositoryMessageBusInterface $bus): Response
  29.     {
  30.         $page $contentDocument;
  31.         $isPost $this->request->isMethod('POST');
  32.         if ($isPost) {
  33.             // Forward API requests to a dedicated controller.
  34.             $submittedData $this->request->request->all();
  35.             $submittedToken $submittedData['_token'] ?? null;
  36.             if (!isset($submittedData['_token'])) {
  37.                 // We assume a submission without CSRF protection is a signed API request.
  38.                 $response $this->forward('App\Controller\ApiController', [
  39.                     'contentDocument' => $contentDocument,
  40.                     'managerRegistry' => $doctrine,
  41.                     'pageRepository' => $pageRepository,
  42.                     'leadRepository' => $leadRepository,
  43.                     'messageBusInterface' => $bus,
  44.                     'request' => $this->request,
  45.                 ]);
  46.                 return $response;
  47.             }
  48.         }
  49.         if (!$page) {
  50.             throw $this->createNotFoundException('The page does not exist');
  51.         }
  52.         if (!$page->isPublished() && null === $this->getUser()) {
  53.             throw $this->createAccessDeniedException('The page does not exist');
  54.         }
  55.         // Prepare templates variables.
  56.         $queryParams $this->request->query->all();
  57.         $templateBasePath self::UPLOAD_DIR.'/'.$page->getFilesystemPath().DIRECTORY_SEPARATOR;
  58.         // Manage forms.
  59.         if ($page instanceof FormPageInterface) {
  60.             $formConfig $page->getFormConfig();
  61.             // Deny access to the form page if no email field is defined and no query param. defines it neither.
  62.             if (!isset($formConfig['email']) && !isset($queryParams['email']) && !isset($queryParams['mail'])) {
  63.                 throw $this->createNotFoundException('This page does not exist');
  64.             }
  65.             // Start managing form submission.
  66.             if ($isPost) {
  67.                 // Submissions can be validated though a CSRF token,
  68.                 // or, if programmatically posted, via a computed sihgnature.
  69.                 $validSubmission FALSE;
  70.                 // Manually verify the CSRF token.
  71.                 // https://symfony.com/doc/current/security/csrf.html#generating-and-checking-csrf-tokens-manually
  72.                 if ($submittedToken && $this->isCsrfTokenValid($page->getMachineName(), $submittedToken)) {
  73.                     unset($submittedData['_token']);
  74.                     $validSubmission true;
  75.                 }
  76.                 if ($validSubmission) {
  77.                     // Instanciate and start populate a Lead.
  78.                     $lead = new Lead;
  79.                     $lead->setFormPage($page);
  80.                     $lead->setQueryParams($queryParams);
  81.                     $cookies $this->request->cookies->all();
  82.                     $cookies array_filter($cookies, function($key) {
  83.                         return in_array($key, ['CookieConsent']);
  84.                     }, ARRAY_FILTER_USE_KEY);
  85.                     if (!empty($cookies['CookieConsent'])) {
  86.                         $cookies['CookieConsent'] = CookieConsentCookieManager::parse($cookies['CookieConsent']);
  87.                     }
  88.                     $lead->setCookies($cookies);
  89.                     $form $this->createForm(LeadType::class, $lead, [
  90.                         'config' => $page->getFormConfig(),
  91.                         'data_class' => Lead::class,
  92.                     ]);
  93.                     $form->submit($submittedData);
  94.                     // Validate form values.
  95.                     if ($form->isSubmitted() && $form->isValid()) {
  96.                         // Manage duplicates.
  97.                         $email $lead->getEmail();
  98.                         if (!$email || ($email && !$clone $leadRepository->findDuplicate($email))) {
  99.                             $entityManager $doctrine->getManager();
  100.                             $entityManager->persist($lead);
  101.                             $entityManager->flush();
  102.                         }
  103.                         // Render the conformation template.
  104.                         return $this->render($templateBasePath.$page->getConfirmationTemplateFilename(), [
  105.                             'lead' => $clone ?? $lead,
  106.                             'page' => $page,
  107.                             'query_params' => $lead->getQueryParams(),
  108.                         ]);
  109.                     }
  110.                 }
  111.             }
  112.             $config $page->getConfig()->getFacebook();
  113.             $accessToken $config->getAccessToken();
  114.             $pixelId $config->getPixelId();
  115.             if ($accessToken && $pixelId) {
  116.                 $bus->dispatch(new FacebookPageViewConversionMessage(
  117.                     $page->getId(),
  118.                     $accessToken,
  119.                     $pixelId,
  120.                     $this->request->getClientIp(),
  121.                     $this->request->headers->get('User-Agent'),
  122.                     $this->request->query->get('fbclid'),
  123.                     $this->request->cookies->get('_fbp')
  124.                 ));
  125.             }
  126.         }
  127.         // Render the page template.
  128.         return $this->render($templateBasePath.$page->getTemplateFilename(), [
  129.             'page' => $page,
  130.             'query_params' => $queryParams,
  131.         ]);
  132.     }
  133. }