From 777bc695c8775b56d42b628c34f64e4bb4dc2d5e Mon Sep 17 00:00:00 2001 From: n0099 Date: Thu, 17 Oct 2024 08:22:47 +0000 Subject: [PATCH] * rename method `getThreadsIdAfter()` to `getThreadsIdWithMaxPostedAtAfter()` as it now also returning the max value of `postedAt` for its replies and their sub replies + param `$postRepositoryFactory` for `getThreadsIdWithMaxPostedAtAfter()` to get table name of other entities after their repository with fid get created @ `__construct()`, also affects `PostRepositoryFactory->newThread()` @ `App\Repository\Post\ThreadRepository` * fix not caching the returned value of `ThreadRepository->getThreadsIdByChunks()` for each fid @ `forums()` * rename the twig variable `threads_id` to `threads` @ `threads()` @ `App\Controller` + `` to show the value of `thread.maxPostedAt` that formated to ISO8601 @ `templates/sitemaps/threads.xml.twig` @ be --- be/src/Controller/SitemapController.php | 21 ++++++------ .../Repository/Post/PostRepositoryFactory.php | 2 +- be/src/Repository/Post/ThreadRepository.php | 34 ++++++++++++++----- be/templates/sitemaps/threads.xml.twig | 5 +-- 4 files changed, 40 insertions(+), 22 deletions(-) diff --git a/be/src/Controller/SitemapController.php b/be/src/Controller/SitemapController.php index 01433dee..0954d350 100644 --- a/be/src/Controller/SitemapController.php +++ b/be/src/Controller/SitemapController.php @@ -27,16 +27,15 @@ public function __construct( #[Route('/sitemaps/forums')] public function forums(): Response { - $threadsIdKeyByFid = collect($this->forumRepository->getOrderedForumsId()) - ->mapWithKeys(fn(int $fid) => [ - $fid => $this->postRepositoryFactory->newThread($fid)->getThreadsIdByChunks(self::$maxUrls), - ]) - ->toArray(); - return $this->cache->get( '/sitemaps/forums', - function (ItemInterface $item) use ($threadsIdKeyByFid) { - $item->expiresAfter(86400); + function (ItemInterface $item) { + $item->expiresAfter(new \DateInterval('P1D')); + $threadsIdKeyByFid = collect($this->forumRepository->getOrderedForumsId()) + ->mapWithKeys(fn(int $fid) => [ + $fid => $this->postRepositoryFactory->newThread($fid)->getThreadsIdByChunks(self::$maxUrls), + ]) + ->toArray(); return $this->renderXml( 'sitemaps/forums.xml.twig', ['threads_id_key_by_fid' => $threadsIdKeyByFid], @@ -55,12 +54,12 @@ public function threads(Request $request, Validator $validator, int $fid): Respo return $this->cache->get( "/sitemaps/forums/$fid/threads?cursor=$cursor", function (ItemInterface $item) use ($fid, $cursor) { - $item->expiresAfter(86400); + $item->expiresAfter(new \DateInterval('P1D')); return $this->renderXml( 'sitemaps/threads.xml.twig', [ - 'threads_id' => - $this->postRepositoryFactory->newThread($fid)->getThreadsIdAfter($cursor, self::$maxUrls), + 'threads' => $this->postRepositoryFactory->newThread($fid) + ->getThreadsIdWithMaxPostedAtAfter($cursor, self::$maxUrls), 'base_url_fe' => $this->getParameter('app.base_url.fe'), ], ); diff --git a/be/src/Repository/Post/PostRepositoryFactory.php b/be/src/Repository/Post/PostRepositoryFactory.php index a1f9f2f0..aff5a20b 100644 --- a/be/src/Repository/Post/PostRepositoryFactory.php +++ b/be/src/Repository/Post/PostRepositoryFactory.php @@ -17,7 +17,7 @@ public function __construct( public function newThread(int $fid): ThreadRepository { - return new ThreadRepository($this->registry, $this->entityManager, $fid); + return new ThreadRepository($this->registry, $this->entityManager, $fid, $this); } public function newReply(int $fid): ReplyRepository diff --git a/be/src/Repository/Post/ThreadRepository.php b/be/src/Repository/Post/ThreadRepository.php index 0afc8adc..65a5e16b 100644 --- a/be/src/Repository/Post/ThreadRepository.php +++ b/be/src/Repository/Post/ThreadRepository.php @@ -3,6 +3,8 @@ namespace App\Repository\Post; use App\DTO\PostKey\Thread as ThreadKey; +use App\Entity\Post\Reply; +use App\Entity\Post\SubReply; use App\Entity\Post\Thread; use Doctrine\ORM\EntityManagerInterface; use Doctrine\ORM\QueryBuilder; @@ -13,8 +15,12 @@ #[Exclude] class ThreadRepository extends PostRepository { - public function __construct(ManagerRegistry $registry, EntityManagerInterface $entityManager, int $fid) - { + public function __construct( + ManagerRegistry $registry, + EntityManagerInterface $entityManager, + int $fid, + private readonly PostRepositoryFactory $postRepositoryFactory, + ) { parent::__construct($registry, $entityManager, Thread::class, $fid); } @@ -46,9 +52,8 @@ public function getThreadsIdByChunks(int $chunkSize): array // https://github.com/doctrine/orm/issues/3542 // https://github.com/doctrine/dbal/issues/5018#issuecomment-2395177479 $entityManager = $this->getEntityManager(); - $connection = $entityManager->getConnection(); $tableName = $entityManager->getClassMetadata(Thread::class)->getTableName(); - $statement = $connection->prepare(<<<"SQL" + $statement = $entityManager->getConnection()->prepare(<<<"SQL" SELECT tid FROM ( SELECT tid, ROW_NUMBER() OVER (ORDER BY tid) rn FROM $tableName ) t WHERE rn % :chunkSize = 0 @@ -57,10 +62,23 @@ public function getThreadsIdByChunks(int $chunkSize): array return $statement->executeQuery()->fetchFirstColumn(); } - public function getThreadsIdAfter(int $after, int $limit): array + public function getThreadsIdWithMaxPostedAtAfter(int $after, int $limit): array { - $dql = 'SELECT t.tid FROM App\Entity\Post\Thread t WHERE t.tid > :after ORDER BY t.tid'; - return $this->createQuery($dql)->setMaxResults($limit) - ->setParameters(compact('after'))->getSingleColumnResult(); + $entityManager = $this->getEntityManager(); + $threadTable = $entityManager->getClassMetadata(Thread::class)->getTableName(); + $replyTable = $this->postRepositoryFactory->newReply($this->getFid()) + ->getEntityManager()->getClassMetadata(Reply::class)->getTableName(); + $subReplyTable = $this->postRepositoryFactory->newSubReply($this->getFid()) + ->getEntityManager()->getClassMetadata(SubReply::class)->getTableName(); + $statement = $entityManager->getConnection()->prepare(<<<"SQL" + SELECT t.tid, GREATEST(t."postedAt", MAX(r."postedAt"), MAX(sr."postedAt")) AS "maxPostedAt" + FROM $threadTable t + JOIN $replyTable r ON r.tid = t.tid + JOIN $subReplyTable sr ON sr.pid = r.pid + WHERE t.tid > :after GROUP BY t.tid ORDER BY t.tid LIMIT :limit + SQL); + $statement->bindValue('after', $after); + $statement->bindValue('limit', $limit); + return $statement->executeQuery()->fetchAllAssociative(); } } diff --git a/be/templates/sitemaps/threads.xml.twig b/be/templates/sitemaps/threads.xml.twig index 1d83c851..2ef48a94 100644 --- a/be/templates/sitemaps/threads.xml.twig +++ b/be/templates/sitemaps/threads.xml.twig @@ -3,9 +3,10 @@ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd" xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"> - {%- for tid in threads_id ~%} + {%- for thread in threads ~%} - {{ base_url_fe }}/posts/tid/{{ tid }} + {{ base_url_fe }}/posts/tid/{{ thread.tid }} + {{ thread.maxPostedAt | date(constant('DateTimeInterface::ATOM'), 'UTC') }} {%- endfor ~%}