src/Aqarmap/Bundle/ListingBundle/Controller/CompoundSearchController.php line 145

  1. <?php
  2. namespace Aqarmap\Bundle\ListingBundle\Controller;
  3. use Aqarmap\Bundle\ListingBundle\Entity\CompoundLocation;
  4. use Aqarmap\Bundle\ListingBundle\Service\CompoundService;
  5. use Aqarmap\Bundle\ListingBundle\Service\ListingManager;
  6. use Aqarmap\Bundle\MainBundle\Constant\CustomParagraphPlaceTypes;
  7. use Aqarmap\Bundle\MainBundle\Entity\CustomParagraph;
  8. use Aqarmap\Bundle\MainBundle\Repository\CustomParagraphRepository;
  9. use Aqarmap\Bundle\SearchBundle\Services\CompoundAdviserSearchService;
  10. use Doctrine\ORM\NonUniqueResultException;
  11. use Gedmo\Translatable\TranslatableListener;
  12. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  13. use Symfony\Component\HttpFoundation\Cookie;
  14. use Symfony\Component\HttpFoundation\RedirectResponse;
  15. use Symfony\Component\HttpFoundation\Request;
  16. use Symfony\Component\HttpFoundation\Response;
  17. use Symfony\Component\Routing\Attribute\Route;
  18. #[Route(path: 'compounds')]
  19. class CompoundSearchController extends AbstractController
  20. {
  21. public function __construct(
  22. private readonly CompoundAdviserSearchService $compoundAdvisorSearchService,
  23. private readonly CompoundService $compoundService,
  24. private readonly TranslatableListener $translatableListener,
  25. ListingManager $listingManager,
  26. private readonly \Doctrine\Persistence\ManagerRegistry $managerRegistry,
  27. ) {
  28. $this->listingManager = $listingManager;
  29. }
  30. /**
  31. * @return array|RedirectResponse
  32. */
  33. #[Route(path: '/advisor', name: 'compound_adviser', methods: ['GET'])]
  34. #[Route(path: '/advisor/matcherLocation', name: 'compound_adviser_location', methods: ['GET'])]
  35. #[Route(path: '/advisor/matcherPriceLevel', name: 'compound_adviser_price', methods: ['GET'])]
  36. #[Route(path: '/advisor/matcherAreaMethod', name: 'compound_adviser_area', methods: ['GET'])]
  37. #[Route(path: '/advisor/matcherPropertyType', name: 'compound_adviser_property_type', methods: ['GET'])]
  38. #[Route(path: '/advisor/matcherFinishType', name: 'compound_adviser_finish_type', methods: ['GET'])]
  39. #[Route(path: '/advisor/matcherDelivery', name: 'compound_adviser_delivery', methods: ['GET'])]
  40. public function adviser(): Response
  41. {
  42. return $this->render('@AqarmapListing/CompoundSearch/adviser.html.twig', []);
  43. }
  44. /**
  45. * Compound advisor Search (POST).
  46. */
  47. #[Route(path: '/advisor', name: 'compound_adviser_search_post', methods: ['POST'])]
  48. public function adviserPost(Request $request): RedirectResponse
  49. {
  50. $criteria = $this->compoundAdvisorSearchService->prepareAdviserScoringCriteria(json_decode($request->request->get('data'), true));
  51. $response = new RedirectResponse($this->generateUrl('compound_adviser_search_results', []));
  52. $cookie = Cookie::create('advisor-criteria', serialize($criteria));
  53. $response->headers->setCookie($cookie);
  54. $response->prepare($request);
  55. $response->send();
  56. return $response;
  57. }
  58. /**
  59. * @throws \Exception
  60. */
  61. #[Route(path: '/advisor/search', name: 'compound_adviser_search_results', methods: ['GET'])]
  62. public function compoundAdviserResult(Request $request): Response
  63. {
  64. $cookies = $request->cookies;
  65. $criteria = [];
  66. if ($cookies->has('advisor-criteria')) {
  67. $criteria = unserialize($cookies->get('advisor-criteria'));
  68. }
  69. $results = $this->compoundAdvisorSearchService->getCompounds($criteria, $request->query->get('page', 1));
  70. $entityManager = $this->managerRegistry->getManager();
  71. $criteria['selectedParagraphId'] = (int) $request->get('custom_paragraph');
  72. $isNoIndexMetaTag = (bool) $request->get('noindex') || $this->compoundAdvisorSearchService->isNoIndexMetaTag($request->query->all());
  73. return $this->render(
  74. '@AqarmapListing/CompoundSearch/compoundAdviserResult.html.twig',
  75. [
  76. 'canonicalUrl' => $canonicalUrl ?? null,
  77. 'listings' => $results,
  78. 'adviserCriteria' => $criteria,
  79. 'listingsCount' => \count($results),
  80. 'customParagraph' => $this->getCustomParagraph($criteria),
  81. 'subLinksSections' => $entityManager->getRepository(\Aqarmap\Bundle\ListingBundle\Entity\Section::class)->getSearchableSection(),
  82. 'isNoIndexMetaTag' => $isNoIndexMetaTag,
  83. 'form' => $this->compoundService->createQuickLeadForm('add_quick_lead'),
  84. 'liveListingsPerUser' => $this->listingManager->getLiveListingsCountPerUser($results->getItems()),
  85. 'isMobile' => false,
  86. ]
  87. );
  88. }
  89. /**
  90. * @return array|RedirectResponse
  91. *
  92. * @throws \Exception
  93. */
  94. #[Route(path: '/', methods: ['GET'], name: 'compound_search')]
  95. #[Route(path: '/{location}', methods: ['GET'], name: 'compound_search_with_location', requirements: ['location' => '.+[^/]'])]
  96. public function compoundSearchResult(Request $request, #[\Symfony\Bridge\Doctrine\Attribute\MapEntity(mapping: ['location' => 'slug'])]
  97. ?CompoundLocation $location = null)
  98. {
  99. $response = $this->compoundService->search($request, $location);
  100. if ($response instanceof Response) {
  101. return $response;
  102. }
  103. return $this->render(
  104. '@AqarmapListing/CompoundSearch/compoundSearchResult.html.twig',
  105. $response
  106. );
  107. }
  108. /**
  109. * Compound Search (POST).
  110. *
  111. * @throws \Exception
  112. */
  113. #[Route(path: '/compound', methods: ['POST'], name: 'compound_Search')]
  114. public function searchPost(Request $request)
  115. {
  116. $redirect = $this->redirectToRoute('compound_search', [], Response::HTTP_MOVED_PERMANENTLY);
  117. $compoundSearchForm = $this->compoundService->compoundSearchForm();
  118. $compoundSearchForm->handleRequest($request);
  119. if ($compoundSearchForm->isValid()) {
  120. $criteria = $this->compoundService->prepareCriteria($compoundSearchForm, $request);
  121. $redirect = $this->redirect(urldecode($this->generateUrl('compound_search', $criteria)), Response::HTTP_MOVED_PERMANENTLY);
  122. }
  123. return $redirect;
  124. }
  125. /**
  126. * @return CustomParagraph|null
  127. */
  128. public function getCustomParagraph(array $criteria)
  129. {
  130. $selectedCustomParagraphId = $criteria['selectedParagraphId'] ?? null;
  131. $criteria = [
  132. 'place' => CustomParagraphPlaceTypes::SEARCH_RESULTS,
  133. 'section' => $criteria['section'] ?? null,
  134. 'location' => $criteria['location'] ?? null,
  135. 'propertyType' => $criteria['propertyType'] ?? null,
  136. ];
  137. /** @var CustomParagraphRepository $customParagraphRepository */
  138. $customParagraphRepository = $this->managerRegistry->getRepository(CustomParagraph::class);
  139. $this->translatableListener->setTranslationFallback(false);
  140. if ($selectedCustomParagraphId) {
  141. $criteria['id'] = $selectedCustomParagraphId;
  142. try {
  143. return $customParagraphRepository
  144. ->get($criteria)
  145. ->getQuery()
  146. ->setMaxResults(1)
  147. ->getOneOrNullResult();
  148. } catch (NonUniqueResultException) {
  149. return null;
  150. }
  151. }
  152. $customParagraphs = $customParagraphRepository
  153. ->get(array_merge($criteria, ['published' => true]))
  154. ->getQuery()
  155. ->getResult();
  156. if (empty($customParagraphs)) {
  157. return null;
  158. }
  159. return $customParagraphs[array_rand($customParagraphs)];
  160. }
  161. }