<?phpnamespace App\Controller\ThemesWebsite\Whileresume\Website;use App\Entity\Articles\Articles;use App\Entity\Cvs\Jobs;use App\Entity\Pages\Pages;use App\Entity\Pages\PagesHasBlocks;use App\Services\Core\Core;use Sensio\Bundle\FrameworkExtraBundle\Configuration\Cache;use Sensio\Bundle\FrameworkExtraBundle\Configuration\IsGranted;use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;use Symfony\Component\EventDispatcher\EventDispatcherInterface;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\Response;use Symfony\Component\Routing\Annotation\Route;use Doctrine\ORM\EntityManagerInterface;use Symfony\Component\HttpFoundation\JsonResponse;use Knp\Component\Pager\PaginatorInterface;/** * Système d'articles */class ArticlesController extends AbstractController{ private $em; private $paginator; public function __construct (EntityManagerInterface $em, PaginatorInterface $paginator ){ $this->em = $em; $this->paginator = $paginator; } /** * Liste des articles * @param Request $request * @return mixed */ public function articles(Request $request) { $locale = $request->getLocale(); $page = $this->em->getRepository(Pages::class)->findOneBy(['locale' => $locale, 'name' => 'articles']); if($page->getType() == "brouillon") { return $this->redirectToRoute('homepage'); } if(!empty($page->getRedirect())) { return $this->redirect($page->getRedirect()); } $articles = $this->em->getRepository(Articles::class)->getFinalArticles($locale); $pagination = $this->paginator->paginate( $articles, $request->query->getInt('page', 1), 20 ); $blocks = $this->em->getRepository(PagesHasBlocks::class)->findBy(['page' => $page, 'type' => 'prod', 'startPage' => false],['sequence' => 'ASC']); $page->setViews((int)$page->getViews() + 1); $this->em->persist($page); $this->em->flush(); return $this->render('application/whileresume/website/articles/list.html.twig', [ 'pagination' => $pagination, 'page' => $page, 'blocks' => $blocks, 'formNewsletter' => null ]); } /** * Lire un article * @param Request $request * @param $slug * @return mixed */ public function article(Request $request, $slug) { $locale = $request->getLocale(); $article = $this->em->getRepository(Articles::class)->getArticle($locale,$slug); if($article->getVisibility() == false) { return $this->redirectToRoute('homepage'); } // Articles similaires (5 max) — basés sur tags + pageslug + keyword + featured + author, puis shuffle pour de la variété $similarArticles = $this->em->getRepository(Articles::class)->getSimilarArticles($article, 5); // Jobs aléatoires (5 max) — pool des 100 derniers jobs online dans la locale, mélangés à chaque chargement $recommendedJobs = $this->getRandomJobsForArticle($locale, 5); return $this->render('application/whileresume/website/articles/article.html.twig',[ 'article' => $article, 'similarArticles' => $similarArticles, 'recommendedJobs' => $recommendedJobs, ]); } /** * Sélection aléatoire de jobs online dans la même locale, à afficher sous l'article. * * On récupère un pool large des derniers jobs online, puis on shuffle côté PHP. * Ça évite ORDER BY RAND() (lent sur grosses tables) tout en garantissant de la * variété à chaque rechargement de page. * * @param string $locale * @param int $limit * @return Jobs[] */ private function getRandomJobsForArticle(string $locale, int $limit = 5): array { $jobsRepo = $this->em->getRepository(Jobs::class); // Pool large = on prend les 100 derniers jobs online dans la locale $pool = $jobsRepo->createQueryBuilder('j') ->where('j.online = :online') ->andWhere('j.locale = :locale') ->setParameter('online', true) ->setParameter('locale', $locale) ->orderBy('j.createdAt', 'DESC') ->setMaxResults(100) ->getQuery() ->getResult(); if (empty($pool)) { return []; } shuffle($pool); return array_slice($pool, 0, $limit); }}