src/Controller/Buzz/IndexController.php line 376

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /**
  4.  * @author Mehrez Labidi
  5.  */
  6. namespace App\Controller\Buzz;
  7. use App\Helper\Utils;
  8. use App\Services\MetaTag;
  9. use App\Services\Buzz\CanonicalUrlService;
  10. use App\Services\Buzz\BuzzIndexPageProvider;
  11. use App\Services\LangCodePaysHandler;
  12. use App\Controller\EntityUsingController;
  13. use Symfony\Component\HttpFoundation\Request;
  14. use Symfony\Component\HttpFoundation\Response;
  15. use Symfony\Component\HttpFoundation\RedirectResponse;
  16. use App\Repository\Buzz\BuzzActualitesRepository;
  17. use Doctrine\ORM\EntityManagerInterface;
  18. use App\Entity\{
  19.     Societes,
  20.     Utilisateur,
  21.     BuzzLiensNewsletter,
  22.     UtilisateursNewsletter,
  23.     InteractionUtilisateur
  24. };
  25. use App\Entity\SocietesPrestataire;
  26. use App\Services\ManagerEntity\DroitsAccesManagers;
  27. use App\Form\Type\Buzz\SendActualiteType;
  28. class IndexController extends EntityUsingController {
  29.     public const MAX_AGE 43200// 12heures
  30.     private LangCodePaysHandler $codePaysHandler;
  31.     private BuzzIndexPageProvider $buzzIndexPageProvider;
  32.     private BuzzActualitesRepository $buzzActualitesRepository;
  33.     private CanonicalUrlService $canonicalUrlService;
  34.     /**
  35.      * @param MetaTag $metaTag
  36.      * @param LangCodePaysHandler $codePaysHandler
  37.      * @param BuzzIndexPageProvider $buzzIndexPageProvider
  38.      * @param BuzzActualitesRepository $buzzActualitesRepository
  39.      * @param CanonicalUrlService $canonicalUrlService
  40.      */
  41.     public function __construct(EntityManagerInterface $emMetaTag $metaTagLangCodePaysHandler $codePaysHandlerBuzzIndexPageProvider $buzzIndexPageProviderBuzzActualitesRepository $buzzActualitesRepositoryCanonicalUrlService $canonicalUrlService) {
  42.         $this->em $em;
  43.         $this->metaTag $metaTag;
  44.         $this->codePaysHandler $codePaysHandler;
  45.         $this->buzzIndexPageProvider $buzzIndexPageProvider;
  46.         $this->buzzActualitesRepository $buzzActualitesRepository;
  47.         $this->canonicalUrlService $canonicalUrlService;
  48.     }
  49.     /**
  50.      * Page d'accueil des actualités Buzz
  51.      * @param Request $request
  52.      * @param string $codePays
  53.      * @return Response
  54.      */
  55.     public function index(Request $request$codePays): Response {
  56.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  57.         $canonicalUrl $this->canonicalUrlService->getBuzzIndexCanonical($cleanCodePays);
  58.         $metaTag $this->metaTag
  59.                 ->setTitle("Toute l'actualité des Fusions-Acquisition et du Capital Investissement")
  60.                 ->setDescription("Suivez en temps réel toute l'actualité des Fusions-Acquisition et du Capital Investissement")
  61.                 ->setCanonical($canonicalUrl);
  62.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_index', [], null$cleanCodePays);
  63.         $countriesWithNewLogic = ['ch''ca''be'];
  64.         if (in_array(strtolower($codePays), $countriesWithNewLogic)) {
  65.             $date $request->query->get('date');
  66.             $groupedArticles $this->buzzIndexPageProvider->getArticlesByWeekForCountry($codePays$date);
  67.             $featured $this->buzzIndexPageProvider->getFeaturedActualite($codePays1);
  68.             $data $this->buzzIndexPageProvider->getInternationalPageData($codePays);
  69.             $pageData $this->buzzIndexPageProvider->getPageDataByWeekForCountry($codePays$date);
  70.             $response $this->render("buzz/index/index_" Utils::codePaysWithoutDash($codePays) . ".html.twig", [
  71.                 'metaTag' => $metaTag,
  72.                 'grouped_articles' => $groupedArticles,
  73.                 'dateRange' => null,
  74.                 'featuredBlog' => null,
  75.                 'featured' => $featured,
  76.                 'first_featured' => $pageData['first_featured'],
  77.                 'next_articles' => $pageData['next_articles'],
  78.                 'grouped_articles' => $pageData['grouped_articles'],
  79.                 'exclude_ids' => $pageData['exclude_ids'],
  80.                 'derniers_jours' => $pageData['derniers_jours'],
  81.                 'hreflangLinks' => $hreflangLinks,
  82.                 'lastMonthsHavingActu' => $this->buzzIndexPageProvider->getLastMonthsHavingActuForCountry($codePays6),
  83.             ]);
  84.         } else {
  85.             $now = new \DateTimeImmutable();
  86.             $dayOfWeek = (int) $now->format('N');
  87.             $isWeekend = ($dayOfWeek === || $dayOfWeek === 7);
  88.             if ($isWeekend && $codePays === 'fr') {
  89.                 $weekendData $this->buzzIndexPageProvider->getWeekendPageData($codePays);
  90.                 $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  91.                 $codePaysWithUnderScore '_' $cleanCodePays '_';
  92.                 $weekendPageData = [
  93.                     'grouped_articles' => $weekendData['grouped_articles'],
  94.                 ];
  95.                 $displayedArticleIds $this->buzzIndexPageProvider->collectDisplayedArticleIds($weekendPageData);
  96.                 
  97.                 $mostReadRaw $this->buzzActualitesRepository->findMostReadArticlesFromIds($displayedArticleIds5$codePays);
  98.                 $mostReadArticles array_map([$this->buzzIndexPageProvider'formatArticle'], $mostReadRaw);
  99.                 $experts_alaune $this->buzzIndexPageProvider->getExpertsALaUneFromOperations(4'fr');
  100.                 $response $this->render("buzz/index/index_fr.html.twig", [
  101.                     'metaTag' => $metaTag,
  102.                     'is_weekend_mode' => true,
  103.                     'weekend_data' => $weekendData,
  104.                     'grouped_articles' => $weekendData['grouped_articles'],
  105.                     'week_label' => $weekendData['week_label'],
  106.                     'dateRange' => null,
  107.                     'featuredBlog' => null,
  108.                     'first_featured' => null,
  109.                     'next_articles' => [],
  110.                     'exclude_ids' => [],
  111.                     'derniers_jours' => $weekendData['derniers_jours'],
  112.                     'articles_plus_lus' => $mostReadArticles,
  113.                     'experts_alaune' => $experts_alaune,
  114.                     'codePays' => $cleanCodePays,
  115.                     'codePaysWithUnderScore' => $codePaysWithUnderScore,
  116.                     'lang' => 'fr',
  117.                     'currentRoute' => $request->attributes->get('_route'),
  118.                     'hreflangLinks' => $hreflangLinks,
  119.                     'authFrom' => $request->query->get('authFrom'''),
  120.                 ]);
  121.                 return $response;
  122.             }
  123.             $pageData $this->buzzIndexPageProvider->getPageData($codePays);
  124.             $featuredIds = [];
  125.             $jours $this->buzzIndexPageProvider->getDerniersJours(6);
  126.             $grouped $pageData['grouped_articles'];
  127.             $dateRange null;
  128.             if (empty($grouped)) {
  129.                 $excludeIds = [];
  130.                 if (!empty($pageData['first_featured'])) {
  131.                     $excludeIds[] = (string) $pageData['first_featured']['id_actualite'];
  132.                 }
  133.                 foreach ($pageData['next_articles'] as $a) {
  134.                     $excludeIds[] = (string) $a['id_actualite'];
  135.                 }
  136.                 if (!empty($pageData['actualites_a_la_une_du_jour'])) {
  137.                     foreach ($pageData['actualites_a_la_une_du_jour'] as $a) {
  138.                         $excludeIds[] = (string) $a['id_actualite'];
  139.                     }
  140.                 }
  141.                 if (!empty($pageData['actualites_a_ce_moment'])) {
  142.                     foreach ($pageData['actualites_a_ce_moment'] as $a) {
  143.                         $excludeIds[] = (string) $a['id_actualite'];
  144.                     }
  145.                 }
  146.                 $excludeIds array_unique($excludeIds);
  147.                 if ($codePays === 'fr') {
  148.                     $ymds = [];
  149.                     $latestYmd $this->buzzActualitesRepository->getLatestDayYmd($codePays);
  150.                     if ($latestYmd) {
  151.                         $ymds[] = $latestYmd;
  152.                         $prev1 $this->buzzActualitesRepository->getPreviousDayYmd($latestYmd$codePays);
  153.                         if ($prev1) {
  154.                             $ymds[] = $prev1;
  155.                             $prev2 $this->buzzActualitesRepository->getPreviousDayYmd($prev1$codePays);
  156.                             if ($prev2) {
  157.                                 $ymds[] = $prev2;
  158.                             }
  159.                         }
  160.                     }
  161.                     $articlesFallback = [];
  162.                     foreach ($ymds as $ymd) {
  163.                         $rows $this->buzzActualitesRepository->findFranceNewsByYmd($ymd50$excludeIds$codePays);
  164.                         $articlesFallback array_merge($articlesFallback$rows);
  165.                     }
  166.                     $articlesFallback array_map([$this->buzzIndexPageProvider'formatArticle'], $articlesFallback);
  167.                     $grouped $this->buzzIndexPageProvider->groupArticlesByDay($articlesFallback);
  168.                     $pageData['grouped_articles'] = $grouped;
  169.                 } else {
  170.                     $dateRange $this->buzzIndexPageProvider->getLastNWorkingDays(5);
  171.                     $articlesFallback $this->buzzActualitesRepository->findNewsInDateRange($dateRange['start'], $dateRange['end'], $codePays$excludeIds);
  172.                     $articlesFallback array_map([$this->buzzIndexPageProvider'formatArticle'], $articlesFallback);
  173.                     $grouped $this->buzzIndexPageProvider->groupArticlesByWeek($articlesFallback);
  174.                     $pageData['grouped_articles'] = $grouped;
  175.                 }
  176.             }
  177.             $i 1;
  178.             while (empty($grouped) && $i <= 4) {
  179.                 $lastWeekStart = (new \DateTimeImmutable("monday -$i week"))->setTime(000);
  180.                 $lastWeekEnd $lastWeekStart->modify('+4 days')->setTime(235959);
  181.                 $excludeIds = [];
  182.                 if (!empty($pageData['first_featured'])) {
  183.                     $excludeIds[] = (string) $pageData['first_featured']['id_actualite'];
  184.                 }
  185.                 foreach ($pageData['next_articles'] as $a) {
  186.                     $excludeIds[] = (string) $a['id_actualite'];
  187.                 }
  188.                 if (!empty($pageData['actualites_a_la_une_du_jour'])) {
  189.                     foreach ($pageData['actualites_a_la_une_du_jour'] as $a) {
  190.                         $excludeIds[] = (string) $a['id_actualite'];
  191.                     }
  192.                 }
  193.                 if (!empty($pageData['actualites_a_ce_moment'])) {
  194.                     foreach ($pageData['actualites_a_ce_moment'] as $a) {
  195.                         $excludeIds[] = (string) $a['id_actualite'];
  196.                     }
  197.                 }
  198.                 $excludeIds array_unique($excludeIds);
  199.                 $articlesFallback $this->buzzActualitesRepository->findNewsInDateRange($lastWeekStart$lastWeekEnd$codePays$excludeIds);
  200.                 $articlesFallback array_map([$this->buzzIndexPageProvider'formatArticle'], $articlesFallback);
  201.                 if ($codePays === 'fr') {
  202.                     $grouped $this->buzzIndexPageProvider->groupArticlesByDay($articlesFallback);
  203.                 } else {
  204.                     $grouped $this->buzzIndexPageProvider->groupArticlesByWeek($articlesFallback);
  205.                 }
  206.                 $pageData['grouped_articles'] = $grouped;
  207.                 $dateRange = ['start' => $lastWeekStart'end' => $lastWeekEnd];
  208.                 $i++;
  209.             }
  210.             $featuredBlog null;
  211.             $featured $this->buzzIndexPageProvider->getFeaturedActualite($codePays1);
  212.             $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  213.             $codePaysWithUnderScore '_' $cleanCodePays '_';
  214.             $experts_alaune $this->buzzIndexPageProvider->getExpertsALaUneFromOperations(4'fr');
  215.             $response $this->render("buzz/index/index_fr.html.twig", [
  216.                 'metaTag' => $metaTag,
  217.                 'grouped_articles' => $pageData['grouped_articles'],
  218.                 'dateRange' => $dateRange,
  219.                 'featuredBlog' => $featuredBlog,
  220.                 'first_featured' => $pageData['first_featured'] ?? null,
  221.                 'next_articles' => $pageData['next_articles'] ?? [],
  222.                 'exclude_ids' => $pageData['exclude_ids'] ?? [],
  223.                 'derniers_jours' => $pageData['derniers_jours'],
  224.                 'actualites_a_la_une_du_jour' => $pageData['actualites_a_la_une_du_jour'] ?? [],
  225.                 'actualites_a_ce_moment' => $pageData['actualites_a_ce_moment'] ?? [],
  226.                 'articles_plus_lus' => $pageData['articles_plus_lus'] ?? [],
  227.                 'experts_alaune' => $experts_alaune,
  228.                 'codePays' => $cleanCodePays,
  229.                 'codePaysWithUnderScore' => $codePaysWithUnderScore,
  230.                 'lang' => 'fr',
  231.                 'currentRoute' => $request->get('_route'),
  232.                 'authFrom' => null,
  233.                 'hreflangLinks' => $hreflangLinks,
  234.             ]);
  235.         }
  236.         $response->setPublic();
  237.         $response->setMaxAge(self::MAX_AGE);
  238.         $response->headers->addCacheControlDirective('must-revalidate'true);
  239.         return $response;
  240.     }
  241.     /**
  242.      * Page des actualités internationales
  243.      * @param Request $request
  244.      * @param string $codePays
  245.      * @return Response
  246.      */
  247.     public function actualiteInternationale(Request $request$codePays): Response {
  248.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  249.         $canonicalUrl $this->canonicalUrlService->getBuzzActualiteInternationaleCanonical($cleanCodePays);
  250.         $metaTag $this->metaTag
  251.                 ->setTitle("L'actualité internationale des Fusions-Acquisitions et du Capital Investissement")
  252.                 ->setDescription("Suivez en temps réel l'actualité internationale des Fusions-Acquisitions et du Capital Investissement")
  253.                 ->setCanonical($canonicalUrl);
  254.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_actualite_internationale', [], null$cleanCodePays);
  255.         $data $this->buzzIndexPageProvider->getInternationalPageData($codePays);
  256.         $juridique $this->buzzIndexPageProvider->getSidebarJuridiqueData($codePays3);
  257.         if (empty($juridique) && $codePays !== 'fr') {
  258.             $juridique $this->buzzIndexPageProvider->getSidebarJuridiqueData('fr'3);
  259.         }
  260.         $experts $this->buzzIndexPageProvider->getSidebarDirectExpertsData('fr');
  261.         $derniers_jours $this->buzzIndexPageProvider->getDerniersJours(6);
  262.         $html $this->renderView('buzz/actualite_internationale.html.twig'array_merge([
  263.             'metaTag' => $metaTag,
  264.             'codePays' => str_replace('_'''$codePays),
  265.             'codePaysWithUnderScore' => $codePays,
  266.             'lang' => 'fr',
  267.             'currentRoute' => $request->get('_route'),
  268.             'authFrom' => null,
  269.             'juridique' => $juridique,
  270.             'experts' => $experts,
  271.             'derniers_jours' => $derniers_jours,
  272.             'hreflangLinks' => $hreflangLinks,
  273.                         ], $data));
  274.         $etag md5($html);
  275.         $response = new Response($html);
  276.         $response->setEtag($etag);
  277.         if ($response->isNotModified($request)) {
  278.             return $response;
  279.         }
  280.         $response->setPublic();
  281.         $response->setMaxAge(self::MAX_AGE);
  282.         return $response;
  283.     }
  284.     /**
  285.      * Page des actualités françaises depuis les autres pays
  286.      * @param Request $request
  287.      * @param string $codePays
  288.      * @return Response
  289.      */
  290.     public function actualiteFrance(Request $request$codePays): Response {
  291.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  292.         $canonicalUrl $this->canonicalUrlService->getBuzzActualiteFranceCanonical($cleanCodePays);
  293.         $metaTag $this->metaTag
  294.                 ->setTitle("L'actualité française des Fusions-Acquisitions et du Capital Investissement")
  295.                 ->setDescription("Suivez en temps réel l'actualité française des Fusions-Acquisitions et du Capital Investissement")
  296.                 ->setCanonical($canonicalUrl);
  297.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_actualite_france', [], null$cleanCodePays);
  298.         $pageData $this->buzzIndexPageProvider->getPageData('fr');
  299.         $juridique $this->buzzIndexPageProvider->getSidebarJuridiqueData('fr'3);
  300.         $experts $this->buzzIndexPageProvider->getSidebarDirectExpertsData('fr');
  301.         $experts_alaune $this->buzzIndexPageProvider->getExpertsALaUneFromOperations(4'fr');
  302.         $html $this->renderView('buzz/actualite_france.html.twig'array_merge($pageData, [
  303.             'metaTag' => $metaTag,
  304.             'codePays' => str_replace('_'''$codePays),
  305.             'codePaysWithUnderScore' => $codePays,
  306.             'lang' => 'fr',
  307.             'currentRoute' => $request->get('_route'),
  308.             'authFrom' => null,
  309.             'juridique' => $juridique,
  310.             'experts' => $experts,
  311.             'experts_alaune' => $experts_alaune,
  312.             'hreflangLinks' => $hreflangLinks,
  313.             'buzz_calendar_date_route' => 'buzz_actualite_france_par_date',
  314.         ]));
  315.         $etag md5($html);
  316.         $response = new Response($html);
  317.         $response->setEtag($etag);
  318.         if ($response->isNotModified($request)) {
  319.             return $response;
  320.         }
  321.         $response->setPublic();
  322.         $response->setMaxAge(self::MAX_AGE);
  323.         return $response;
  324.     }
  325.     /**
  326.      * Page "En direct des experts" avec filtrage par type
  327.      * @param BuzzIndexPageProvider $buzzIndexPageProvider
  328.      * @param Request $request
  329.      * @param string $codePays
  330.      * @return Response
  331.      */
  332.     public function enDirectDesExperts(BuzzIndexPageProvider $buzzIndexPageProviderRequest $request$codePays): Response {
  333.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  334.         $type $request->query->get('type''');
  335.         $canonicalUrl $this->canonicalUrlService->getBuzzEnDirectDesExpertsCanonical($cleanCodePays$type);
  336.         $metaTag $this->getMetaTagForExpertType($type);
  337.         $metaTag->setCanonical($canonicalUrl);
  338.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_en_direct_des_experts', [], $type$cleanCodePays);
  339.         $page max(1, (int) $request->query->get('page'1));
  340.         $limit 20;
  341.         $offset = ($page 1) * $limit;
  342.         $total $buzzIndexPageProvider->countEnDirectDesExperts($type$codePays);
  343.         $actualites $buzzIndexPageProvider->getEnDirectDesExpertsFormatted($type$limit$codePays$offset);
  344.         $totalPages = (int) ceil($total $limit);
  345.         $paginationLinks $this->canonicalUrlService->getBuzzPaginationLinks('buzz_en_direct_des_experts', [], $type$cleanCodePays$page$totalPages);
  346.         $first_featured $actualites[0] ?? null;
  347.         $next_articles array_slice($actualites12);
  348.         $main_articles array_slice($actualites317);
  349.         $juridique $buzzIndexPageProvider->getSidebarJuridiqueData($codePays3);
  350.         if (empty($juridique) && $codePays !== 'fr') {
  351.             $juridique $buzzIndexPageProvider->getSidebarJuridiqueData('fr'3);
  352.         }
  353.         $remaining_articles array_slice($actualites3);
  354.         $grouped_articles $buzzIndexPageProvider->groupArticlesByDay($remaining_articles);
  355.         $webinarFormationData $buzzIndexPageProvider->getWebinarFormationData();
  356.         if (isset($webinarFormationData['webinar']) && is_array($webinarFormationData['webinar'])) {
  357.             if (!isset($webinarFormationData['webinar']['titre'])) {
  358.                 $webinarFormationData['webinar']['titre'] = '';
  359.             }
  360.         }
  361.         $html $this->renderView('buzz/en_direct_des_experts.html.twig', [
  362.             'metaTag' => $metaTag,
  363.             'first_featured' => $first_featured,
  364.             'next_articles' => $next_articles,
  365.             'main_articles' => $main_articles,
  366.             'grouped_articles' => $grouped_articles,
  367.             'type' => $type,
  368.             'juridique' => $juridique,
  369.             'page' => $page,
  370.             'limit' => $limit,
  371.             'total' => $total,
  372.             'nbPages' => ceil($total $limit),
  373.             'webinarData' => $webinarFormationData['webinar'],
  374.             'formationData' => $webinarFormationData['formation'],
  375.             'hreflangLinks' => $hreflangLinks,
  376.             'paginationLinks' => $paginationLinks,
  377.         ]);
  378.         $etag md5($html);
  379.         $response = new Response($html);
  380.         $response->setEtag($etag);
  381.         if ($response->isNotModified($request)) {
  382.             return $response// 304 Not Modified
  383.         }
  384.         $response->setPublic();
  385.         $response->setMaxAge(self::MAX_AGE);
  386.         return $response;
  387.     }
  388.     /**
  389.      * Récupère les métadonnées appropriées selon le type d'expert
  390.      * 
  391.      * @param string $type
  392.      * @return MetaTag
  393.      */
  394.     private function getMetaTagForExpertType(string $type): MetaTag {
  395.         switch ($type) {
  396.             case 'reference':
  397.                 return $this->metaTag
  398.                                 ->setTitle("Toutes les opérations réalisées par les experts en cession d'entreprise")
  399.                                 ->setDescription("Suivez en temps réel toutes les opérations réalisées par les experts en cession d'entreprise, fusions-acquisitions et en levée de fonds");
  400.             case 'autre':
  401.                 return $this->metaTag
  402.                                 ->setTitle("Toutes les autres actualités des conseils en cession d'entreprise")
  403.                                 ->setDescription("Suivez en temps réel toutes les autres actualités postées par les experts en cession d'entreprise, fusions-acquisitions et en levée de fonds");
  404.             case 'nomination':
  405.                 return $this->metaTag
  406.                                 ->setTitle("Toutes les nominations des conseils en cession d'entreprise")
  407.                                 ->setDescription("Suivez en temps réel toutes les nominations des experts en cession d'entreprise, fusions-acquisitions et en levée de fonds");
  408.             case 'evenement':
  409.                 return $this->metaTag
  410.                                 ->setTitle("Tous les événements des experts en cession d'entreprise")
  411.                                 ->setDescription("Suivez en temps réel tous les événements auxquels participent les experts en cession d'entreprise, fusions-acquisitions et en levée de fonds");
  412.             case 'expertise':
  413.                 return $this->metaTag
  414.                                 ->setTitle("Tous les avis d'experts des conseils en cession d'entreprise")
  415.                                 ->setDescription("Suivez en temps réel tous les avis d'expert rédigés par les conseils en cession d'entreprise, fusions-acquisitions et en levée de fonds");
  416.             case 'reflexion':
  417.                 return $this->metaTag
  418.                                 ->setTitle("Tous les billets d'humeur des conseils en cession d'entreprise")
  419.                                 ->setDescription("Suivez en temps réel tous les billets d'humeur rédigés par les experts en cession d'entreprise, fusions-acquisitions et en levée de fonds");
  420.             case 'emploi':
  421.                 return $this->metaTag
  422.                                 ->setTitle("Toutes les offres d'emploi des conseils en cession d'entreprise")
  423.                                 ->setDescription("Suivez en temps réel toutes les offres d'emploi proposées par les experts en cession d'entreprise, fusions-acquisitions et en levée de fonds");
  424.             default:
  425.                 return $this->metaTag
  426.                                 ->setTitle("L'actualité collaborative des Experts - Toutes les actualités")
  427.                                 ->setDescription("Suivez en temps réel toute l'actualité collaborative des experts en cession d'entreprise, fusions-acquisitions et en levée de fonds");
  428.         }
  429.     }
  430.     /**
  431.      * Récupère les métadonnées appropriées pour les détails d'articles
  432.      * 
  433.      * @param array $articleData
  434.      * @return MetaTag
  435.      */
  436.     private function getMetaTagForArticleDetail(array $articleData): MetaTag {
  437.         $titre $articleData['titre_actualite'] ?? '';
  438.         $sousTitre $articleData['sous_titre'] ?? '';
  439.         $description $articleData['description_actualite'] ?? '';
  440.         $title = !empty($titre) ? $titre "Actualité - Fusions-Acquisitions et Capital Investissement";
  441.         if (!empty($sousTitre)) {
  442.             $desc $sousTitre;
  443.         } elseif (!empty($description)) {
  444.             $desc strlen($description) > 160 substr($description0157) . '...' $description;
  445.         } else {
  446.             $desc "Consultez cette actualité dans le domaine des fusions-acquisitions et du capital investissement";
  447.         }
  448.         return $this->metaTag
  449.                         ->setTitle($title)
  450.                         ->setDescription($desc);
  451.     }
  452.     /**
  453.      * Récupère les métadonnées appropriées pour les pages de sociétés
  454.      * 
  455.      * @param array $infos
  456.      * @param string $typeSociete
  457.      * @return MetaTag
  458.      */
  459.     private function getMetaTagForSociete(array $infosstring $typeSociete): MetaTag {
  460.         $raisonSociale $infos['raison_sociale'] ?? '';
  461.         $description $infos['description'] ?? '';
  462.         $secteur $infos['secteur'] ?? '';
  463.         $title $typeSociete === 'prestataire' ? (!empty($raisonSociale) ? $raisonSociale " - Cabinet de conseil en fusions-acquisitions" "Cabinet de conseil en fusions-acquisitions") : (!empty($raisonSociale) ? $raisonSociale " - Actualités fusions-acquisitions" "Actualités fusions-acquisitions");
  464.         if (!empty($description)) {
  465.             $desc strlen($description) > 160 substr($description0157) . '...' $description;
  466.         } elseif (!empty($secteur)) {
  467.             $desc "Découvrez " $raisonSociale " dans le secteur " $secteur " - Actualités et informations sur les fusions-acquisitions";
  468.         } else {
  469.             $desc "Consultez les actualités et informations sur " $raisonSociale " dans le domaine des fusions-acquisitions et du capital investissement";
  470.         }
  471.         return $this->metaTag
  472.                         ->setTitle($title)
  473.                         ->setDescription($desc);
  474.     }
  475.     /**
  476.      * Page de détail d'une actualité
  477.      * 
  478.      * @param Request $request
  479.      * @param string $slug
  480.      * @param string $id
  481.      * @param string $codePays
  482.      * @param BuzzIndexPageProvider $provider
  483.      * @param DroitsAccesManagers $droitsAccesManagers
  484.      * @return Response
  485.      */
  486.     public function detail(Request $request$slug$id$codePaysBuzzIndexPageProvider $providerDroitsAccesManagers $droitsAccesManagers): Response {
  487.         $backUrl $this->computeBackUrl($request$codePays);
  488.         $articleData $provider->getArticleDetailById((int) $id);
  489.   
  490.         if (!$articleData) {
  491.             $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  492.             $url $this->generateUrl('buzz_index', ['codePays' => $cleanCodePays]);
  493.             return new RedirectResponse($urlResponse::HTTP_MOVED_PERMANENTLY);
  494.         }
  495.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  496.         $canonicalUrl $this->canonicalUrlService->getBuzzActualiteCanonical((int) $id$slug$cleanCodePays);
  497.         $metaTag $this->getMetaTagForArticleDetail($articleData);
  498.         $metaTag->setCanonical($canonicalUrl);
  499.         if (!empty($articleData['should_noindex']) && $articleData['should_noindex'] === true) {
  500.             $metaTag->setRobots('noindex, nofollow');
  501.         }
  502.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_actualite_detail', ['slug' => $slug'id' => $id], null$cleanCodePays);
  503.         $alternates $this->canonicalUrlService->convertHreflangToAlternates($hreflangLinks);
  504.         $metaTag->setAlternates($alternates);
  505.         $operationId null;
  506.         if (!empty($articleData['id_operation'])) {
  507.             $operationId = (int) $articleData['id_operation'];
  508.         }
  509.         $idSecteur $provider->getSecteurWithFallback((int) $id$operationId);
  510.         $lastActualites = [];
  511.         if (!empty($articleData['id_societe_prestataire'])) {
  512.             $lastActualites $provider->getLastActualitesBySocietePrestataire($articleData['id_societe_prestataire']);
  513.         }
  514.         $investisseurs_experts $this->buzzIndexPageProvider->getInvestisseursExpertsByOperation($operationId);
  515.         
  516.         if (!empty($articleData['autorisation_blog']) && $articleData['autorisation_blog'] === 'non') {
  517.             $investisseurs_experts array_filter($investisseurs_experts, function($bloc) {
  518.                 $nomRole mb_strtolower(trim($bloc['nom_role'] ?? ''), 'UTF-8');
  519.                 $nomRole str_replace(['é''è''ê''ë'], 'e'$nomRole);
  520.                 return !preg_match('/^investisseur/i'$nomRole) && !preg_match('/^acqu[eé]reur/i'$nomRole);
  521.             });
  522.             $investisseurs_experts array_values($investisseurs_experts);
  523.         }
  524.         
  525.         $societe_toutes_actualites = [];
  526.         if (empty($articleData['autorisation_blog']) || $articleData['autorisation_blog'] !== 'non') {
  527.             $societe_toutes_actualites $this->buzzIndexPageProvider->getSocieteToutesActualites($operationId);
  528.         }
  529.         $societesAReprendre = [];
  530.         $acquereursSecteur = [];
  531.         $secteurInfo null;
  532.         if ($operationId) {
  533.             $societesAReprendre $this->buzzIndexPageProvider->getSocietesAReprendreDansSecteurByOperation($operationId5$idSecteur);
  534.             $acquereursSecteur $this->buzzIndexPageProvider->getAcquereursDansSecteurByOperation($operationId5$idSecteur);
  535.             $secteurInfo $idSecteur $this->buzzIndexPageProvider->getSecteurInfo($idSecteur) : null;
  536.         }
  537.         $user $this->getUser();
  538.         $typeActualite $articleData['type_actualite'] ?? null;
  539.         $canSeeSousTitre true;
  540.         $statusAuth 2;
  541.         if ($typeActualite === 'juridique_et_fiscale') {
  542.             if (!$user) {
  543.                 $canSeeSousTitre false;
  544.                 $statusAuth 0;
  545.             } else {
  546.                 $hasAccess $droitsAccesManagers->hasJuridiqueAccess($user);
  547.                 $canSeeSousTitre $hasAccess;
  548.                 $statusAuth $canSeeSousTitre 1;
  549.             }
  550.         }
  551.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  552.         $sendForm $this->createForm(SendActualiteType::class, null, [
  553.             'id_actualite' => (int) $id,
  554.         ]);
  555.         $publicKey $this->getParameter('RECAPTCHA_PUBLIC_KEY') ?? '';
  556.         $response $this->render('buzz/fragments/detail.html.twig', [
  557.                     'article' => $articleData,
  558.                     'backUrl' => $backUrl,
  559.                     'codePays' => $cleanCodePays,
  560.                     'codePaysWithUnderScore' => $codePays,
  561.                     'idSecteur' => $idSecteur,
  562.                     'operationId' => $operationId,
  563.                     'lang' => 'fr',
  564.                     'currentRoute' => $request->get('_route'),
  565.                     'authFrom' => null,
  566.                     'metaTag' => $metaTag,
  567.                     'show_experts_references' => true,
  568.                     'investisseurs_experts' => $investisseurs_experts,
  569.                     'societe_toutes_actualites' => $societe_toutes_actualites,
  570.                     'canSeeSousTitre' => $canSeeSousTitre,
  571.                     'statusAuth' => $statusAuth,
  572.                     'societes_a_reprendre' => $societesAReprendre,
  573.                     'acquereurs_secteur' => $acquereursSecteur,
  574.                     'secteur_info' => $secteurInfo,
  575.                     'hreflangLinks' => $hreflangLinks,
  576.                     'send_form' => $sendForm->createView(),
  577.                     'RECAPTCHA_PUBLIC_KEY' => $publicKey,
  578.         ]);
  579.         if (!empty($articleData['should_noindex']) && $articleData['should_noindex'] === true) {
  580.             $response->headers->set('X-Robots-Tag''noindex, nofollow');
  581.         }
  582.         return $response;
  583.     }
  584.     /**
  585.      * Calcule une URL de retour fiable pour la page détail
  586.      */
  587.     private function computeBackUrl(Request $requeststring $codePays): string {
  588.         $returnParam = (string) ($request->query->get('return''') ?: $request->query->get('f_return'''));
  589.         if ($returnParam !== '') {
  590.             if (strpos($returnParam'http') !== 0) {
  591.                 return $returnParam;
  592.             }
  593.             $retHost parse_url($returnParamPHP_URL_HOST);
  594.             if (!empty($retHost) && $retHost === $request->getHost()) {
  595.                 return $returnParam;
  596.             }
  597.         }
  598.         $referer = (string) $request->headers->get('referer''');
  599.         $currentUrl = (string) $request->getUri();
  600.         if ($referer !== '' && $referer !== $currentUrl) {
  601.             $isLoginRef strpos($referer'/login') !== false;
  602.             $isSocieteRef strpos($referer'/actualite-societe-') !== false;
  603.             if (!$isLoginRef && !$isSocieteRef) {
  604.                 return $referer;
  605.             }
  606.         }
  607.         return $this->generateUrl('buzz_index', [
  608.                     'codePays' => Utils::codePaysWithoutDash($codePays)
  609.         ]);
  610.     }
  611.     /**
  612.      * Page des actualités d'une société
  613.      * 
  614.      * @param Request $request
  615.      * @param string $slug
  616.      * @param string $id
  617.      * @param string $codePays
  618.      * @param EntityManagerInterface $em
  619.      * @param BuzzIndexPageProvider $provider
  620.      * @return Response
  621.      */
  622.     public function actualiteSocietes(Request $request$slug$id$codePaysEntityManagerInterface $emBuzzIndexPageProvider $provider): Response {
  623.         $idActualiteContexte $request->query->get('idActualite');
  624.         $societe $em->getRepository(SocietesPrestataire::class)->find($id);
  625.         if ($societe) {
  626.             $typeSociete 'prestataire';
  627.         } else {
  628.             $societe $em->getRepository(Societes::class)->find($id);
  629.             if ($societe) {
  630.                 $typeSociete 'news';
  631.             } else {
  632.                 throw $this->createNotFoundException('Société non trouvée');
  633.             }
  634.         }
  635.         $infos $provider->getSocieteInfosMultiTable($id);
  636.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  637.         $canonicalUrl $this->canonicalUrlService->getBuzzActualiteSocieteCanonical((int) $id$slug$cleanCodePays);
  638.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_actualite_societe', ['slug' => $slug'id' => $id], null$cleanCodePays);
  639.         $metaTag $this->getMetaTagForSociete($infos$typeSociete);
  640.         $metaTag->setCanonical($canonicalUrl);
  641.         if ($typeSociete === 'prestataire') {
  642.             $dernieresActualites $provider->getDernieresActualitesPourSociete($infos1000);
  643.         } else {
  644.             $dernieresActualites $provider->getDernieresActualitesPourSociete($infos1000);
  645.         }
  646.         $article array_merge($infos, [
  647.             'societe_infos' => $infos,
  648.             'imgAffichage' => $infos['imgAffichage'] ?? null,
  649.             'imgAffichageEnError' => $infos['imgAffichageEnError'] ?? null,
  650.             'raison_sociale' => $infos['raison_sociale'] ?? '',
  651.             'dernieres_actualites_societe' => $dernieresActualites,
  652.             'lienSocieteCom' => $infos['lienSocieteCom'] ?? '',
  653.             'lienAnnuaireParticipation' => $infos['lienAnnuaireParticipation'] ?? '',
  654.             'lienFicheComplete' => $infos['lienFicheComplete'] ?? '',
  655.             'adresse_complete' => $infos['adresse_complete'] ?? '',
  656.             'caEffectif' => $infos['caEffectif'] ?? '',
  657.             'utiliserArtviper' => $infos['utiliserArtviper'] ?? '',
  658.             'carteAffichage' => $infos['carteAffichage'] ?? '',
  659.             'lienParticipation' => $infos['lienParticipation'] ?? '',
  660.             'numero_siren' => $infos['numero_siren'] ?? '',
  661.             'ca_n' => $infos['ca_n'] ?? '',
  662.             'annee_n' => $infos['annee_n'] ?? '',
  663.             'effectif_salarie_n' => $infos['effectif_salarie_n'] ?? '',
  664.             'url_site_web' => $infos['url_site_web'] ?? '',
  665.             'site_internet' => $infos['site_internet'] ?? '',
  666.             'nom_contact1' => $infos['nom_contact1'] ?? '',
  667.             'telephone' => $infos['telephone'] ?? '',
  668.             'adresse' => $infos['adresse'] ?? '',
  669.             'code_postal' => $infos['code_postal'] ?? '',
  670.             'ville' => $infos['ville'] ?? '',
  671.             'pays' => $infos['pays'] ?? '',
  672.             'id_pays' => $infos['id_pays'] ?? '',
  673.             'resume_service' => $infos['resume_service'] ?? '',
  674.             'resume_activite' => $infos['resume_activite'] ?? '',
  675.             'description_activite' => $infos['description_activite'] ?? '',
  676.             'fax' => $infos['fax'] ?? '',
  677.             'mail_contact' => $infos['mail_contact'] ?? '',
  678.         ]);
  679.         $mainActualite $dernieresActualites[0] ?? null;
  680.         $mainActualiteTitre $mainActualite['titre_actualite'] ?? null;
  681.         $idActualiteRef null;
  682.         if (!empty($idActualiteContexte) && ctype_digit((string) $idActualiteContexte)) {
  683.             $idActualiteRef = (int) $idActualiteContexte;
  684.         } else {
  685.             $idActualiteRef = !empty($dernieresActualites[0]['id_actualite']) ? (int) $dernieresActualites[0]['id_actualite'] : null;
  686.         }
  687.         $idSecteur null;
  688.         if ($idActualiteRef) {
  689.             $idSecteur $provider->getSecteurFromActualite($idActualiteRef);
  690.         }
  691.         if (!$idSecteur) {
  692.             $idSecteur $provider->getSecteurLePlusPopulaire();
  693.         }
  694.         if (!$idSecteur) {
  695.             $idSecteur $provider->getPremierSecteurDisponible();
  696.         }
  697.         $operationId null;
  698.         if ($idActualiteRef) {
  699.             $operationId $provider->getOperationIdFromActualite($idActualiteRef);
  700.         }
  701.         $societesAReprendre $this->buzzIndexPageProvider->getSocietesAReprendreDansSecteurByOperation($operationId5$idSecteur);
  702.         $acquereursSecteur $this->buzzIndexPageProvider->getAcquereursDansSecteurByOperation($operationId5$idSecteur);
  703.         $secteurInfo $this->buzzIndexPageProvider->getSecteurInfo($idSecteur);
  704.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  705.         return $this->render('buzz/fragments/actualite_societe.html.twig', [
  706.                     'article' => $article,
  707.                     'metaTag' => $metaTag,
  708.                     'codePays' => $cleanCodePays,
  709.                     'codePaysWithUnderScore' => $codePays,
  710.                     'lang' => 'fr',
  711.                     'currentRoute' => $request->get('_route'),
  712.                     'authFrom' => null,
  713.                     'show_experts_references' => true,
  714.                     'mainActualiteTitre' => $mainActualiteTitre,
  715.                     'firstActualite' => $idActualiteRef ? ['id_actualite' => $idActualiteRef] : null,
  716.                     'idSecteur' => $idSecteur,
  717.                     'operationId' => $operationId,
  718.                     'idActualite' => $idActualiteRef,
  719.                     'societes_a_reprendre' => $societesAReprendre,
  720.                     'acquereurs_secteur' => $acquereursSecteur,
  721.                     'secteur_info' => $secteurInfo,
  722.                     'hreflangLinks' => $hreflangLinks,
  723.         ]);
  724.     }
  725.     /**
  726.      * Page des actualités par date spécifique
  727.      * 
  728.      * @param Request $request
  729.      * @param string $date
  730.      * @param string $codePays
  731.      * @return Response
  732.      */
  733.     public function actualitesParDate(Request $request$date$codePays): Response {
  734.         if (!preg_match('/^\d{8}$/', (string) $date)) {
  735.             $clean Utils::codePaysWithoutDash($codePays);
  736.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  737.         }
  738.         $dateObj = \DateTimeImmutable::createFromFormat('Ymd'$date);
  739.         if (!$dateObj) {
  740.             $clean Utils::codePaysWithoutDash($codePays);
  741.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  742.         }
  743.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  744.         if ($cleanCodePays !== 'fr') {
  745.             return $this->redirectToRoute('buzz_actualite_france_par_date', [
  746.                         'date' => $date,
  747.                         'codePays' => $codePays
  748.             ]);
  749.         }
  750.         $now = new \DateTimeImmutable();
  751.         $twoYearsAgo $now->modify('-2 years');
  752.         if ($dateObj $now || $dateObj $twoYearsAgo) {
  753.             $clean Utils::codePaysWithoutDash($codePays);
  754.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  755.         }
  756.         $dateObj = \DateTimeImmutable::createFromFormat('Ymd'$date);
  757.         $date_label_fr $dateObj $this->buzzIndexPageProvider->formatDateLongFr($dateObj) : '';
  758.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  759.         $canonicalUrl $this->canonicalUrlService->getBuzzDateCanonical($date$cleanCodePays);
  760.         $metaTag $this->metaTag
  761.                 ->setTitle("Actualités du " $date_label_fr " - Fusions-Acquisitions et Capital Investissement")
  762.                 ->setDescription("Consultez toutes les actualités du " $date_label_fr " dans le domaine des fusions-acquisitions et du capital investissement")
  763.                 ->setCanonical($canonicalUrl);
  764.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_actualite_par_date', ['date' => $date], null$cleanCodePays);
  765.         $actualitesALaUne $this->buzzActualitesRepository->findActualitesALaUneDuJourByDate($date'_fr_'5);
  766.         $actualitesALaUne array_map([$this->buzzIndexPageProvider'formatArticle'], $actualitesALaUne);
  767.         $excludeIds = [];
  768.         if (!empty($actualitesALaUne)) {
  769.             $excludeIds array_column($actualitesALaUne'id_actualite');
  770.         }
  771.         $articles $this->buzzActualitesRepository->findNewsByDateWithVersion($date'france');
  772.         if (empty($articles)) {
  773.             $articles $this->buzzActualitesRepository->findNewsByDateWithVersion($date'classique');
  774.         }
  775.         if (empty($articles)) {
  776.             $articles $this->buzzActualitesRepository->findNewsByDate($date'_fr_');
  777.         }
  778.         if (!empty($excludeIds)) {
  779.             $articles array_values(array_filter($articles, function ($a) use ($excludeIds) {
  780.                         return !in_array($a['id_actualite'], $excludeIdstrue);
  781.                     }));
  782.         }
  783.         $articles array_map([$this->buzzIndexPageProvider'formatArticle'], $articles);
  784.         $derniers_jours $this->buzzIndexPageProvider->getDerniersJours(5$dateObj);
  785.         return $this->render('buzz/index/actualites_par_date.html.twig', [
  786.                     'metaTag' => $metaTag,
  787.                     'articles' => $articles,
  788.                     'actualites_a_la_une_du_jour' => $actualitesALaUne,
  789.                     'date' => $dateObj,
  790.                     'date_label_fr' => $date_label_fr,
  791.                     'codePays' => str_replace('_'''$codePays),
  792.                     'codePaysWithUnderScore' => $codePays,
  793.                     'lang' => 'fr',
  794.                     'currentRoute' => $request->get('_route'),
  795.                     'authFrom' => null,
  796.                     'derniers_jours' => $derniers_jours,
  797.                     'hreflangLinks' => $hreflangLinks,
  798.         ]);
  799.     }
  800.     /**
  801.      * Page des actualités internationales par date spécifique
  802.      * 
  803.      * @param string $date
  804.      * @param string $codePays
  805.      * @return Response
  806.      */
  807.     public function actualitesInternationalesParDate($date$codePays): Response {
  808.         if (!preg_match('/^\d{8}$/', (string) $date)) {
  809.             $clean Utils::codePaysWithoutDash($codePays);
  810.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  811.         }
  812.         $dateObj = \DateTimeImmutable::createFromFormat('Ymd'$date);
  813.         if (!$dateObj) {
  814.             $clean Utils::codePaysWithoutDash($codePays);
  815.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  816.         }
  817.         $now = new \DateTimeImmutable();
  818.         $twoYearsAgo $now->modify('-2 years');
  819.         if ($dateObj $now || $dateObj $twoYearsAgo) {
  820.             $clean Utils::codePaysWithoutDash($codePays);
  821.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  822.         }
  823.         $dateObj = \DateTimeImmutable::createFromFormat('Ymd'$date);
  824.         $date_label_fr $dateObj $this->buzzIndexPageProvider->formatDateLongFr($dateObj) : '';
  825.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  826.         $canonicalUrl $this->canonicalUrlService->getBuzzActualiteInternationaleParDateCanonical($date$cleanCodePays);
  827.         $metaTag $this->metaTag
  828.                 ->setTitle("Actualités internationales du " $date_label_fr " - Fusions-Acquisitions et Capital Investissement")
  829.                 ->setDescription("Consultez toutes les actualités internationales du " $date_label_fr " dans le domaine des fusions-acquisitions et du capital investissement")
  830.                 ->setCanonical($canonicalUrl);
  831.         $actualitesALaUne $this->buzzActualitesRepository->findActualitesALaUneDuJourInternationalByDate($date$codePays5);
  832.         $actualitesALaUne array_map([$this->buzzIndexPageProvider'formatArticle'], $actualitesALaUne);
  833.         $excludeIds = [];
  834.         if (!empty($actualitesALaUne)) {
  835.             $excludeIds array_column($actualitesALaUne'id_actualite');
  836.         }
  837.         $articlesRaw $this->buzzActualitesRepository->findInternationalNewsByDate($date$codePays);
  838.         if (!empty($excludeIds)) {
  839.             $articlesRaw array_values(array_filter($articlesRaw, function ($a) use ($excludeIds) {
  840.                         return !in_array($a['id_actualite'], $excludeIdstrue);
  841.                     }));
  842.         }
  843.         $articles array_map([$this->buzzIndexPageProvider'formatArticle'], $articlesRaw);
  844.         $featured $articles[0] ?? null;
  845.         $next_articles array_slice($articles12);
  846.         $other_articles array_slice($articles3);
  847.         $derniers_jours $this->buzzIndexPageProvider->getDerniersJours(5$dateObj);
  848.         return $this->render('buzz/actualite_internationale_par_date.html.twig', [
  849.                     'metaTag' => $metaTag,
  850.                     'featured' => $featured,
  851.                     'next_articles' => $next_articles,
  852.                     'other_articles' => $other_articles,
  853.                     'actualites_a_la_une_du_jour' => $actualitesALaUne,
  854.                     'date' => $dateObj,
  855.                     'date_label_fr' => $date_label_fr,
  856.                     'codePaysWithUnderScore' => $codePays,
  857.                     'derniers_jours' => $derniers_jours,
  858.         ]);
  859.     }
  860.     /**
  861.      * Page des actualités françaises par date spécifique (pour les pays non-français)
  862.      * 
  863.      * @param Request $request
  864.      * @param string $date
  865.      * @param string $codePays
  866.      * @return Response
  867.      */
  868.     public function actualitesFranceParDate(Request $request$date$codePays): Response {
  869.         if (!preg_match('/^\d{8}$/', (string) $date)) {
  870.             $clean Utils::codePaysWithoutDash($codePays);
  871.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  872.         }
  873.         $dateObj = \DateTimeImmutable::createFromFormat('Ymd'$date);
  874.         if (!$dateObj) {
  875.             $clean Utils::codePaysWithoutDash($codePays);
  876.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  877.         }
  878.         $now = new \DateTimeImmutable();
  879.         $twoYearsAgo $now->modify('-2 years');
  880.         if ($dateObj $now || $dateObj $twoYearsAgo) {
  881.             $clean Utils::codePaysWithoutDash($codePays);
  882.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  883.         }
  884.         $dateObj = \DateTimeImmutable::createFromFormat('Ymd'$date);
  885.         $date_label_fr $dateObj $this->buzzIndexPageProvider->formatDateLongFr($dateObj) : '';
  886.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  887.         $canonicalUrl $this->canonicalUrlService->getBuzzDateCanonical($date$cleanCodePays);
  888.         $metaTag $this->metaTag
  889.                 ->setTitle("Actualités françaises du " $date_label_fr " - Fusions-Acquisitions et Capital Investissement")
  890.                 ->setDescription("Consultez toutes les actualités françaises du " $date_label_fr " dans le domaine des fusions-acquisitions et du capital investissement")
  891.                 ->setCanonical($canonicalUrl);
  892.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_actualite_france_par_date', ['date' => $date], null$cleanCodePays);
  893.         $actualitesALaUne $this->buzzActualitesRepository->findActualitesALaUneDuJourByDate($date'_fr_'5);
  894.         $actualitesALaUne array_map([$this->buzzIndexPageProvider'formatArticle'], $actualitesALaUne);
  895.         $excludeIds = [];
  896.         if (!empty($actualitesALaUne)) {
  897.             $excludeIds array_column($actualitesALaUne'id_actualite');
  898.         }
  899.         $articles $this->buzzActualitesRepository->findNewsByDateWithVersion($date'france');
  900.         if (empty($articles)) {
  901.             $articles $this->buzzActualitesRepository->findNewsByDateWithVersion($date'classique');
  902.         }
  903.         if (empty($articles)) {
  904.             $articles $this->buzzActualitesRepository->findNewsByDate($date'_fr_');
  905.         }
  906.         if (!empty($excludeIds)) {
  907.             $articles array_values(array_filter($articles, function ($a) use ($excludeIds) {
  908.                         return !in_array($a['id_actualite'], $excludeIdstrue);
  909.                     }));
  910.         }
  911.         $articles array_map([$this->buzzIndexPageProvider'formatArticle'], $articles);
  912.         $derniers_jours $this->buzzIndexPageProvider->getDerniersJours(5$dateObj);
  913.         return $this->render('buzz/actualite_france_par_date.html.twig', [
  914.                     'metaTag' => $metaTag,
  915.                     'articles' => $articles,
  916.                     'actualites_a_la_une_du_jour' => $actualitesALaUne,
  917.                     'date' => $dateObj,
  918.                     'date_label_fr' => $date_label_fr,
  919.                     'codePays' => $cleanCodePays,
  920.                     'codePaysWithUnderScore' => $codePays,
  921.                     'lang' => 'fr',
  922.                     'currentRoute' => $request->get('_route'),
  923.                     'authFrom' => null,
  924.                     'derniers_jours' => $derniers_jours,
  925.                     'hreflangLinks' => $hreflangLinks,
  926.         ]);
  927.     }
  928.     /**
  929.      * Page des actualités par mois
  930.      * 
  931.      * @param string $month
  932.      * @param string $codePays
  933.      * @return Response
  934.      */
  935.     public function actualitesParMois($month$codePays): Response {
  936.         if (!is_numeric($month) || $month || $month 12) {
  937.             $clean Utils::codePaysWithoutDash($codePays);
  938.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  939.         }
  940.         $year date('Y');
  941.         $lastMonths $this->buzzIndexPageProvider->getLastMonthsHavingActuForCountry(Utils::codePaysWithoutDash($codePays), 6);
  942.         $monthExists false;
  943.         foreach ($lastMonths as $allowedMonth) {
  944.             if ($allowedMonth['year'] == $year && $allowedMonth['number'] == $month) {
  945.                 $monthExists true;
  946.                 break;
  947.             }
  948.         }
  949.         if (!$monthExists) {
  950.             $clean Utils::codePaysWithoutDash($codePays);
  951.             return $this->redirectToRoute('buzz_index', ['codePays' => $clean]);
  952.         }
  953.         $date = \DateTimeImmutable::createFromFormat('!m'$month);
  954.         $monthName $date Utils::$moisFR[$date->format('n') - 1] : $month;
  955.         $monthSlug sprintf('%02d'$month);
  956.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  957.         $canonicalUrl $this->canonicalUrlService->getBuzzActualitesParMoisCanonical($monthSlug$cleanCodePays);
  958.         $metaTag $this->metaTag
  959.                 ->setTitle("Actualités de " $monthName " " $year " - Fusions-Acquisitions et Capital Investissement")
  960.                 ->setDescription("Consultez toutes les actualités de " $monthName " " $year " dans le domaine des fusions-acquisitions et du capital investissement")
  961.                 ->setCanonical($canonicalUrl);
  962.         $featuredRaw $this->buzzActualitesRepository->findFeaturedActualiteOfMonth((int) $year, (int) $month$codePays);
  963.         $firstFeatured $featuredRaw $this->buzzIndexPageProvider->formatArticle($featuredRaw) : null;
  964.         $featuredIds $firstFeatured ? [$firstFeatured['id_actualite']] : [];
  965.         $mainArticlesRaw $this->buzzActualitesRepository->findNewsByMonth((int) $year, (int) $month$codePays$featuredIds);
  966.         $mainArticles array_map(
  967.                 [$this->buzzIndexPageProvider'formatArticle'],
  968.                 array_map(function ($a) {
  969.                     return (array) $a;
  970.                 }, $mainArticlesRaw)
  971.         );
  972.         return $this->render('buzz/mois_avec_actualites.html.twig', [
  973.                     'first_featured' => $firstFeatured,
  974.                     'main_articles' => $mainArticles,
  975.                     'year' => $year,
  976.                     'metaTag' => $metaTag,
  977.                     'month' => $month,
  978.                     'monthName' => $monthName,
  979.                     'codePaysWithUnderScore' => $codePays,
  980.                     'lastMonthsHavingActu' => $this->buzzIndexPageProvider->getLastMonthsHavingActuForCountry($codePays6),
  981.         ]);
  982.     }
  983.     /**
  984.      * Page des actualités weekend
  985.      * 
  986.      * @param string $codePays
  987.      * @param string|null $date
  988.      * @return Response
  989.      */
  990.     public function weekend($codePays, ?string $date null): Response {
  991.         $codePaysClean Utils::codePaysWithoutDash($codePays);
  992.         $weekendData $this->buzzIndexPageProvider->getWeekendPageData($codePaysClean$date);
  993.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  994.         $canonicalUrl $this->canonicalUrlService->getBuzzWeekendCanonical($cleanCodePays$date);
  995.         $metaTag = new MetaTag();
  996.         $metaTag->setTitle('Revue de presse de la semaine - FUSACQ Buzz');
  997.         $metaTag->setDescription('Retrouvez les actualités sélectionnées de la semaine dans le domaine des fusions-acquisitions et du capital-investissement.');
  998.         $metaTag->setCanonical($canonicalUrl);
  999.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_weekend', ['date' => $date], null$cleanCodePays);
  1000.         return $this->render('buzz/index/weekend.html.twig', [
  1001.                     'grouped_articles' => $weekendData['grouped_articles'],
  1002.                     'week_start' => $weekendData['week_start'],
  1003.                     'week_end' => $weekendData['week_end'],
  1004.                     'week_label' => $weekendData['week_label'],
  1005.                     'derniers_jours' => $weekendData['derniers_jours'],
  1006.                     'metaTag' => $metaTag,
  1007.                     'codePaysWithUnderScore' => $codePays,
  1008.                     'hreflangLinks' => $hreflangLinks,
  1009.         ]);
  1010.     }
  1011.     /**
  1012.      * Page "Publier des actualités"
  1013.      */
  1014.     public function publierDesActualites(Request $request$codePays): Response {
  1015.         $cleanCodePays $this->canonicalUrlService->cleanCodePays($codePays);
  1016.         $canonicalUrl $this->canonicalUrlService->getBuzzPublierActualitesCanonical($cleanCodePays);
  1017.         $metaTag $this->metaTag
  1018.                 ->setTitle("Publiez vos actualités - FUSACQ Buzz")
  1019.                 ->setDescription("Publiez vos actualités sur FUSACQ Buzz. Experts, sociétés et repreneurs, diffusez vos opérations de fusions-acquisitions.")
  1020.                 ->setCanonical($canonicalUrl);
  1021.         $hreflangLinks $this->canonicalUrlService->getBuzzHreflangLinks('buzz_publier_actualites', [], null$cleanCodePays);
  1022.         return $this->render('buzz/fragments/publier_des_actualites.html.twig', [
  1023.                     'metaTag' => $metaTag,
  1024.                     'codePays' => $cleanCodePays,
  1025.                     'codePaysWithUnderScore' => $codePays,
  1026.                     'lang' => 'fr',
  1027.                     'currentRoute' => $request->get('_route'),
  1028.                     'authFrom' => null,
  1029.                     'hreflangLinks' => $hreflangLinks,
  1030.         ]);
  1031.     } 
  1032. }