source: sipes/modules_contrib/revision_moderation/revision_moderation.module @ c43ea01

stableversion-3.0
Last change on this file since c43ea01 was 177a560, checked in by José Gregorio Puentes <jpuentes@…>, 8 años ago

se agrego el directorio de modulos contribuidos de drupal

  • Propiedad mode establecida a 100644
File size: 15.6 KB
Línea 
1<?php
2// $Id: revision_moderation.module,v 1.39.2.12 2009/12/17 06:18:07 brauerranch Exp $
3
4/**
5 * @file
6 * Allows moderation of node revisions while existing revisions stay visible.
7 */
8
9// Actions module support.
10include_once drupal_get_path('module', 'revision_moderation') .'/revision_moderation_actions.inc';
11
12/**
13 * Implementation of hook_menu().
14 */
15function revision_moderation_menu() {
16  $items = array();
17
18  // Admin menu
19  $items['admin/content/node/revisions'] = array(
20    'title' => t('Pending revisions'),
21    'page callback' => 'revision_moderation_pending_revisions_admin',
22    'access arguments' => array('administer nodes'),
23    'type' => MENU_LOCAL_TASK,
24  );
25
26  // Admin menu
27  $items['admin/settings/revision_moderation'] = array(
28    'title' => t('Revision moderation'),
29    'page callback' => 'drupal_get_form',
30    'page arguments' => array('revision_moderation_settings'),
31    'description' => t('Configure revision publishing options.'),
32    'access arguments' => array('administer nodes'),
33  );
34
35  // Callback to allow users to edit revisions.
36  $items['node/%node/revisions/%/edit'] = array(
37    'title' => t('Edit revision'),
38    'load arguments' => array(3),
39    'page callback' => 'revision_moderation_edit',
40    'page arguments' => array(1),
41    'access callback' => '_node_revision_access',
42    'access arguments' => array(1, 'update'),
43    'file' => 'node.pages.inc',
44    'file path' => drupal_get_path('module', 'node'),
45    'type' => MENU_CALLBACK,
46  );
47
48  // Callback to allow users to publish revisions directly.
49  $items['node/%node/revisions/%/publish'] = array(
50    'title' => t('Publish revision'),
51    'load arguments' => array(3),
52    'page callback' => 'drupal_get_form',
53    'page arguments' => array('revision_moderation_publish_confirm', 1),
54    'access callback' => '_node_revision_access',
55    'access arguments' => array(1, 'update'),
56    'type' => MENU_CALLBACK,
57  );
58
59  return $items;
60}
61
62/**
63 * Menu permission callback.
64 */
65function revision_moderation_admin_perm($nid) {
66  $node = node_load($nid);
67  $access = user_access('administer nodes') || (user_access('view revisions') && node_access('update', $node));
68  return $access;
69}
70
71/**
72 * Menu callback; admin settings page.
73 */
74function revision_moderation_settings() {
75  $form['revision_moderation_exempt'] = array(
76    '#type' => 'checkbox',
77    '#title' => t('Exempt administrators from revision moderation'),
78    '#default_value' => variable_get('revision_moderation_exempt', 1),
79    '#description' => t('With this option enabled, users with the "administer nodes" privilege will bypass the moderation system, and their revisions will be published immediately.'),
80  );
81
82  return system_settings_form($form);
83}
84
85/**
86 * Implementation of hook_form_alter().
87 */
88function revision_moderation_form_alter(&$form, $form_state, $form_id) {
89  // On node edit forms, add in the "New revisions in moderation" option.
90  if (isset($form['#id']) && $form['#id'] == 'node-form') {
91    $default_value = in_array('revision_moderation', variable_get("node_options_{$form['type']['#value']}", array('status', 'promote')));
92    if ($form['nid']['#value']) {
93      $result = db_result(db_query('SELECT revision_moderation FROM {revision_moderation} WHERE nid = %d', $form['nid']['#value']));
94      if ($result !== FALSE) {
95        $default_value = $result;
96      }
97    }
98    // Only show the checkbox if user has 'administer nodes' privileges.
99    if (!empty($node->revision) || user_access('administer nodes')) {
100      $form['revision_information']['revision_moderation'] = array(
101        '#type' => 'checkbox',
102        '#title' => t('New revisions in moderation'),
103        '#default_value' => $default_value,
104      );
105    }
106    else {
107      $form['revision_moderation'] = array(
108        '#type' => 'value',
109        '#value' => $default_value,
110      );
111    }
112  }
113  // Also add option to node settings form
114  elseif ($form_id == 'node_type_form') {
115    $form['workflow']['node_options']['#options']['revision_moderation'] = t('New revisions in moderation');
116  }
117}
118
119/**
120 * Implementation of hook_nodeapi().
121 */
122function revision_moderation_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
123  $args = arg();
124  switch ($op) {
125    case 'insert':
126      // Store revision moderation setting of this node.
127      drupal_write_record('revision_moderation', $node);
128      break;
129
130    case 'update':
131      // Update revision moderation setting of this node.
132      drupal_write_record('revision_moderation', $node, 'nid');
133      break;
134
135    case 'delete':
136      // Delete record from revision_moderation table when node is deleted.
137      db_query('DELETE FROM {revision_moderation} WHERE nid = %d', $node->nid);
138      break;
139
140    case 'load':
141      // Set a revision_moderation property which can be checked later.
142      $node->revision_moderation = db_result(db_query('SELECT revision_moderation FROM {revision_moderation} WHERE nid = %d', $node->nid));
143      break;
144
145    case 'view':
146      // Cannot use _node_revision_access() here, it's static cached with 1 op
147      $access_update = user_access('revert revisions');
148      $access_delete = user_access('delete revisions');
149      // Display more descriptive message at the top of node revision views, including operations
150      // that the current user has available to them.
151      $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));
152      if ($node->vid != $current_vid) {
153        $links = array(); // Array of links to show along with the message.
154        if ($access_update) {
155          // Add a link directly to the diff if we have Diff module installed.
156          if (module_exists('diff')) {
157           if ($node->vid > $current_vid) {
158             $difflink = "node/$node->nid/revisions/view/$current_vid/$node->vid";
159           }
160           else {
161             $difflink = "node/$node->nid/revisions/view/$node->vid/$current_vid";
162           }
163           $links[] = l(t('Compare revisions'), $difflink);
164          }
165          $links[] = l(t('Edit revision'), "node/$node->nid/revisions/$node->vid/edit");
166          // If this revision is old, show an option to revert to it.
167          // Otherwise, show an option to publish it.
168          if ($node->vid < $current_vid) {
169            $links[] = l(t('Revert to revision'), "node/$node->nid/revisions/$node->vid/revert");
170          }
171          else {
172            $links[] = l(t('Publish revision'), "node/$node->nid/revisions/$node->vid/publish");
173          }
174        }
175        if ($access_delete) {
176          $links[] = l(t('Delete revision'), "node/$node->nid/revisions/$node->vid/delete");
177        }
178        // Get username for the revision rather than the original node.
179        $revision_author = user_load($node->revision_uid);
180        drupal_set_message(t('You are currently viewing a revision of this post created on @date by !author.', array('@date' => format_date($node->revision_timestamp, 'small'), '!author' => theme('username', $revision_author))) . theme('item_list', $links));
181      }
182      elseif ($node->revision_moderation == 1 && !$teaser) {
183        // Notify admin if a node has pending revisions.
184        if ($access_update && arg(2) != 'revisions' && revision_moderation_get_node_pending_revisions($node->nid)) {
185          drupal_set_message(t('This post has one or more pending revisions: <a href="@list">view list of revisions</a>.', array('@list' => url("node/$node->nid/revisions"))));
186        }
187      }
188      break;
189  }
190
191  // Only do this logic for non-admin users on nodes with revision moderation
192  // turned on.
193  // And not editing a chose revision
194  if ($node->nid && $node->revision_moderation == 1 && arg(2) != 'revisions'
195    && (!user_access('administer nodes') || !variable_get('revision_moderation_exempt', 1))) {
196    switch ($op) {
197      case 'prepare':
198        // If user has a pending revision for this node, load the latest version of
199        // it instead.
200        if ($revisions = revision_moderation_get_node_pending_revisions($node->nid)) {
201          global $user;
202          foreach ($revisions as $revision) {
203            if ($revision->uid == $user->uid) {
204              drupal_set_message(t('Editing your latest revision, which is still pending moderation.'));
205              $node = node_load($node->nid, $revision->vid);
206              break;
207            }
208          }
209        }
210        break;
211
212      case 'presave':
213        $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));
214        $node->original_node = node_load($node->nid, $current_vid);
215        break;
216
217      case 'update':
218        if (isset($node->original_node)) {
219          // Update node table's vid to the original value.
220
221          db_query("UPDATE {node} SET vid = %d, title = '%s', status = %d, moderate = %d WHERE nid = %d", $node->original_node->vid, $node->original_node->title, $node->original_node->status, $node->original_node->moderate, $node->nid);
222
223          // If node doesn't exist in revision_moderation table, add it.
224          $in_db = db_result(db_query("SELECT revision_moderation FROM {revision_moderation} WHERE nid = %d", $node->nid));
225          if ($in_db === FALSE) {
226            db_query("INSERT INTO {revision_moderation} (nid, revision_moderation) VALUES(%d, 1)", $node->nid);
227          }
228
229          drupal_set_message(t('Your changes have been submitted for moderation.'));
230        }
231        break;
232    }
233  }
234  else if ($node->nid && $node->revision_moderation == 1 && end($args) == 'edit') {
235    switch ($op) {
236      case 'prepare':
237                $revision_author = user_load($node->revision_uid);
238                drupal_set_message(t('You are currently editing a revision of this post created on @date by !author.', array('@date' => format_date($node->revision_timestamp, 'small'), '!author' => theme('username', $revision_author))));
239        break;
240      case 'presave':
241        $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));
242        $node->original_node = node_load($node->nid, $current_vid);
243        break;
244
245      case 'update':
246        if (isset($node->original_node)) {
247          // Update node table's vid to the original value.
248
249          db_query("UPDATE {node} SET vid = %d, title = '%s', status = %d, moderate = %d WHERE nid = %d", $node->original_node->vid, $node->original_node->title, $node->original_node->status, $node->original_node->moderate, $node->nid);
250          drupal_set_message(t('Your changes have been submitted for moderation.'));
251        }
252        break;
253    }
254  }
255 
256}
257
258/**
259 * Implementation of hook_block().
260 */
261function revision_moderation_block($op = 'list', $delta = 0, $edit = array()) {
262  if ($op == 'list') {
263    $blocks[0]['info'] = t('Pending revisions');
264
265    return $blocks;
266  }
267  elseif ($op == 'view') {
268    $block = array();
269
270    if (user_access('administer nodes')) {
271      $output = '';
272      $list = array();
273
274      $nodes = revision_moderation_get_all_pending_revisions(10);
275      if (count($nodes)) {
276        foreach ($nodes as $node) {
277          $list[] = l($node->title, "node/$node->nid/revisions/$node->vid/view");
278        }
279        $output .= theme('item_list', $list);
280        $output .= '<p>'. l(t('View all pending revisions'), 'admin/content/node/revisions') .'</p>';
281      }
282      else {
283        $output .= t('No pending revisions found.');
284      }
285
286      $block['subject'] = t('Pending revisions');
287      $block['content'] = $output;
288    }
289
290    return $block;
291  }
292}
293
294/**
295 * Menu callback to display list of nodes with pending revisions.
296 */
297function revision_moderation_pending_revisions_admin() {
298  return theme('revision_moderation_pending_revisions_admin');
299}
300
301/**
302 * Implementation of hook_theme().
303 */
304function revision_moderation_theme() {
305  return array(
306    'revision_moderation_pending_revisions_admin' => array(
307      'arguments' => array(),
308    ),
309  );
310}
311
312/**
313 * Displays list of nodes with pending revisions.
314 */
315function theme_revision_moderation_pending_revisions_admin() {
316  $nodes = revision_moderation_get_all_pending_revisions(50);
317  if (count($nodes)) {
318    $header = array(
319      t('Title'),
320      t('Type'),
321      t('Updated by'),
322      t('Last updated'),
323    );
324    $rows = array();
325    foreach ($nodes as $node) {
326      $rows[] = array(
327        l($node->title, "node/$node->nid/revisions"),
328        check_plain(node_get_types('name', $node)),
329        theme('username', user_load(array('uid' => $node->uid))),
330        format_date($node->timestamp),
331      );
332    }
333    return theme('table', $header, $rows);
334  }
335  else {
336    return '<p>'. t('No pending revisions found.') .'</p>';
337  }
338}
339
340/**
341 * Retrieve list of all pending revisions.
342 *
343 * @param $limit
344 *  The number of pending revisions to retrieve.
345 */
346function revision_moderation_get_all_pending_revisions($limit) {
347  // Obtain a list of nodes with revisions higher than current published revision.
348  $sql = "SELECT n.nid, r.vid, n.type, r.title, r.body, r.uid, r.timestamp FROM {node} n INNER JOIN {node_revisions} r ON n.nid = r.nid WHERE r.vid > n.vid ORDER BY r.vid DESC LIMIT %d";
349  $result = db_query($sql, $limit);
350  $revisions = array();
351  while ($revision = db_fetch_object($result)) {
352    $revisions[$revision->nid] = $revision;
353  }
354
355  return $revisions;
356}
357
358/**
359 * Retrieve list of all pending revisions for a given node.
360 *
361 * @param $nid
362 *  The node ID to retrieve.
363 */
364function revision_moderation_get_node_pending_revisions($nid) {
365  // Obtain a list of revisions higher than current published revision for a given node.
366  $sql = "SELECT n.nid, r.vid, r.uid FROM {node} n INNER JOIN {node_revisions} r ON n.nid = r.nid WHERE r.vid > n.vid AND n.nid = %d ORDER BY r.vid DESC";
367  $result = db_query($sql, $nid);
368  $revisions = array();
369  while ($revision = db_fetch_object($result)) {
370    $revisions[$revision->vid] = $revision;
371  }
372
373  return $revisions;
374}
375
376/**
377 * Menu callback; edit revision.
378 */
379function revision_moderation_edit($node) {
380  // Get username for the revision rather than the original node.
381  //$revision_author = user_load($node->revision_uid);
382  //drupal_set_message(t('You are currently editing a revision of this post created on @date by !author.', array('@date' => format_date($node->revision_timestamp, 'small'), '!author' => theme('username', $revision_author))));
383  return drupal_get_form($node->type .'_node_form', $node);
384}
385
386/**
387 * Returns a confirmation page for publishing a revision.
388 *
389 * @param $node
390 *   The node object for which revision is to be published.
391 */
392function revision_moderation_publish_confirm($form_state, $node) {
393  $form['node_id'] = array('#type' => 'value', '#value' => $node->nid);
394  $form['title'] = array('#type' => 'value', '#value' => $node->title);
395  $form['revision'] = array('#type' => 'value', '#value' => $node->vid);
396  $form['type'] = array('#type' => 'value', '#value' => $node->type);
397
398  return confirm_form($form, t('Are you sure you want to publish this revision for %title?', array('%title' => $node->title)), 'node/'. $node->nid .'/revisions/'. $node->vid, t('Publishing this revision will make it public for all users.'), t('Publish'), t('Cancel'));
399}
400
401/**
402 * Submission handler for the publish confirm form.
403 * Publishes a revision directly.
404 */
405function revision_moderation_publish_confirm_submit($form, &$form_state) {
406  $nid = $form_state['values']['node_id'];
407  $title = $form_state['values']['title'];
408  $vid = $form_state['values']['revision'];
409  $type = $form_state['values']['type'];
410
411  db_query("UPDATE {node} SET vid = %d, title = '%s' WHERE nid = %d", $vid, $title, $nid);
412  // Clear the cache so an anonymous poster can see the changes
413  cache_clear_all();
414  drupal_set_message('The selected revision has been published.');
415  watchdog('content', '@type: published %title revision %revision', array('@type' => t($type), '%title' => $title, '%revision' => $vid), WATCHDOG_NOTICE, l(t('view'), "node/$nid/revisions/$vid/view"));
416  $form_state['redirect'] = 'node/'. $nid;
417}
Nota: Vea TracBrowser para ayuda de uso del navegador del repositorio.