src/App/Controller/WantedJobsSearchController.php line 66

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Blacklisting;
  4. use App\Entity\CarryThroughData;
  5. use App\Entity\ConversationMessage\ConversationMessage;
  6. use App\Entity\DebuggingInfoBag;
  7. use App\Entity\RecurrentJob;
  8. use App\Entity\SeoTranslationParameters;
  9. use App\Entity\UsageEvent;
  10. use App\Entity\User;
  11. use App\Entity\WantedJob;
  12. use App\Entity\WantedJobsSearch\WantedJobsSearchParameters;
  13. use App\Entity\WantedJobsSearch\WantedJobsSearchResult;
  14. use App\Entity\WantedJobsSearch\WantedJobsSearchResultset;
  15. use App\Event\SearchForWantedJobsStartedEvent;
  16. use App\Event\SearchtermEnteredEvent;
  17. use App\Exception\UncallableSearchPageException;
  18. use App\Exception\UnknownZipcodeException;
  19. use App\Form\WantedJobsSearchParametersType;
  20. use App\Repository\ZipcodeCircumcirclesRepository;
  21. use App\Service\AnonymousUserInfoService;
  22. use App\Service\BlacklistingService;
  23. use App\Service\CircuitbreakerService;
  24. use App\Service\DebuggingService;
  25. use App\Service\FeatureFlagService;
  26. use App\Service\FeatureLimitationsService;
  27. use App\Service\Membership\MembershipService;
  28. use App\Service\NotificationService;
  29. use App\Service\ProfileBlocksService;
  30. use App\Service\RegistrationService;
  31. use App\Service\SessionService;
  32. use App\Service\UsageEventService;
  33. use App\Service\WantedJobsSearchService;
  34. use App\Value\GeneralApplicationSettingsValue;
  35. use App\Value\PossibleAvailabilitiesValue;
  36. use App\Value\ZipcodeRadiusesValue;
  37. use Doctrine\ORM\EntityManagerInterface;
  38. use Exception;
  39. use FOS\UserBundle\Form\Factory\FactoryInterface;
  40. use JanusHercules\DatawarehouseIntegration\Domain\Entity\BusinessEvent;
  41. use JanusHercules\DatawarehouseIntegration\Domain\Service\BusinessEventDomainService;
  42. use Monolog\Logger;
  43. use Psr\Log\LoggerInterface;
  44. use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
  45. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  46. use Symfony\Component\HttpFoundation\JsonResponse;
  47. use Symfony\Component\HttpFoundation\RedirectResponse;
  48. use Symfony\Component\HttpFoundation\Request;
  49. use Symfony\Component\HttpFoundation\Response;
  50. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  51. use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
  52. use Symfony\Contracts\Translation\TranslatorInterface;
  53. class WantedJobsSearchController extends AbstractController implements DoAdditionalUserChecksControllerInterface
  54. {
  55. use SearchControllerHelper;
  56. public function __construct(
  57. private readonly FeatureFlagService $featureFlagService
  58. ) {
  59. }
  60. /** @throws Exception */
  61. public function formAction(
  62. Request $request,
  63. TranslatorInterface $translator,
  64. SessionService $sessionService,
  65. SessionInterface $session,
  66. FeatureLimitationsService $featureLimitationsService,
  67. WantedJobsSearchService $wantedJobsSearchService
  68. ): Response {
  69. /** @var User $user */
  70. $user = $this->getUser();
  71. if ($user instanceof User && $user->isJobseeker()) {
  72. $this->addFlash(
  73. 'info',
  74. $translator->trans('wanted_jobs_search.alert_jobseekers_not_allowed')
  75. );
  76. return $this->redirectToRoute('recurrent_jobs_search.form');
  77. }
  78. $formPrefillZipcode = '';
  79. if ($user instanceof User && $user->isJobofferer()) {
  80. $formPrefillZipcode = $user->getDefaultJoboffererProfile()->getZipcode() ?? '';
  81. }
  82. $formPrefillOccupationalFieldSearchterm = '';
  83. if ($request->get('occupationalFieldSearchterm')) {
  84. $formPrefillOccupationalFieldSearchterm = $request->get('occupationalFieldSearchterm');
  85. }
  86. $wantedJobsSearchParameters = new WantedJobsSearchParameters(
  87. $formPrefillOccupationalFieldSearchterm,
  88. $formPrefillZipcode,
  89. ZipcodeRadiusesValue::ALL[1],
  90. WantedJob::EXPERIENCE_NONE
  91. );
  92. $sessionService->resetProfileIdsForMultiMessageSelection($session);
  93. $form = $this->createForm(
  94. WantedJobsSearchParametersType::class,
  95. $wantedJobsSearchParameters,
  96. [
  97. 'action' => $this->generateUrl('wanted_jobs_search.results') . '#results',
  98. 'method' => 'GET'
  99. ]
  100. );
  101. $joboffererProfileCanEditZipcodeForWantedJobsSearch = true;
  102. $joboffererProfileId = null;
  103. if (!is_null($user) && !is_null($user->getDefaultJoboffererProfile())) {
  104. $joboffererProfileCanEditZipcodeForWantedJobsSearch = $featureLimitationsService->joboffererProfileCanEditZipcodeForWantedJobsSearch($user->getDefaultJoboffererProfile());
  105. $joboffererProfileId = $user->getDefaultJoboffererProfile()->getId();
  106. }
  107. $response = $this->render('/wanted_jobs_search/form.html.twig', [
  108. 'form' => $form->createView(),
  109. 'waitingInfo' => $wantedJobsSearchService->getWaitingInfo($user),
  110. 'joboffererProfileCanEditZipcodeForWantedJobsSearch' => $joboffererProfileCanEditZipcodeForWantedJobsSearch,
  111. 'joboffererProfileId' => $joboffererProfileId,
  112. 'limitedInSearch' => !is_null($user) && !is_null($user->getDefaultJoboffererProfile()) ? $user->getDefaultJoboffererProfile()->isLimitedInSearch() : false
  113. ]
  114. );
  115. $response->setVary('Cookie');
  116. $response->setSharedMaxAge(60);
  117. return $response;
  118. }
  119. public function profileSelectionForMultipleMessageAddApiAction(
  120. Request $request,
  121. SessionService $sessionService,
  122. SessionInterface $session
  123. ): Response {
  124. if ($request->getMethod() === Request::METHOD_OPTIONS) {
  125. return new Response('', Response::HTTP_NO_CONTENT, ['Allow' => 'OPTIONS, POST']);
  126. }
  127. if (!is_null($request->get('jobseekerProfileId'))) {
  128. $sessionService->addProfileIdForMultiMessageSelection($session, $request->get('jobseekerProfileId'));
  129. }
  130. return new Response('', Response::HTTP_NO_CONTENT);
  131. }
  132. public function profileSelectionForMultipleMessageDeleteApiAction(
  133. Request $request,
  134. SessionService $sessionService,
  135. SessionInterface $session
  136. ): Response {
  137. if ($request->getMethod() !== Request::METHOD_DELETE) {
  138. return new Response('', Response::HTTP_NO_CONTENT, ['Allow' => 'DELETE']);
  139. }
  140. if (!is_null($request->get('jobseekerProfileId'))) {
  141. $sessionService->deleteProfileIdForMultiMessageSelection($session, $request->get('jobseekerProfileId'));
  142. }
  143. return new Response('', Response::HTTP_NO_CONTENT);
  144. }
  145. public function profileSelectionForMultipleMessageGetApiAction(
  146. Request $request,
  147. SessionService $sessionService,
  148. SessionInterface $session
  149. ): Response {
  150. if ($request->getMethod() === Request::METHOD_OPTIONS) {
  151. return new Response('', Response::HTTP_NO_CONTENT, ['Allow' => 'OPTIONS, POST']);
  152. }
  153. return new JsonResponse($sessionService->getProfileIdsForMultiMessageSelection($session));
  154. }
  155. /**
  156. * @throws \Doctrine\DBAL\Driver\Exception
  157. * @throws \Doctrine\DBAL\Exception
  158. */
  159. public function resultsAction(
  160. Request $request,
  161. TranslatorInterface $translator,
  162. EntityManagerInterface $em,
  163. SessionService $sessionService,
  164. SessionInterface $session,
  165. DebuggingService $debuggingService,
  166. BusinessEventDomainService $businessEventDomainService,
  167. WantedJobsSearchService $wantedJobsSearchService,
  168. LoggerInterface $logger,
  169. NotificationService $notificationService,
  170. UsageEventService $usageEventService,
  171. EventDispatcherInterface $eventDispatcher,
  172. AnonymousUserInfoService $anonymousUserInfoService,
  173. ZipcodeCircumcirclesRepository $zipcodeCircumcirclesRepository,
  174. ProfileBlocksService $profileBlocksService,
  175. FeatureLimitationsService $featureLimitationsService,
  176. CircuitbreakerService $circuitbreakerService,
  177. BlacklistingService $blacklistingService,
  178. MembershipService $membershipService,
  179. FactoryInterface $formFactory,
  180. RegistrationService $registrationService,
  181. ): Response {
  182. $page = $this->getPage($request);
  183. $showAnonymousResults = true;
  184. $conversionEventId = null;
  185. // whenever a new search is done, we forget about previously selected profiles for multi message
  186. if (isset($_GET['searchButton']) && !isset($_POST['searchButton']) && $session->get('uriOfLastSuccessfulSearchResultsPage') !== $request->getRequestUri()) {
  187. $sessionService->resetProfileIdsForMultiMessageSelection($session);
  188. }
  189. $receivingJobseekerProfileIds = $sessionService->getProfileIdsForMultiMessageSelection($session);
  190. /** @var User $user */
  191. $user = $this->getUser();
  192. $userHasMembership = false;
  193. if ($user instanceof User) {
  194. if ($user->isJobofferer()) {
  195. $userHasMembership = $membershipService->userHasActiveMembership($user);
  196. $showAnonymousResults = false;
  197. $notificationService->uncancelNotification($user, NotificationService::NOTIFICATION_TYPE_UNREAD_CONVERSATION_MESSAGES);
  198. $notificationService->uncancelNotification($user, NotificationService::NOTIFICATION_TYPE_UNREAD_JOBRADAR_MATCHES);
  199. if (!is_null($circuitbreakerService->checkForTooManySearchRequestsAndReturnSeverityLevel($user))) {
  200. $this->addFlash(
  201. 'danger',
  202. 'Bei deinem Account wurden verdächtige Aktivitäten festgestellt und du kannst für ' . $circuitbreakerService->checkForTooManySearchRequestsAndReturnSeverityLevel($user) . ' keine Suchen mehr durchführen. Falls es sich um einen Fehler handeln sollte, melde dich gerne bei info@joboo.de.'
  203. );
  204. return $this->redirectToRoute('homepage');
  205. }
  206. }
  207. if ($user->isJobseeker() && !$user->hasAtLeastOneAdminRole()) {
  208. $this->addFlash(
  209. 'info',
  210. $translator->trans('wanted_jobs_search.alert_jobseekers_not_allowed')
  211. );
  212. return $this->redirectToRoute('recurrent_jobs_search.form');
  213. }
  214. if ($blacklistingService->isEmailBlacklistedForType(
  215. $user->getEmail(),
  216. Blacklisting::BLACKLISTING_TYPE_SEARCH
  217. )) {
  218. $this->addFlash(
  219. 'danger',
  220. 'Bei deinem Account wurden verdächtige Aktivitäten festgestellt und du kannst vorerst keine Suchen mehr durchführen.
  221. Falls es sich um einen Fehler handeln sollte, melde dich gerne bei info@joboo.de.'
  222. );
  223. return $this->redirectToRoute('homepage');
  224. }
  225. }
  226. $form = $this->createForm(
  227. WantedJobsSearchParametersType::class,
  228. null,
  229. [
  230. 'action' => $this->generateUrl('wanted_jobs_search.results') . '#results',
  231. 'method' => 'GET'
  232. ]
  233. );
  234. try {
  235. $form->handleRequest($request);
  236. } catch (Exception $e) {
  237. $logger->warning($e->getMessage(), ['exception' => $e]);
  238. $this->addFlash(
  239. 'danger',
  240. $translator->trans('wanted_jobs_search.alert_parameters_not_allowed')
  241. );
  242. return $this->redirectToRoute('wanted_jobs_search.form');
  243. }
  244. if ($form->isSubmitted() && $form->isValid()) {
  245. /** @var WantedJobsSearchParameters $searchParams */
  246. $searchParams = $form->getData();
  247. $enteredSearchtermForTracking = $searchParams->getFilterSearchterm();
  248. if ($user instanceof User && $user->isJobofferer() && $user->getDefaultJoboffererProfile()->isLimitedInSearch()
  249. && !in_array($searchParams->getFilterZipcode(), $wantedJobsSearchService->getZipcodesBelongingToJoboffererProfile($user->getDefaultJoboffererProfile()))
  250. ) {
  251. $this->addFlash(
  252. 'danger',
  253. $translator->trans('wanted_jobs_search.alert_parameters_not_allowed')
  254. );
  255. return $this->redirectToRoute('wanted_jobs_search.form');
  256. }
  257. // Our heuristic here is very simple:
  258. // If the request does not contain a query param "page", we assume that the user comes from submitting the
  259. // search form, and not from navigating through the pages. This is what we consider a newly started search.
  260. // This doesn't prevent the event from being dispatched on page reloads, or when repeatedly opening the
  261. // page through other means (like a click on a bookmark, or in an email, etc).
  262. if (is_null($request->get('page'))) {
  263. $eventDispatcher->dispatch(
  264. new SearchForWantedJobsStartedEvent($user, $searchParams, $request, true),
  265. SearchForWantedJobsStartedEvent::class
  266. );
  267. }
  268. if (is_null($user)) {
  269. $anonymousUserInfoService->setSearchInformationWantedJobsSearch($searchParams);
  270. }
  271. $context = is_null($user)
  272. ? \App\Entity\SearchtermEnteredEvent::CONTEXT_WANTED_JOBS_SEARCH_ANONYMOUS
  273. : \App\Entity\SearchtermEnteredEvent::CONTEXT_WANTED_JOBS_SEARCH_LOGGED_IN;
  274. $numberOfResultsPerPage = $showAnonymousResults
  275. ? GeneralApplicationSettingsValue::WANTED_JOBS_SEARCH_ANONYMOUS_MAX_NUMBER_OF_RESULTS_PER_PAGE
  276. : GeneralApplicationSettingsValue::WANTED_JOBS_SEARCH_NONANONYMOUS_MAX_NUMBER_OF_RESULTS_PER_PAGE;
  277. $maximumTotalNumberOfResults = GeneralApplicationSettingsValue::WANTED_JOBS_SEARCH_MAX_NUMBER_OF_PAGES * $numberOfResultsPerPage;
  278. $fullResultset = new WantedJobsSearchResultset($searchParams);
  279. try {
  280. $fullResultset = $wantedJobsSearchService->getResultset(
  281. $searchParams,
  282. $maximumTotalNumberOfResults,
  283. 0,
  284. $showAnonymousResults,
  285. $user,
  286. $maximumTotalNumberOfResults
  287. );
  288. } catch (UnknownZipcodeException $e) {
  289. $debuggingInfoBag = new DebuggingInfoBag(
  290. 'unknown-zipcode-wanted-jobs-search',
  291. 'Unknown zipcode ' . $searchParams->getFilterZipcode() . ' in wanted jobs search', '',
  292. Logger::WARNING);
  293. $debuggingInfoBag->setRequest($request);
  294. if ($user) {
  295. $debuggingInfoBag->setUser($user);
  296. }
  297. $debuggingService->log($debuggingInfoBag);
  298. } catch (Exception $e) {
  299. $userId = null;
  300. if (!is_null($user)) {
  301. $userId = $user->getId();
  302. }
  303. throw new Exception('An exception occurred while trying to search for wanted jobs: "' . $e->getMessage() . '". The query string is ' . $request->getQueryString() . ', and the userId is ' . print_r($userId, true), 0, $e);
  304. }
  305. $subscriptionUrl = null;
  306. $joboffererSparseResultsTemplate = null;
  307. if ($user instanceof User
  308. && $user->isJobofferer()
  309. && $fullResultset->getTotalNumberOfResults() <= 5
  310. ) {
  311. if ($userHasMembership) {
  312. $joboffererSparseResultsTemplate = 'jobofferer_modal_subscription.html.twig';
  313. } else {
  314. $businessEventDomainService->writeNewEvent(
  315. BusinessEvent::EVENT_TYPE_SPARSE_RESULTS_AFTER_SEARCH,
  316. $user
  317. );
  318. $subscriptionUrl = $this->generateUrl('account.subscription.jobofferer.index', []) . '?sparseResults';
  319. $joboffererSparseResultsTemplate = 'jobofferer_modal_no_subscription.html.twig';
  320. }
  321. }
  322. if ($fullResultset->getTotalNumberOfResults() > 0) { // We want to be able to return to this search result later
  323. $session->set('uriOfLastSuccessfulSearchResultsPage', $request->getRequestUri());
  324. }
  325. $eventDispatcher->dispatch(
  326. new SearchtermEnteredEvent($request, $user, $enteredSearchtermForTracking, null, null, $context, $fullResultset->getTotalNumberOfResults(), $fullResultset->getBlocksInfo()->getNumberOfResultsPerBlock()),
  327. SearchtermEnteredEvent::class
  328. );
  329. if (!$showAnonymousResults) {
  330. $usageEventService->eventHasOccurredForUser($user, UsageEvent::EVENT_TYPE_JOBOFFERER_HAS_USED_SEARCH_FOR_WANTED_JOBS);
  331. if ($fullResultset->getTotalNumberOfResults() < 5) {
  332. $businessEventDomainService->writeNewEvent(
  333. BusinessEvent::EVENT_TYPE_WANTEDJOBSSEARCH_NOTENOUGHRESULTS,
  334. $user,
  335. null,
  336. null,
  337. json_encode([
  338. 'searchParams' => $searchParams,
  339. 'requestUri' => $request->getRequestUri()
  340. ])
  341. );
  342. } else {
  343. $businessEventDomainService->writeNewEvent(
  344. BusinessEvent::EVENT_TYPE_WANTEDJOBSSEARCH_ENOUGHRESULTS,
  345. $user,
  346. null,
  347. null,
  348. json_encode([
  349. 'searchParams' => $searchParams,
  350. 'requestUri' => $request->getRequestUri()
  351. ])
  352. );
  353. }
  354. }
  355. $fullResultset->sliceResults(0, $maximumTotalNumberOfResults);
  356. try {
  357. $resultsetForCurrentPage = $fullResultset->getResultsetForPage($fullResultset, $page, $numberOfResultsPerPage);
  358. } catch (UncallableSearchPageException $e) {
  359. return $this->render('/errors/notfound.html.twig', [], new Response(null, Response::HTTP_NOT_FOUND));
  360. }
  361. if ($showAnonymousResults) {
  362. $newConversationMessageSubjectPrefill = '';
  363. $newConversationMessageBodyPrefill = '';
  364. $registrationCarryThroughData = new CarryThroughData();
  365. $registrationCarryThroughData->setWantedJobsSearchParameters($searchParams);
  366. } else {
  367. $newConversationMessagePrefillOccupationalField = $searchParams->getFilterSearchtermForDisplay();
  368. $newConversationMessageBodyPrefillAvailabilities = '';
  369. foreach (PossibleAvailabilitiesValue::WEEKDAYS as $weekday) {
  370. foreach (PossibleAvailabilitiesValue::TIMES_OF_DAY as $timeOfDay) {
  371. $methodName = 'getFilterIsRequiredOn' . $weekday . $timeOfDay;
  372. if ($searchParams->$methodName() === true) {
  373. $newConversationMessageBodyPrefillAvailabilities .= '- ' .
  374. $translator->trans('availabilities_weekday.' . $weekday) .
  375. ' ' .
  376. $translator->trans('availabilities_time_of_day.' . $timeOfDay) .
  377. "\n";
  378. }
  379. }
  380. }
  381. }
  382. // Build an array of all jobseekers we already have contacted with a message in the past,
  383. // in order to show this information on the results page
  384. $conversationMessagesSentDatesForJobseekerProfiles = [];
  385. if (!$showAnonymousResults) {
  386. $jobseekerProfiles = [];
  387. /** @var WantedJobsSearchResult $result */
  388. foreach ($resultsetForCurrentPage->getResults() as $key => $result) {
  389. /** @var WantedJob $wantedJob */
  390. $wantedJob = $result->getWantedJob();
  391. // Also, don't show results with a wantedJob by a user that we have blocked
  392. if ($profileBlocksService->isProfileOrCustomerBlockedByProfile($user->getDefaultJoboffererProfile(), $wantedJob->getJobseekerProfile())) {
  393. $resultsetForCurrentPage->removeResult($key);
  394. } else {
  395. if (in_array($wantedJob->getJobseekerProfile(), $jobseekerProfiles)) {
  396. $resultsetForCurrentPage->removeResult($key);
  397. } else {
  398. $jobseekerProfiles[] = $wantedJob->getJobseekerProfile();
  399. }
  400. }
  401. }
  402. try {
  403. $conversationMessageRepository = $em->getRepository(ConversationMessage::class);
  404. $conversationMessagesSentDatesForJobseekerProfiles = $conversationMessageRepository->getLastSentDatesForReceiverProfiles(
  405. $user->getDefaultJoboffererProfile(),
  406. $jobseekerProfiles,
  407. true
  408. );
  409. } catch (Exception $e) {
  410. $logger->warning('Could not get last sent dates for jobseeker profiles of wanted jobs in search results', ['exception' => $e]);
  411. }
  412. }
  413. if ($showAnonymousResults) {
  414. $resultsArray = (array)$resultsetForCurrentPage->getResults();
  415. $alreadyPortrayedJobseekers = [];
  416. foreach ($resultsArray as $key => $result) {
  417. if (in_array($result->getWantedJob()->getJobseekerProfile()->getId(), $alreadyPortrayedJobseekers)) {
  418. unset($resultsArray[$key]);
  419. } else {
  420. $alreadyPortrayedJobseekers[] = $result->getWantedJob()->getJobseekerProfile()->getId();
  421. }
  422. }
  423. shuffle($resultsArray);
  424. $resultsetForCurrentPage->resetResults();
  425. $resultsetForCurrentPage->setResults($resultsArray);
  426. }
  427. $joboffererProfileCanEditZipcodeForWantedJobsSearch = true;
  428. $joboffererProfileId = null;
  429. if (!is_null($user) && !is_null($user->getDefaultJoboffererProfile())) {
  430. $joboffererProfileCanEditZipcodeForWantedJobsSearch = $featureLimitationsService->joboffererProfileCanEditZipcodeForWantedJobsSearch($user->getDefaultJoboffererProfile());
  431. $joboffererProfileId = $user->getDefaultJoboffererProfile()->getId();
  432. }
  433. $response = $this->render('/wanted_jobs_search/results.html.twig', [
  434. 'jobofferer_template' => $joboffererSparseResultsTemplate,
  435. 'subscription_url' => $subscriptionUrl,
  436. 'showAnonymousResults' => $showAnonymousResults,
  437. 'form' => $form->createView(),
  438. 'resultsetForCurrentPage' => $resultsetForCurrentPage,
  439. 'totalNumberOfResults' => $fullResultset->getTotalNumberOfResults(),
  440. 'currentPage' => $page,
  441. 'searchParams' => $searchParams,
  442. 'seoTranslationParameters' => new SeoTranslationParameters(
  443. $searchParams->getFilterSearchterm(),
  444. $searchParams->getFilterZipcode(),
  445. (string)$zipcodeCircumcirclesRepository->getCityForZipcode($searchParams->getFilterZipcode())
  446. ),
  447. 'numberOfResultsPerPage' => $numberOfResultsPerPage,
  448. 'conversationMessagesSentDatesForJobseekerProfiles' => $conversationMessagesSentDatesForJobseekerProfiles,
  449. 'maxNumberOfPages' => GeneralApplicationSettingsValue::WANTED_JOBS_SEARCH_MAX_NUMBER_OF_PAGES,
  450. 'receivingJobseekerProfileIds' => $receivingJobseekerProfileIds,
  451. 'numberOfReceivingJobseekerProfileIds' => sizeof($receivingJobseekerProfileIds),
  452. 'conversionEventId' => !is_null($user) && !$user->hasAtLeastOneAdminRole() ? $conversionEventId : null,
  453. 'waitingInfo' => $wantedJobsSearchService->getWaitingInfo($user),
  454. 'joboffererProfileCanEditZipcodeForWantedJobsSearch' => $joboffererProfileCanEditZipcodeForWantedJobsSearch,
  455. 'joboffererProfileId' => $joboffererProfileId,
  456. 'limitedInSearch' => !is_null($user) && !is_null($user->getDefaultJoboffererProfile()) ? $user->getDefaultJoboffererProfile()->isLimitedInSearch() : false]
  457. );
  458. if ($showAnonymousResults) { // Don't cache for logged-in users. If a user marks a result as "favorite", this would not be reflected upon page reload
  459. $response->setVary('Cookie');
  460. $response->setSharedMaxAge(60);
  461. }
  462. return $response;
  463. } else {
  464. return $this->render('/wanted_jobs_search/form.html.twig', [
  465. 'form' => $form->createView(),
  466. 'waitingInfo' => $wantedJobsSearchService->getWaitingInfo($user),
  467. ]
  468. );
  469. }
  470. }
  471. public function landingpageAction(
  472. Request $request
  473. ): RedirectResponse {
  474. return $this->redirectToRoute('homepage', [
  475. 'request' => $request
  476. ], 307);
  477. }
  478. /**
  479. * @ParamConverter("recurrentJob", class="App\Entity\RecurrentJob", options={"id" = "recurrentJobId"}))
  480. */
  481. public function specificRecurrentJobAction(
  482. RecurrentJob $recurrentJob,
  483. Request $request
  484. ): RedirectResponse {
  485. $wantedJobsSearchParameters = WantedJobsSearchParameters::fromRecurrentJob($recurrentJob);
  486. return $this->redirectToRoute('wanted_jobs_search.results',
  487. [
  488. 'wanted_jobs_search_parameters' => $wantedJobsSearchParameters->asArray(),
  489. ]
  490. );
  491. }
  492. }