<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
use Symfony\Contracts\Translation\TranslatorInterface;
use App\Utils\IresaManager;
use App\Utils\Residences;
use App\Services\ToolService;
use App\Services\SeasonService;
use App\Services\ImhotepHebergementService;
use App\Services\SlugRouterService;
use App\Entity\Typologie;
use App\Entity\Residence;
use App\Entity\mediaResidence;
use App\Entity\Language;
use App\Entity\Destination;
/**
* @Route("/{_locale}", requirements={"_locale": "en|fr"})
*/
class DestinationController extends AbstractController
{
private $em;
private $session;
private $flashbag;
private $user;
private $seasonService;
private $iresaManager;
private $toolService;
private $helper;
private $cacheManager;
private $translator;
private $residenceService;
private $imhotepService;
private $slugRouterService;
function __construct(EntityManagerInterface $em, SessionInterface $session, SeasonService $seasonService, IresaManager $iresaManager, ToolService $toolService, UploaderHelper $helper, CacheManager $cacheManager, TranslatorInterface $translator, Residences $residenceService, ImhotepHebergementService $imhotepService, SlugRouterService $slugRouterService) {
$this->em = $em;
$this->session = $session;
$this->flashbag = $this->session->getFlashBag();
$this->seasonService = $seasonService;
$this->iresaManager = $iresaManager;
$this->toolService = $toolService;
$this->helper = $helper;
$this->cacheManager = $cacheManager;
$this->translator = $translator;
$this->residenceService = $residenceService;
$this->imhotepService = $imhotepService;
$this->slugRouterService = $slugRouterService;
}
/**
* Route de compatibilité - Ancienne structure avec ID
* Redirige 301 vers la nouvelle structure sans ID
* @Route("/destination/{slug}/{id}", name="ac_platform_destination", requirements={"id"="\d+"})
*/
public function destinationLegacyRedirect(Request $request, string $slug, int $id): Response
{
// Charger la destination par ID pour récupérer son slug canonique
$locale = $request->getLocale();
$lang = $this->em->getRepository(Language::class)->findOneByCode($locale);
$destination = $this->em->getRepository(Destination::class)->findOneByLang([
'lang_id' => $lang->getId(),
'code_traduction' => $id
]);
if (!$destination) {
throw $this->createNotFoundException('Destination inexistante');
}
// Redirection 301 permanente vers la nouvelle structure avec slug canonique
$canonicalSlug = $destination->getCanonical();
if (empty($canonicalSlug)) {
// Fallback sur le slug historique si pas de canonical
$canonicalSlug = $destination->getSlug() ?: $slug;
}
// Préserver les query parameters
$queryParams = $request->query->all();
return $this->redirectToRoute('ac_platform_destination_slug',
array_merge(['slug' => $canonicalSlug], $queryParams),
301
);
}
/**
* Route principale - Nouvelle structure avec slug uniquement
* @Route("/destination/{slug}", name="ac_platform_destination_slug")
*/
public function destinationActionRequest(Request $request, string $slug): Response
{
$locale = $request->getLocale();
// Résoudre le slug vers une destination
$result = $this->slugRouterService->resolveDestinationSlug($slug, $locale);
if (!$result) {
throw $this->createNotFoundException('Destination non trouvée');
}
// Vérifier si on doit rediriger vers le slug canonique
if (!$result['is_canonical'] && !empty($result['canonical_slug'])) {
// Préserver les query parameters
$queryParams = $request->query->all();
return $this->redirectToRoute('ac_platform_destination_slug',
array_merge(['slug' => $result['canonical_slug']], $queryParams),
301
);
}
$destination = $result['entity'];
$id = $destination->getCodeTraduction(); // Récupérer l'ID depuis l'entité
if ($id == 0) {
$id = 2; // Défaut => France
}
$locale = $request->getLocale();
$lang = $this->em->getRepository(Language::class)->findOneByCode($locale);
// Récupération des paramètres de recherche
$datearrivee = $request->query->get('datearrivee', '');
$dureeRequest = $request->query->get('duree');
$nbpax = $request->query->get('nbpax');
$nbadultes = $request->query->get('nbadultes');
$nbenfants = $request->query->get('nbenfants');
$search = $request->query->get('search');
// Liste des durées par défaut
$listDurees = !empty($dureeRequest) ? [$dureeRequest] : [7, 14, 21, 5, 4, 3, 2];
// Recherche optimisée avec IresaManager
$availabilityResult = $this->iresaManager->findBestAvailability($id, $datearrivee, $listDurees);
if ($availabilityResult === false) {
//$code = $this->translator->trans('erreur.erreurs.100', [], 'app');
//return $this->redirect($this->generateUrl('ac_platform_error', ['code' => $code]));
throw $this->createNotFoundException('Destination non trouvée');
}
$result = $availabilityResult['result'];
$duree = $availabilityResult['duree'];
$queryParams = $availabilityResult['query_params'];
$hebergements = $result["FichesLieuHebergement"];
$reponses = $result["ListReponses"];
$prestations = $result["FichesPrestation"];
// Comptage et validation des hébergements
$countheb = 0;
$hebergement = null;
foreach ($hebergements as $heb) {
if (!empty($heb["ListFiches"])) {
$countheb++;
$hebergement = $heb;
}
}
if ($countheb == 0) {
$code = $this->translator->trans('erreur.erreurs.101', [], 'app');
//return $this->redirect($this->generateUrl('ac_platform_error', ['code' => $code]));
//throw $this->createNotFoundException('Destination non trouvée');
// Pas d'hébergement trouvé, on affiche la page avec message adapté
}
// Construction des données pour la vue
//$listeHebergements = $this->iresaManager->buildAccommodationsList($hebergements);
// Titre et description
$titre = $search ?
$this->translator->trans('themes.noResult.titre', [], 'app') :
$destination->getTitreLong();
$description = $search ?
$this->translator->trans('themes.noResult.description', [], 'app') :
$destination->getIntroduction();
// Traitement des fiches avec le service existant
$this->residenceService->setLocale($locale);
$fiches = $this->residenceService->getSejours($hebergements, $reponses, $lang, $nbpax);
// Photos de profil
$photoProfil = [];
foreach ($fiches as $k => $fiche) {
$residence = $fiche['residence'];
if ($residence instanceof Residence) {
$season = $this->seasonService->getSeason();
$slider = $this->em->getRepository(mediaResidence::class)->findOneByLocation(
$residence->getId(),
"content",
$lang,
$season
);
if ($slider instanceof mediaResidence) {
$image_path = $this->helper->asset($slider, 'imageFile');
$image_link = $this->cacheManager->getBrowserPath($image_path, 'offre');
$photoProfil[$k] = $image_link;
}
}
}
$aff_date = $request->query->get('aff_date', false);
$vars = [
"page" => "destination",
"id" => $id,
"mod" => "destination",
"hebergements" => $hebergements,
"searchBloc" => true,
"aff_date" => $aff_date,
"datearrivee" => $datearrivee,
"duree" => $duree,
"nbadultes" => $nbadultes,
"nbenfants" => $nbenfants,
'nbpax' => $nbpax,
'titre' => $titre,
'description' => $description,
"reponses" => $fiches,
"photoProfil" => $photoProfil,
"metaTitle" => $destination->getMetaTitle(),
"metaDescription" => $destination->getMetaDescription(),
"seoTitle" => $destination->getSeoTitle(),
"seoContent" => $destination->getSeoContent(),
"countheb" => $countheb,
//"listeHebergements" => $listeHebergements,
"current_entity" => $destination, // Pour le menu de changement de langue
"current_entity_type" => 'Destination' // Type d'entité pour le menu
];
return $this->render('/front/Recherche/destination.html.twig', $vars);
}
/**
* Récupère les hébergements d’un lieu et de sa descendance.
*
* @Route("/infos/hebergements/{idLieu}", name="hebergements_lieu")
*/
public function hebergements_lieu(int $idLieu, Request $request): JsonResponse
{
// Paramètre optionnel ?view=all pour afficher toutes les résidences
$view = $request->query->get('view', '');
$destination = $this->em->getRepository(Destination::class)->findOneBy(['idIresa' => $idLieu]);
// Récupération des résidences à partir du service Imhotep
$residences = $this->imhotepService->getHebergementsByLieu($idLieu);
$hebergements = [];
foreach ($residences as $residence) {
// Recherche du parent direct (Destination) via le champ destinationIdiresa
$destinationParent = $this->em->getRepository(Destination::class)->findOneBy(['idIresa' => $residence->getDestinationIdiresa()]);
// Construction dynamique du chemin
$cheminParts = [];
$courante = $destinationParent;
while ($courante !== null) {
// On utilise TitreCourt, mais vous pouvez choisir TitreLong selon vos besoins
$cheminParts[] = $courante->getTitreCourt();
$cheminInfos[] = [
'id' => (int) $courante->getId(),
'idiresa' => (int) $courante->getIdIresa(),
'nom' => (string) $courante->getTitreCourt(),
'etat' => (bool) $courante->getEtat(),
];
$courante = $courante->getParent();
}
// On inverse pour avoir la racine en premier (France / …)
$chemin = implode(' / ', array_reverse($cheminParts));
$hebergements[] = [
'id' => (int) $residence->getId(),
'idiresa' => (int) $residence->getIdiresa(),
'chemin' => (string) $chemin,
// 'cheminInfos' => (array) $cheminInfos,
//'commercialisation' => (bool) $residence->getCommercialisation(),
'hebergement_nom' => $residence->getNom(),
'lieu_id' => $destinationParent? (int) $destinationParent->getId() : null,
'lieu_idiresa' => $destinationParent? (int) $destinationParent->getIdIresa() : null,
'lieu_nom' => $destinationParent? (string) $destinationParent->getTitreCourt() : null,
//'lieu_etat' => $destinationParent? (bool) $destinationParent->getEtat() : null,
];
}
// Construction du retour JSON
$response = [
'destination' => [
'id' => (int) $destination? $destination->getId() : null,
'idiresa' => (int) $idLieu,
'nom' => $destination? (string) $destination->getTitreCourt() : null,
],
'hebergements' => $hebergements,
];
return new JsonResponse($response);
}
}