From 68acec2717d4096e3d5160ff36a6994500ec549e Mon Sep 17 00:00:00 2001 From: jwilson3 Date: Wed, 26 Aug 2015 14:55:21 -0400 Subject: [PATCH] Issue #1408838 by jwilson3, Kristen Pol, miteshmap, gabriel.achille, DamienMcKenna, colan: Increase performance on node history page. --- workbench_moderation.module | 30 +++++------------------- workbench_moderation.node.inc | 54 +++++++++++++++++++++++++++++++++---------- 2 files changed, 48 insertions(+), 36 deletions(-) diff --git a/workbench_moderation.module b/workbench_moderation.module index 5a2ff16..1a2f0a0 100644 --- a/workbench_moderation.module +++ b/workbench_moderation.module @@ -186,14 +186,15 @@ function workbench_moderation_menu_alter(&$items) { $items['node/%node/revisions']['page arguments'] = array(1); // Override the node revision view callback. - $items['node/%node/revisions/%/view']['page callback'] = 'workbench_moderation_node_view_revision'; - $items['node/%node/revisions/%/view']['file path'] = drupal_get_path('module', 'workbench_moderation'); - $items['node/%node/revisions/%/view']['file'] = 'workbench_moderation.node.inc'; - + $items['node/%node/revisions/%/view']['page callback'] = 'workbench_moderation_node_view_revision'; + $items['node/%node/revisions/%/view']['file path'] = drupal_get_path('module', 'workbench_moderation'); + $items['node/%node/revisions/%/view']['file'] = 'workbench_moderation.node.inc'; // For revert and delete operations, use our own access check. $items['node/%node/revisions/%/revert']['access callback'] = '_workbench_moderation_revision_access'; + $items['node/%node/revisions/%/revert']['access arguments'] = array(1, 'update'); $items['node/%node/revisions/%/delete']['access callback'] = '_workbench_moderation_revision_access'; + $items['node/%node/revisions/%/delete']['access arguments'] = array(1, 'delete'); // Provide a container administration menu item, if one doesn't already exist. if (!isset($items['admin/config/workbench'])) { @@ -527,27 +528,8 @@ function _workbench_moderation_revision_access($node, $op) { } } - // Temporarily give the node an impossible revision. - // _node_revision_access() keeps access check results in a static variable - // indexed by revision only, not by op. Thus, subsequent checks on the same - // vid for different ops yield the same result, regardless of permissions. - // Setting a fake vid here allows us to store different static results per op. - $tmp = $node->vid; - switch ($op) { - case 'update': - $node->vid = -1; - break; - case 'delete': - $node->vid = -2; - break; - } - // Check access. - $access = _node_revision_access($node, $op); - - // Restore the original revision id. - $node->vid = $tmp; - return $access; + return _node_revision_access($node, $op); } /** diff --git a/workbench_moderation.node.inc b/workbench_moderation.node.inc index efe9c4a..a5f6862 100644 --- a/workbench_moderation.node.inc +++ b/workbench_moderation.node.inc @@ -83,14 +83,15 @@ function workbench_moderation_node_history_view($node) { drupal_set_title(t('History of %title', array('%title' => $node->title)), PASS_THROUGH); // Get all of the node revisions, each with its most recent moderation. - $query = db_select('node', 'n'); + $query = db_select('node', 'n')->extend('PagerDefault'); $query->leftJoin('node_revision', 'r', 'n.nid = r.nid'); $query->leftJoin('users', 'u', 'r.uid = u.uid'); $query->addField('n', 'vid', 'live_revision'); $query->condition('n.nid', $node->nid) ->orderBy('r.vid', 'DESC') ->fields('r', array('nid', 'vid', 'title', 'log', 'uid', 'timestamp')) - ->fields('u', array('name')); + ->fields('u', array('name')) + ->limit(30); $revisions = $query->execute() ->fetchAllAssoc('vid'); @@ -129,14 +130,36 @@ function workbench_moderation_node_history_view($node) { // Revision operations. $revision_operations = array(); - if (isset($node->workbench_moderation['published']) && $revision->vid == $node->workbench_moderation['published']->vid) { - $revision_operations['view'] = workbench_moderation_access_link(t('View'), "node/{$revision->nid}"); - } - elseif ($revision->vid == $node->workbench_moderation['current']->vid) { - $revision_operations['view'] = workbench_moderation_access_link(t('View'), "node/{$revision->nid}/current-revision"); + + // Loading the node at the specific revision using node_load() is too slow + // when there are many revisions, thus we fake it by cloning the original + // node and changing the 'vid' and the 'my_revision' elements required for + // granting access to the revision operations (view, update/revert, delete). + $node_revision = clone $node; + $node_revision->vid = $revision->vid; + $node_revision->workbench_moderation['my_revision'] = $revision; + + // View operation. + if (_workbench_moderation_revision_access($node_revision, 'view')) { + // Link to the node page if this is the published revision. + if (isset($node->workbench_moderation['published']) && $revision->vid == $node->workbench_moderation['published']->vid) { + $url = "node/{$revision->nid}"; + } + // The special case "current-revision" link handles routing for the + // current unpublished revision. + elseif ($revision->vid == $node->workbench_moderation['current']->vid) { + $url = "node/{$revision->nid}/current-revision"; + } + // Otherwise, link to the normal revision view page. + else { + $url = "node/{$revision->nid}/revisions/{$revision->vid}/view"; + } + $revision_operations['view'] = l(t('View'), $url); } - else { - $revision_operations['view'] = workbench_moderation_access_link(t('View'), "node/{$revision->nid}/revisions/{$revision->vid}/view"); + + // Revert operation. + if (_workbench_moderation_revision_access($node_revision, 'update')) { + $revision_operations['revert'] = l(t('Revert'), "node/{$revision->nid}/revisions/{$revision->vid}/revert"); } // Provide a courtesy edit operation if this is the current revision. @@ -154,8 +177,10 @@ function workbench_moderation_node_history_view($node) { $revision_operations['edit'] = l($edit_operation_title, "node/{$revision->nid}/edit", array('query' => array('destination' => "node/{$revision->nid}/moderation"))); } - $revision_operations['revert'] = workbench_moderation_access_link(t('Revert'), "node/{$revision->nid}/revisions/{$revision->vid}/revert"); - $revision_operations['delete'] = workbench_moderation_access_link(t('Delete'), "node/{$revision->nid}/revisions/{$revision->vid}/delete"); + // Delete operation. + if (_workbench_moderation_revision_access($node_revision, 'delete')) { + $revision_operations['delete'] = l(t('Delete'), "node/{$revision->nid}/revisions/{$revision->vid}/delete"); + } $row['data']['revision'] = implode(' | ', array_filter($revision_operations)); @@ -236,7 +261,7 @@ function workbench_moderation_node_history_view($node) { $header = array(t('Revision'), t('Title'), t('Date'), t('Revision actions'), t('Moderation actions')); // Return properly styled output. - return array( + $build['pager_table'] = array( '#attached' => array( 'css' => array( drupal_get_path('module', 'workbench_moderation') . '/css/workbench_moderation.css', @@ -246,6 +271,11 @@ function workbench_moderation_node_history_view($node) { '#header' => $header, '#rows' => $rows, ); + + // Attach the pager theme. + $build['pager_pager'] = array('#theme' => 'pager'); + + return $build; } /** -- 2.1.4