summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorGábor Hojtsy <gabor@hojtsy.hu>2007-12-20 09:20:41 +0000
committerGábor Hojtsy <gabor@hojtsy.hu>2007-12-20 09:20:41 +0000
commit1e63dd1ae61c1e70e33c6cfa5b269c661f3122f7 (patch)
treeb3f289352d198e79cc70fc24929c3dfe80e88c4e /modules
parentf761b8745c306703e0f78b5abdcc900044f5b602 (diff)
downloadbrdo-1e63dd1ae61c1e70e33c6cfa5b269c661f3122f7.tar.gz
brdo-1e63dd1ae61c1e70e33c6cfa5b269c661f3122f7.tar.bz2
#201536 by chx: centralizing permission checking code in node revision handling, removing lots of duplicate code
Diffstat (limited to 'modules')
-rw-r--r--modules/node/node.module57
-rw-r--r--modules/node/node.pages.inc75
2 files changed, 47 insertions, 85 deletions
diff --git a/modules/node/node.module b/modules/node/node.module
index 76c000a50..5839b5889 100644
--- a/modules/node/node.module
+++ b/modules/node/node.module
@@ -1043,7 +1043,10 @@ function node_build_content($node, $teaser = FALSE, $page = FALSE) {
/**
* 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) {
@@ -1069,7 +1072,7 @@ function theme_node_log_message($log) {
* Implementation of hook_perm().
*/
function node_perm() {
- $perms = array('administer content types', 'administer nodes', 'access content', 'view revisions', 'revert revisions');
+ $perms = array('administer content types', 'administer nodes', 'access content', 'view revisions', 'revert revisions', 'delete revisions');
foreach (node_get_types() as $type) {
if ($type->module == 'node') {
@@ -1304,8 +1307,31 @@ function node_link($type, $node = NULL, $teaser = FALSE) {
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();
+ if (!isset($access[$node->vid])) {
+ $node_current_revision = node_load($node->nid);
+ $is_current_revision = $node_current_revision->vid == $node->vid;
+ // 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.
+ // Also, if you try to revert to or delete the current revision, that's
+ // not good.
+ if ($is_current_revision && (db_result(db_query('SELECT COUNT(vid) FROM {node_revisions} WHERE nid = %d', $node->nid)) == 1 || $op == 'update' || $op == 'delete')) {
+ $access[$node->vid] = FALSE;
+ }
+ elseif (user_access('administer nodes')) {
+ $access[$node->vid] = TRUE;
+ }
+ else {
+ $map = array('view' => 'view revisions', 'update' => 'revert revisions', 'delete' => 'delete revisions');
+ // First check the user permission, second check the access to the
+ // current revision and finally, if the node passed in is not the current
+ // revision then access to that, too.
+ $access[$node->vid] = isset($map[$op]) && user_access($map[$op]) && node_access($op, $node_current_revision) && ($is_current_revision || node_access($op, $node));
+ }
+ }
+ return $access[$node->vid];
}
function _node_add_access() {
@@ -1450,28 +1476,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',
- 'page callback' => 'node_revision_delete',
- 'page arguments' => array(1, 3),
+ 'load arguments' => array(3),
+ 'page callback' => 'drupal_get_form',
+ 'page arguments' => array('node_revision_delete_confirm', 1),
'access callback' => '_node_revision_access',
- 'access arguments' => array(1, 3),
+ 'access arguments' => array(1, 'delete'),
'file' => 'node.pages.inc',
'type' => MENU_CALLBACK,
);
diff --git a/modules/node/node.pages.inc b/modules/node/node.pages.inc
index 1092240f1..6861626c6 100644
--- a/modules/node/node.pages.inc
+++ b/modules/node/node.pages.inc
@@ -506,38 +506,6 @@ function node_delete_confirm_submit($form, &$form_state) {
}
/**
- * 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) {
@@ -553,7 +521,7 @@ function node_revision_overview($node) {
$revert_permission = TRUE;
}
$delete_permission = FALSE;
- if (user_access('administer nodes')) {
+ if ((user_access('delete revisions') || user_access('administer nodes')) && node_access('delete', $node)) {
$delete_permission = TRUE;
}
foreach ($revisions as $revision) {
@@ -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) {
@@ -624,28 +573,6 @@ function node_revision_revert_confirm_submit($form, &$form_state) {
$form_state['redirect'] = 'node/'. $node_revision->nid .'/revisions';
}
-/**
- * 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');
- }
- }
- }
- drupal_access_denied();
-}
-
function node_revision_delete_confirm($form_state, $node_revision) {
$form['#node_revision'] = $node_revision;
return confirm_form($form, t('Are you sure you want to delete the revision from %revision-date?', array('%revision-date' => format_date($node_revision->revision_timestamp))), 'node/'. $node_revision->nid .'/revisions', t('This action cannot be undone.'), t('Delete'), t('Cancel'));