src/Controller/Buzz/NewslettersController.php line 62

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. namespace App\Controller\Buzz;
  4. use App\Helper\Utils;
  5. use App\Controller\EntityUsingController;
  6. use App\Form\Models\NewslettersInscription;
  7. use App\Form\Type\NewslettersInscriptionType;
  8. use App\Services\ManagerEntity\UtilisateursNewsletterManagers;
  9. use App\Services\MetaTag;
  10. use App\Services\Buzz\CanonicalUrlService;
  11. use App\Repository\Buzz\BuzzActualitesRepository;
  12. use Symfony\Component\HttpFoundation\Request;
  13. use Symfony\Component\HttpFoundation\Response;
  14. use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
  15. class NewslettersController extends EntityUsingController
  16. {
  17.     private const DEFAULT_LANG 'fr';
  18.     private const DEFAULT_ID_PAYS '33';
  19.     private const DEFAULT_LIMIT 25;
  20.     private const MONTHS_BACK 2;
  21.     private const BASE_NEWSLETTER_URL 'https://www.fusacq.com/buzz/newsletter';
  22.     private const ID_PAYS_MAP = [
  23.         'fr' => '33',
  24.         'be' => '32',
  25.         'ch' => '41',
  26.         'ca' => '01',
  27.     ];
  28.     private MetaTag $metaTag;
  29.     private BuzzActualitesRepository $buzzActualitesRepository;
  30.     private CanonicalUrlService $canonicalUrlService;
  31.     /**
  32.      * Constructeur du contrôleur des newsletters Buzz
  33.      *
  34.      * @param MetaTag $metaTag 
  35.      * @param BuzzActualitesRepository $buzzActualitesRepository 
  36.      * @param CanonicalUrlService $canonicalUrlService 
  37.      */
  38.     public function __construct(
  39.         MetaTag $metaTag,
  40.         BuzzActualitesRepository $buzzActualitesRepository,
  41.         CanonicalUrlService $canonicalUrlService
  42.     ) {
  43.         $this->metaTag $metaTag;
  44.         $this->buzzActualitesRepository $buzzActualitesRepository;
  45.         $this->canonicalUrlService $canonicalUrlService;
  46.     }
  47.     /**
  48.      * Affiche le formulaire d'abonnement à la newsletter et gère la soumission
  49.      *
  50.      * @param Request $request 
  51.      * @param string $codePays 
  52.      * @param UtilisateursNewsletterManagers $unm 
  53.      * @return Response Réponse HTTP
  54.      */
  55.     public function inscription(Request $requeststring $codePaysUtilisateursNewsletterManagers $unm): Response
  56.     {
  57.         $cleanCodePays $this->cleanCodePays($codePays);
  58.         $codePaysWithUnderScore '_' $cleanCodePays '_';
  59.         $routeName = (string) $request->attributes->get('_route');
  60.         $metaTag $this->buildMetaTagInscription($cleanCodePays)
  61.             ->setTitle("S'inscrire à la newsletter Fusacq | Actualités fusion-acquisition et reprise d'entreprise")
  62.             ->setDescription("Inscrivez-vous gratuitement à la newsletter Fusacq et recevez les dernières opportunités et actualités du marché de la fusion-acquisition, cession et reprise d'entreprise en France.");
  63.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks(
  64.             'buzz_newsletters_inscription',
  65.             [],
  66.             null,
  67.             $cleanCodePays
  68.         );
  69.         $model $this->createNewsletterModel($request);
  70.         $form $this->createForm(NewslettersInscriptionType::class, $model, [
  71.             'action' => $this->generateUrl($routeName, ['codePays' => $codePaysWithUnderScore]),
  72.             'method' => 'POST',
  73.         ]);
  74.         $form->handleRequest($request);
  75.         if ($form->isSubmitted()) {
  76.             if ($form->isValid()) {
  77.                 $data $form->getData();
  78.                 $unm->inscription($data);
  79.                 $this->addFlash("success_inscri_news""votre inscription a nos newsletters a bien ete prise en compte");
  80.             } else {
  81.                 $this->addFlash("error_inscri_news""votre inscription a nos newsletters a echoue");
  82.             }
  83.         }
  84.         return $this->render('buzz/newsletters/inscription.html.twig', [
  85.             'form' => $form->createView(),
  86.             'metaTag' => $metaTag,
  87.             'codePays' => $cleanCodePays,
  88.             'codePaysWithUnderScore' => $codePaysWithUnderScore,
  89.             'lang' => self::DEFAULT_LANG,
  90.             'currentRoute' => $routeName,
  91.             'authFrom' => (string) $request->query->get('authFrom'''),
  92.             'hreflangLinks' => $hreflangLinks,
  93.         ]);
  94.     }
  95.     /**
  96.      * Affiche la liste des archives de newsletters
  97.      *
  98.      * @param Request $request 
  99.      * @param string $codePays 
  100.      * @param UtilisateursNewsletterManagers $unm 
  101.      * @return Response Réponse HTTP
  102.      */
  103.     public function liste(Request $requeststring $codePays): Response
  104.     {
  105.         $cleanCodePays $this->cleanCodePays($codePays);
  106.         $routeName = (string) $request->attributes->get('_route');
  107.         $metaTag $this->buildMetaTagListe($cleanCodePays);
  108.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks(
  109.             'buzz_newsletters_liste',
  110.             [],
  111.             null,
  112.             $cleanCodePays
  113.         );
  114.         $idPays $this->getIdPays($codePays$request);
  115.         $dateRange $this->getDateRange();
  116.         $page max(1, (int) $request->query->get('id_page'1));
  117.         $offset = ($page 1) * self::DEFAULT_LIMIT;
  118.         $total $this->buzzActualitesRepository->countNewslettersInterval(
  119.             $dateRange['debut'],
  120.             $dateRange['fin'],
  121.             $idPays
  122.         );
  123.         $rows $this->buzzActualitesRepository->getNewslettersInterval(
  124.             $dateRange['debut'],
  125.             $dateRange['fin'],
  126.             self::DEFAULT_LIMIT,
  127.             $offset,
  128.             $idPays
  129.         );
  130.         $totalPages = (int) ceil($total self::DEFAULT_LIMIT);
  131.         $paginationLinks $this->buildPaginationLinks(
  132.             $cleanCodePays,
  133.             $page,
  134.             $totalPages,
  135.             $idPays,
  136.             $dateRange
  137.         );
  138.         $rows $this->formatNewsletterRows($rows$codePays$idPays);
  139.         return $this->render('buzz/newsletters/liste.html.twig', [
  140.             'metaTag' => $metaTag,
  141.             'codePays' => $cleanCodePays,
  142.             'codePaysWithUnderScore' => $codePays,
  143.             'lang' => self::DEFAULT_LANG,
  144.             'currentRoute' => $routeName,
  145.             'authFrom' => (string) $request->query->get('authFrom'''),
  146.             'id_pays' => $idPays,
  147.             'date_debut_affichage' => $this->formatDateForDisplay($dateRange['debut']),
  148.             'date_fin_affichage' => $this->formatDateForDisplay($dateRange['fin']),
  149.             'rows' => $rows,
  150.             'hreflangLinks' => $hreflangLinks,
  151.             'paginationLinks' => $paginationLinks,
  152.             'page' => $page,
  153.             'last_page' => $totalPages,
  154.             'show_pagination' => $total self::DEFAULT_LIMIT,
  155.             'total' => $total,
  156.         ]);
  157.     }
  158.     /**
  159.      * Nettoie le code pays en retirant les underscores
  160.      *
  161.      * @param string $codePays
  162.      * @return string Code 
  163.      */
  164.     private function cleanCodePays(string $codePays): string
  165.     {
  166.         return str_replace('_'''$codePays);
  167.     }
  168.     /**
  169.      * Construit les meta tags pour la page d'inscription
  170.      *
  171.      * @param string $cleanCodePays 
  172.      * @return MetaTag Instance 
  173.      */
  174.     private function buildMetaTagInscription(string $cleanCodePays): MetaTag
  175.     {
  176.         $canonicalUrl $this->canonicalUrlService->getBuzzNewslettersInscriptionCanonical($cleanCodePays);
  177.         return $this->metaTag
  178.             ->setTitle("Newsletters FUSACQ Buzz - Inscription")
  179.             ->setDescription("Inscrivez-vous aux newsletters FUSACQ Buzz (quotidienne et internationale).")
  180.             ->setCanonical($canonicalUrl);
  181.     }
  182.     /**
  183.      * Construit les meta tags pour la page de liste
  184.      *
  185.      * @param string $cleanCodePays 
  186.      * @return MetaTag Instance 
  187.      */
  188.     private function buildMetaTagListe(string $cleanCodePays): MetaTag
  189.     {
  190.         $canonicalUrl $this->canonicalUrlService->getBuzzNewslettersListeCanonical($cleanCodePays);
  191.         return $this->metaTag
  192.             ->setTitle("Newsletters FUSACQ Buzz - Archives")
  193.             ->setDescription("Consultez les archives des newsletters quotidiennes FUSACQ Buzz.")
  194.             ->setCanonical($canonicalUrl);
  195.     }
  196.     /**
  197.      * Crée le modèle d'inscription newsletter avec l'email depuis l'URL si présent
  198.      *
  199.      * @param Request $request 
  200.      * @return NewslettersInscription 
  201.      */
  202.     private function createNewsletterModel(Request $request): NewslettersInscription
  203.     {
  204.         $model = new NewslettersInscription();
  205.         $emailFromUrl $request->query->get('email');
  206.         if ($emailFromUrl !== null) {
  207.             $model->mail = (string) $emailFromUrl;
  208.         }
  209.         return $model;
  210.     }
  211.     /**
  212.      * Récupère l'ID pays à partir du code pays ou de la requête
  213.      *
  214.      * @param string $codePays
  215.      * @param Request $request 
  216.      * @return string ID pays
  217.      */
  218.     private function getIdPays(string $codePaysRequest $request): string
  219.     {
  220.         $cleanCodePays strtolower($this->cleanCodePays($codePays));
  221.         $idPays self::ID_PAYS_MAP[$cleanCodePays] ?? self::DEFAULT_ID_PAYS;
  222.         return (string) $request->query->get('id_pays'$idPays);
  223.     }
  224.     /**
  225.      * Récupère la plage de dates pour les archives (2 derniers mois)
  226.      *
  227.      * @return array{debut: string, fin: string} 
  228.      */
  229.     private function getDateRange(): array
  230.     {
  231.         $dateFin date('Ymd');
  232.         $dateDebut = (new \DateTimeImmutable())
  233.             ->modify('-' self::MONTHS_BACK ' months')
  234.             ->format('Ymd');
  235.         return [
  236.             'debut' => $dateDebut,
  237.             'fin' => $dateFin,
  238.         ];
  239.     }
  240.     /**
  241.      * Construit les liens de pagination
  242.      *
  243.      * @param string $cleanCodePays 
  244.      * @param int $page 
  245.      * @param int $totalPages 
  246.      * @param string $idPays 
  247.      * @param array{debut: string, fin: string} 
  248.      * @return array 
  249.      */
  250.     private function buildPaginationLinks(
  251.         string $cleanCodePays,
  252.         int $page,
  253.         int $totalPages,
  254.         string $idPays,
  255.         array $dateRange
  256.     ): array {
  257.         $queryParams = [
  258.             'id_pays' => $idPays,
  259.             'date_debut' => $dateRange['debut'],
  260.             'date_fin' => $dateRange['fin'],
  261.         ];
  262.         return $this->canonicalUrlService->getBuzzPaginationLinksWithQuery(
  263.             'buzz_newsletters_liste',
  264.             [],
  265.             null,
  266.             $cleanCodePays,
  267.             $page,
  268.             $totalPages,
  269.             $queryParams
  270.         );
  271.     }
  272.     /**
  273.      * Formate les lignes de newsletters pour l'affichage
  274.      *
  275.      * @param array $rows 
  276.      * @param string $codePaysWithUnderscore 
  277.      * @param string $idPays
  278.      * @return array Lignes formatées
  279.      */
  280.     private function formatNewsletterRows(array $rowsstring $codePaysWithUnderscore '_fr_'string $idPays '33'): array
  281.     {
  282.         foreach ($rows as &$row) {
  283.             $row['date_affichage'] = $this->formatDateForDisplay($row['date_envoi'], '/');
  284.             
  285.             $pattern "/Le buzz du ([0-9a-zA-Zéüû ]*) :/";
  286.             $titre preg_replace($pattern""$row['titre']);
  287.             $row['titre'] = $titre;
  288.             
  289.             $slug Utils::slugify($row['titre']);
  290.             $slug str_replace('-.''.'$slug);
  291.             $url $this->generateUrl('buzz_newsletter_show', [
  292.                 'idNewsletter' => $row['id_newsletter'],
  293.                 'slug' => $slug,
  294.                 'codePays' => $codePaysWithUnderscore
  295.             ], UrlGeneratorInterface::ABSOLUTE_URL);
  296.             
  297.             // Ajouter id_pays dans l'URL si différent du pays par défaut
  298.             if ($idPays !== self::DEFAULT_ID_PAYS) {
  299.                 $url .= '?id_pays=' $idPays;
  300.             }
  301.             
  302.             $row['url'] = $url;
  303.         }
  304.         unset($row);
  305.         return $rows;
  306.     }
  307.     /**
  308.      * Affiche une newsletter individuelle par son ID
  309.      *
  310.      * @param Request $request
  311.      * @param int $idNewsletter
  312.      * @param string $codePays
  313.      * @return Response
  314.      */
  315.     public function show(Request $requestint $idNewsletterstring $codePays '_fr_'): Response
  316.     {
  317.         $idPays $this->getIdPays($codePays$request);
  318.         
  319.         $newsletter $this->buzzActualitesRepository->findNewsletterByIdAndPays($idNewsletter$idPays);
  320.         if (!$newsletter) {
  321.             throw $this->createNotFoundException('Newsletter introuvable');
  322.         }
  323.         $contenuHtml $newsletter['contenu_html'] ?? '';
  324.         if (empty($contenuHtml)) {
  325.             throw $this->createNotFoundException('Contenu de la newsletter introuvable');
  326.         }
  327.         if ($idNewsletter <= 1728) {
  328.             $contenuHtml str_replace(
  329.                 "https://www.fusacq.com/buzz/images/logo_bleu.png",
  330.                 "https://content.fusacq.com/static/dev-fusacq/buzz/images/logo_bleu.png",
  331.                 $contenuHtml
  332.             );
  333.         }
  334.         if (isset($newsletter['date_envoi']) && $newsletter['date_envoi']) {
  335.             $dateEnvoi = \DateTime::createFromFormat('Ymd'$newsletter['date_envoi']);
  336.             if ($dateEnvoi) {
  337.                 $dateSuivante = clone $dateEnvoi;
  338.                 $dateSuivante->modify('+1 day');
  339.                 $dateSuivanteYmd $dateSuivante->format('Ymd');
  340.                 
  341.                 $urlActualitesDateSuivante $this->generateUrl('buzz_actualite_par_date', [
  342.                     'date' => $dateSuivanteYmd,
  343.                     'codePays' => $codePays
  344.                 ], UrlGeneratorInterface::ABSOLUTE_URL);
  345.                 
  346.                 $contenuHtml str_replace('${urlActualitesDateSuivante}'$urlActualitesDateSuivante$contenuHtml);
  347.                 $contenuHtml str_replace('<!--###urlActualitesDateSuivante###-->'$urlActualitesDateSuivante$contenuHtml);
  348.             }
  349.         }
  350.         return new Response($contenuHtmlResponse::HTTP_OK, [
  351.             'Content-Type' => 'text/html; charset=utf-8',
  352.         ]);
  353.     }
  354.     /**
  355.      * Convertit le code pays en ID pays 
  356.      *
  357.      * @param string $codePays 
  358.      * @return string 
  359.      */
  360.     private function getIdPaysFromCodePays(string $codePays): string
  361.     {
  362.         return self::ID_PAYS_MAP[$codePays] ?? self::DEFAULT_ID_PAYS;
  363.     }
  364.     /**
  365.      * Formate une date au format Ymd pour l'affichage
  366.      *
  367.      * @param string $dateYmd
  368.      * @param string $separator 
  369.      * @return string Date formatée 
  370.      */
  371.     private function formatDateForDisplay(string $dateYmdstring $separator '-'): string
  372.     {
  373.         return substr($dateYmd62) . $separator substr($dateYmd42) . $separator substr($dateYmd04);
  374.     }
  375. }