src/App/Controller/RecurrentJobsShareController.php line 1138

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\ApplicationEvent;
  4. use App\Entity\Blacklisting;
  5. use App\Entity\OccupationalField;
  6. use App\Entity\PlatformSite;
  7. use App\Entity\RecurrentJob;
  8. use App\Entity\User;
  9. use App\Event\RecurrentJobSharePageRequestedEvent;
  10. use App\Event\RecurrentJobWillForwardToExternalUrlEvent;
  11. use App\Event\UserTermsAndConditionsAcceptedEvent;
  12. use App\Repository\ZipcodeCircumcirclesRepository;
  13. use App\Service\AnonymousUserInfoService;
  14. use App\Service\ApplicationEventService;
  15. use App\Service\BlacklistingService;
  16. use App\Service\CaptchaService;
  17. use App\Service\ConversionEventService;
  18. use App\Service\CriteoService;
  19. use App\Service\ExtendedApplication\ExtendedApplicationBaseService;
  20. use App\Service\ExtendedApplication\ExtendedApplicationCustomerService;
  21. use App\Service\FeatureLimitationsService;
  22. use App\Service\RecurrentJobContentDistributionValueService;
  23. use App\Service\RecurrentJobService;
  24. use App\Service\RecurrentJobsSearchService;
  25. use App\Service\RecurrentJobsShareService;
  26. use App\Service\RouterHelperService;
  27. use App\Service\SessionService;
  28. use App\Utility\GuidUtility;
  29. use App\Value\MimeTypes;
  30. use Doctrine\ORM\EntityManagerInterface;
  31. use Exception;
  32. use FOS\UserBundle\Form\Factory\FactoryInterface;
  33. use GuzzleHttp\Exception\GuzzleException;
  34. use JanusHercules\DatawarehouseIntegration\Domain\Entity\BusinessEvent;
  35. use JanusHercules\DatawarehouseIntegration\Domain\Service\BusinessEventDomainService;
  36. use JanusHercules\ExtendedApplicationQuestionnaire\Domain\Service\ExtendedApplicationQuestionsDomainService;
  37. use Knp\Snappy\Pdf;
  38. use Psr\Http\Client\ClientExceptionInterface;
  39. use Psr\Log\LoggerInterface;
  40. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  41. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  42. use Symfony\Component\Form\FormInterface;
  43. use Symfony\Component\HttpFoundation\RedirectResponse;
  44. use Symfony\Component\HttpFoundation\Request;
  45. use Symfony\Component\HttpFoundation\RequestStack;
  46. use Symfony\Component\HttpFoundation\Response;
  47. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  48. use Symfony\Component\Routing\RouterInterface;
  49. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  50. use Symfony\Contracts\Translation\TranslatorInterface;
  51. use Throwable;
  52. class RecurrentJobsShareController extends AbstractController
  53. {
  54. private RecurrentJobsShareService $recurrentJobsShareService;
  55. private EntityManagerInterface $entityManager;
  56. private RequestStack $requestStack;
  57. private SessionService $sessionService;
  58. private EventDispatcherInterface $eventDispatcher;
  59. private LoggerInterface $logger;
  60. private TranslatorInterface $translator;
  61. private RouterHelperService $routerHelperService;
  62. private FactoryInterface $formFactory;
  63. private FeatureLimitationsService $featureLimitationsService;
  64. private ExtendedApplicationBaseService $extendedApplicationBaseService;
  65. private string $routerRequestContextHost;
  66. private string $routerRequestContextScheme;
  67. private string $routerRequestContextBaseUrl;
  68. public function __construct(
  69. RecurrentJobsShareService $recurrentJobsShareService,
  70. EntityManagerInterface $entityManager,
  71. RequestStack $requestStack,
  72. SessionService $sessionService,
  73. EventDispatcherInterface $eventDispatcher,
  74. LoggerInterface $logger,
  75. TranslatorInterface $translator,
  76. RouterHelperService $routerHelperService,
  77. FactoryInterface $formFactory,
  78. FeatureLimitationsService $featureLimitationsService,
  79. ExtendedApplicationBaseService $extendedApplicationBaseService,
  80. string $routerRequestContextHost,
  81. string $routerRequestContextScheme,
  82. string $routerRequestContextBaseUrl
  83. ) {
  84. $this->recurrentJobsShareService = $recurrentJobsShareService;
  85. $this->entityManager = $entityManager;
  86. $this->requestStack = $requestStack;
  87. $this->sessionService = $sessionService;
  88. $this->eventDispatcher = $eventDispatcher;
  89. $this->logger = $logger;
  90. $this->translator = $translator;
  91. $this->routerHelperService = $routerHelperService;
  92. $this->formFactory = $formFactory;
  93. $this->featureLimitationsService = $featureLimitationsService;
  94. $this->extendedApplicationBaseService = $extendedApplicationBaseService;
  95. $this->routerRequestContextHost = $routerRequestContextHost;
  96. $this->routerRequestContextScheme = $routerRequestContextScheme;
  97. $this->routerRequestContextBaseUrl = $routerRequestContextBaseUrl;
  98. }
  99. /**
  100. * @ParamConverter("recurrentJob", class="App\Entity\RecurrentJob", options={"id" = "recurrentJobId"})
  101. *
  102. * @throws Exception
  103. */
  104. public function viewAction(
  105. ?RecurrentJob $recurrentJob,
  106. FeatureLimitationsService $featureLimitationsService,
  107. Request $request,
  108. ZipcodeCircumcirclesRepository $zipcodeCircumcirclesRepository,
  109. AnonymousUserInfoService $anonymousUserInfoService,
  110. ConversionEventService $conversionEventService,
  111. ExtendedApplicationBaseService $extendedApplicationBaseService,
  112. RecurrentJobsSearchService $recurrentJobsSearchService,
  113. ExtendedApplicationQuestionsDomainService $extendedApplicationQuestionsDomainService,
  114. ExtendedApplicationCustomerService $extendedApplicationCustomerService
  115. ) {
  116. /** @var User|null $user */
  117. $user = $this->getUser();
  118. if (!is_null($recurrentJob) && $recurrentJob->getJoboffererProfile()->getUser() === $user) {
  119. return $this->render(
  120. 'recurrent_jobs/share/view.html.twig',
  121. [
  122. 'recurrentJob' => $recurrentJob,
  123. 'recurrentJobBundesland' => $zipcodeCircumcirclesRepository->getBundeslandForRecurrentJob($recurrentJob),
  124. 'showAnonymous' => $featureLimitationsService->userMustSeeRecurrentJobAnonymized($user, $recurrentJob),
  125. 'newConversationMessageSubjectPrefillBase64' => null,
  126. 'newConversationMessageBodyPrefillBase64' => null,
  127. 'isPartOfASearchResultList' => false,
  128. 'highlightedOccupationalField' => $this->getHighlightedOccupationalField($request),
  129. 'additionalFiles' => $recurrentJob->getJoboffererProfile()->getAdditionalFiles(),
  130. 'jobseekerHasAlreadyAppliedViaExtendedApplication' => (
  131. $user->isJobseeker()
  132. && $extendedApplicationBaseService->extendedApplicationFromJobseekerToRecurrentJobAlreadyExists(
  133. $recurrentJob,
  134. $user->getDefaultJobseekerProfile()
  135. )
  136. ),
  137. 'fromSearch' => $request->get('fromSearch')
  138. ]
  139. );
  140. }
  141. $this->eventDispatcher->dispatch(
  142. new RecurrentJobSharePageRequestedEvent(
  143. $recurrentJob,
  144. $user,
  145. $request,
  146. (int)$request->get(ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_CAMPAIGN_ID, -1),
  147. PlatformSite::PLATFORM_SITE_ID_JOBOO
  148. ),
  149. RecurrentJobSharePageRequestedEvent::class
  150. );
  151. if (is_null($recurrentJob) || !$recurrentJob->isActive()) {
  152. $recurrentJobsSearchService->syncRecurrentJobIdWithElasticSearch(
  153. $request->get('recurrentJobId')
  154. );
  155. if (!is_null($recurrentJob)) {
  156. $recurrentJob = $recurrentJobsSearchService->getSimilarActiveRecurrentJob($recurrentJob, $request);
  157. if (is_null($recurrentJob)) {
  158. $this->addFlash(
  159. 'danger',
  160. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  161. );
  162. return $this->redirectToRoute('recurrent_jobs_search.form');
  163. } else {
  164. $this->addFlash(
  165. 'warning',
  166. $this->translator->trans('recurrent_jobs_search.alert_job_inactive_but_alternative')
  167. );
  168. return $this->redirectToRoute('recurrent_jobs.share', array_merge(['recurrentJobId' => $recurrentJob->getId()], $request->query->all()));
  169. }
  170. } else {
  171. $this->addFlash(
  172. 'danger',
  173. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  174. );
  175. return $this->redirectToRoute('recurrent_jobs_search.form');
  176. }
  177. }
  178. if ($request->get('utm_source') === 'google_jobs_apply') {
  179. return $this->redirect(
  180. $this->generateUrl('recurrent_jobs.share',
  181. ['recurrentJobId' => $recurrentJob->getId()]
  182. )
  183. . '?'
  184. . $conversionEventService->getQueryStringParameterForGoalReachedConversionTrackingInitiation(
  185. ConversionEventService::CAMPAIGN_ID_GOOGLE_FOR_JOBS,
  186. 0,
  187. $recurrentJob
  188. )
  189. );
  190. }
  191. if ($this
  192. ->featureLimitationsService
  193. ->recurrentJobAlwaysForwardsToExternalJobPostInsteadOfShowingSharePage($recurrentJob)
  194. ) {
  195. return $this->redirectToRoute(
  196. 'recurrent_jobs.forward_to_external_job_post',
  197. array_merge(['recurrentJobId' => $recurrentJob->getId(), 'directForwarding' => 'true'], $request->query->all())
  198. );
  199. }
  200. $anonymousUserInfoService->setInfoIncomingExternalRecurrentJobsView($recurrentJob);
  201. $ordinaryForm = $this->formFactory->createForm();
  202. $this->sessionService->setRecurrentJobUriToOfferForReturn(
  203. $this->requestStack->getSession(),
  204. $this->routerHelperService->generate(
  205. 'recurrent_jobs.share',
  206. [
  207. 'recurrentJobId' => $recurrentJob->getId(),
  208. 'seo_slug' => ''
  209. ],
  210. UrlGeneratorInterface::ABSOLUTE_URL
  211. )
  212. );
  213. if (!is_null($user)) {
  214. if ($recurrentJob->getStatus() === RecurrentJob::STATUS_ACTIVE
  215. || (
  216. ($recurrentJob->getStatus() === RecurrentJob::STATUS_DRAFT || $recurrentJob->isInactive())
  217. && ($recurrentJob->getJoboffererProfile()->getUser()->getId() === $user->getId())
  218. )
  219. ) {
  220. $form = $this->getExtendedApplicationForm(
  221. $recurrentJob,
  222. $user,
  223. $request,
  224. $extendedApplicationQuestionsDomainService,
  225. $extendedApplicationCustomerService
  226. );
  227. $form = !is_null($form) ? $form->createView() : null;
  228. $conversationMessagePrefill = $this
  229. ->recurrentJobsShareService
  230. ->presetConversationMessage(
  231. $recurrentJob,
  232. $featureLimitationsService,
  233. $user
  234. );
  235. return $this->render(
  236. 'recurrent_jobs/share/view.html.twig',
  237. [
  238. 'recurrentJob' => $recurrentJob,
  239. 'recurrentJobBundesland' => $zipcodeCircumcirclesRepository->getBundeslandForRecurrentJob($recurrentJob),
  240. 'showAnonymous' => $featureLimitationsService->userMustSeeRecurrentJobAnonymized($user, $recurrentJob),
  241. 'newConversationMessageSubjectPrefillBase64' => base64_encode($conversationMessagePrefill['subject']),
  242. 'newConversationMessageBodyPrefillBase64' => base64_encode($conversationMessagePrefill['body']),
  243. 'isPartOfASearchResultList' => false,
  244. 'highlightedOccupationalField' => $this->getHighlightedOccupationalField($request),
  245. 'additionalFiles' => $recurrentJob->getJoboffererProfile()->getAdditionalFiles(),
  246. 'ordinaryRegistrationForm' => $ordinaryForm->createView(),
  247. 'form' => $form,
  248. 'jobseekerHasAlreadyAppliedViaExtendedApplication' => (
  249. $user->isJobseeker()
  250. && $extendedApplicationBaseService->extendedApplicationFromJobseekerToRecurrentJobAlreadyExists(
  251. $recurrentJob,
  252. $user->getDefaultJobseekerProfile()
  253. )
  254. ),
  255. 'fromSearch' => $request->get('fromSearch')
  256. ]
  257. );
  258. } else {
  259. $this->addFlash(
  260. 'danger',
  261. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  262. );
  263. if ($user->isJobseeker()) {
  264. return $this->redirectToRoute('recurrent_jobs_search.form');
  265. } else {
  266. return $this->redirectToRoute('wanted_jobs_search.form');
  267. }
  268. }
  269. } else {
  270. if ($recurrentJob->getStatus() === RecurrentJob::STATUS_ACTIVE) {
  271. $form = $this->getExtendedApplicationForm(
  272. $recurrentJob,
  273. $user,
  274. $request,
  275. $extendedApplicationQuestionsDomainService,
  276. $extendedApplicationCustomerService
  277. );
  278. $form = !is_null($form) ? $form->createView() : null;
  279. return $this->render(
  280. 'recurrent_jobs/share/view.html.twig',
  281. [
  282. 'recurrentJob' => $recurrentJob,
  283. 'recurrentJobBundesland' => $zipcodeCircumcirclesRepository->getBundeslandForRecurrentJob($recurrentJob),
  284. 'showAnonymous' => $featureLimitationsService->userMustSeeRecurrentJobAnonymized($user, $recurrentJob),
  285. 'isPartOfASearchResultList' => false,
  286. 'highlightedOccupationalField' => $this->getHighlightedOccupationalField($request),
  287. 'additionalFiles' => $recurrentJob->getJoboffererProfile()->getAdditionalFiles(),
  288. 'form' => $form,
  289. 'ordinaryRegistrationForm' => $ordinaryForm->createView(),
  290. 'jobseekerHasAlreadyAppliedViaExtendedApplication' => false,
  291. 'anonymousJobSearch' => $request->get('anonymousJobSearch')
  292. ]
  293. );
  294. } else {
  295. if (!is_null($recurrentJob = $recurrentJobsSearchService->getSimilarActiveRecurrentJob($recurrentJob, $request))) {
  296. $this->addFlash(
  297. 'warning',
  298. $this->translator->trans('recurrent_jobs_search.alert_job_inactive_but_alternative')
  299. );
  300. return $this->redirectToRoute('recurrent_jobs.share', array_merge(['recurrentJobId' => $recurrentJob->getId()], $request->query->all()));
  301. } else {
  302. $this->addFlash(
  303. 'danger',
  304. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  305. );
  306. return $this->redirectToRoute('recurrent_jobs_search.form');
  307. }
  308. }
  309. }
  310. }
  311. /**
  312. * @ParamConverter("recurrentJob", class="App\Entity\RecurrentJob", options={"id" = "recurrentJobId"})
  313. *
  314. * @throws Exception
  315. */
  316. public function requestedFromSearchResultAction(
  317. ?RecurrentJob $recurrentJob,
  318. Request $request,
  319. RecurrentJobContentDistributionValueService $recurrentJobContentDistributionValueService
  320. ) {
  321. if (is_null($recurrentJob)) {
  322. $this->addFlash(
  323. 'danger',
  324. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  325. );
  326. return $this->redirectToRoute('recurrent_jobs_search.form');
  327. }
  328. $customer = null;
  329. if ($recurrentJob->isLinkedToExternalPartner() && !is_null($recurrentJob->getIntegratedExternalPartnerCustomer())) {
  330. $customer = $recurrentJob->getIntegratedExternalPartnerCustomer();
  331. }
  332. if (
  333. $this->featureLimitationsService->recurrentJobAlwaysForwardsToExternalJobPostInsteadOfShowingSharePage($recurrentJob)
  334. || (!is_null($customer)
  335. && $customer->hasClickBasedBilling()
  336. && $this->featureLimitationsService->recurrentJobMustLinkExternally($recurrentJob))
  337. ) {
  338. return $this->redirectToRoute(
  339. 'recurrent_jobs.forward_to_external_job_post',
  340. array_merge(['recurrentJobId' => $recurrentJob->getId(), 'directForwarding' => 'true'], $request->query->all())
  341. );
  342. } else {
  343. return $this->redirectToRoute(
  344. 'recurrent_jobs.share',
  345. array_merge(['recurrentJobId' => $recurrentJob->getId(), 'directForwarding' => 'true', 'fromSearch' => true], $request->query->all())
  346. );
  347. }
  348. }
  349. /**
  350. * @ParamConverter("recurrentJob", class="App\Entity\RecurrentJob", options={"id" = "recurrentJobId"})
  351. *
  352. * @throws Exception
  353. */
  354. public function viewOrForwardAction(
  355. ?RecurrentJob $recurrentJob,
  356. Request $request,
  357. FeatureLimitationsService $featureLimitationsService,
  358. RouterInterface $router
  359. ): Response {
  360. if (is_null($recurrentJob)) {
  361. $this->addFlash(
  362. 'danger',
  363. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  364. );
  365. return $this->redirect(
  366. $this->routerRequestContextScheme . '://'
  367. . $this->routerRequestContextHost
  368. . $this->routerRequestContextBaseUrl
  369. . $router->generate(
  370. 'recurrent_jobs_search.form'
  371. )
  372. );
  373. }
  374. $ctaTypeId = null;
  375. if (!is_null($request->get('ctaTypeId'))) {
  376. $ctaTypeId = (int)$request->get('ctaTypeId');
  377. }
  378. if ($recurrentJob->belongsToIntegratedExternalPartnerCustomer()
  379. && $featureLimitationsService->recurrentJobMustLinkExternally($recurrentJob)
  380. && $recurrentJob->getIntegratedExternalPartnerCustomer()->isDirectForwarded()
  381. ) {
  382. /* This action is available under multiple routes, one for each of our platform sites:
  383. * - joboo (recurrent_jobs.view_or_forward)
  384. * - recruit (recruit_dl.recurrent_jobs.view_or_forward)
  385. * - jobooOnline (joboo_online.recurrent_jobs.view_or_forward)
  386. *
  387. * Because each platform site is made available under its own top level domain,
  388. * a problem arises if we redirect from, say recruit-dl.de to joboo.de:
  389. *
  390. * The initial visit is to recruit-dl.de, and the application starts a new PHP session
  391. * for the visiting client. The session id is stored in a cookie, but the cookie is
  392. * only valid for the recruit-dl.de domain.
  393. *
  394. * Under this session, certain tracking mechanisms take place, e.g. its stored
  395. * that for a Conversion Tracking campaign, steps 0 and 1 have occured.
  396. *
  397. * This prepares the system to track the goal reached (step 2) conversion event.
  398. *
  399. * However, if we then redirect the client to joboo.de, the session cookie is not
  400. * valid for this domain, and the client will start a new session.
  401. *
  402. * This new session will not have the tracking information from the previous session,
  403. * and accordingly, the goal reached conversion event will not be tracked.
  404. *
  405. * Therefore, we need to identify the platform site that the client is currently on,
  406. * and use the redirect route for that platform site, while avoiding a top-level domain change
  407. * during redirection.
  408. */
  409. $platformSiteId = PlatformSite::getPlatformSiteIdByRequest($request);
  410. if ($platformSiteId === PlatformSite::PLATFORM_SITE_ID_RECRUIT_DL) {
  411. $routename = 'recruit_dl.external_partners.forward_to_external_job_post';
  412. } elseif ($platformSiteId === PlatformSite::PLATFORM_SITE_ID_JOBOO_ONLINE) {
  413. $routename = 'joboo_online.external_partners.forward_to_external_job_post';
  414. } else {
  415. $routename = 'recurrent_jobs.forward_to_external_job_post';
  416. }
  417. return $this->redirect(
  418. $router->generate(
  419. $routename,
  420. array_merge(
  421. [
  422. 'recurrentJobId' => $recurrentJob->getId(),
  423. 'directForwarding' => 'true',
  424. 'ctaTypeId' => $ctaTypeId
  425. ],
  426. $request->query->all()
  427. )
  428. )
  429. );
  430. }
  431. return $this->redirect(
  432. $this->routerRequestContextScheme . '://'
  433. . $this->routerRequestContextHost
  434. . $this->routerRequestContextBaseUrl
  435. . $router->generate(
  436. 'recurrent_jobs.share',
  437. array_merge(['recurrentJobId' => $recurrentJob->getId()], $request->query->all())
  438. )
  439. );
  440. }
  441. /**
  442. * @ParamConverter("recurrentJob", class="App\Entity\RecurrentJob", options={"id" = "recurrentJobId"})
  443. *
  444. * @throws Exception
  445. */
  446. public function viewOrForwardEbayAction(?RecurrentJob $recurrentJob, Request $request, ConversionEventService $conversionEventService)
  447. {
  448. if (is_null($recurrentJob)) {
  449. $this->addFlash(
  450. 'danger',
  451. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  452. );
  453. return $this->redirectToRoute('recurrent_jobs_search.form');
  454. }
  455. $ctaTypeId = null;
  456. if (!is_null($request->get('ctaTypeId'))) {
  457. $ctaTypeId = (int)$request->get('ctaTypeId');
  458. }
  459. if ($recurrentJob->belongsToIntegratedExternalPartnerCustomer() && $recurrentJob->getIntegratedExternalPartnerCustomer()->isDirectForwardedEbay()) {
  460. return $this->redirectToRoute('recurrent_jobs.forward_to_external_job_post', array_merge(['recurrentJobId' => $recurrentJob->getId(), 'directForwarding' => 'true', 'ctyTypeId' => $ctaTypeId], $request->query->all()));
  461. }
  462. return $this->redirectToRoute('recurrent_jobs.share', array_merge(['recurrentJobId' => $recurrentJob->getId()], $request->query->all()));
  463. }
  464. /**
  465. * @ParamConverter("recurrentJob", class="App\Entity\RecurrentJob", options={"id" = "recurrentJobId"})
  466. */
  467. public function viewOrForwardKleinanzeigenAction(?RecurrentJob $recurrentJob, Request $request)
  468. {
  469. if (is_null($recurrentJob)) {
  470. $this->addFlash(
  471. 'danger',
  472. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  473. );
  474. return $this->redirectToRoute('recurrent_jobs_search.form');
  475. }
  476. return $this->redirectToRoute('recurrent_jobs.view_or_forward_ebay', array_merge(['recurrentJobId' => $recurrentJob->getId(), ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_CAMPAIGN_ID => ConversionEventService::CAMPAIGN_ID_EBAY, ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_SUBCAMPAIGN_ID => (int)$request->get('variante', 0)], $request->query->all()));
  477. }
  478. public function extendedApplicationThanksAction(Request $request, EntityManagerInterface $entityManager, CriteoService $criteoService)
  479. {
  480. $relatedRecurrentJobId = $criteoService->getLastSuccessfullCriteoConversionForUserid($request->get('userId', null));
  481. $showTalentPixel = $request->get('showTalentPixel');
  482. /** @var User $user */
  483. $user = $entityManager->find(User::class, $request->get('userId'));
  484. return $this->render(
  485. 'extended_application/thanks.html.twig',
  486. [
  487. 'user' => $user,
  488. 'recurrentJobId' => $relatedRecurrentJobId,
  489. 'showTalentPixel' => $showTalentPixel,
  490. 'confirmationNecessary' => !(!is_null($user) && $user->isEnabled()),
  491. ]
  492. );
  493. }
  494. /**
  495. * @ParamConverter("recurrentJob", class="App\Entity\RecurrentJob", options={"id" = "recurrentJobId"})
  496. *
  497. * @throws Exception
  498. */
  499. public function handleExtendedApplicationAction(
  500. Request $request,
  501. ?RecurrentJob $recurrentJob,
  502. CaptchaService $captchaService,
  503. ZipcodeCircumcirclesRepository $zipcodeCircumcirclesRepository,
  504. ExtendedApplicationBaseService $extendedApplicationBaseService,
  505. ApplicationEventService $applicationEventService,
  506. BlacklistingService $blacklistingService,
  507. ExtendedApplicationQuestionsDomainService $extendedApplicationQuestionsDomainService,
  508. ExtendedApplicationCustomerService $extendedApplicationCustomerService
  509. ): RedirectResponse|Response {
  510. try {
  511. if (is_null($recurrentJob)) {
  512. $this->addFlash(
  513. 'danger',
  514. $this->translator->trans('recurrent_jobs_search.alert_job_inactive')
  515. );
  516. return $this->redirectToRoute('recurrent_jobs_search.form');
  517. }
  518. /** @var ?User $user */
  519. $user = $this->getUser();
  520. $formOptions = [
  521. 'cvForExtendedApplicationsMandatory' => (!is_null($this->getUser())
  522. && !is_null($recurrentJob->getIntegratedExternalPartnerCustomer())
  523. && $recurrentJob->getIntegratedExternalPartnerCustomer()->cvForExtendedApplicationsMandatory()),
  524. 'phoneNumberForExtendedApplicationsMandatory' => $extendedApplicationBaseService->phoneNumberForExtendedApplicationsMandatory($recurrentJob),
  525. 'extendedApplicationQuestions' => $extendedApplicationQuestionsDomainService->getActiveExtendedApplicationQuestionsForRecurrentJob($recurrentJob),
  526. 'user' => $user,
  527. 'isJoboo' => true,
  528. 'showTertiaryCvFile' => $extendedApplicationCustomerService->extendedApplicationForRecurrentJobMustShowTertiaryCvFile($recurrentJob),
  529. 'tertiaryCvFileConfig' => $extendedApplicationCustomerService->getTertiaryCvFileUploadFieldConfigurationForRecurrentJob($recurrentJob)
  530. ];
  531. $jobseekerProfile = !is_null($user) ? $user->getDefaultJobseekerProfile() : null;
  532. if (!is_null($jobseekerProfile) && !empty($jobseekerProfile->getDocumentFileName())) {
  533. $formOptions['defaultCVFileName'] = $jobseekerProfile->getDocumentFileName();
  534. }
  535. $form = $this->recurrentJobsShareService->getExtendedApplicationForm($formOptions)->handleRequest($request);
  536. $ordinaryForm = $this->formFactory->createForm();
  537. $renderParameters = [
  538. 'recurrentJob' => $recurrentJob,
  539. 'additionalFiles' => $recurrentJob->getJoboffererProfile()->getAdditionalFiles(),
  540. 'recurrentJobBundesland' => $zipcodeCircumcirclesRepository->getBundeslandForRecurrentJob($recurrentJob),
  541. 'showAnonymous' => true,
  542. 'isPartOfASearchResultList' => false,
  543. 'highlightedOccupationalField' => $this->getHighlightedOccupationalField($request),
  544. 'form' => $form->createView(),
  545. 'ordinaryRegistrationForm' => $ordinaryForm->createView()
  546. ];
  547. if ($form->isSubmitted() && $form->isValid()) {
  548. if (is_null($this->getUser()) && !$captchaService->requestContainsValidCaptchaSolution($request)) {
  549. $renderParameters['errorMessage'] = $this->translator->trans('recurrent_jobs_search.alert_application_captcha_error');
  550. $applicationEventService->writeNewEvent(
  551. ApplicationEvent::EVENT_CATEGORY_ERROR,
  552. ApplicationEvent::EVENT_TYPE_CAPTCHA_RETURNED_ERROR,
  553. $this->getUser(),
  554. null,
  555. null,
  556. json_encode(['url' => $request->getUri()])
  557. );
  558. return $this->render(
  559. 'recurrent_jobs/share/view.html.twig',
  560. $renderParameters
  561. );
  562. }
  563. $useDefaultDocument = false;
  564. if (isset($form['useDefaultDocument']) && !empty($form->get('useDefaultDocument')->getData())) {
  565. $useDefaultDocument = $form->get('useDefaultDocument')->getData();
  566. }
  567. $usePrimaryUploadedFile = isset($form['useUploadedPrimaryFile'])
  568. && !empty($form->get('useUploadedPrimaryFile')->getData())
  569. && $form->get('useUploadedPrimaryFile')->getData();
  570. $uploadedPrimaryCvFile = null;
  571. if ($usePrimaryUploadedFile || $useDefaultDocument) {
  572. $uploadedPrimaryCvFile = $this
  573. ->recurrentJobsShareService
  574. ->getUploadedFile(
  575. $request,
  576. 'primaryCvFile',
  577. $useDefaultDocument ? $jobseekerProfile->getDocumentFileName() : null
  578. );
  579. }
  580. if (!is_null($uploadedPrimaryCvFile)) {
  581. if (!in_array($uploadedPrimaryCvFile->getMimeType(), MimeTypes::ALLOWED_FOR_USER_UPLOAD_EXTENDED_APPLICATION)) {
  582. $renderParameters['errorMessage'] = $this->translator->trans('recurrent_jobs_search.alert_application_mimetype_error', ['%mimetype' => $uploadedPrimaryCvFile->getMimeType()]);
  583. return $this->render(
  584. 'recurrent_jobs/share/view.html.twig',
  585. $renderParameters,
  586. new Response(null, Response::HTTP_BAD_REQUEST)
  587. );
  588. }
  589. }
  590. $useSecondaryUploadedFile = isset($form['useUploadedSecondaryFile'])
  591. && !empty($form->get('useUploadedSecondaryFile')->getData())
  592. && $form->get('useUploadedSecondaryFile')->getData();
  593. $uploadedSecondaryCvFile = null;
  594. if ($useSecondaryUploadedFile) {
  595. $uploadedSecondaryCvFile = $this
  596. ->recurrentJobsShareService
  597. ->getUploadedFile($request, 'secondaryCvFile');
  598. }
  599. if (!is_null($uploadedSecondaryCvFile)) {
  600. if (!in_array($uploadedSecondaryCvFile->getMimeType(), MimeTypes::ALLOWED_FOR_USER_UPLOAD_ALL)) {
  601. $renderParameters['errorMessage'] = $this->translator->trans('recurrent_jobs_search.alert_application_mimetype_error', ['%mimetype' => $uploadedSecondaryCvFile->getMimeType()]);
  602. return $this->render(
  603. 'recurrent_jobs/share/view.html.twig',
  604. $renderParameters,
  605. new Response(null, Response::HTTP_BAD_REQUEST)
  606. );
  607. }
  608. }
  609. $useTertiaryUploadedFile = isset($form['useUploadedTertiaryFile'])
  610. && !empty($form->get('useUploadedTertiaryFile')->getData())
  611. && $form->get('useUploadedTertiaryFile')->getData();
  612. $uploadedTertiaryCvFile = null;
  613. if ($useTertiaryUploadedFile) {
  614. $uploadedTertiaryCvFile = $this
  615. ->recurrentJobsShareService
  616. ->getUploadedFile($request, 'tertiaryCvFile');
  617. }
  618. if (!is_null($uploadedTertiaryCvFile)) {
  619. if (!in_array($uploadedTertiaryCvFile->getMimeType(), MimeTypes::ALLOWED_FOR_USER_UPLOAD_ALL)) {
  620. $renderParameters['errorMessage'] = $this->translator->trans('recurrent_jobs_search.alert_application_mimetype_error', ['%mimetype' => $uploadedTertiaryCvFile->getMimeType()]);
  621. return $this->render(
  622. 'recurrent_jobs/share/view.html.twig',
  623. $renderParameters,
  624. new Response(null, Response::HTTP_BAD_REQUEST)
  625. );
  626. }
  627. }
  628. if ($blacklistingService->isEmailBlacklistedForType(
  629. trim(
  630. mb_strtolower($form->getData()->getEmail())
  631. ),
  632. Blacklisting::BLACKLISTING_TYPE_REGISTRATION
  633. )) {
  634. $renderParameters['errorMessage'] = 'Leider kannst du dich nicht über JOBOO!® bewerben. Kontaktiere uns gerne, falls hier ein Fehler vorliegt unter info@joboo.de';
  635. return $this->render(
  636. 'recurrent_jobs/share/view.html.twig',
  637. $renderParameters
  638. );
  639. }
  640. if (!is_null($user = $this->entityManager
  641. ->getRepository(User::class)
  642. ->findOneBy(['email' => trim(mb_strtolower($form->getData()->getEmail()))]))
  643. && $this->extendedApplicationBaseService->extendedApplicationFromJobseekerToRecurrentJobAlreadyExists(
  644. $recurrentJob,
  645. $user->getDefaultJobseekerProfile()
  646. )
  647. ) {
  648. $renderParameters['errorMessage'] = 'Du hast dich auf diesen Job bereits beworben. Es gibt noch viele andere interessante Jobs auf JOBOO!®';
  649. return $this->render(
  650. 'recurrent_jobs/share/view.html.twig',
  651. $renderParameters
  652. );
  653. }
  654. if (is_null($form->getData()->getFirstname())
  655. || is_null($form->getData()->getLastname())
  656. || is_null($form->getData()->getEmail())
  657. || (is_null($form->getData()->getPhone())
  658. && $extendedApplicationBaseService->phoneNumberForExtendedApplicationsMandatory($recurrentJob)
  659. )
  660. ) {
  661. $renderParameters['errorMessage'] = 'Bitte fülle alle Pflichtfelder der Bewerbung aus.';
  662. return $this->render(
  663. 'recurrent_jobs/share/view.html.twig',
  664. $renderParameters,
  665. new Response(null, Response::HTTP_BAD_REQUEST)
  666. );
  667. }
  668. if (is_null($request->get(ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_CAMPAIGN_ID))
  669. || !in_array(
  670. (int)$request->get(ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_CAMPAIGN_ID),
  671. ConversionEventService::AVAILABLE_CAMPAIGN_IDS_FOR_INCOMING_TRAFFIC
  672. )
  673. ) {
  674. $campaignId = null;
  675. } else {
  676. $campaignId = (int)$request->get(ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_CAMPAIGN_ID);
  677. }
  678. $extendedApplication = $extendedApplicationBaseService->handleNewExtendedApplication(
  679. $form->getData(),
  680. $recurrentJob,
  681. $uploadedPrimaryCvFile,
  682. $uploadedSecondaryCvFile,
  683. $uploadedTertiaryCvFile,
  684. $this->getUser(),
  685. $request,
  686. $campaignId,
  687. User::CREATED_VIA_JOBOO_RECURRENT_JOB_LANDINGPAGE,
  688. PlatformSite::PLATFORM_SITE_ID_JOBOO,
  689. $form
  690. );
  691. if (is_null($user)) {
  692. $user = $extendedApplication->getJobseekerProfile()?->getUser();
  693. }
  694. if ($form->has('termsAndConditionsAccepted') && !is_null($user) && $form->get('termsAndConditionsAccepted')->getData()) {
  695. $this->eventDispatcher->dispatch(
  696. new UserTermsAndConditionsAcceptedEvent(
  697. $user,
  698. $recurrentJob
  699. ),
  700. UserTermsAndConditionsAcceptedEvent::class
  701. );
  702. }
  703. if (!is_null($this->getUser())) {
  704. $this->addFlash('success', 'Deine Bewerbung wurde erfolgreich abgeschickt');
  705. return $this->redirectToRoute(
  706. 'recurrent_jobs.share',
  707. array_merge(
  708. ['recurrentJobId' => $recurrentJob->getId()],
  709. $request->query->all()
  710. ),
  711. Response::HTTP_SEE_OTHER
  712. );
  713. } else {
  714. return $this->redirectToRoute(
  715. 'recurrent_jobs.share.extended_application.thanks',
  716. [
  717. 'userId' => $extendedApplication->getJobseekerProfile()->getUser()->getId(),
  718. 'showTalentPixel' => ((int)$request->get(ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_CAMPAIGN_ID) === ConversionEventService::CAMPAIGN_ID_TALENTCOM)
  719. ],
  720. Response::HTTP_SEE_OTHER
  721. );
  722. }
  723. } else {
  724. $renderParameters['errorMessage'] = $this->translator->trans('recurrent_jobs_search.alert_application_unknown_error');
  725. return $this->render(
  726. 'recurrent_jobs/share/view.html.twig',
  727. $renderParameters
  728. );
  729. }
  730. } catch (Throwable $t) {
  731. $this->logger->error($t->getMessage());
  732. $this->addFlash(
  733. 'danger',
  734. $this->translator->trans('recurrent_jobs_search.alert_application_unknown_error')
  735. );
  736. return $this->redirectToRoute('recurrent_jobs_search.form');
  737. }
  738. }
  739. public function removeTrailingSlashAction(Request $request)
  740. {
  741. return $this->redirect(
  742. $this->recurrentJobsShareService->removeTrailingSlash($request),
  743. Response::HTTP_MOVED_PERMANENTLY
  744. );
  745. }
  746. /** @throws Exception */
  747. public function generatePrintTemplateFromRecurrentJobAction(string $recurrentJobId, Pdf $pdf, ConversionEventService $conversionEventService): Response
  748. {
  749. /** @var RecurrentJob $recurrentJob */
  750. $recurrentJob = $this->entityManager->find(RecurrentJob::class, $recurrentJobId);
  751. if (is_null($recurrentJob)) {
  752. throw new Exception('No recurrent job found for id ' . $recurrentJobId . '.');
  753. }
  754. $html = $this->renderView('recurrent_jobs/print_template.html.twig', [
  755. 'recurrentJob' => $recurrentJob
  756. ]);
  757. $pdf->setOption('enable-local-file-access', true);
  758. $pdf->setOption('lowquality', false);
  759. $pdf->setOption('encoding', 'UTF-8');
  760. $pdf->setOption('margin-top', 5);
  761. $pdf->setOption('margin-right', 5);
  762. $pdf->setOption('margin-bottom', 5);
  763. $pdf->setOption('margin-left', 5);
  764. $content = $pdf->getOutputFromHtml($html);
  765. $response = new Response();
  766. $response->headers->set('Content-Type', 'application/pdf');
  767. $response->headers->set(
  768. 'Content-Disposition',
  769. 'attachment;filename="'
  770. . mb_substr(
  771. urlencode(
  772. $recurrentJob->getBusinessName()
  773. . '-'
  774. . $recurrentJob->getOccupationalFieldSearchterm()
  775. . '-'
  776. . $recurrentJob->getZipcode()
  777. . '-'
  778. . $recurrentJob->getCity()
  779. ),
  780. 0,
  781. 251
  782. )
  783. . '.pdf"'
  784. );
  785. $response->setContent($content);
  786. $conversionEventService->handleConversionGoalReached(ConversionEventService::CAMPAIGN_ID_RECURRENT_JOBS_TO_PRINT_INFO_MAIL);
  787. return $response;
  788. }
  789. /**
  790. * @throws Exception
  791. */
  792. private function getExtendedApplicationForm(
  793. RecurrentJob $recurrentJob,
  794. ?User $user,
  795. ?Request $request,
  796. ExtendedApplicationQuestionsDomainService $extendedApplicationQuestionsDomainService,
  797. ExtendedApplicationCustomerService $extendedApplicationCustomerService
  798. ): ?FormInterface {
  799. $extendedApplication = $this->extendedApplicationBaseService->prefillForm($user);
  800. $jobseekerProfile = $extendedApplication->getJobseekerProfile();
  801. if ($this->featureLimitationsService->recurrentJobMustDisplayExtendedApplicationForm($recurrentJob, $user)) {
  802. $formOptions = [
  803. 'method' => Request::METHOD_POST,
  804. 'action' => $this->generateUrl(
  805. 'recurrent_jobs.share.extended_application.handle',
  806. array_merge(
  807. $request->query->all(),
  808. [
  809. 'recurrentJobId' => $recurrentJob->getId(),
  810. ]
  811. )
  812. ),
  813. 'cvForExtendedApplicationsMandatory' => (!is_null($this->getUser()) && !is_null($recurrentJob->getIntegratedExternalPartnerCustomer()) && $recurrentJob->getIntegratedExternalPartnerCustomer()->cvForExtendedApplicationsMandatory()),
  814. 'phoneNumberForExtendedApplicationsMandatory' => $this->extendedApplicationBaseService->phoneNumberForExtendedApplicationsMandatory($recurrentJob),
  815. 'extendedApplicationQuestions' => $extendedApplicationQuestionsDomainService->getActiveExtendedApplicationQuestionsForRecurrentJob($recurrentJob),
  816. 'isJoboo' => true,
  817. 'user' => $user,
  818. 'showTertiaryCvFile' => $extendedApplicationCustomerService->extendedApplicationForRecurrentJobMustShowTertiaryCvFile($recurrentJob),
  819. 'tertiaryCvFileConfig' => $extendedApplicationCustomerService->getTertiaryCvFileUploadFieldConfigurationForRecurrentJob($recurrentJob)
  820. ];
  821. if (!is_null($jobseekerProfile) && !empty($jobseekerProfile->getDocumentFileName())) {
  822. $formOptions['defaultCVFileName'] = $jobseekerProfile->getDocumentFileName();
  823. }
  824. return $this->recurrentJobsShareService->getExtendedApplicationForm($formOptions, $extendedApplication);
  825. }
  826. return null;
  827. }
  828. private function getHighlightedOccupationalField(Request $request): ?string
  829. {
  830. return !is_null($request->get('highlightedOccupationalFieldId', null))
  831. ? $this->entityManager->find(OccupationalField::class, (int)$request->get('highlightedOccupationalFieldId', null))
  832. : null;
  833. }
  834. /** @throws Exception */
  835. public function forwardToJobPostThatIsRecurrentJobAction(
  836. Request $request,
  837. string $recurrentJobId,
  838. EntityManagerInterface $entityManager,
  839. RecurrentJobService $recurrentJobService,
  840. EventDispatcherInterface $eventDispatcher,
  841. RouterHelperService $routerHelperService,
  842. TranslatorInterface $translator,
  843. ConversionEventService $conversionEventService,
  844. BusinessEventDomainService $businessEventDomainService,
  845. FeatureLimitationsService $featureLimitationsService
  846. ): Response {
  847. if ($request->get('isMobileAppRequest') === true) {
  848. $user = $entityManager->getRepository(User::class)->find($request->get('userId'));
  849. } else {
  850. /** @var ?User $user */
  851. $user = $this->getUser();
  852. }
  853. GuidUtility::validOrThrow($recurrentJobId);
  854. /** @var RecurrentJob $recurrentJob * */
  855. $recurrentJob = $entityManager->getRepository(RecurrentJob::class)->find($recurrentJobId);
  856. $disableForwardingPage = $request->get('disableDirectForwardingPage', false);
  857. if (is_null($recurrentJob)) {
  858. $this->logger->info(
  859. "Tried to forward to job post that is recurrent job with id '$recurrentJobId', but the recurrent job not exist."
  860. );
  861. return new Response(null, Response::HTTP_NOT_FOUND);
  862. }
  863. if (!$recurrentJob->isActive()) {
  864. return $this->redirect($routerHelperService->generate(
  865. 'recurrent_jobs.share',
  866. ['recurrentJobId' => $recurrentJob->getId()]
  867. ));
  868. }
  869. if (!is_null($request->get(ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_CAMPAIGN_ID))
  870. && !is_null($request->get(ConversionEventService::QUERY_STRING_PARAM_NAME_CONVERSION_SUBCAMPAIGN_ID))
  871. && !is_null($request->get('initiateConversionTracking'))
  872. && $request->get('initiateConversionTracking')
  873. ) {
  874. $conversionEventService->initiateGoalReachedConversionTrackingBasedOnRequest($request);
  875. }
  876. $conversionEventService->handleRequest($request);
  877. $conversionEventService->handleConversionGoalReached(ConversionEventService::CAMPAIGN_ID_INTEGRATED_EXTERNAL_PARTNER_CUSTOMER_PREMIUM_RADAR, 0, $request, $user, $recurrentJob);
  878. $context = null;
  879. if (!is_null($premiumRadarContext = $request->get('premiumRadarContext'))) {
  880. $businessEventDomainService->writeNewEvent(BusinessEvent::EVENT_TYPE_INTEGRATED_EXTERNAL_PARTNER_CUSTOMER_PREMIUM_RADAR_LINK_CLICKED, $user, $recurrentJob, null, json_encode(['premiumRadarContext' => $premiumRadarContext, 'externalPartnerForwarding' => 'false', 'relatedWantedJobId' => $request->get('relatedWantedJobId')]));
  881. $context = 'premiumRadar';
  882. }
  883. if (is_null($context)) {
  884. $context = $request->get('request');
  885. }
  886. $conversionCampaignId = null;
  887. if (!is_null($request->get('__ggctci'))) {
  888. $conversionCampaignId = (int)$request->get('__ggctci');
  889. }
  890. $platformSiteId = PlatformSite::PLATFORM_SITE_ID_JOBOO;
  891. if (!is_null($request->get('platformSite'))) {
  892. if (in_array((int)$request->get('platformSite'), PlatformSite::AVAILABLE_PLATFORM_IDS)) {
  893. $platformSiteId = (int)$request->get('platformSite');
  894. }
  895. }
  896. $ctaTypeId = null;
  897. if (!is_null($request->get('ctaTypeId'))) {
  898. $ctaTypeId = (int)$request->get('ctaTypeId');
  899. }
  900. if ($recurrentJobService->recurrentJobMustLinkToSharePage(
  901. $recurrentJob,
  902. $conversionCampaignId,
  903. $platformSiteId,
  904. $ctaTypeId)) {
  905. if ($this
  906. ->featureLimitationsService
  907. ->recurrentJobAlwaysForwardsToExternalJobPostInsteadOfShowingSharePage($recurrentJob)
  908. ) {
  909. throw new Exception("Impossible situation: recurrent job '{$recurrentJob->getId()}' must link to share page AND always forwards to external job post instead of showing share page.");
  910. }
  911. return $this->redirect($routerHelperService->generate(
  912. 'recurrent_jobs.share',
  913. array_merge(['recurrentJobId' => $recurrentJob->getId()], $request->query->all())
  914. ));
  915. }
  916. $redirectUrl = $recurrentJobService->getExternalRedirectUrlToBeForwardedTo($recurrentJob, $user, $conversionCampaignId, $platformSiteId, $ctaTypeId);
  917. if (is_null($redirectUrl) || $redirectUrl === '') {
  918. $this->addFlash('danger', $translator->trans('external_partners.forwarding_impossible'));
  919. return $this->redirect($routerHelperService->generate(
  920. 'recurrent_jobs.share',
  921. array_merge(['recurrentJobId' => $recurrentJob->getId()], $request->query->all())
  922. ));
  923. } else {
  924. if (!is_null($request->get('conversionCampaignId'))) {
  925. if (in_array((int)$request->get('conversionCampaignId'), ConversionEventService::AVAILABLE_CAMPAIGN_IDS_FOR_INCOMING_TRAFFIC)) {
  926. $conversionCampaignId = (int)$request->get('conversionCampaignId');
  927. }
  928. }
  929. try {
  930. if ($featureLimitationsService->userNeedsToSeeCaptchaBeforeForwardingToExternalJoboffer(
  931. $request,
  932. $conversionCampaignId
  933. )) {
  934. $businessEventDomainService->writeNewEvent(
  935. BusinessEvent::EVENT_TYPE_USER_SEES_CAPTCHA_PAGE_BEFORE_FORWARDING,
  936. $user,
  937. $recurrentJob
  938. );
  939. return $this->render(
  940. 'recurrent_jobs/forwarding_page_captcha.html.twig',
  941. [
  942. 'urlToForwardTo' => $this->routerHelperService->generate(
  943. 'recurrent_jobs.forward_to_external_job_post',
  944. array_merge(
  945. $request->query->all(),
  946. [
  947. 'recurrentJobId' => $recurrentJobId
  948. ]
  949. )
  950. )
  951. ]
  952. );
  953. }
  954. } catch (GuzzleException|ClientExceptionInterface $e) {
  955. return $this->redirect($routerHelperService->generate(
  956. 'recurrent_jobs.share',
  957. array_merge(['recurrentJobId' => $recurrentJob->getId()], $request->query->all())
  958. ));
  959. }
  960. $eventDispatcher->dispatch(
  961. new RecurrentJobWillForwardToExternalUrlEvent(
  962. $recurrentJob,
  963. $user,
  964. $context,
  965. $request,
  966. $conversionCampaignId,
  967. $platformSiteId
  968. ),
  969. RecurrentJobWillForwardToExternalUrlEvent::class
  970. );
  971. $redirectUrl = mb_ereg_replace('utm_source=j2w', 'utm_source=DEJoboo', $redirectUrl);
  972. if (!$this->featureLimitationsService->recurrentJobMustAttachJobooUtmParameterToExternalForwardingUrl($recurrentJob)) {
  973. $redirectUrl = mb_ereg_replace('\?utm_source=joboo&', '?', $redirectUrl);
  974. $redirectUrl = mb_ereg_replace('\?utm_source=joboo', '', $redirectUrl);
  975. $redirectUrl = mb_ereg_replace('&utm_source=joboo', '', $redirectUrl);
  976. }
  977. if ($disableForwardingPage) {
  978. return $this->redirect($redirectUrl);
  979. } else {
  980. return $this->render(
  981. 'recurrent_jobs/forwarding_page.html.twig',
  982. [
  983. 'urlToForwardTo' => $redirectUrl
  984. ]
  985. );
  986. }
  987. }
  988. }
  989. /**
  990. * @throws \Doctrine\DBAL\Exception
  991. */
  992. public function showRecurrentJobsBelongingToJobooGmbhAction(RecurrentJobService $recurrentJobService): Response
  993. {
  994. $recurrentJobIds = $recurrentJobService->findAllRecurrentJobsBelongingToJobooGmbh();
  995. $recurrentJobsToDisplay = [];
  996. foreach ($recurrentJobIds as $recurrentJobId) {
  997. /** @var RecurrentJob $recurrentJob */
  998. $recurrentJob = $this->entityManager->find(RecurrentJob::class, $recurrentJobId);
  999. if (!is_null($recurrentJob) && $recurrentJobService->recurrentJobBelongingToJobooGmbHCanGetDisplayed($recurrentJob)) {
  1000. $recurrentJobsToDisplay[] = $recurrentJob;
  1001. }
  1002. }
  1003. return $this->render(
  1004. '/recurrent_jobs/recurrent_jobs_belonging_to_joboo_gmbh.html.twig',
  1005. [
  1006. 'recurrentJobs' => $recurrentJobsToDisplay
  1007. ]
  1008. );
  1009. }
  1010. }