=== modified file 'includes/menu.inc' --- includes/menu.inc 2007-12-08 14:06:20 +0000 +++ includes/menu.inc 2007-12-17 15:13:17 +0000 @@ -387,6 +387,9 @@ function _menu_load_objects($item, &$map // the map. $args[$i] = &$map; } + if (is_int($arg)) { + $args[$i] = isset($path_map[$arg]) ? $path_map[$arg] : ''; + } } array_unshift($args, $value); $return = call_user_func_array($function, $args); === modified file 'includes/theme.inc' --- includes/theme.inc 2007-12-08 15:15:25 +0000 +++ includes/theme.inc 2007-12-17 14:01:33 +0000 @@ -1736,8 +1736,9 @@ function template_preprocess_page(&$vari // Closure should be filled last. $variables['closure'] = theme('closure'); - if ((arg(0) == 'node') && is_numeric(arg(1))) { - $variables['node'] = node_load(arg(1)); + $router_item = menu_get_item(); + if (isset($router_item['map'][1]) && is_object($router_item['map'][1]) && !empty($router_item['map'][1]->_is_node)) { + $variables['node'] = $router_item['map'][1]; } // Compile a list of classes that are going to be applied to the body element. === modified file 'modules/comment/comment.install' --- modules/comment/comment.install 2007-12-17 12:23:00 +0000 +++ modules/comment/comment.install 2007-12-17 16:20:33 +0000 @@ -1,8 +1,6 @@ COMMENT_MODE_THREADED_EXPANDED, 'comment_default_order' => COMMENT_ORDER_NEWEST_FIRST, === modified file 'modules/node/node.module' --- modules/node/node.module 2007-12-17 12:41:20 +0000 +++ modules/node/node.module 2007-12-17 16:12:17 +0000 @@ -709,6 +709,7 @@ function node_load($param = array(), $re } if ($node && $node->nid) { + $node->_is_node = TRUE; // Call the node specific callback (if any) and piggy-back the // results to the node or overwrite some values. if ($extra = node_invoke($node, 'load')) { @@ -1050,7 +1051,10 @@ function node_build_content($node, $teas /** * Generate a page displaying a single node, along with its comments. */ -function node_show($node, $cid) { +function node_show($node, $cid, $message = FALSE) { + if ($message) { + drupal_set_title(t('Revision of %title from %date', array('%title' => $node->title, '%date' => format_date($node->revision_timestamp)))); + } $output = node_view($node, FALSE, TRUE); if (function_exists('comment_render') && $node->comment) { @@ -1311,8 +1315,29 @@ function node_link($type, $node = NULL, return $links; } -function _node_revision_access($node) { - return (user_access('view revisions') || user_access('administer nodes')) && node_access('view', $node) && db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node->nid)) > 1; +function _node_revision_access($node, $op = 'view') { + static $access = array(); + // Did node_load succeed? + if (!$node) { + return FALSE; + } + if (!isset($access[$node->vid])) { + $node_current_revision = node_load($node->nid); + // There should be at least two revisions. If the vid of the given node + // and the vid of the current revision differs, then we already have two + // different revisions so there is no need for a separate database check. + if ($node_current_revision->vid == $node->vid && db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node->nid)) == 1) { + $access[$node->vid] = FALSE; + } + elseif (user_access('administer nodes')) { + $access[$node->vid] = TRUE; + } + else { + $map = array('view' => 'view revisions', 'update' > 'revert revisions'); + $access[$node->vid] = isset($map[$op]) && user_access($map[$op]) && node_access($op, $node) && node_access($op, $node_current_revision); + } + } + return $access[$node->vid]; } function _node_add_access() { @@ -1457,28 +1482,37 @@ function node_menu() { 'type' => MENU_CALLBACK); $items['node/%node/revisions'] = array( 'title' => 'Revisions', - 'page callback' => 'node_revisions', + 'page callback' => 'node_revision_overview', + 'page arguments' => array(1), 'access callback' => '_node_revision_access', 'access arguments' => array(1), 'weight' => 2, 'file' => 'node.pages.inc', 'type' => MENU_LOCAL_TASK, ); + $items['node/%node/revisions/%/view'] = array( + 'title' => 'Revisions', + 'page callback' => 'node_show', + 'page arguments' => array(1, NULL, TRUE), + 'type' => MENU_CALLBACK, + ); $items['node/%node/revisions/%/revert'] = array( 'title' => 'Revert to earlier revision', - 'page callback' => 'node_revision_revert', - 'page arguments' => array(1, 3), + 'load arguments' => array(3), + 'page callback' => 'drupal_get_form', + 'page arguments' => array('node_revision_revert_confirm', 1), 'access callback' => '_node_revision_access', - 'access arguments' => array(1, 3), + 'access arguments' => array(1, 'update'), 'file' => 'node.pages.inc', 'type' => MENU_CALLBACK, ); $items['node/%node/revisions/%/delete'] = array( 'title' => 'Delete earlier revision', + 'load arguments' => array(3), 'page callback' => 'node_revision_delete', - 'page arguments' => array(1, 3), + 'page arguments' => array(1), 'access callback' => '_node_revision_access', - 'access arguments' => array(1, 3), + 'access arguments' => array(1, 'delete'), 'file' => 'node.pages.inc', 'type' => MENU_CALLBACK, ); === modified file 'modules/node/node.pages.inc' --- modules/node/node.pages.inc 2007-12-17 10:14:05 +0000 +++ modules/node/node.pages.inc 2007-12-17 16:12:17 +0000 @@ -506,38 +506,6 @@ function node_delete_confirm_submit($for } /** - * Menu callback for revisions related activities. - */ -function node_revisions() { - if (is_numeric(arg(1)) && arg(2) == 'revisions') { - $op = arg(4) ? arg(4) : 'overview'; - switch ($op) { - case 'overview': - $node = node_load(arg(1)); - if ((user_access('view revisions') || user_access('administer nodes')) && node_access('view', $node)) { - return node_revision_overview($node); - } - drupal_access_denied(); - return; - case 'view': - if (is_numeric(arg(3))) { - $node = node_load(arg(1), arg(3)); - if ($node->nid) { - if ((user_access('view revisions') || user_access('administer nodes')) && node_access('view', $node)) { - drupal_set_title(t('Revision of %title from %date', array('%title' => $node->title, '%date' => format_date($node->revision_timestamp)))); - return node_show($node, arg(2)); - } - drupal_access_denied(); - return; - } - } - break; - } - } - drupal_not_found(); -} - -/** * Generate an overview table of older revisions of a node. */ function node_revision_overview($node) { @@ -583,25 +551,6 @@ function node_revision_overview($node) { } /** - * Revert to the revision with the specified revision number. A node and nodeapi "update" event is triggered - * (via the node_save() call) when a revision is reverted. - */ -function node_revision_revert($node, $revision) { - global $user; - - if ((user_access('revert revisions') || user_access('administer nodes')) && node_access('update', $node)) { - $node_revision = node_load($node->nid, $revision); - if ($node_revision->vid) { - return drupal_get_form('node_revision_revert_confirm', $node_revision); - } - else { - drupal_set_message(t('You tried to revert to an invalid revision.'), 'error'); - drupal_goto('node/'. $node->nid .'/revisions'); - } - } - drupal_access_denied(); -} -/** * Ask for confirmation of the reversion to prevent against CSRF attacks. */ function node_revision_revert_confirm($form_state, $node_revision) { @@ -628,22 +577,17 @@ function node_revision_revert_confirm_su * Delete the revision with specified revision number. A "delete revision" nodeapi event is invoked when a * revision is deleted. */ -function node_revision_delete($node, $revision) { - if (user_access('administer nodes')) { - if (node_access('delete', $node)) { - // Don't allow deleting the current revision. - if ($revision != $node->vid) { - // Load the specific revision instead of the current one. - $node_revision = node_load($node->nid, $revision); - return drupal_get_form('node_revision_delete_confirm', $node_revision); - } - else { - drupal_set_message(t('Deletion failed. You tried to delete the current revision.')); - drupal_goto('node/'. $node->nid .'/revisions'); - } - } +function node_revision_delete($node_revision) { + // Load the current revision instead of the specified one. + $node = node_load($node_revision->nid); + // Don't allow deleting the current revision. + if ($node_revision->vid != $node->vid) { + return drupal_get_form('node_revision_delete_confirm', $node_revision); + } + else { + drupal_set_message(t('Deletion failed. You tried to delete the current revision.')); + drupal_goto('node/'. $node->nid .'/revisions'); } - drupal_access_denied(); } function node_revision_delete_confirm($form_state, $node_revision) { @@ -656,7 +600,7 @@ function node_revision_delete_confirm_su db_query("DELETE FROM {node_revisions} WHERE nid = %d AND vid = %d", $node_revision->nid, $node_revision->vid); node_invoke_nodeapi($node_revision, 'delete revision'); watchdog('content', '@type: deleted %title revision %revision.', array('@type' => $node_revision->type, '%title' => $node_revision->title, '%revision' => $node_revision->vid)); - drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_get_types('name', $node_revision), '%title' => $node_revision->title))); + drupal_set_message(t('Revision from %revision-date of @type %title has been deleted.', array('%revision-date' => format_date($node_revision->revision_timestamp), '@type' => node_get_types('name', $node_revision), '%title' => $node_revision->title))); $form_state['redirect'] = 'node/'. $node_revision->nid; if (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node_revision->nid)) > 1) { $form_state['redirect'] .= '/revisions';