Loading core/lib/Drupal/Core/Entity/Controller/VersionHistoryController.php +12 −8 Original line number Diff line number Diff line Loading @@ -210,25 +210,29 @@ protected function loadRevisions(RevisionableInterface $entity) { $entityStorage = $this->entityTypeManager->getStorage($entity->getEntityTypeId()); assert($entityStorage instanceof RevisionableStorageInterface); $result = $entityStorage->getQuery() $query = $entityStorage->getQuery() ->accessCheck(FALSE) ->allRevisions() ->condition($entityType->getKey('id'), $entity->id()) ->sort($entityType->getKey('revision'), 'DESC') ->pager(self::REVISIONS_PER_PAGE) ->execute(); ->pager(self::REVISIONS_PER_PAGE); // Only show revisions that are affected by the language that is being // displayed. if ($translatable) { $query->condition($entityType->getKey('langcode'), $entity->language()->getId()) ->condition($entityType->getKey('revision_translation_affected'), '1'); } $result = $query->execute(); $currentLangcode = $this->languageManager ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT) ->getId(); foreach ($entityStorage->loadMultipleRevisions(array_keys($result)) as $revision) { // Only show revisions that are affected by the language that is being // displayed. if (!$translatable || ($revision->hasTranslation($currentLangcode) && $revision->getTranslation($currentLangcode)->isRevisionTranslationAffected())) { yield ($translatable ? $revision->getTranslation($currentLangcode) : $revision); } } } /** * Generates an overview table of revisions of an entity. Loading core/modules/node/src/Controller/NodeController.php +86 −85 Original line number Diff line number Diff line Loading @@ -148,9 +148,6 @@ public function revisionOverview(NodeInterface $node) { foreach ($this->getRevisionIds($node, $node_storage) as $vid) { /** @var \Drupal\node\NodeInterface $revision */ $revision = $node_storage->loadRevision($vid); // Only show revisions that are affected by the language that is being // displayed. if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) { $username = [ '#theme' => 'username', '#account' => $revision->getRevisionUser(), Loading @@ -164,16 +161,16 @@ public function revisionOverview(NodeInterface $node) { // current language will be the same of the current default revision in // this case. $is_current_revision = $revision->isDefaultRevision() || (!$current_revision_displayed && $revision->wasDefaultRevision()); if (!$is_current_revision) { if ($is_current_revision) { $link = $node->toLink($date)->toString(); $current_revision_displayed = TRUE; } else { $link = Link::fromTextAndUrl($date, new Url('entity.node.revision', [ 'node' => $node->id(), 'node_revision' => $vid, ]))->toString(); } else { $link = $node->toLink($date)->toString(); $current_revision_displayed = TRUE; } $row = []; $column = [ Loading Loading @@ -242,7 +239,6 @@ public function revisionOverview(NodeInterface $node) { $rows[] = $row; } } } $build['node_revisions_table'] = [ '#theme' => 'table', Loading Loading @@ -275,6 +271,8 @@ public function addPageTitle(NodeTypeInterface $node_type) { /** * Gets a list of node revision IDs for a specific node. * * Only returns revisions that are affected by the $node language. * * @param \Drupal\node\NodeInterface $node * The node entity. * @param \Drupal\node\NodeStorageInterface $node_storage Loading @@ -284,11 +282,14 @@ public function addPageTitle(NodeTypeInterface $node_type) { * Node revision IDs (in descending order). */ protected function getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) { $entityType = $node->getEntityType(); $result = $node_storage->getQuery() ->accessCheck(TRUE) ->allRevisions() ->condition($node->getEntityType()->getKey('id'), $node->id()) ->sort($node->getEntityType()->getKey('revision'), 'DESC') ->condition($entityType->getKey('langcode'), $node->language()->getId()) ->condition($entityType->getKey('revision_translation_affected'), '1') ->condition($entityType->getKey('id'), $node->id()) ->sort($entityType->getKey('revision'), 'DESC') ->pager(50) ->execute(); return array_keys($result); Loading core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php +50 −6 Original line number Diff line number Diff line Loading @@ -144,36 +144,31 @@ public function testNodeRevisionsTabWithDefaultRevision(): void { // Create the node. $node = $this->drupalCreateNode(); $storage = \Drupal::entityTypeManager()->getStorage($node->getEntityTypeId()); // Create a new revision based on the default revision. // Revision 2. $node = $storage->load($node->id()); $node->setNewRevision(TRUE); $node->save(); // Revision 3. $node = $storage->load($node->id()); $node->setNewRevision(TRUE); $node->save(); // Revision 4. // Trigger translation changes in order to show the revision. $node = $storage->load($node->id()); $node->setTitle($this->randomString()); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); // Revision 5. $node = $storage->load($node->id()); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); $node_id = $node->id(); $this->drupalGet('node/' . $node_id . '/revisions'); $this->drupalGet($node->toUrl('version-history')); // Verify that the latest affected revision having been a default revision // is displayed as the current one. Loading @@ -194,6 +189,55 @@ public function testNodeRevisionsTabWithDefaultRevision(): void { $this->assertSession()->linkByHrefNotExists('/node/' . $node_id . '/revisions/5/revert'); } /** * Tests the revision tab paginates correctly with affected translations. */ public function testNodeRevisionsTabPagerAffectedTranslations(): void { $this->drupalLogin($this->editor); $node = $this->drupalCreateNode(); // Create 49 revisions with translation changes so there are a total of 50 // including the initial revision. for ($i = 1; $i < 50; $i++) { $node->setTitle($this->randomString()) ->setRevisionLogMessage('translation change ' . $i); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); } // Create 50 revisions without translation changes. for ($i = 0; $i < 50; $i++) { $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); } // There should be the initial 50 revisions and no pager as the // non-affecting revisions are filtered out before pagination. $this->drupalGet($node->toUrl('version-history')); $assert = $this->assertSession(); $assert->pageTextContains('translation change 49'); $assert->elementsCount('css', '.node-revision-table tbody tr', 50); $assert->elementNotExists('css', '.pager'); // Create another translation affecting revision. $node->setTitle($this->randomString()) ->setRevisionLogMessage('translation change 50'); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); // There should now be a pager, and the current revision should be on the // second page. $this->drupalGet($node->toUrl('version-history')); $assert->elementExists('css', '.pager'); $assert->elementNotExists('css', '.revision-current'); $this->clickLink('Page 2'); $assert->elementsCount('css', '.node-revision-table tbody tr', 1); $assert->elementExists('css', '.revision-current'); } /** * Checks the Revisions tab. * Loading core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php +8 −1 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ use Drupal\Core\Entity\Attribute\ContentEntityType; use Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider; use Drupal\Core\Entity\Routing\RevisionHtmlRouteProvider; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; Loading Loading @@ -37,7 +38,10 @@ 'delete' => EntityTestDeleteForm::class, ], 'views_data' => EntityViewsData::class, 'route_provider' => ['html' => DefaultHtmlRouteProvider::class], 'route_provider' => [ 'html' => DefaultHtmlRouteProvider::class, 'revision' => RevisionHtmlRouteProvider::class, ], ], links: [ 'add-form' => '/entity_test_mulrev/add/{type}', Loading @@ -46,6 +50,9 @@ 'delete-form' => '/entity_test/delete/entity_test_mulrev/{entity_test_mulrev}', 'edit-form' => '/entity_test_mulrev/manage/{entity_test_mulrev}/edit', 'revision' => '/entity_test_mulrev/{entity_test_mulrev}/revision/{entity_test_mulrev_revision}/view', 'revision-delete-form' => '/entity_test_mulrev/{entity_test_mulrev}/revision/{entity_test_mulrev_revision}/delete', 'revision-revert-form' => '/entity_test_mulrev/{entity_test_mulrev}/revision/{entity_test_mulrev_revision}/revert', 'version-history' => '/entity_test_mulrev/{entity_test_mulrev}/revisions', ], admin_permission: 'administer entity_test content', base_table: 'entity_test_mulrev', Loading core/tests/Drupal/FunctionalTests/Entity/RevisionVersionHistoryTest.php +11 −3 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ namespace Drupal\FunctionalTests\Entity; use Drupal\Core\Entity\Controller\VersionHistoryController; use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\entity_test\Entity\EntityTestRev; use Drupal\entity_test_revlog\Entity\EntityTestWithRevisionLog; use Drupal\Tests\BrowserTestBase; Loading Loading @@ -316,9 +317,9 @@ public function testOperationDeleteRevision(): void { * Test revisions are paginated. */ public function testRevisionsPagination(): void { /** @var \Drupal\entity_test\Entity\EntityTestRev $entity */ $entity = EntityTestRev::create([ 'type' => 'entity_test_rev', /** @var \Drupal\entity_test\Entity\EntityTestMulRev $entity */ $entity = EntityTestMulRev::create([ 'type' => 'entity_test_mulrev', 'name' => 'view all revisions,view revision', ]); $entity->save(); Loading @@ -333,6 +334,13 @@ public function testRevisionsPagination(): void { $entity->setName('view all revisions,view revision,' . $i)->save(); } // Create revisions without translation changes to ensure these do not // affect pagination. for ($i = 0; $i < VersionHistoryController::REVISIONS_PER_PAGE; $i++) { $entity->setNewRevision(TRUE); $entity->save(); } $this->drupalGet($entity->toUrl('version-history')); $this->assertSession()->elementsCount('css', 'table tbody tr', VersionHistoryController::REVISIONS_PER_PAGE); $this->assertSession()->elementExists('css', '.pager'); Loading Loading
core/lib/Drupal/Core/Entity/Controller/VersionHistoryController.php +12 −8 Original line number Diff line number Diff line Loading @@ -210,25 +210,29 @@ protected function loadRevisions(RevisionableInterface $entity) { $entityStorage = $this->entityTypeManager->getStorage($entity->getEntityTypeId()); assert($entityStorage instanceof RevisionableStorageInterface); $result = $entityStorage->getQuery() $query = $entityStorage->getQuery() ->accessCheck(FALSE) ->allRevisions() ->condition($entityType->getKey('id'), $entity->id()) ->sort($entityType->getKey('revision'), 'DESC') ->pager(self::REVISIONS_PER_PAGE) ->execute(); ->pager(self::REVISIONS_PER_PAGE); // Only show revisions that are affected by the language that is being // displayed. if ($translatable) { $query->condition($entityType->getKey('langcode'), $entity->language()->getId()) ->condition($entityType->getKey('revision_translation_affected'), '1'); } $result = $query->execute(); $currentLangcode = $this->languageManager ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT) ->getId(); foreach ($entityStorage->loadMultipleRevisions(array_keys($result)) as $revision) { // Only show revisions that are affected by the language that is being // displayed. if (!$translatable || ($revision->hasTranslation($currentLangcode) && $revision->getTranslation($currentLangcode)->isRevisionTranslationAffected())) { yield ($translatable ? $revision->getTranslation($currentLangcode) : $revision); } } } /** * Generates an overview table of revisions of an entity. Loading
core/modules/node/src/Controller/NodeController.php +86 −85 Original line number Diff line number Diff line Loading @@ -148,9 +148,6 @@ public function revisionOverview(NodeInterface $node) { foreach ($this->getRevisionIds($node, $node_storage) as $vid) { /** @var \Drupal\node\NodeInterface $revision */ $revision = $node_storage->loadRevision($vid); // Only show revisions that are affected by the language that is being // displayed. if ($revision->hasTranslation($langcode) && $revision->getTranslation($langcode)->isRevisionTranslationAffected()) { $username = [ '#theme' => 'username', '#account' => $revision->getRevisionUser(), Loading @@ -164,16 +161,16 @@ public function revisionOverview(NodeInterface $node) { // current language will be the same of the current default revision in // this case. $is_current_revision = $revision->isDefaultRevision() || (!$current_revision_displayed && $revision->wasDefaultRevision()); if (!$is_current_revision) { if ($is_current_revision) { $link = $node->toLink($date)->toString(); $current_revision_displayed = TRUE; } else { $link = Link::fromTextAndUrl($date, new Url('entity.node.revision', [ 'node' => $node->id(), 'node_revision' => $vid, ]))->toString(); } else { $link = $node->toLink($date)->toString(); $current_revision_displayed = TRUE; } $row = []; $column = [ Loading Loading @@ -242,7 +239,6 @@ public function revisionOverview(NodeInterface $node) { $rows[] = $row; } } } $build['node_revisions_table'] = [ '#theme' => 'table', Loading Loading @@ -275,6 +271,8 @@ public function addPageTitle(NodeTypeInterface $node_type) { /** * Gets a list of node revision IDs for a specific node. * * Only returns revisions that are affected by the $node language. * * @param \Drupal\node\NodeInterface $node * The node entity. * @param \Drupal\node\NodeStorageInterface $node_storage Loading @@ -284,11 +282,14 @@ public function addPageTitle(NodeTypeInterface $node_type) { * Node revision IDs (in descending order). */ protected function getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) { $entityType = $node->getEntityType(); $result = $node_storage->getQuery() ->accessCheck(TRUE) ->allRevisions() ->condition($node->getEntityType()->getKey('id'), $node->id()) ->sort($node->getEntityType()->getKey('revision'), 'DESC') ->condition($entityType->getKey('langcode'), $node->language()->getId()) ->condition($entityType->getKey('revision_translation_affected'), '1') ->condition($entityType->getKey('id'), $node->id()) ->sort($entityType->getKey('revision'), 'DESC') ->pager(50) ->execute(); return array_keys($result); Loading
core/modules/node/tests/src/Functional/NodeRevisionsUiTest.php +50 −6 Original line number Diff line number Diff line Loading @@ -144,36 +144,31 @@ public function testNodeRevisionsTabWithDefaultRevision(): void { // Create the node. $node = $this->drupalCreateNode(); $storage = \Drupal::entityTypeManager()->getStorage($node->getEntityTypeId()); // Create a new revision based on the default revision. // Revision 2. $node = $storage->load($node->id()); $node->setNewRevision(TRUE); $node->save(); // Revision 3. $node = $storage->load($node->id()); $node->setNewRevision(TRUE); $node->save(); // Revision 4. // Trigger translation changes in order to show the revision. $node = $storage->load($node->id()); $node->setTitle($this->randomString()); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); // Revision 5. $node = $storage->load($node->id()); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); $node_id = $node->id(); $this->drupalGet('node/' . $node_id . '/revisions'); $this->drupalGet($node->toUrl('version-history')); // Verify that the latest affected revision having been a default revision // is displayed as the current one. Loading @@ -194,6 +189,55 @@ public function testNodeRevisionsTabWithDefaultRevision(): void { $this->assertSession()->linkByHrefNotExists('/node/' . $node_id . '/revisions/5/revert'); } /** * Tests the revision tab paginates correctly with affected translations. */ public function testNodeRevisionsTabPagerAffectedTranslations(): void { $this->drupalLogin($this->editor); $node = $this->drupalCreateNode(); // Create 49 revisions with translation changes so there are a total of 50 // including the initial revision. for ($i = 1; $i < 50; $i++) { $node->setTitle($this->randomString()) ->setRevisionLogMessage('translation change ' . $i); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); } // Create 50 revisions without translation changes. for ($i = 0; $i < 50; $i++) { $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); } // There should be the initial 50 revisions and no pager as the // non-affecting revisions are filtered out before pagination. $this->drupalGet($node->toUrl('version-history')); $assert = $this->assertSession(); $assert->pageTextContains('translation change 49'); $assert->elementsCount('css', '.node-revision-table tbody tr', 50); $assert->elementNotExists('css', '.pager'); // Create another translation affecting revision. $node->setTitle($this->randomString()) ->setRevisionLogMessage('translation change 50'); $node->isDefaultRevision(FALSE); $node->setNewRevision(TRUE); $node->save(); // There should now be a pager, and the current revision should be on the // second page. $this->drupalGet($node->toUrl('version-history')); $assert->elementExists('css', '.pager'); $assert->elementNotExists('css', '.revision-current'); $this->clickLink('Page 2'); $assert->elementsCount('css', '.node-revision-table tbody tr', 1); $assert->elementExists('css', '.revision-current'); } /** * Checks the Revisions tab. * Loading
core/modules/system/tests/modules/entity_test/src/Entity/EntityTestMulRev.php +8 −1 Original line number Diff line number Diff line Loading @@ -6,6 +6,7 @@ use Drupal\Core\Entity\Attribute\ContentEntityType; use Drupal\Core\Entity\Routing\DefaultHtmlRouteProvider; use Drupal\Core\Entity\Routing\RevisionHtmlRouteProvider; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\Core\Entity\EntityTypeInterface; use Drupal\Core\Field\BaseFieldDefinition; Loading Loading @@ -37,7 +38,10 @@ 'delete' => EntityTestDeleteForm::class, ], 'views_data' => EntityViewsData::class, 'route_provider' => ['html' => DefaultHtmlRouteProvider::class], 'route_provider' => [ 'html' => DefaultHtmlRouteProvider::class, 'revision' => RevisionHtmlRouteProvider::class, ], ], links: [ 'add-form' => '/entity_test_mulrev/add/{type}', Loading @@ -46,6 +50,9 @@ 'delete-form' => '/entity_test/delete/entity_test_mulrev/{entity_test_mulrev}', 'edit-form' => '/entity_test_mulrev/manage/{entity_test_mulrev}/edit', 'revision' => '/entity_test_mulrev/{entity_test_mulrev}/revision/{entity_test_mulrev_revision}/view', 'revision-delete-form' => '/entity_test_mulrev/{entity_test_mulrev}/revision/{entity_test_mulrev_revision}/delete', 'revision-revert-form' => '/entity_test_mulrev/{entity_test_mulrev}/revision/{entity_test_mulrev_revision}/revert', 'version-history' => '/entity_test_mulrev/{entity_test_mulrev}/revisions', ], admin_permission: 'administer entity_test content', base_table: 'entity_test_mulrev', Loading
core/tests/Drupal/FunctionalTests/Entity/RevisionVersionHistoryTest.php +11 −3 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ namespace Drupal\FunctionalTests\Entity; use Drupal\Core\Entity\Controller\VersionHistoryController; use Drupal\entity_test\Entity\EntityTestMulRev; use Drupal\entity_test\Entity\EntityTestRev; use Drupal\entity_test_revlog\Entity\EntityTestWithRevisionLog; use Drupal\Tests\BrowserTestBase; Loading Loading @@ -316,9 +317,9 @@ public function testOperationDeleteRevision(): void { * Test revisions are paginated. */ public function testRevisionsPagination(): void { /** @var \Drupal\entity_test\Entity\EntityTestRev $entity */ $entity = EntityTestRev::create([ 'type' => 'entity_test_rev', /** @var \Drupal\entity_test\Entity\EntityTestMulRev $entity */ $entity = EntityTestMulRev::create([ 'type' => 'entity_test_mulrev', 'name' => 'view all revisions,view revision', ]); $entity->save(); Loading @@ -333,6 +334,13 @@ public function testRevisionsPagination(): void { $entity->setName('view all revisions,view revision,' . $i)->save(); } // Create revisions without translation changes to ensure these do not // affect pagination. for ($i = 0; $i < VersionHistoryController::REVISIONS_PER_PAGE; $i++) { $entity->setNewRevision(TRUE); $entity->save(); } $this->drupalGet($entity->toUrl('version-history')); $this->assertSession()->elementsCount('css', 'table tbody tr', VersionHistoryController::REVISIONS_PER_PAGE); $this->assertSession()->elementExists('css', '.pager'); Loading