<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Yaml\Yaml;
use Symfony\Component\Yaml\Exception\ParseException;
use Symfony\Component\Yaml\Exception;
use Twig\Environment;
use Liip\ImagineBundle\Imagine\Cache\CacheManager;
use Vich\UploaderBundle\Templating\Helper\UploaderHelper;
use Symfony\Contracts\Translation\TranslatorInterface;
use App\Entity\Residence;
use App\Entity\Typologie;
use App\Entity\Promo;
use App\Entity\VenteFlash;
use App\Entity\mediaResidence;
use App\Entity\blog;
use App\Entity\slider;
use App\Entity\Language;
use App\Entity\miseenavant;
use App\Entity\Theme;
use App\Entity\InscritNewsletter;
use App\Utils\IresaManager;
use App\Services\SeasonService;
use App\Services\ToolService;
use App\Services\SlugRouterService;
use App\Services\SlugService;
use App\Form\InscritNewsletterType;
/**
* @Route("/{_locale}", requirements={"_locale": "en|fr"})
*/
class DefaultController extends AbstractController
{
/**
* @var EntityManagerInterface
*/
private $em;
private $seasonService;
private $iresaManager;
private $toolService;
private $uploadHelper;
private $cacheManager;
private $translator;
private $twig;
private $slugRouterService;
public function __construct(EntityManagerInterface $em, SeasonService $seasonService, IresaManager $iresaManager, ToolService $toolService, UploaderHelper $uploadHelper, CacheManager $cacheManager, TranslatorInterface $translator, Environment $twig, SlugRouterService $slugRouterService)
{
$this->em = $em;
$this->seasonService = $seasonService;
$this->iresaManager = $iresaManager;
$this->toolService = $toolService;
$this->uploadHelper = $uploadHelper;
$this->cacheManager = $cacheManager;
$this->translator = $translator;
$this->twig = $twig;
$this->slugRouterService = $slugRouterService;
}
/**
* @Route("/", name="ac_platform_homepage")
*/
public function index(Request $request)
{
$session = $request->getSession();
$locale = $request->getLocale();
$lang = $this->em->getRepository(Language::class)->findOneByCode($locale);
if($request->query->has('_locale')) {
return $this->redirect($this->generateUrl('ac_platform_homepage', ['_locale' => $request->query->get('_locale')]));
}
$session->remove('next');
$session->remove('nextan');
$MiseEnAvantMajeur = $this->em->getRepository(blog::class)->getHome($lang);
$MisesEnAvantMineur = $this->em->getRepository(miseenavant::class)->getHome($lang);
$slider = $this->em->getRepository(slider::class)->getHome($lang);
$repository = $this->em->getRepository(Promo::class);
$promos = $repository->getBonsPlansDuMoment();
$photoProfil = [];
foreach($promos as $promo) {
$residence = $this->em->getRepository(Residence::class)->findOneByIdiresa($promo->getIdLieuHebergement());
if($residence instanceof residence) {
$season = $this->seasonService->getSeason();
$mediaResidence = $this->em->getRepository(mediaResidence::class)->findOneByLocation($residence->getId(), "content", $lang, $season);
if($mediaResidence instanceof mediaResidence) {
$image_path = $this->uploadHelper->asset($mediaResidence, 'imageFile');
$image_link = $this->cacheManager->getBrowserPath($image_path, 'offre');
$photoProfil[$promo->getId()] = $image_link;
}
}
}
$vars = array(
"page_code" => "home",
"searchBloc" => true,
"mod" => "promo",
"MiseEnAvantMajeur" => $MiseEnAvantMajeur,
"MisesEnAvantMineur" => $MisesEnAvantMineur,
"slider" => $slider,
"promos" => $promos,
"photoProfil" => $photoProfil
);
return $this->render('/front/Default/index.html.twig', $vars);
}
/**
* @Route("/dest/e/{code}", name="ac_platform_error")
*/
public function error(Request $request, $code)
{
$locale = $request->getLocale();
$lang = $this->em->getRepository(Language::class)->findOneByCode($locale);
if($request->query->has('_locale')) {
return $this->redirect($this->generateUrl('ac_platform_homepage', ['_locale' => $request->query->get('_locale')]));
}
$code_id = $this->translator->trans('erreur.' . $code, [], 'app');
switch($code_id) {
case 100: // erreur 100 / moteur de recherche / Pas d'hébergement trouvé
$title = "Ouups ! Petit problème...";
$message = "Nous n'avons trouvé aucune destination avec vos paramètres de recherche";
break;
case 101: // erreur 101 / moteur de recherche / Pas de destination trouvée
$title = "Ouups ! Petit problème...";
$message = "Aucun séjour ne correspond à vos souhaits. <br/>Nous vous invitons à renouveler votre recherche avec des dates différentes.";
break;
case 102: // erreur_102 / moteur de recherche / destination inconnue
$title = "Ouups ! Petit problème...";
$message = "Cette destination n'existe pas";
break;
case 200: // erreur 200 / Hebergement remonté mais pas de tarif
$title = "Ouups ! Petit problème...";
$message = "Il y a eu un problème technique avec cette réservation, merci de nous contacter au 04 82 98 36 42";
break;
}
$repository = $this->em->getRepository(Promo::class);
$promos = $repository->getBonsPlansDuMoment();
$vars = array(
"searchBloc" => true,
"title" => $title,
"message" => $message,
);
return $this->render('/front/Default/error.html.twig', $vars);
}
/**
* @Route("/themes", name="ac_platform_themes")
*/
public function themes(Request $request)
{
$locale = $request->getLocale();
$lang = $this->em->getRepository(Language::class)->findOneByCode($locale);
$criteria = [
'lang' => $lang,
'etat' => true
];
$orderBy = ['ordre' => 'ASC'];
$themes = $this->em->getRepository(Theme::class)->findBy($criteria, $orderBy);
$themesWithUrls = [];
foreach ($themes as $theme) {
$themesWithUrls[] = [
'entity' => $theme,
'url' => $this->slugRouterService->generateCanonicalUrl($theme, 'ac_platform_theme_slug', ['_locale' => $locale])
];
}
$vars = [
'themes' => $themesWithUrls
];
return $this->render('/front/Moteur/themes.html.twig', $vars);
}
public function chglng(Request $request)
{
$lng = strtolower($request->request->get("lng"));
$uri = $request->request->get("uri");
$uri = str_replace("/".$request->getLocale()."/", "/".$lng."/", $uri);
return new JsonResponse($uri);
}
/**
* @Route("/inscription-newsletter", name="ac_platform_inscriptionnewsletter")
*/
public function newsletter(Request $request)
{
$inscritNewsletter = new InscritNewsletter();
$form = $this->createForm(InscritNewsletterType::class, $inscritNewsletter);
if ($request->isXmlHttpRequest()) {
// La requête est une requête Ajax
$email = $request->request->get('email');
if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
$retour = 'ko';
return new JsonResponse($retour);
}
$newsletter = $this->em->getRepository(InscritNewsletter::class)->findOneByEmail($email);
if(!$newsletter instanceof InscritNewsletter) {
$newsletter = new InscritNewsletter();
$newsletter->setEmail($email);
$newsletter->setEtat(1);
$this->em->persist($newsletter);
$this->em->flush();
$retour = 'ok';
} else {
$retour = 'email_exists';
}
return new JsonResponse($retour);
}
return $this->render('/front/Default/newsletter.html.twig', array(
'form'=>$form->createView()
));
}
public function familles(Request $request) {
$moteur = $this->iresaManager->getDataMoteur();
$familles = $moteur->ListFamillesLieuHebergement;
$retour = array(
"familles" => $familles
);
return $this->render('/front/Moteur/familles.html.twig', $retour);
}
public function checkpanier(Request $request)
{
$session = $request->getSession();
$resas = $session->get('resas');
if($resas) {
$dt = new \DateTime;
foreach($resas as $resa) {
echo $dt->getTimestamp() - $resa["timestamp"];
if( $dt->getTimestamp() - $resa["timestamp"] > 3600) {
$session->remove('resas');
}
}
}
return new JsonResponse("");
}
/**
* @Route("/menu", name="ac_platform_menu")
*/
public function menu(Request $request)
{
$route = $request->query->get('route_name');
$params = $request->query->get('params');
$params = is_null($params) ? [] : $params;
$currentLocale = $request->getLocale();
$repository = $this->em->getRepository(Promo::class);
$count = $repository->countPromos();
$haspromo = $count > 0 ? true: false;
$venteFlash = new VenteFlash();
try {
$projectRoot = $this->getParameter('kernel.project_dir');
$parameter = Yaml::parse(file_get_contents($projectRoot.'/var/config/vente-flash.yaml'));
$venteFlash->setParameter($parameter);
} catch (ParseException $exception) {
//dump('Unable to parse the YAML string: %s', $exception->getMessage());
}
$categories = [];
$promosCategories = Promo::CATEGORIES;
$now = new \DateTime();
$now = new \DateTime( $now->format('Y-m-d'));
if($venteFlash->actif && $now >= $venteFlash->operationDateDebut && $now <= $venteFlash->operationDateFin) {
array_unshift($promosCategories, Promo::CATEGORY_VENTES_FLASH);
}
foreach($promosCategories as $category ) {
$method = $this->translator->trans("promos." . $category . ".method" , [], 'promos');
if(method_exists( $repository, $method)) {
$promos = $repository->{$method}();
if(count($promos) > 0){
$categories[] = $category;
}
}
}
// Générer les URLs de changement de langue via le service
$url_fr = $this->slugRouterService->generateUrlForLocale($route, $params, $currentLocale, 'fr');
$url_en = $this->slugRouterService->generateUrlForLocale($route, $params, $currentLocale, 'en');
$vars = array(
"haspromo" => $haspromo,
"categories" => $categories,
"route_name" => $route,
"params" => $params,
"url_fr" => $url_fr,
"url_en" => $url_en
);
return $this->render('/front/Default/menu.html.twig', $vars);
}
/**
* Génère l'URL pour une locale donnée
*/
private function generateLocaleUrl(?string $route, array $params, string $currentLocale, string $targetLocale): ?string
{
if (empty($route)) {
return null;
}
// Routes de résidences
if (in_array($route, ['ac_platform_produit_slug', 'ac_platform_produit'])) {
return $this->generateResidenceLocaleUrl($params, $targetLocale);
}
// Routes de destinations
if (in_array($route, ['ac_platform_destination_slug', 'ac_platform_destination'])) {
return $this->generateDestinationLocaleUrl($params, $targetLocale);
}
// Fallback : changer juste la locale
try {
return $this->generateUrl($route, array_merge($params, ['_locale' => $targetLocale]));
} catch (\Exception $e) {
return null;
}
}
/**
* Génère l'URL d'une résidence dans une locale donnée
*/
private function generateResidenceLocaleUrl(array $params, string $targetLocale): ?string
{
$slug = $params['slug'] ?? null;
$id = $params['id'] ?? null;
$residence = null;
// Trouver la résidence depuis le slug
if ($slug) {
$result = $this->slugService->findEntityBySlug($slug);
if ($result && $result['entity'] instanceof \App\Entity\OptionResidence) {
$residence = $result['entity']->getResidence();
}
}
// Ou depuis l'ID
if (!$residence && $id) {
$residence = $this->em->getRepository(\App\Entity\Residence::class)->findOneBy(['idiresa' => $id]);
}
if (!$residence) {
return null;
}
// Trouver l'OptionResidence pour la langue cible
$lang = $this->em->getRepository(\App\Entity\Language::class)->findOneBy(['code' => $targetLocale]);
if (!$lang) {
return null;
}
$optionResidence = $this->em->getRepository(\App\Entity\OptionResidence::class)->findOneBy([
'residence' => $residence,
'lang' => $lang
]);
if (!$optionResidence || !$optionResidence->getCanonical()) {
return null;
}
// Générer l'URL avec le slug canonique
$newParams = array_merge($params, ['slug' => $optionResidence->getCanonical(), '_locale' => $targetLocale]);
unset($newParams['id']); // Retirer l'ID de l'ancienne structure
try {
return $this->generateUrl('ac_platform_produit_slug', $newParams);
} catch (\Exception $e) {
return null;
}
}
/**
* Génère l'URL d'une destination dans une locale donnée
*/
private function generateDestinationLocaleUrl(array $params, string $targetLocale): ?string
{
$slug = $params['slug'] ?? null;
$id = $params['id'] ?? null;
$destination = null;
// 1. Trouver la destination depuis le slug
if ($slug) {
$result = $this->slugService->findEntityBySlug($slug);
if ($result && $result['entity'] instanceof \App\Entity\Destination) {
$destination = $result['entity'];
}
}
// Ou depuis l'ID (route legacy)
if (!$destination && $id) {
$destination = $this->em->getRepository(\App\Entity\Destination::class)->find($id);
}
if (!$destination) {
return null;
}
// 2. Récupérer l'idiresa ou code_traduction pour trouver la version dans l'autre langue
$idiresa = $destination->getIdIresa() ?: $destination->getCodeTraduction();
if (!$idiresa) {
return null;
}
// 3. Trouver la Destination dans la langue cible
$lang = $this->em->getRepository(\App\Entity\Language::class)->findOneBy(['code' => $targetLocale]);
if (!$lang) {
return null;
}
$targetDestination = $this->em->getRepository(\App\Entity\Destination::class)->findOneBy([
'id_iresa' => $idiresa,
'lang' => $lang
]);
if (!$targetDestination) {
return null;
}
// 4. Utiliser le slug canonique de la destination cible
$targetSlug = $targetDestination->getCanonical() ?: $targetDestination->getSlug();
if (!$targetSlug) {
return null;
}
// 5. Générer l'URL avec le bon slug
$newParams = array_merge($params, ['slug' => $targetSlug, '_locale' => $targetLocale]);
unset($newParams['id']); // Retirer l'ID de l'ancienne structure
try {
return $this->generateUrl('ac_platform_destination_slug', $newParams);
} catch (\Exception $e) {
return null;
}
}
/**
* @Route("/footer", name="ac_platform_footer")
*/
public function footer(Request $request)
{
$locale = $request->getLocale();
$locale = $request->getLocale();
$lang = $this->em->getRepository(Language::class)->findOneByCode($locale);
$residences = $this->em->getRepository(Residence::class)->findEnabled($lang);
$vars = array(
"hebergements" => $residences
);
$html = $this->twig->render('/front/Default/footer.html.twig', $vars);
$twig = new Response($html);
$twig->headers->set('Content-Type', 'text/html');
return $twig;
}
}