src/Helper/Cruise/CruiseHelper.php line 90

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Helper\Cruise;
  4. use App\Controller\Website\ListController;
  5. use App\Helper\Partner\PartnerHelper;
  6. use App\Helper\SuluHelper;
  7. use App\Repository\Cabin\CabinTypeRepository;
  8. use App\Repository\Itinerary\StopoverRepository;
  9. use Crea\MediaBundle\Entity\Enum\MediaFamilyCodeEnum;
  10. use Crea\MediaBundle\Entity\MediaFile;
  11. use Crea\MediaBundle\Helper\MediaTagQueryHelper;
  12. use Croisiland\CommonBundle\Entity\Cabin\CabinType;
  13. use Croisiland\CommonBundle\Entity\Company\Company;
  14. use Croisiland\CommonBundle\Entity\Cruise\Cruise;
  15. use Croisiland\CommonBundle\Entity\Itinerary\DestinationMain;
  16. use Croisiland\CommonBundle\Entity\Itinerary\DestinationSecondary;
  17. use Croisiland\CommonBundle\Entity\Itinerary\Stopover;
  18. use Croisiland\CommonBundle\Entity\Partner\Partner;
  19. use Croisiland\CommonBundle\Entity\Ship\Ship;
  20. use Croisiland\CommonBundle\Entity\Tag\Tag;
  21. use Croisiland\CommonBundle\Model\CruiseSearchModel;
  22. use Croisiland\CommonBundle\Serializer\CruiseSearchModelSerializer;
  23. use Croisiland\CommonBundle\Service\CruiseSearchService;
  24. use Doctrine\Common\Collections\ArrayCollection;
  25. use Doctrine\ORM\NonUniqueResultException;
  26. use Doctrine\ORM\NoResultException;
  27. use Random\RandomException;
  28. class CruiseHelper
  29. {
  30. public function __construct(
  31. private readonly CruiseSearchService $cruiseSearchService,
  32. private readonly CruiseSearchModelSerializer $cruiseSearchModelSerializer,
  33. private MediaTagQueryHelper $mediaTagQueryHelper,
  34. private StopoverRepository $stopoverRepository,
  35. private CabinTypeRepository $cabinTypeRepository,
  36. private PartnerHelper $partnerHelper,
  37. private SuluHelper $suluHelper,
  38. ) {
  39. }
  40. /**
  41. * @param array<object> $searchElements available objects : Companies, Ship, Tags, Partner,
  42. * @param int $limit default 5
  43. * @param bool $random default false
  44. * @return Cruise[]
  45. *
  46. * @throws NoResultException
  47. * @throws NonUniqueResultException
  48. */
  49. public function searchCruises(array $searchElements, int $limit = 5, bool $random = false): array
  50. {
  51. $model = $this->getCruiseSearchModelFromSearchElements($searchElements);
  52. if (null === $model->getPartner()){
  53. $partner = $this->partnerHelper->getCurrentPartner();
  54. if ($partner){
  55. $model->setPartner($partner);
  56. }
  57. }
  58. $model->setPerPage($limit);
  59. $model->setRandomized($random);
  60. $result = $this->cruiseSearchService->search($model);
  61. return $result['paginated_result'];
  62. }
  63. /**
  64. * Génère une URL de liste de croisières avec des paramètres de recherche.
  65. *
  66. * @param array<object> $searchElements available objects : Companies, Ship, Tags, Partner,
  67. * @param string|null $locale Locale. Si null, utilise la locale actuelle.
  68. * @param string|null $webspaceKey Clé du webspace. Si null, utilise le webspace actuel.
  69. * @param string|null $domain Domaine personnalisé. Si null, utilise le domaine actuel.
  70. * @param string|null $scheme Schéma (ex: 'https'). Si null, utilise le schéma actuel.
  71. * @param bool $withoutDomain Si true, retourne une URL relative (sans domaine).
  72. *
  73. * @return string URL générée avec paramètres GET.
  74. */
  75. public function getCruiseSearchUrl(
  76. array $searchElements,
  77. ?string $locale = null,
  78. ?string $webspaceKey = null,
  79. ?string $domain = null,
  80. ?string $scheme = null,
  81. bool $withoutDomain = true): string
  82. {
  83. $model = $this->getCruiseSearchModelFromSearchElements($searchElements);
  84. if (null === $model->getPartner()){
  85. $partner = $this->partnerHelper->getCurrentPartner();
  86. if ($partner){
  87. $model->setPartner($partner);
  88. }
  89. }
  90. $queryParameters = $this->cruiseSearchModelSerializer->toQueryParameters($model);
  91. return $this->suluHelper->generateUrlWithQueryParams(
  92. ListController::BASE_PATH,
  93. $queryParameters,
  94. $locale,
  95. $webspaceKey,
  96. $domain,
  97. $scheme,
  98. $withoutDomain
  99. );
  100. }
  101. /**
  102. * @param array<object> $searchElements available objects : Companies, Ship, Tags, DestinationMain, DestinationSecondary,
  103. */
  104. private function getCruiseSearchModelFromSearchElements(array $searchElements): CruiseSearchModel
  105. {
  106. // TODO update with adder and removers in the CruiseSearchModel
  107. $model = new CruiseSearchModel();
  108. foreach ($searchElements as $element) {
  109. if ($element instanceof Company) {
  110. $model->addCompany($element);
  111. }
  112. if ($element instanceof Ship) {
  113. $model->addShip($element);
  114. }
  115. if ($element instanceof Tag) {
  116. $model->addTag($element);
  117. }
  118. if ($element instanceof DestinationMain) {
  119. $model->addDestinationMain($element);
  120. }
  121. if ($element instanceof DestinationSecondary) {
  122. $model->addDestinationSecondary($element);
  123. }
  124. if ($element instanceof Stopover) {
  125. $model->addDeparturePort($element);
  126. }
  127. }
  128. return $model;
  129. }
  130. /**
  131. * Retourne un tableau contenant l'objet à afficher et le nom de la classe en minuscule, utilisable pour concatener avec le nom du template
  132. * @return array{
  133. * subject: null|DestinationSecondary|Ship|DestinationMain|Company,
  134. * template: null|string
  135. * }
  136. */
  137. public function getSearchMainSubjectInfos(CruiseSearchModel $searchModel): array
  138. {
  139. $result = [
  140. 'subject' => null,
  141. 'template' => null,
  142. ];
  143. $collections = [
  144. // TODO $searchModel->getOffers()
  145. $searchModel->getDestinationsSecondary(),
  146. $searchModel->getShips(),
  147. $searchModel->getDestinationsMain(),
  148. $searchModel->getCompanies(),
  149. ];
  150. foreach ($collections as $collection) {
  151. if (!$collection->isEmpty()) {
  152. $lowest = null;
  153. foreach ($collection as $item) {
  154. /** @var DestinationSecondary|Ship|DestinationMain|Company $item */
  155. if ($lowest === null || $item->getListOrder() < $lowest->getListOrder()) {
  156. $lowest = $item;
  157. }
  158. }
  159. $result['subject'] = $lowest;
  160. $className = explode('\\', get_class($lowest));
  161. $result['template'] = mb_convert_case(end($className), MB_CASE_LOWER, "UTF-8");
  162. }
  163. }
  164. return $result;
  165. }
  166. /**
  167. * @param Cruise $cruise
  168. * @return array{
  169. * ship: MediaFile[],
  170. * stopovers: MediaFile[],
  171. * cabinTypes: MediaFile[]
  172. * }
  173. * @throws RandomException
  174. */
  175. public function getCruiseRelatedMedias(Cruise $cruise): array
  176. {
  177. // get media from Ship no tags, only Images, not random
  178. $shipMedias = $this->mediaTagQueryHelper->getMedias([], $cruise->getShip(), MediaFamilyCodeEnum::FAM_IMAGE, true);
  179. // get media from each itinerary stopovers no tags, only Images, not random
  180. $stopoversMedias = [];
  181. foreach ($this->stopoverRepository->findStopoversForCruise($cruise) as $stopover) {
  182. $stopoversMedias = array_merge(
  183. $stopoversMedias,
  184. $this->mediaTagQueryHelper->getMedias([], $stopover, MediaFamilyCodeEnum::FAM_IMAGE, true)
  185. );
  186. }
  187. // get media from each cruise cabinTypes no tags, only Images, not random
  188. $cabinTypesMedias = [];
  189. foreach ( $this->cabinTypeRepository->getCabinTypesForCruise($cruise) as $cabinType ) {
  190. $cabinTypesMedias = array_merge(
  191. $cabinTypesMedias,
  192. $this->mediaTagQueryHelper->getMedias([], $cabinType, MediaFamilyCodeEnum::FAM_IMAGE, true)
  193. );
  194. }
  195. return [
  196. 'ship' => $shipMedias,
  197. 'stopovers' => $stopoversMedias,
  198. 'cabinTypes' => $cabinTypesMedias,
  199. ];
  200. }
  201. }