Issue #2746033 by amateescu, mohit_aghera, kamalrajsahu21, dawehner, xjm, catch, rfay: NodeController::revisionOverview() does not have a pager, which results in unlimited queries

8.2.x
xjm 2016-07-20 13:14:24 -05:00
parent 7bce285820
commit a0fc0b0d0b
2 changed files with 74 additions and 16 deletions

View File

@ -8,6 +8,7 @@ use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Url;
use Drupal\node\NodeStorageInterface;
use Drupal\node\NodeTypeInterface;
use Drupal\node\NodeInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
@ -170,12 +171,9 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
$delete_permission = (($account->hasPermission("delete $type revisions") || $account->hasPermission('delete all revisions') || $account->hasPermission('administer nodes')) && $node->access('delete'));
$rows = array();
$vids = $node_storage->revisionIds($node);
$default_revision = $node->getRevisionId();
foreach (array_reverse($vids) as $vid) {
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
@ -265,6 +263,8 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
'#attributes' => ['class' => 'node-revision-table'],
);
$build['pager'] = array('#type' => 'pager');
return $build;
}
@ -281,4 +281,25 @@ class NodeController extends ControllerBase implements ContainerInjectionInterfa
return $this->t('Create @name', array('@name' => $node_type->label()));
}
/**
* Gets a list of node revision IDs for a specific node.
*
* @param \Drupal\node\NodeInterface
* The node entity.
* @param \Drupal\node\NodeStorageInterface $node_storage
* The node storage handler.
*
* @return int[]
* Node revision IDs (in descending order).
*/
protected function getRevisionIds(NodeInterface $node, NodeStorageInterface $node_storage) {
$result = $node_storage->getQuery()
->allRevisions()
->condition($node->getEntityType()->getKey('id'), $node->id())
->sort($node->getEntityType()->getKey('revision'), 'DESC')
->pager(50)
->execute();
return array_keys($result);
}
}

View File

@ -2,6 +2,8 @@
namespace Drupal\node\Tests;
use Drupal\node\NodeInterface;
/**
* Create a node with revisions and test viewing, saving, reverting, and
* deleting revisions for user with access to all.
@ -15,7 +17,7 @@ class NodeRevisionsAllTest extends NodeTestBase {
protected function setUp() {
parent::setUp();
$node_storage = $this->container->get('entity.manager')->getStorage('node');
// Create and log in user.
$web_user = $this->drupalCreateUser(
array(
@ -45,6 +47,24 @@ class NodeRevisionsAllTest extends NodeTestBase {
for ($i = 0; $i < $revision_count; $i++) {
$logs[] = $node->revision_log = $this->randomMachineName(32);
$node = $this->createNodeRevision($node);
$nodes[] = clone $node;
}
$this->nodes = $nodes;
$this->revisionLogs = $logs;
}
/**
* Creates a new revision for a given node.
*
* @param \Drupal\node\NodeInterface $node
* A node object.
*
* @return \Drupal\node\NodeInterface
* A node object with up to date revision information.
*/
protected function createNodeRevision(NodeInterface $node) {
// Create revision with a random title and body and update variables.
$node->title = $this->randomMachineName();
$node->body = array(
@ -54,13 +74,7 @@ class NodeRevisionsAllTest extends NodeTestBase {
$node->setNewRevision();
$node->save();
$node_storage->resetCache(array($node->id()));
$node = $node_storage->load($node->id()); // Make sure we get revision information.
$nodes[] = clone $node;
}
$this->nodes = $nodes;
$this->revisionLogs = $logs;
return $node;
}
/**
@ -145,6 +159,29 @@ class NodeRevisionsAllTest extends NodeTestBase {
'%title' => $nodes[2]->getTitle(),
'%revision-date' => format_date($old_revision_date),
)));
// Create 50 more revisions in order to trigger paging on the revisions
// overview screen.
$node = $nodes[0];
for ($i = 0; $i < 50; $i++) {
$logs[] = $node->revision_log = $this->randomMachineName(32);
$node = $this->createNodeRevision($node);
$nodes[] = clone $node;
}
$this->drupalGet('node/' . $node->id() . '/revisions');
// Check that the pager exists.
$this->assertRaw('page=1');
// Check that the last revision is displayed on the first page.
$this->assertText(end($logs));
// Go to the second page and check that one of the initial three revisions
// is displayed.
$this->clickLink(t('Page 2'));
$this->assertText($logs[2]);
}
}