src/Aqarmap/Bundle/SearchBundle/Controller/Api/V4/ListingSearchController.php line 592

  1. ], $response->getStatusCode());
  2. }
  3. #[Rest\Get('/api/v4/listings', options: ['i18n' => false], name: 'aqarmap_api_get_listings')]
  4. #[Rest\Get('/api/v4/listings/search', options: ['i18n' => false], name: 'aqarmap_api_listings_search_v4')]
  5. public function getListings(Request $request, ListingRepository $listingRepository, ListingManager $listingManager, CacheInterface $cache, MessageBusInterface $messageBus)
  6. {
  7. /** @var UserInterface $user */
  8. $user = $this->getUser();
  9. $hasSearchScoringRole = $user && $user->hasRole('ROLE_SEARCH_SCORING');
  10. if (!$hasSearchScoringRole && ($request->get('esdebug') || $request->get('scoredebug'))) {
  11. $request->query->remove('esdebug');
  12. $request->query->remove('scoredebug');
  13. }
  14. if ($request->get('location')) {
  15. $request->query->set('locations', explode(',', $request->query->get('location', '')));
  16. }
  17. $cacheKey = sprintf('api_listings_search_v4_%s_%s', $request->getLocale(), md5(http_build_query($request->query->all())));
  18. $cachedSerialize = $cache->getItem($cacheKey);
  19. if (!$cachedSerialize->isHit() || empty($cachedSerialize->get())) {
  20. $listingsElasticResponse = $listingManager->getListingsElasticResponse($request);
  21. $listingsQueryBuilder = $listingRepository->getListingsByIds(array_column($listingsElasticResponse['items'], 'id'));
  22. if ('aqarmap_api_listings_search_v4' === $request->attributes->get('_route')) {
  23. $listingsElasticResponse['pagination']['totalPages'] = (float) $listingsElasticResponse['pagination']['totalPages'];
  24. }
  25. $listings = $listingsQueryBuilder->getQuery()->getResult();
  26. $data = [
  27. 'default' => $this->mapPaginatedBody($listingsElasticResponse, $listings),
  28. 'related' => [],
  29. ];
  30. $data = $this->serializer->serialize(
  31. $data,
  32. 'json',
  33. SerializationContext::create()
  34. ->setGroups('SearchV4')
  35. ->enableMaxDepthChecks()
  36. );
  37. $cachedSerialize->set($data);
  38. $cachedSerialize->expiresAfter(3600 * 3);
  39. $cache->save($cachedSerialize);
  40. }
  41. return new Response($cachedSerialize->get());
  42. }
  43. #[Rest\Get('/api/v4/listings/debug', options: ['i18n' => false], name: 'aqarmap_api_get_listings_debug')]
  44. public function getListingsEsDebug(Request $request, ListingManager $listingManager)
  45. {
  46. /** @var UserInterface $user */
  47. $user = $this->getUser();
  48. if (!($user && $user->hasRole('ROLE_SEARCH_SCORING'))) {
  49. throw new UnauthorizedHttpException();
  50. }
  51. $request->query->set('esdebug', 1);
  52. if ($request->get('location')) {
  53. $request->query->set('locations', explode(',', $request->query->get('location', '')));
  54. }
  55. $listingsDebugElasticResponse = $listingManager->getListingsDebugElasticResponse($request);
  56. if ('aqarmap_api_listings_search_v4' === $request->attributes->get('_route')) {
  57. $listingsDebugElasticResponse['pagination']['totalPages'] = (float) $listingsDebugElasticResponse['pagination']['totalPages'];
  58. }
  59. $data = [
  60. 'default' => $this->mapPaginatedBody($listingsDebugElasticResponse, $listingsDebugElasticResponse['items']),
  61. ];
  62. return new JsonResponse($data);
  63. }
  64. #[Rest\Get('/api/v4/listings/search/ssr-data', options: ['i18n' => false], name: 'aqarmap_api_get_listings_search_ssr-data')]
  65. public function getListingsSearchSSRData(Request $request, ListingManager $listingManager, CacheInterface $cache, SectionService $sectionService)
  66. {
  67. $cacheKey = sprintf('api_listings_search_ssr_data_%s_%s', $request->getLocale(), md5(http_build_query($request->query->all())));
  68. $cachedResponse = $cache->getItem($cacheKey);
  69. if (!$cachedResponse->isHit() || empty($cachedResponse->get())) {
  70. $customParagraph = $locationChildren = $slugResolver = $faqData = $locationParents = [];
  71. if ($request->get('location')) {
  72. $request->query->set('locations', explode(',', $request->query->get('location', '')));
  73. }
  74. $location = $request->get('locations') ? $request->get('locations')[0] : null;
  75. $location = $this->locationRepository->findOneBy(['slug' => $location]);
  76. $section = $this->sectionRepository->findOneBy(['slug' => $request->query->get('section')]);
  77. $propertyType = $this->propertyTypeRepository->findOneBy(['slug' => $request->query->get('propertyType')]);
  78. if ($location) {
  79. $locationChildren = $listingManager->getSerializedLocationChildren($location);
  80. $locationParents = $listingManager->getLocationParents($location, $request->getLocale());
  81. }
  82. if ($section && $propertyType && $location) {
  83. $longTail = $this->seoListingSearchService->getSerializedLongTailData($section, $propertyType, $location) ?? [];
  84. }
  85. if ($section && $propertyType) {
  86. $byOwnerOnly = filter_var($request->get('byOwnerOnly'), FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) ?? false;
  87. $customParagraph = $listingManager->getSerializedCustomParagraph($section, $propertyType, $location, $byOwnerOnly) ?? [];
  88. $slugResolver = $listingManager->getSerializedResolvedSlugs($section, $propertyType, (array) $request->query->get('locations', []));
  89. $faqData = $listingManager->getFaqs($section, $propertyType, $location, $request->getLocale());
  90. }
  91. $response = [
  92. 'locationChildren' => !empty($locationChildren) ? json_decode((string) $locationChildren, true) : [],
  93. 'longTail' => !empty($longTail) ? json_decode((string) $longTail, true) : [],
  94. 'customParagraph' => !empty($customParagraph) ? json_decode((string) $customParagraph, true) : [],
  95. 'slugResolver' => !empty($slugResolver) ? json_decode((string) $slugResolver, true) : [],
  96. 'faqData' => $faqData,
  97. 'locationParents' => $locationParents,
  98. 'sections' => json_decode((string) $sectionService->getSerializedSections(), true),
  99. 'propertyTypeChips' => $listingManager->getListingPropertyTypesChips($request, $location, $section, $propertyType),
  100. ];
  101. $cachedResponse->set(json_encode($response));
  102. $cachedResponse->expiresAfter(3600 * 3);
  103. $cache->save($cachedResponse);
  104. }
  105. return new JsonResponse(json_decode((string) $cachedResponse->get(), true));
  106. }
  107. #[Rest\Get('/api/v4/listings/trigger-search', options: ['i18n' => false], name: 'aqarmap_api_trigger_search_listings_v4')]
  108. public function triggerSearchListings(Request $request, MessageBusInterface $messageBus)
  109. {
  110. $user = $this->getUser();
  111. if ($request->get('location')) {
  112. $request->query->set('locations', explode(',', $request->query->get('location', '')));
  113. }
  114. if ($request->get('keywordSearch')) {
  115. $this->eventDispatcher->dispatch(new SearchTriggerEvent($request));
  116. }
  117. if ($user) {
  118. $messageBus->dispatch(new Search($request->query, $user));
  119. }
  120. return new JsonResponse([
  121. 'statusCode' => Response::HTTP_OK,
  122. 'statusMessage' => 'Search triggered successfully!',
  123. ]);
  124. }
  125. private function mapPaginatedBody(array $result, array $listings): array
  126. {
  127. if (!$result['pagination']) {
  128. return [
  129. 'statusCode' => $this->getStatusCode(),
  130. 'statusMessage' => $this->getStatusMessage(),
  131. 'paginate' => [],
  132. 'data' => [],
  133. 'errors' => $this->getErrors(),
  134. ];
  135. }
  136. return [
  137. 'statusCode' => $this->getStatusCode(),
  138. 'statusMessage' => $this->getStatusMessage(),
  139. 'paginate' => $result['pagination'],
  140. 'data' => $listings,
  141. 'errors' => $this->getErrors(),
  142. ];
  143. }
  144. }