diff --git a/src/Blog/Repository/BlogRepository.php b/src/Blog/Repository/BlogRepository.php index 08b05620..e427fe3d 100644 --- a/src/Blog/Repository/BlogRepository.php +++ b/src/Blog/Repository/BlogRepository.php @@ -53,6 +53,13 @@ class BlogRepository extends ServiceEntityRepository * The admin review queue: posts awaiting a doctor's decision, newest first. * @return Blog[] */ + /* + * هر چهار فهرست روی `id` هم مرتب می‌شوند، نه فقط `createdAt`. + * + * `created_at` ثانیه‌ای است و ده‌ها مقاله می‌توانند دقیقاً یک مقدار داشته باشند؛ + * ترتیب بین ردیف‌های برابر در MySQL تضمین‌شده نیست. بدون این tiebreaker، دو صفحهٔ + * پیاپیِ همان فهرست می‌توانند یک مقاله را دوبار بدهند و مقالهٔ دیگری را هرگز. + */ public function findByReviewStatus(string $reviewStatus, int $page = 1, int $limit = 20): array { return $this->createQueryBuilder('b') @@ -61,6 +68,7 @@ class BlogRepository extends ServiceEntityRepository ->where('b.reviewStatus = :rs') ->setParameter('rs', $reviewStatus) ->orderBy('b.createdAt', 'DESC') + ->addOrderBy('b.id', 'DESC') ->setFirstResult(($page - 1) * $limit) ->setMaxResults($limit) ->getQuery()->getResult(); @@ -86,6 +94,7 @@ class BlogRepository extends ServiceEntityRepository $qb = $this->adminQb($status, $search) ->leftJoin('b.city', 'c')->addSelect('c') ->orderBy('b.createdAt', 'DESC') + ->addOrderBy('b.id', 'DESC') ->setFirstResult(($page - 1) * $limit) ->setMaxResults($limit); return $qb->getQuery()->getResult(); @@ -120,6 +129,7 @@ class BlogRepository extends ServiceEntityRepository ->where('b.representation = :rep') ->setParameter('rep', $rep) ->orderBy('b.createdAt', 'DESC') + ->addOrderBy('b.id', 'DESC') ->setFirstResult(($page - 1) * $limit) ->setMaxResults($limit); if ($status !== null && $status !== '') { @@ -166,6 +176,7 @@ class BlogRepository extends ServiceEntityRepository ->where('b.status = :status') ->setParameter('status', Blog::STATUS_PUBLISHED) ->orderBy('b.createdAt', 'DESC') + ->addOrderBy('b.id', 'DESC') ->setFirstResult(($page - 1) * $limit) ->setMaxResults($limit);