src/Controller/Website/ListController.php line 69

Open in your IDE?
  1. <?php
  2. namespace App\Controller\Website;
  3. use App\Helper\Cruise\CruiseHelper;
  4. use App\Helper\Partner\PartnerHelper;
  5. use App\Helper\SuluHelper;
  6. use Croisiland\CommonBundle\Form\CruiseSearchFullFormType;
  7. use Croisiland\CommonBundle\Model\CruiseSearchModel;
  8. use Croisiland\CommonBundle\Repository\CruiseSearchRepository;
  9. use Croisiland\CommonBundle\Service\CruiseSearchService;
  10. use Croisiland\CommonBundle\Serializer\CruiseSearchModelSerializer;
  11. use Doctrine\ORM\NonUniqueResultException;
  12. use Doctrine\ORM\NoResultException;
  13. use Sulu\Component\Content\Compat\StructureInterface;
  14. use Symfony\Component\HttpFoundation\Response;
  15. class ListController extends BaseWebsiteController
  16. {
  17. const string BASE_PATH = '/croisieres';
  18. public function __construct(
  19. private readonly CruiseSearchService $cruiseSearchService,
  20. private readonly CruiseSearchModelSerializer $cruiseSearchModelSerializer,
  21. private readonly CruiseSearchRepository $cruiseSearchRepository,
  22. private readonly CruiseHelper $cruiseHelper,
  23. private readonly SuluHelper $suluHelper,
  24. private readonly PartnerHelper $partnerHelper,
  25. ) {
  26. }
  27. /**
  28. * @throws NonUniqueResultException
  29. * @throws NoResultException
  30. */
  31. public function indexAction(StructureInterface $structure, $preview = false, $partial = false): Response
  32. {
  33. $partner = $this->partnerHelper->getCurrentPartner();
  34. $request = $this->container->get('request_stack')->getCurrentRequest();
  35. $attributes = $this->getSharedLayoutFormViews();
  36. $searchUrl = null;
  37. $cruiseSearch = $this->cruiseSearchModelSerializer->fromRequest($request);
  38. $cruiseSearch->setPartner($partner);
  39. $hasInitialParameters = $this->cruiseSearchService->hasSearchParameters($cruiseSearch);
  40. $form = $this->createForm(CruiseSearchFullFormType::class, $cruiseSearch, [
  41. 'visible_fields' => CruiseListSearchFormConfiguration::visibleFields(),
  42. ]);
  43. $form->handleRequest($request);
  44. $cruiseSearch->setPerPage(CruiseListSearchFormConfiguration::perPage());
  45. $result = $this->cruiseSearchService->search($cruiseSearch);
  46. $result = $this->applyFilteredCruiseCount($result, $cruiseSearch);
  47. if (($form->isSubmitted() && $form->isValid()) || $hasInitialParameters) {
  48. $searchUrl = $this->suluHelper->generateUrlWithQueryParams(self::BASE_PATH, $result['search_url_parameters']);
  49. }
  50. $attributes['form'] = $form->createView();
  51. $attributes['cruiseSearchResult'] = $result;
  52. $attributes['searchUrl'] = $searchUrl;
  53. $attributes['searchMainSubjectInfos'] = $this->cruiseHelper->getSearchMainSubjectInfos($cruiseSearch);
  54. return $this->renderStructure(
  55. $structure,
  56. $attributes,
  57. $preview,
  58. $partial
  59. );
  60. }
  61. /**
  62. * Le décompte du bundle (`countSearchResults`) est lancé sans les filtres :
  63. * le total reste celui du catalogue alors que les cartes sont filtrées.
  64. * On recalcule le total à partir des identifiants qui passent les filtres.
  65. *
  66. * @param array<string, mixed> $result
  67. *
  68. * @return array<string, mixed>
  69. */
  70. private function applyFilteredCruiseCount(array $result, CruiseSearchModel $cruiseSearch): array
  71. {
  72. if (!$this->hasUserSearchFilters($cruiseSearch)) {
  73. return $result;
  74. }
  75. $filteredCount = count(
  76. $this->cruiseSearchRepository->getCruisesIdsFromCruiseSearchModel($cruiseSearch, false)
  77. );
  78. $perPage = (int) ($result['pagination']['per_page'] ?? 0);
  79. if ($perPage < 1) {
  80. $perPage = 1;
  81. }
  82. $currentPage = (int) ($result['pagination']['current_page'] ?? 1);
  83. $totalPages = (int) ceil($filteredCount / $perPage);
  84. $result['pagination']['total_count'] = $filteredCount;
  85. $result['pagination']['total_pages'] = $totalPages;
  86. $result['pagination']['has_next_page'] = $currentPage < $totalPages;
  87. $result['pagination']['has_previous_page'] = $currentPage > 1;
  88. return $result;
  89. }
  90. private function hasUserSearchFilters(CruiseSearchModel $cruiseSearch): bool
  91. {
  92. if (!$cruiseSearch->getCompanies()->isEmpty()) {
  93. return true;
  94. }
  95. if (!$cruiseSearch->getShips()->isEmpty()) {
  96. return true;
  97. }
  98. if (!$cruiseSearch->getDeparturePorts()->isEmpty()) {
  99. return true;
  100. }
  101. if (!$cruiseSearch->getDestinationsMain()->isEmpty()) {
  102. return true;
  103. }
  104. if (!$cruiseSearch->getDestinationsSecondary()->isEmpty()) {
  105. return true;
  106. }
  107. if (!$cruiseSearch->getTags()->isEmpty()) {
  108. return true;
  109. }
  110. if (!$cruiseSearch->getOffers()->isEmpty()) {
  111. return true;
  112. }
  113. if ($cruiseSearch->getPeriodStartDate() !== null || $cruiseSearch->getPeriodEndDate() !== null) {
  114. return true;
  115. }
  116. if ($cruiseSearch->getPriceMinimum() !== null || $cruiseSearch->getPriceMaximum() !== null) {
  117. return true;
  118. }
  119. if (trim((string) $cruiseSearch->getKeywords()) !== '') {
  120. return true;
  121. }
  122. if (trim((string) $cruiseSearch->getCruiseCode()) !== '') {
  123. return true;
  124. }
  125. if ($cruiseSearch->getDurations() !== []) {
  126. return true;
  127. }
  128. return $cruiseSearch->getWorldTour() !== null;
  129. }
  130. }