src/Controller/DefaultController.php line 204

Open in your IDE?
  1. <?php
  2. namespace App\Controller;
  3. use App\Entity\Atouts;
  4. use App\Entity\Banner;
  5. use App\Entity\LegalPage;
  6. use App\Entity\Continent;
  7. use App\Entity\Destination;
  8. use App\Entity\Flight;
  9. use App\Entity\Formule;
  10. use App\Entity\HebergemntOffer;
  11. use App\Entity\Highlight;
  12. use App\Entity\Included;
  13. use App\Entity\Informations;
  14. use App\Entity\Itinerary;
  15. use App\Entity\ItineraryPic;
  16. use App\Entity\Offer;
  17. use App\Entity\OfferHebergement;
  18. use App\Entity\OfferInfo;
  19. use App\Entity\QuoteRequest;
  20. use App\Entity\TypeVoyage;
  21. use Symfony\Bridge\Twig\Mime\TemplatedEmail;
  22. use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
  23. use Symfony\Component\HttpFoundation\Response;
  24. use Symfony\Component\Routing\Annotation\Route;
  25. use Symfony\Component\HttpFoundation\Request;
  26. use Symfony\Component\Mailer\MailerInterface;
  27. use Symfony\Component\Mime\Address;
  28. use Symfony\Contracts\HttpClient\HttpClientInterface;
  29. class DefaultController extends AbstractController
  30. {
  31.     /**
  32.      * @Route("/", name="app")
  33.      */
  34.     public function index()
  35.     {
  36.         $em $this->getDoctrine()->getManager();
  37.         $offEscapade $em->getRepository(Offer::class)->findBy(['type'=>1'isPublish'=>true]);
  38.         $offCircuit $em->getRepository(Offer::class)->findBy(['type'=>2'isPublish'=>true]);
  39.         $ourOffer $em->getRepository(Offer::class)->findBy(['OurOffer'=>1'isPublish'=>true]);
  40.         $infos $em->getRepository(Informations::class)->findOneBy(['id'=>1]);   
  41.         $continents $em->getRepository(Continent::class)->findAll();
  42.         $atouts $em->getRepository(Atouts::class)->findAll();
  43.         $banner $em->getRepository(Banner::class)->findOneBy(['page'=>"contact"]); 
  44.         //dd($atouts); 
  45.         return $this->render('default/index.html.twig',[
  46.             'offEscapade'=>$offEscapade,
  47.             'offCircuit'=>$offCircuit,
  48.             'ourOffer'=>$ourOffer,
  49.             'continents'=>$continents,
  50.             'infos'=>$infos,
  51.             'atouts'=>$atouts,
  52.             'banner'=>$banner
  53.         ]);
  54.     }
  55.     /**
  56.     * @Route("/search", name="search", methods={"GET"})
  57.     */
  58.     public function search(Request $request)
  59.     {
  60.         $em $this->getDoctrine()->getManager();
  61.     $q trim($request->query->get('q'''));
  62.     $results = [];
  63.     if ($q !== '') {
  64.         $results $em->getRepository(Offer::class)->searchOffers($q);
  65.     }
  66.     //dd($results);
  67.     return $this->render('default/search.html.twig', [
  68.         'query'   => $q,
  69.         'results' => $results
  70.     ]);
  71.     }
  72.      /**
  73.      * @Route("/oo", name="footer")
  74.      */
  75.     public function footer()
  76.     {
  77.         $em $this->getDoctrine()->getManager();
  78.         $infos $em->getRepository(Informations::class)->findOneBy(['id'=>1]);   
  79.         return $this->render('default/footer.html.twig',['infos'=>$infos]);
  80.     }
  81.     /**
  82.      * @Route("/continent/{slug}", name="o.continent")
  83.      */
  84.     public function continent($slug)
  85.     {
  86.         $em $this->getDoctrine()->getManager();
  87.         $continent $em->getRepository(Continent::class)->findOneBy(['slug'=>$slug]);
  88.         $offers $em->getRepository(Offer::class)->findBy(['continent'=>$continent'isPublish'=>true]);
  89.         return $this->render('default/continent.html.twig',
  90.         ['offers'=>$offers,
  91.          'continent'=>$continent,
  92.         ]);
  93.     }
  94.     /**
  95.      * @Route("/o-escapade/destination/{slug}", name="o.escapade.destination")
  96.      */
  97.     public function escapadeDestination($slug)
  98.     {
  99.         $em $this->getDoctrine()->getManager();
  100.         // Cherche d'abord par destination slug, sinon par offre slug
  101.         $destination $em->getRepository(Destination::class)->findOneBy(['slug' => $slug]);
  102.         if ($destination) {
  103.             $offer $em->getRepository(Offer::class)->findOneBy(['destination' => $destination'isPublish' => true]);
  104.         } else {
  105.             $offer $em->getRepository(Offer::class)->findOneBy(['slug' => $slug'isPublish' => true]);
  106.             $destination $offer $offer->getDestination() : null;
  107.         }
  108.         if (!$offer) { throw $this->createNotFoundException(); }
  109.         $offerHebergement $em->getRepository(OfferHebergement::class)->findBy(['offer' => $offer]);
  110.         $formules $em->getRepository(Formule::class)->findBy(['offer' => $offer]);
  111.         return $this->render('default/escapade-destination.html.twig', [
  112.             'destination' => $destination,
  113.             'offerHebergement' => $offerHebergement,
  114.             'formules' => $formules,
  115.             'offer' => $offer,
  116.         ]);
  117.     }
  118.     /**
  119.      * @Route("/o-escapade", name="o.escapade")
  120.      * @Route("/o-circuit", name="o.circuit")
  121.      * @Route("/o-roadtrip", name="o.roadtrip")
  122.      * @Route("/o-croisiere", name="o.croisiere")
  123.      */
  124.     public function Ooffers(Request $request)
  125.     {   
  126.         $em $this->getDoctrine()->getManager();
  127.         $routeName $request->attributes->get('_route');
  128.          if($routeName == 'o.escapade'){
  129.         $typeOffer $em->getRepository(TypeVoyage::class)->findOneBy(['id'=>1]);
  130.         $offers $em->getRepository(Offer::class)->findBy(['type'=>1'isPublish'=>true]);
  131.         }
  132.         if($routeName == 'o.circuit'){
  133.         $typeOffer $em->getRepository(TypeVoyage::class)->findOneBy(['id'=>2]);
  134.         $offers $em->getRepository(Offer::class)->findBy(['type'=>2'isPublish'=>true]);
  135.         }
  136.          if($routeName == 'o.roadtrip'){
  137.         $typeOffer $em->getRepository(TypeVoyage::class)->findOneBy(['id'=>3]);
  138.         $offers $em->getRepository(Offer::class)->findBy(['type'=>3'isPublish'=>true]);
  139.          }
  140.         if($routeName == 'o.croisiere'){
  141.         $typeOffer $em->getRepository(TypeVoyage::class)->findOneBy(['id'=>4]);
  142.         $offers $em->getRepository(Offer::class)->findBy(['type'=>4'isPublish'=>true]);
  143.          }
  144.         return $this->render('default/offers.html.twig', ['offers'=>$offers,'typeOffer'=> $typeOffer]);
  145.     }
  146.     
  147.     /**
  148.      * @Route("/o-circuit/destination-ex", name="o.circuit.destination-ex")
  149.      */
  150.     public function circuitDestinationEx()
  151.     {
  152.         $em $this->getDoctrine()->getManager();
  153.         return $this->render('default/circuit-destination-ex.html.twig');
  154.     }
  155.     /**
  156.      * @Route("/o-road/destination-ex", name="o.road.destination-ex")
  157.      */
  158.     public function roadtDestinationEx()
  159.     {
  160.         $em $this->getDoctrine()->getManager();
  161.         return $this->render('default/roadtrip-destination.html.twig');
  162.     }
  163.      /**
  164.      * @Route("/o-tropik-agence-de-voyage-en-guadeloupe", name="o.agency.legacy")
  165.      */
  166.     public function agencyLegacy(): Response
  167.     {
  168.         return $this->redirectToRoute('o.agency', [], 301);
  169.     }
  170.     /**
  171.      * @Route("/o-tropik-agence-de-voyages-en-guadeloupe", name="o.agency")
  172.      */
  173.     public function agency()
  174.     {
  175.         $em $this->getDoctrine()->getManager();
  176.         $offers $em->getRepository(Offer::class)->findBy(['OurOffer'=>1'isPublish'=>true]);
  177.         return $this->render('default/agency.html.twig',['offers'=>$offers]);
  178.     }
  179.     /**
  180.      * @Route("/o-croisiere/destination-ex", name="o.ccroisiere.destination")
  181.      */
  182.     public function oCroisiere()
  183.     {
  184.         $em $this->getDoctrine()->getManager();
  185.         $id =3;
  186.         $offer $em->getRepository(Offer::class)->findOneBy(['id'=>$id]);
  187.         return $this->render('default/croisiere-destination.html.twig',
  188.         ['offer'=>$offer]);
  189.     }
  190.     /**
  191.      * @Route("/o-circuit/{slug}", name="o.circuit.destination")
  192.      * @Route("/o-roadtrip/{slug}", name="o.roadtrip.destination")
  193.      * @Route("/o-croisiere/{slug}", name="o.croisiere.destination")
  194.      */
  195.     public function oOffer(Request $request$slug)
  196.     {
  197.         $em $this->getDoctrine()->getManager();
  198.         $routeName $request->attributes->get('_route');
  199.         $offer $em->getRepository(Offer::class)->findOneBy(['slug'=>$slug'isPublish'=>true]);
  200.         if (!$offer) { throw $this->createNotFoundException(); }
  201.         $highlight =  $em->getRepository(Highlight::class)->findBy(['offer'=>$offer]);
  202.         $itinerary $em->getRepository(Itinerary::class)->findBy(['offer'=>$offer]);
  203.         $photoItinerary $em->getRepository(ItineraryPic::class)->findBy(['Offer'=>$offer]);
  204.         $hebergementOffer $em->getRepository(HebergemntOffer::class)->findBy(['offer'=>$offer]);
  205.         $flight $em->getRepository(Flight::class)->findBy(['offer'=>$offer]) ;
  206.         $infos $em->getRepository(OfferInfo::class)->findBy(['offer'=>$offer]) ; 
  207.         $included $em->getRepository(Included::class)->findBy(['Offer'=>$offer]) ;
  208.           $routeName $request->attributes->get('_route');
  209.         if($routeName == 'o.circuit.destination'){
  210.         
  211.         return $this->render('default/circuit-destination.html.twig',
  212.          ['offer'=>$offer
  213.         'highlight'=>$highlight,
  214.         'photoItinerary'=>$photoItinerary,
  215.         'hebergementOffer'=>$hebergementOffer,
  216.         'included'=>$included,
  217.         'flight'=>$flight,
  218.         'infos'=>$infos,
  219.         'itinerary'=>$itinerary]);
  220.         }
  221.           if($routeName == 'o.roadtrip.destination'){
  222.         
  223.         return $this->render('default/roadtrip-destination.html.twig',
  224.         ['offer'=>$offer
  225.         'highlight'=>$highlight,
  226.         'flight'=>$flight,
  227.         'photoItinerary'=>$photoItinerary,
  228.         'hebergementOffer'=>$hebergementOffer,
  229.         'included'=>$included,
  230.         'infos'=>$infos,
  231.         'itinerary'=>$itinerary]);
  232.         }
  233.           if($routeName == 'o.croisiere.destination'){
  234.         
  235.         return $this->render('default/croisiere-destination.html.twig',
  236.         ['offer'=>$offer
  237.         'highlight'=>$highlight,
  238.         'flight'=>$flight,
  239.         'photoItinerary'=>$photoItinerary,
  240.         'hebergementOffer'=>$hebergementOffer,
  241.         'included'=>$included,
  242.         'infos'=>$infos,
  243.         'itinerary'=>$itinerary]);
  244.         }
  245.     }
  246.      /**
  247.      * @Route("/o-contact", name="o.contact")
  248.      * @Route("/demande-de-devis", name="o.devis")
  249.      */
  250.     public function contact(Request $request)
  251.     {
  252.         $em $this->getDoctrine()->getManager();
  253.         $routeName $request->attributes->get('_route');
  254.         if($routeName == 'o.contact'){
  255.           $em $this->getDoctrine()->getManager();
  256.           $infos $em->getRepository(Informations::class)->findOneBy(['id'=>1]);
  257.           $banner $em->getRepository(Banner::class)->findOneBy(['page'=>"contact"]);
  258.         return $this->render('default/contact.html.twig',['infos'=>$infos'banner'=>$banner'hcaptchaSiteKey'=>$_ENV['HCAPTCHA_SITE_KEY']]);
  259.         }
  260.          $routeName $request->attributes->get('_route');
  261.          if($routeName == 'o.devis'){
  262.             $typeSejour $em->getRepository(TypeVoyage::class)->findAll();
  263.             $banner $em->getRepository(Banner::class)->findOneBy(['page'=>"devis"]);
  264.          return $this->render('default/devis.html.twig',['typeSejour'=>$typeSejour,'banner'=>$banner'hcaptchaSiteKey'=>$_ENV['HCAPTCHA_SITE_KEY']]);
  265.         }
  266.     }
  267.     /**
  268.      * @Route("/o-contact/send", name="contact.send", methods={"POST"})
  269.      */
  270.     public function contactSend(Request $requestMailerInterface $mailerHttpClientInterface $httpClient): Response
  271.     {
  272.         $em $this->getDoctrine()->getManager();
  273.         $infos $em->getRepository(Informations::class)->findOneBy(['id' => 1]);
  274.         $banner $em->getRepository(Banner::class)->findOneBy(['page' => 'contact']);
  275.         if (!$this->verifyHCaptcha($request->request->get('h-captcha-response'''), $httpClient)) {
  276.             $this->addFlash('error''Vérification anti-spam échouée. Merci de réessayer.');
  277.             return $this->render('default/contact.html.twig', ['infos' => $infos'banner' => $banner'hcaptchaSiteKey' => $_ENV['HCAPTCHA_SITE_KEY']]);
  278.         }
  279.         $name    trim((string) $request->request->get('name'''));
  280.         $email   trim((string) $request->request->get('email'''));
  281.         $phone   trim((string) $request->request->get('phone'''));
  282.         $subject trim((string) $request->request->get('subject''Message de contact'));
  283.         $message trim((string) $request->request->get('message'''));
  284.         if ($name === '' || $email === '' || $message === '') {
  285.             $this->addFlash('error''Merci de remplir les champs obligatoires.');
  286.             return $this->render('default/contact.html.twig', ['infos' => $infos'banner' => $banner]);
  287.         }
  288.         $mail = (new TemplatedEmail())
  289.             ->from(new Address($_ENV['MAIL_FROM'], 'Otropik'))
  290.             ->to($_ENV['MAIL_TO'])
  291.             ->replyTo(new Address($email$name))
  292.             ->subject('[Contact] ' $subject)
  293.             ->htmlTemplate('emails/contact.html.twig')
  294.             ->context(compact('name''email''phone''subject''message'));
  295.         $mailer->send($mail);
  296.         $this->addFlash('success''Votre message a bien été envoyé. Nous vous répondrons sous 24–48h.');
  297.         return $this->redirectToRoute('o.contact');
  298.     }
  299.     private function verifyHCaptcha(string $tokenHttpClientInterface $httpClient): bool
  300.     {
  301.         if ($token === '') return false;
  302.         $response $httpClient->request('POST''https://hcaptcha.com/siteverify', [
  303.             'body' => [
  304.                 'secret'   => $_ENV['HCAPTCHA_SECRET_KEY'],
  305.                 'response' => $token,
  306.             ],
  307.         ]);
  308.         $data $response->toArray(false);
  309.         return $data['success'] ?? false;
  310.     }
  311.         /**
  312.         * @Route("/devis/send", name="quote.request.send", methods={"POST"})
  313.         */
  314.         public function send(Request $requestMailerInterface $mailerHttpClientInterface $httpClient)
  315.         {
  316.             $em $this->getDoctrine()->getManager();
  317.             if (!$this->verifyHCaptcha($request->request->get('h-captcha-response'''), $httpClient)) {
  318.                 $this->addFlash('error''Vérification anti-spam échouée. Merci de réessayer.');
  319.                 return $this->redirectToRoute('o.devis');
  320.             }
  321.             $tripTypeId  $request->request->getInt('tripType') ?: null;
  322.             $typeSejour  $em->getRepository(TypeVoyage::class)->findOneBy(['id' => $tripTypeId]);
  323.             $destination trim((string) $request->request->get('destination'''));
  324.             $fullName    trim((string) $request->request->get('fullName'''));
  325.             $clientEmail trim((string) $request->request->get('email'''));
  326.             if ($destination === '' || $fullName === '' || $clientEmail === '') {
  327.                 $this->addFlash('error''Merci de remplir les champs obligatoires.');
  328.                 return $this->redirectToRoute('o.devis');
  329.             }
  330.             $startDateStr = (string) $request->request->get('startDate''');
  331.             $startDate null;
  332.             if ($startDateStr !== '') {
  333.                 try { $startDate = new \DateTimeImmutable($startDateStr); } catch (\Throwable $e) {}
  334.             }
  335.             $qr = new QuoteRequest();
  336.             $qr->setTripVoyage($typeSejour)
  337.                 ->setDestination($destination)
  338.                 ->setStartDate($startDate)
  339.                 ->setDurrationDays($request->request->getInt('durationDays') ?: null)
  340.                 ->setTravAdults(max(1$request->request->getInt('travAdults'2)))
  341.                 ->setTravChildren(max(0$request->request->getInt('travChildren'0)))
  342.                 ->setChildrenAge(trim((string) $request->request->get('childrenAges')))
  343.                 ->setBudgetForm($request->request->getInt('budgetFrom') ?: null)
  344.                 ->setBoardType(trim((string) $request->request->get('boardType')))
  345.                 ->setInterest(trim((string) $request->request->get('interests')))
  346.                 ->setMessage(trim((string) $request->request->get('message')))
  347.                 ->setFullName($fullName)
  348.                 ->setEmail($clientEmail)
  349.                 ->setPhone(trim((string) $request->request->get('phone')))
  350.                 ->setNewsletter((bool) $request->request->get('newsletter'))
  351.                 ->setRgpd(true)
  352.                 ->setCreatedAt(new \DateTimeImmutable())
  353.                 ->setStatus('new');
  354.             $em->persist($qr);
  355.             $em->flush();
  356.             $mail = (new TemplatedEmail())
  357.                 ->from(new Address($_ENV['MAIL_FROM'], 'OTropik'))
  358.                 ->to($_ENV['MAIL_TO'])
  359.                 ->replyTo(new Address($clientEmail$fullName))
  360.                 ->subject('Nouvelle demande de devis — ' $destination)
  361.                 ->htmlTemplate('emails/quote_request.html.twig')
  362.                 ->context(['qr' => $qr]);
  363.             $mailer->send($mail);
  364.             $this->addFlash('success''Demande envoyée ! On revient vers vous sous 24–48h ouvrées.');
  365.             return $this->redirectToRoute('o.devis');
  366.         }
  367.     /**
  368.      * @Route("/mentions-legales", name="legal.mentions")
  369.      * @Route("/conditions-generales-utilisation", name="legal.cgu")
  370.      * @Route("/politique-de-confidentialite", name="legal.privacy")
  371.      */
  372.     public function legalPage(Request $request): Response
  373.     {
  374.         $em $this->getDoctrine()->getManager();
  375.         $routeName $request->attributes->get('_route');
  376.         $typeMap = [
  377.             'legal.mentions' => LegalPage::TYPE_MENTIONS,
  378.             'legal.cgu'      => LegalPage::TYPE_CGU,
  379.             'legal.privacy'  => LegalPage::TYPE_PRIVACY,
  380.         ];
  381.         $page $em->getRepository(LegalPage::class)->findOneBy(['type' => $typeMap[$routeName]]);
  382.         if (!$page) {
  383.             throw $this->createNotFoundException('Page légale introuvable.');
  384.         }
  385.         return $this->render('default/legal.html.twig', ['page' => $page]);
  386.     }
  387. }