src/Controller/Page/ApplicantController.php line 203

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Page;
  3. use App\Component\Configuration\Util\Config;
  4. use App\Decorator\ApplicantDecorator as ApplicantFormDecorator;
  5. use App\Entity\Applicant;
  6. use App\Entity\ApplicantForm;
  7. use App\Entity\ApplyWithWhatsapp;
  8. use App\Entity\Recruiter;
  9. use App\Entity\SiteUserData;
  10. use App\Entity\Vacancy;
  11. use App\Event\ApplyWithWhatsappEvent;
  12. use App\Event\GetResponseVacancyEvent;
  13. use App\Event\NewsletterEvent;
  14. use App\Event\VacancyEvents;
  15. use App\Event\VacancyRedirectEvent;
  16. use App\EventListener\FeatureFlagListener;
  17. use App\Form\ApplyWithWhatsappType;
  18. use App\Form\Setting\VacancySettingType;
  19. use App\Model\Tealium\Base;
  20. use App\Renderer\Page as PageRenderer;
  21. use App\Renderer\VacancyRenderer;
  22. use App\Service\ApplicantService;
  23. use App\Service\VacancyService;
  24. use App\Templating\Decorator as ThemeTemplateDecorator;
  25. use App\Transformer\SiteUserDataToApplicantTransformer;
  26. use Doctrine\ORM\EntityManagerInterface;
  27. use Doctrine\ORM\NonUniqueResultException;
  28. use Doctrine\ORM\NoResultException;
  29. use Flagception\Manager\FeatureManagerInterface;
  30. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  31. use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  32. use Symfony\Component\Form\FormError;
  33. use Symfony\Component\Form\FormInterface;
  34. use Symfony\Component\HttpFoundation\JsonResponse;
  35. use Symfony\Component\HttpFoundation\RedirectResponse;
  36. use Symfony\Component\HttpFoundation\Request;
  37. use Symfony\Component\HttpFoundation\RequestStack;
  38. use Symfony\Component\HttpFoundation\Response;
  39. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  40. use Symfony\Component\Routing\Annotation\Route;
  41. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  42. use Twig\Error\LoaderError;
  43. use Twig\Error\RuntimeError;
  44. use Twig\Error\SyntaxError;
  45. #[Route(path'/solliciteren')]
  46. class ApplicantController extends AbstractController
  47. {
  48.     private ApplicantFormDecorator $applicantFormDecorator;
  49.     private PageRenderer $pageRenderer;
  50.     private ThemeTemplateDecorator $themeTemplateDecorator;
  51.     private EventDispatcherInterface $eventDispatcher;
  52.     private ?Request $masterRequest;
  53.     private FeatureManagerInterface $featureManager;
  54.     private VacancyService $vacancyService;
  55.     private ApplicantService $applicantService;
  56.     private SessionInterface $session;
  57.     private Config $config;
  58.     public function __construct(
  59.         ApplicantFormDecorator $applicantFormDecorator,
  60.         PageRenderer $pageRenderer,
  61.         ThemeTemplateDecorator $themeTemplateDecorator,
  62.         EventDispatcherInterface $eventDispatcher,
  63.         RequestStack $requestStack,
  64.         FeatureManagerInterface $featureManager,
  65.         VacancyService $vacancyService,
  66.         ApplicantService $applicantService,
  67.         SessionInterface $session,
  68.         Config $config,
  69.         private readonly ParameterBagInterface $parameterBag,
  70.         private readonly SiteUserDataToApplicantTransformer $siteUserDataTransformer,
  71.     ) {
  72.         $this->applicantFormDecorator $applicantFormDecorator;
  73.         $this->pageRenderer $pageRenderer;
  74.         $this->themeTemplateDecorator $themeTemplateDecorator;
  75.         $this->eventDispatcher $eventDispatcher;
  76.         $this->masterRequest $requestStack->getMainRequest();
  77.         $this->featureManager $featureManager;
  78.         $this->vacancyService $vacancyService;
  79.         $this->applicantService $applicantService;
  80.         $this->session $session;
  81.         $this->config $config;
  82.     }
  83.     /**
  84.      * @throws \Throwable
  85.      */
  86.     #[Route(path'/{id}'name'applicant_apply'requirements: ['id' => '\d+'])]
  87.     public function formAction(int $idRequest $request): RedirectResponse|Response
  88.     {
  89.         if ($request->query->has('async') && $request->query->get('async')) {
  90.             return $this->asyncFormAction($request$id);
  91.         }
  92.         $vacancy $this->getDoctrine()->getRepository(Vacancy::class)->find($idnullnulltrue);
  93.         if (!$vacancy || !$vacancy->canApply()) {
  94.             $this->addFlash('warning''De vacature kan niet worden gevonden');
  95.             return $this->redirectToRoute('vacancies');
  96.         }
  97.         $event = new GetResponseVacancyEvent($vacancy$request);
  98.         $this->eventDispatcher->dispatch($eventVacancyEvents::VACANCY_APPLICATION_INITIALIZE);
  99.         if (null !== $event->getResponse()) {
  100.             return $event->getResponse();
  101.         }
  102.         $applicant = new Applicant();
  103.         $params = ['id' => $id];
  104.         if ($request->query) {
  105.             $params array_merge($request->query->all(), $params);
  106.         }
  107.         $form $this->applicantFormDecorator->getForm(
  108.             $applicant,
  109.             $vacancy,
  110.             $this->generateUrl('vacancy_apply'$params)
  111.         );
  112.         $form->handleRequest($request);
  113.         if ($form->isSubmitted() && $form->isValid()) {
  114.             $applicant->setLocale($request->getLocale());
  115.             $this->applicantFormDecorator->handleForm($form$applicant$vacancy);
  116.             $event = new GetResponseVacancyEvent($vacancy$request);
  117.             $this->eventDispatcher->dispatch($eventVacancyEvents::VACANCY_APPLICATION_COMPLETED);
  118.             return $event->getResponse() ?? $this->applicantService->generateSuccessRedirect(
  119.                 $applicant,
  120.                 $applicant->getVacancy()
  121.             );
  122.         }
  123.         if (!$applicantForm $vacancy->getApplicantForm()) {
  124.             $applicantForm $this->getDoctrine()->getRepository(ApplicantForm::class)
  125.                 ->findOneBy(['default' => true]);
  126.         }
  127.         $response $this
  128.             ->pageRenderer
  129.             ->renderPage(
  130.                 '{vacancy_apply}',
  131.                 $this->themeTemplateDecorator->getTemplate('@default/pages/vacancy_apply.html.twig'),
  132.                 [
  133.                     'applicantForm' => $applicantForm,
  134.                     'applicant' => $applicant,
  135.                     'vacancy' => $vacancy,
  136.                     'form' => $form->createView(),
  137.                 ]
  138.             );
  139.         $response->setSharedMaxAge(0);
  140.         return $response;
  141.     }
  142.     /**
  143.      * @throws NoResultException
  144.      * @throws NonUniqueResultException
  145.      * @throws \JsonException
  146.      */
  147.     #[Route(path'/{id}/modal'name'applicant_apply_modal')]
  148.     public function formModalAction(int $idRequest $requeststring $template '@default/pages/Modal/vacancy_apply_modal.html.twig', ?string $action null, ?string $errorRedirectUrl null): JsonResponse|Response
  149.     {
  150.         if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_CHILD_SITE)) {
  151.             $vacancyRepository $this->getDoctrine()->getManager('parent')->getRepository(Vacancy::class);
  152.             $siteUserRepository $this->getDoctrine()->getManager('parent')->getRepository(SiteUserData::class);
  153.         } else {
  154.             $vacancyRepository $this->getDoctrine()->getRepository(Vacancy::class);
  155.             $siteUserRepository $this->getDoctrine()->getRepository(SiteUserData::class);
  156.         }
  157.         $vacancy $vacancyRepository->find($id);
  158.         $validStrategies = [VacancySettingType::DELETED_STRATEGY_SHOW_WITH_APPLYVacancySettingType::DELETED_STRATEGY_SHOW_WITHOUT_APPLY];
  159.         if (!$vacancy &&
  160.             \in_array($this->config->get('site_vacancy_deleted_vacancy_strategy'), $validStrategiestrue)
  161.         ) {
  162.             $vacancy $vacancyRepository->findDeletedVacancy($id);
  163.         }
  164.         if (!$vacancy) {
  165.             $this->addFlash('warning''De vacature kan niet worden gevonden');
  166.             return new Response('');
  167.         }
  168.         $event = new GetResponseVacancyEvent($vacancy$request);
  169.         $this->eventDispatcher->dispatch($eventVacancyEvents::VACANCY_APPLICATION_INITIALIZE);
  170.         if (!$request->isXmlHttpRequest() && null !== $event->getResponse()) {
  171.             return $event->getResponse();
  172.         }
  173.         $sessionName sprintf('vacancy_%d_application'$id);
  174.         $applicant = new Applicant();
  175.         $applicant->setVacancy($vacancy);
  176.         if ($this->session->has($sessionName)) {
  177.             $applicant $this->session->get($sessionName)['applicant'];
  178.         }
  179.         if ($siteUserData $siteUserRepository->findOneBy([
  180.             'user' => $this->getUser(),
  181.         ])) {
  182.             $applicant $this->siteUserDataTransformer->transform($siteUserData);
  183.             $applicant->setEmail($this->getUser()?->getEmail());
  184.         }
  185.         $form $this->applicantFormDecorator->getForm(
  186.             $applicant,
  187.             $vacancy,
  188.             $action ?? $this->generateUrl('applicant_apply_modal'array_merge(['id' => $id]))
  189.         );
  190.         if ($this->session->has($sessionName)) {
  191.             foreach ($this->session->get($sessionName)['errors'] as $typeName => $error) {
  192.                 if (\is_array($error)) {
  193.                     $error reset($error);
  194.                 }
  195.                 if ($form->has($typeName)) {
  196.                     $form->get($typeName)->addError(new FormError($error));
  197.                 } else {
  198.                     $form->addError(new FormError($error));
  199.                 }
  200.             }
  201.             $this->session->remove($sessionName);
  202.         }
  203.         $form->handleRequest($request);
  204.         if (!$applicantForm $vacancy->getApplicantForm()) {
  205.             $applicantForm $this->getDoctrine()->getRepository(ApplicantForm::class)
  206.                 ->findOneBy(['default' => true]);
  207.         }
  208.         if ($form->isSubmitted()) {
  209.             if ($form->isValid()) {
  210.                 $applicant->setLocale($request->getLocale());
  211.                 $this->processApplicant($form$applicant$vacancy);
  212.                 $event = new GetResponseVacancyEvent($vacancy$request);
  213.                 $this->eventDispatcher->dispatch($eventVacancyEvents::VACANCY_APPLICATION_COMPLETED);
  214.                 if (!$request->isXmlHttpRequest() && null !== $event->getResponse()) {
  215.                     return $event->getResponse();
  216.                 }
  217.                 if ($request->isXmlHttpRequest()) {
  218.                     return new JsonResponse([
  219.                         'redirect' => $this->applicantService->generateSuccessRedirectUrl($applicant$vacancy),
  220.                     ]);
  221.                 }
  222.                 return $this->applicantService->generateSuccessRedirect($applicant$vacancy);
  223.             }
  224.             /** @var Applicant $applicant */
  225.             $applicant $form->getData()
  226.                 ->setCVFile(null)
  227.                 ->setMotivationFile(null);
  228.             $this->session->set($sessionName, [
  229.                 'applicant' => $applicant,
  230.                 'errors' => $this->getErrorsFromForm($form),
  231.             ]);
  232.             if (!$request->isXmlHttpRequest()) {
  233.                 return $errorRedirectUrl $this->redirect($errorRedirectUrl) :
  234.                     $this->redirectToRoute(
  235.                         'vacancy_detail',
  236.                         [
  237.                             'id' => $vacancy->getId(),
  238.                             'slug' => $vacancy->getSlug(),
  239.                             'apply' => 'apply',
  240.                         ]
  241.                     );
  242.             }
  243.         }
  244.         return $this->render(
  245.             $this->themeTemplateDecorator->getTemplate($template),
  246.             [
  247.                 'applicantForm' => $applicantForm,
  248.                 'applicant' => $applicant,
  249.                 'vacancy' => $vacancy,
  250.                 'form' => $form->createView(),
  251.             ]
  252.         );
  253.     }
  254.     /**
  255.      * @throws NoResultException
  256.      * @throws NonUniqueResultException
  257.      * @throws \JsonException
  258.      */
  259.     #[Route(path'/{id}/inline'name'applicant_apply_inline'options: ['expose' => true], requirements: ['id' => '\d+'])]
  260.     public function inlineFormAction(int $idRequest $request): Response
  261.     {
  262.         return $this->formModalAction(
  263.             $id,
  264.             $request,
  265.             '@default/pages/vacancy_apply_inline.html.twig',
  266.             $this->generateUrl('applicant_apply_inline', ['id' => $id])
  267.         );
  268.     }
  269.     #[Route(path'/open/inline'name'applicant_open_apply_inline'options: ['expose' => true])]
  270.     public function inlineOpenFormAction(): Response
  271.     {
  272.         $applicant = new Applicant();
  273.         $form $this->applicantFormDecorator->getOpenForm($applicant$this->generateUrl('applicant_open_apply_inline'));
  274.         if (!$form instanceof FormInterface) {
  275.             throw $this->createNotFoundException();
  276.         }
  277.         return $this->render('@default/pages/vacancy_apply_inline.html.twig', [
  278.             'form' => $form->createView(),
  279.         ]);
  280.     }
  281.     #[Route(path'/inline/send'name'applicant_apply_inline_post'options: ['expose' => true])]
  282.     public function inlineFormPostAction(Request $request): Response
  283.     {
  284.         $vacancy null;
  285.         if ($request->get('id')) {
  286.             $vacancy $this->getDoctrine()->getRepository(Vacancy::class)->find($request->get('id'));
  287.         }
  288.         $applicant = new Applicant();
  289.         $form $this->applicantFormDecorator->getOpenForm($applicant);
  290.         if ($vacancy) {
  291.             $form $this->applicantFormDecorator->getForm(
  292.                 $applicant,
  293.                 $vacancy
  294.             );
  295.         }
  296.         if (!$form) {
  297.             return new JsonResponse([]);
  298.         }
  299.         $form->handleRequest($request);
  300.         if ($form->isSubmitted()) {
  301.             if ($form->isValid()) {
  302.                 $applicant->setLocale($request->getLocale());
  303.                 $this->processApplicant($form$applicant$vacancy);
  304.                 $applicantIdForDatalayer $this->config->get('site_google_show_external_applicant_id') ?
  305.                     $applicant->getExternalId() : $applicant->getId();
  306.                 return new JsonResponse([
  307.                     'success' => true,
  308.                     'applicant_id' => $applicantIdForDatalayer,
  309.                     'applicant_query' => $this->config->get('site_google_applicant_query_name'),
  310.                 ]);
  311.             }
  312.             return new JsonResponse([
  313.                 'success' => false,
  314.                 'error' => 'Form could not be submitted',
  315.                 'validation' => $this->getErrorsFromForm($form),
  316.             ], 500);
  317.         }
  318.         return new JsonResponse([]);
  319.     }
  320.     /**
  321.      * @throws \JsonException
  322.      */
  323.     private function processApplicant(FormInterface $formApplicant $applicant, ?Vacancy $vacancy)
  324.     {
  325.         if ($vacancy) {
  326.             $this->applicantFormDecorator->handleForm($form$applicant$vacancy);
  327.         } else {
  328.             $this->applicantFormDecorator->handleOpenForm($form$applicant);
  329.         }
  330.         if ($this->parameterBag->get('site_newsletter_in_privacy_statement')) {
  331.             $this->eventDispatcher->dispatch(
  332.                 new NewsletterEvent($applicant->getEmail()),
  333.                 NewsletterEvent::REGISTERED
  334.             );
  335.         }
  336.     }
  337.     private function getErrorsFromForm(FormInterface $form): array
  338.     {
  339.         $errors = [];
  340.         foreach ($form->getErrors() as $error) {
  341.             $errors[] = $error->getMessage();
  342.         }
  343.         foreach ($form->all() as $childForm) {
  344.             if (($childForm instanceof FormInterface) && $childErrors $this->getErrorsFromForm($childForm)) {
  345.                 $errors[$childForm->getName()] = $childErrors;
  346.             }
  347.         }
  348.         return $errors;
  349.     }
  350.     /**
  351.      * @throws SyntaxError
  352.      * @throws RuntimeError
  353.      * @throws LoaderError
  354.      */
  355.     public function asyncFormAction(Request $requestint $id): Response
  356.     {
  357.         try {
  358.             $applicantForm $this->applicantService->getAsyncApplicantFormForVacancy($id);
  359.             $vacancyWrapper $this->vacancyService->getVacancyFromRequest($request);
  360.             $vacancy $vacancyWrapper?->vacancy;
  361.         } catch (\Exception) {
  362.             $this->addFlash('warning''Something went wrong');
  363.             return $this->redirectToRoute('vacancy_detail_without_slug', ['id' => $id]);
  364.         }
  365.         $applicant = new Applicant();
  366.         $applicant->setVacancy($vacancy);
  367.         $form $this->applicantFormDecorator->createForm(
  368.             $applicantForm,
  369.             $applicant,
  370.             $this->generateUrl('applicant_apply_modal_async', ['id' => $id]),
  371.             $vacancy
  372.         )->getForm();
  373.         $form->handleRequest($request);
  374.         if ($form->isSubmitted() && $form->isValid()) {
  375.             try {
  376.                 $responseData $this->applicantService->handleForm($request$applicant$vacancy);
  377.                 return $this->redirectToRoute(
  378.                     'vacancy_apply_thanks',
  379.                     [
  380.                         'id' => $vacancy->getId(),
  381.                         $this->config->get('site_google_applicant_query_name') => $responseData['id'],
  382.                     ]
  383.                 );
  384.             } catch (\Exception) {
  385.                 $this->addFlash('warning''Something went wrong');
  386.             }
  387.             return $this->redirectToRoute('vacancy_detail_without_slug', ['id' => $id]);
  388.         }
  389.         return $this
  390.             ->pageRenderer
  391.             ->renderPage(
  392.                 '{vacancy_apply}',
  393.                 $this->themeTemplateDecorator->getTemplate('@default/pages/vacancy_apply.html.twig'),
  394.                 [
  395.                     'applicantForm' => $applicantForm,
  396.                     'applicant' => $applicant,
  397.                     'vacancy' => $vacancy,
  398.                     'form' => $form->createView(),
  399.                 ]
  400.             )->setSharedMaxAge(0);
  401.     }
  402.     #[Route(path'/{id}/async'name'applicant_apply_modal_async')]
  403.     public function asyncFormModalAction(Request $requestint $id): Response
  404.     {
  405.         try {
  406.             $applicantForm $this->applicantService->getAsyncApplicantFormForVacancy($id);
  407.             $vacancyWrapper $this->vacancyService->getVacancyFromRequest($request);
  408.             $vacancy $vacancyWrapper?->vacancy;
  409.         } catch (\Exception) {
  410.             $this->addFlash('warning''Something went wrong');
  411.             return $this->redirectToRoute('vacancy_detail_without_slug', ['id' => $id]);
  412.         }
  413.         $applicant = new Applicant();
  414.         $applicant->setVacancy($vacancy);
  415.         $form $this->applicantFormDecorator->createForm(
  416.             $applicantForm,
  417.             $applicant,
  418.             $this->generateUrl('applicant_apply_modal_async', ['id' => $id]),
  419.             $vacancy
  420.         )->getForm();
  421.         $form->handleRequest($request);
  422.         if ($form->isSubmitted() && $form->isValid()) {
  423.             try {
  424.                 $responseData $this->applicantService->handleForm($request$applicant$vacancy);
  425.                 return $this->redirectToRoute(
  426.                     'vacancy_apply_thanks',
  427.                     [
  428.                         'id' => $vacancy->getId(),
  429.                         $this->config->get('site_google_applicant_query_name') => $responseData['id'],
  430.                     ]
  431.                 );
  432.             } catch (\Exception) {
  433.                 $this->addFlash('warning''Something went wrong');
  434.             }
  435.             return $this->redirectToRoute('vacancy_detail_without_slug', ['id' => $id]);
  436.         }
  437.         return $this->render(
  438.             $this->themeTemplateDecorator->getTemplate('@default/pages/Modal/vacancy_apply_modal.html.twig'),
  439.             [
  440.                 'applicantForm' => $applicantForm,
  441.                 'applicant' => $applicant,
  442.                 'vacancy' => $vacancy,
  443.                 'form' => $form->createView(),
  444.             ]
  445.         );
  446.     }
  447.     /**
  448.      * @throws LoaderError
  449.      * @throws RuntimeError
  450.      * @throws SyntaxError
  451.      */
  452.     #[Route(path'/thanks'name'vacancy_apply_thanks'options: ['expose' => true])]
  453.     public function thanksAction(
  454.         Request $request,
  455.         EntityManagerInterface $entityManager,
  456.         EntityManagerInterface $parentEntityManager,
  457.         VacancyRenderer $vacancyRenderer
  458.     ): Response {
  459.         $applicantId $request->get($this->config->get('site_google_applicant_query_name'));
  460.         if (null === $applicantId) {
  461.             throw $this->createNotFoundException();
  462.         }
  463.         $applicantRepo $entityManager->getRepository(Applicant::class);
  464.         if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_CHILD_SITE)) {
  465.             $applicantRepo $parentEntityManager->getRepository(Applicant::class);
  466.         }
  467.         /** @var Applicant $applicant */
  468.         $applicant $applicantRepo->find($applicantId);
  469.         $vacancyRepo $entityManager->getRepository(Vacancy::class);
  470.         if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_CHILD_SITE)) {
  471.             $vacancyRepo $parentEntityManager->getRepository(Vacancy::class);
  472.         }
  473.         $vacancy null;
  474.         if ($id $request->get('id')) {
  475.             $vacancy $vacancyRepo->find($id);
  476.         }
  477.         if (
  478.             !$vacancy &&
  479.             !empty($this->config->get('site_google_vacancy_query_name')) &&
  480.             $request->query->has($this->config->get('site_google_vacancy_query_name'))
  481.         ) {
  482.             $externalId $request->query->get($this->config->get('site_google_vacancy_query_name'));
  483.             $vacancy $vacancyRepo->findOneBy(['externalId' => $externalId]);
  484.             if (!$vacancy) {
  485.                 $vacancy $vacancyRepo->findOneBy(['externalReference' => $externalId]);
  486.             }
  487.         }
  488.         $recruiter null;
  489.         // Applicant can be null when redirecting from external application
  490.         if ($applicant) {
  491.             $recruiter $this->applicantService->getApplicantOwner($applicant);
  492.         }
  493.         if (!$recruiter) {
  494.             $recruiter $entityManager->getRepository(Recruiter::class)->findOneBy([]);
  495.         }
  496.         $tealium null;
  497.         if ($vacancy && $this->featureManager->isActive(FeatureFlagListener::FEATURE_TEALIUM)) {
  498.             $tealium Base::createForVacancy($vacancy$this->config);
  499.             $tealium->addProperty('job_application_id'$applicant?->getId() ?? $applicantId);
  500.         }
  501.         $multimedia null;
  502.         if ($this->featureManager->isActive(FeatureFlagListener::FEATURE_MULTI_MEDIA)) {
  503.             $multimedia $this->applicantService->getSuccessMultiMedia($vacancy$request->getLocale());
  504.         }
  505.         if ($vacancy instanceof Vacancy) {
  506.             $vacancyRenderer->calculateGallery($vacancy);
  507.         }
  508.         return $this->pageRenderer
  509.             ->renderPage(
  510.                 '{vacancy_apply_thanks}',
  511.                 '@default/pages/vacancy_apply_thanks.html.twig',
  512.                 [
  513.                     'vacancy' => $vacancy,
  514.                     'recruiter' => $recruiter,
  515.                     'applicant' => $applicant,
  516.                     'multimedia' => $multimedia,
  517.                     'e_commerce_script' => $this->applicantService->renderECommerceScript($request$vacancy),
  518.                     'head_end_script' => $this->applicantService->renderHeadEndScriptForVacancyDetail($vacancy),
  519.                     'body_end_script' => $this->applicantService->renderBodyEndScriptForVacancyDetail(),
  520.                 ],
  521.                 [],
  522.                 [],
  523.                 null,
  524.                 null,
  525.                 null,
  526.                 [
  527.                     'tealium_element' => $tealium,
  528.                 ]
  529.             );
  530.     }
  531.     /**
  532.      * @throws LoaderError
  533.      * @throws RuntimeError
  534.      * @throws SyntaxError
  535.      */
  536.     #[Route(path'/'name'applicant_apply_open')]
  537.     public function applyOpenAction(Request $request): Response
  538.     {
  539.         $applicant = new Applicant();
  540.         $form $this->applicantFormDecorator->getOpenForm($applicant$this->generateUrl('applicant_apply_open'));
  541.         if (!$form instanceof FormInterface) {
  542.             throw $this->createNotFoundException();
  543.         }
  544.         $form->handleRequest($request);
  545.         if ($form->isSubmitted() && $form->isValid()) {
  546.             $applicant->setLocale($request->getLocale());
  547.             $this->applicantFormDecorator->handleOpenForm($form$applicant);
  548.             $this->applicantService->generateSuccessRedirect(
  549.                 $applicant
  550.             );
  551.         }
  552.         return $this->pageRenderer
  553.             ->renderPage(
  554.                 '{vacancy_form}',
  555.                 $this->themeTemplateDecorator->getTemplate('@default/pages/vacancy_apply_open.html.twig'),
  556.                 [
  557.                     'applicant' => $applicant,
  558.                     'form' => $form->createView(),
  559.                 ]
  560.             );
  561.     }
  562.     /**
  563.      * @throws \Exception
  564.      */
  565.     public function connexysFormModalAction(int $idRequest $requestEntityManagerInterface $entityManager): Response
  566.     {
  567.         $vacancy $entityManager->getRepository(Vacancy::class)->find($id);
  568.         return $this->render($this->themeTemplateDecorator->getTemplate('@default/pages/Modal/connexys_vacancy_apply_modal.html.twig'), [
  569.             'vacancy' => $vacancy,
  570.         ]);
  571.     }
  572.     /**
  573.      * @throws \Exception
  574.      */
  575.     #[Route(path'/form/connexys-open'name'applicant_connexys_open_modal_snippet')]
  576.     public function connexysOpenFormModalAction(): Response
  577.     {
  578.         return $this->render($this->themeTemplateDecorator->getTemplate('pages/Modal/connexys_vacancy_open_apply_modal.html.twig'));
  579.     }
  580.     /**
  581.      * Middleware for redirects on external url.
  582.      */
  583.     #[Route(path'/redirect/{id}'name'redirect_to_apply')]
  584.     public function externalUrlRedirectAction(Vacancy $vacancy): RedirectResponse
  585.     {
  586.         if (empty($vacancy->getExternalUrl())) {
  587.             return $this->redirectToRoute('vacancy_detail', ['id' => $vacancy->getId(), 'slug' => $vacancy->getSlug()]);
  588.         }
  589.         $this->eventDispatcher->dispatch(new VacancyRedirectEvent($vacancy));
  590.         return $this->redirect($vacancy->getExternalUrl());
  591.     }
  592.     public function connexysPageFormModalAction(EntityManagerInterface $entityManager): Response
  593.     {
  594.         $route $entityManager->getRepository(RouteEntity::class)->findOneBy([
  595.             'name' => $this->masterRequest->get('_route'),
  596.         ]);
  597.         // check if route exists and page exists
  598.         /** @var Page $page */
  599.         if (!$route || !$page $route->getPage()) {
  600.             return new Response('');
  601.         }
  602.         // check if connexys page configuration exists
  603.         if (!$connexysConfiguration $page->getConnexysPageConfiguration()) {
  604.             return new Response('');
  605.         }
  606.         // check if all mandatory attributes are not empty
  607.         if (
  608.             empty($connexysConfiguration->getVacancyTitle())
  609.         ) {
  610.             return new Response('');
  611.         }
  612.         return $this->render($this->themeTemplateDecorator->getTemplate('@default/pages/Modal/connexys_page_vacancy_apply_modal.html.twig'), [
  613.             'originalVacancyId' => $connexysConfiguration->getOriginalVacancyId(),
  614.             'vacancyId' => $connexysConfiguration->getVacancyId(),
  615.             'vacancyTitle' => $connexysConfiguration->getVacancyTitle(),
  616.         ]);
  617.     }
  618.     #[Route(path'/whatsapp_form'name'whatsapp_form'options: ['expose' => true])]
  619.     public function whatsappForm(Request $request): Response
  620.     {
  621.         $applyWithWhatsapp = new ApplyWithWhatsapp();
  622.         $form $this->createForm(ApplyWithWhatsappType::class, $applyWithWhatsapp);
  623.         $form->handleRequest($request);
  624.         if ($form->isSubmitted() && $form->isValid()) {
  625.             $em $this->getDoctrine()->getManager();
  626.             $em->persist($applyWithWhatsapp);
  627.             $em->flush();
  628.             $this->eventDispatcher->dispatch(new ApplyWithWhatsappEvent($applyWithWhatsapp), ApplyWithWhatsappEvent::APPLIED_WITH_WHATSAPP);
  629.             return new Response($this->parameterBag->get('site_apply_with_whatsapp_thanks'));
  630.         }
  631.         return $this->render('form/apply_with_whatsapp.html.twig', [
  632.             'form' => $form->createView(),
  633.         ]);
  634.     }
  635.     #[Route(path'/open-application-embed'name'open_application_embed'options: ['expose' => true])]
  636.     public function openApplicationEmbed(): Response
  637.     {
  638.         return $this->render('api/open_application_embed.html.twig');
  639.     }
  640. }