From ab75cee93bab7a0908b294814a20433ad336d184 Mon Sep 17 00:00:00 2001
From: Lee Rowlands <lee.rowlands@previousnext.com.au>
Date: Tue, 19 Sep 2023 07:54:45 +1000
Subject: [PATCH] Issue #3384725 by acbramley, smustgrave: Add pagination to
 VersionHistoryController

(cherry picked from commit 9048b09bb197994d0e291726c33c314e08516976)
---
 .../Controller/VersionHistoryController.php   |  5 +++
 .../Entity/RevisionVersionHistoryTest.php     | 41 +++++++++++++++++++
 2 files changed, 46 insertions(+)

diff --git a/core/lib/Drupal/Core/Entity/Controller/VersionHistoryController.php b/core/lib/Drupal/Core/Entity/Controller/VersionHistoryController.php
index 8d069e5aeabc..d93140f3bbbc 100644
--- a/core/lib/Drupal/Core/Entity/Controller/VersionHistoryController.php
+++ b/core/lib/Drupal/Core/Entity/Controller/VersionHistoryController.php
@@ -25,6 +25,8 @@
  */
 class VersionHistoryController extends ControllerBase {
 
+  const REVISIONS_PER_PAGE = 50;
+
   /**
    * Constructs a new VersionHistoryController.
    *
@@ -213,6 +215,7 @@ protected function loadRevisions(RevisionableInterface $entity) {
       ->allRevisions()
       ->condition($entityType->getKey('id'), $entity->id())
       ->sort($entityType->getKey('revision'), 'DESC')
+      ->pager(self::REVISIONS_PER_PAGE)
       ->execute();
 
     $currentLangcode = $this->languageManager
@@ -249,6 +252,8 @@ protected function revisionOverview(RevisionableInterface $entity): array {
       $build['entity_revisions_table']['#rows'][$revision->getRevisionId()] = $this->buildRow($revision);
     }
 
+    $build['pager'] = ['#type' => 'pager'];
+
     (new CacheableMetadata())
       // Only dealing with this entity and no external dependencies.
       ->addCacheableDependency($entity)
diff --git a/core/tests/Drupal/FunctionalTests/Entity/RevisionVersionHistoryTest.php b/core/tests/Drupal/FunctionalTests/Entity/RevisionVersionHistoryTest.php
index bcfb7e810f3e..28ea85730eb0 100644
--- a/core/tests/Drupal/FunctionalTests/Entity/RevisionVersionHistoryTest.php
+++ b/core/tests/Drupal/FunctionalTests/Entity/RevisionVersionHistoryTest.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\FunctionalTests\Entity;
 
+use Drupal\Core\Entity\Controller\VersionHistoryController;
 use Drupal\entity_test\Entity\EntityTestRev;
 use Drupal\entity_test_revlog\Entity\EntityTestWithRevisionLog;
 use Drupal\Tests\BrowserTestBase;
@@ -323,4 +324,44 @@ public function testOperationDeleteRevision(): void {
     $this->assertSession()->elementExists('named', ['link', 'Delete'], $row1);
   }
 
+  /**
+   * Test revisions are paginated.
+   */
+  public function testRevisionsPagination(): void {
+    /** @var \Drupal\entity_test\Entity\EntityTestRev $entity */
+    $entity = EntityTestRev::create([
+      'type' => 'entity_test_rev',
+      'name' => 'view all revisions,view revision',
+    ]);
+    $entity->save();
+
+    $firstRevisionId = $entity->getRevisionId();
+
+    for ($i = 0; $i < VersionHistoryController::REVISIONS_PER_PAGE; $i++) {
+      $entity->setNewRevision(TRUE);
+      // We need to change something on the entity for it to be considered a new
+      // revision to display. We need "view all revisions" and "view revision"
+      // in a comma separated string to grant access.
+      $entity->setName('view all revisions,view revision,' . $i)->save();
+    }
+
+    $this->drupalGet($entity->toUrl('version-history'));
+    $this->assertSession()->elementsCount('css', 'table tbody tr', VersionHistoryController::REVISIONS_PER_PAGE);
+    $this->assertSession()->elementExists('css', '.pager');
+
+    /** @var \Drupal\Core\Entity\RevisionableStorageInterface $storage */
+    $storage = $this->container->get('entity_type.manager')->getStorage($entity->getEntityTypeId());
+    $firstRevision = $storage->loadRevision($firstRevisionId);
+    $secondRevision = $storage->loadRevision($firstRevisionId + 1);
+    // We should see everything up to the second revision, but not the first.
+    $this->assertSession()->linkByHrefExists($secondRevision->toUrl('revision')->toString());
+    $this->assertSession()->linkByHrefNotExists($firstRevision->toUrl('revision')->toString());
+    // The next page should show just the first revision.
+    $this->clickLink('Go to next page');
+    $this->assertSession()->elementsCount('css', 'table tbody tr', 1);
+    $this->assertSession()->elementExists('css', '.pager');
+    $this->assertSession()->linkByHrefNotExists($secondRevision->toUrl('revision')->toString());
+    $this->assertSession()->linkByHrefExists($firstRevision->toUrl('revision')->toString());
+  }
+
 }
-- 
GitLab