src/Controller/DefaultController.php line 39

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