/[drupal]/contributions/modules/revision_moderation/revision_moderation.module
ViewVC logotype

Diff of /contributions/modules/revision_moderation/revision_moderation.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph | View Patch Patch

revision 1.49, Sat Dec 27 22:27:36 2008 UTC revision 1.49.2.1, Sun Oct 18 20:19:52 2009 UTC
# Line 1  Line 1 
1  <?php  <?php
2  // $Id: revision_moderation.module,v 1.48 2008/12/24 15:24:01 add1sun Exp $  // $Id: revision_moderation.module,v 1.49 2008/12/27 22:27:36 add1sun Exp $
3    
4  /**  /**
5   * @file   * @file
# Line 7  Line 7 
7   */   */
8    
9  // Actions module support.  // Actions module support.
10  include_once drupal_get_path('module', 'revision_moderation') .'/revision_moderation_actions.inc';  include_once drupal_get_path('module', 'revision_moderation') . '/revision_moderation_actions.inc';
11    
12  /**  /**
13   * Implementation of hook_menu().   * Implement hook_menu().
14   */   */
15  function revision_moderation_menu() {  function revision_moderation_menu() {
16    $items = array();    $items = array();
17    
18    // Admin menu    // Admin menu
19    $items['admin/content/node/revisions'] = array(    $items['admin/content/node/revisions'] = array(
20      'title' => t('Pending revisions'),      'title' => 'Pending revisions',
21      'page callback' => 'revision_moderation_pending_revisions_admin',      'page callback' => 'revision_moderation_pending_revisions_admin',
22      'access arguments' => array('administer nodes'),      'access arguments' => array('administer nodes'),
23      'type' => MENU_LOCAL_TASK,      'type' => MENU_LOCAL_TASK,
24    );    );
25    
26    // Admin menu    // Admin menu
27    $items['admin/settings/revision_moderation'] = array(    $items['admin/config/content/revision_moderation'] = array(
28      'title' => t('Revision moderation'),      'title' => 'Revision moderation',
29      'page callback' => 'drupal_get_form',      'page callback' => 'drupal_get_form',
30      'page arguments' => array('revision_moderation_settings'),      'page arguments' => array('revision_moderation_settings'),
31      'description' => t('Configure revision publishing options.'),      'description' => 'Configure revision publishing options.',
32      'access arguments' => array('administer nodes'),      'access arguments' => array('administer nodes'),
33    );    );
34    
35    // Callback to allow users to edit revisions.    // Callback to allow users to edit revisions.
36    $items['node/%node/revisions/%/edit'] = array(    $items['node/%node/revisions/%/edit'] = array(
37      'title' => t('Edit revision'),      'title' => 'Edit revision',
38      'load arguments' => array(3),      'load arguments' => array(3),
39      'page callback' => 'revision_moderation_edit',      'page callback' => 'revision_moderation_edit',
40      'page arguments' => array(1),      'page arguments' => array(1),
# Line 47  function revision_moderation_menu() { Line 47  function revision_moderation_menu() {
47    
48    // Callback to allow users to publish revisions directly.    // Callback to allow users to publish revisions directly.
49    $items['node/%node/revisions/%/publish'] = array(    $items['node/%node/revisions/%/publish'] = array(
50      'title' => t('Publish revision'),      'title' => 'Publish revision',
51      'load arguments' => array(3),      'load arguments' => array(3),
52      'page callback' => 'drupal_get_form',      'page callback' => 'drupal_get_form',
53      'page arguments' => array('revision_moderation_publish_confirm', 1),      'page arguments' => array('revision_moderation_publish_confirm', 1),
# Line 62  function revision_moderation_menu() { Line 62  function revision_moderation_menu() {
62  /**  /**
63   * Menu permission callback.   * Menu permission callback.
64   */   */
65  function revision_moderation_admin_perm($nid) {  function revision_moderation_admin_permisson($nid) {
66    $node = node_load($nid);    $node = node_load($nid);
67    $access = user_access('administer nodes') || (user_access('view revisions') && node_access('update', $node));    $access = user_access('administer nodes') || (user_access('view revisions') && node_access('update', $node));
68    return $access;    return $access;
# Line 83  function revision_moderation_settings() Line 83  function revision_moderation_settings()
83  }  }
84    
85  /**  /**
86   * Implementation of hook_form_alter().   * Implement hook_form_alter().
87   */   */
88  function revision_moderation_form_alter(&$form, $form_state, $form_id) {  function revision_moderation_form_alter(&$form, $form_state, $form_id) {
89    // On node edit forms, add in the "New revisions in moderation" option.    // On node edit forms, add in the "New revisions in moderation" option.
90    if (isset($form['#id']) && $form['#id'] == 'node-form') {    if (!empty($form['#node_edit_form'])) {
91      $default_value = in_array('revision_moderation', variable_get("node_options_{$form['type']['#value']}", array('status', 'promote')));      $default_value = in_array('revision_moderation', variable_get("node_options_{$form['type']['#value']}", array('status', 'promote')));
92      if ($form['nid']['#value']) {      if ($form['nid']['#value']) {
93        $result = db_result(db_query('SELECT revision_moderation FROM {revision_moderation} WHERE nid = %d', $form['nid']['#value']));        $result = db_query_range('SELECT revision_moderation FROM {revision_moderation} WHERE nid = :nid', 0, 1, array(':nid' => $form['nid']['#value'], ))->fetchField();
94        if ($result !== FALSE) {        if ($result !== FALSE) {
95          $default_value = $result;          $default_value = $result;
96        }        }
# Line 117  function revision_moderation_form_alter( Line 117  function revision_moderation_form_alter(
117  }  }
118    
119  /**  /**
120   * Implementation of hook_nodeapi().   * Implement hook_node_insert().
121   */   */
122  function revision_moderation_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {  function revision_moderation_node_insert($node) {
123    switch ($op) {    // Store revision moderation setting of this node.
124      case 'insert':    drupal_write_record('revision_moderation', $node);
125        // Store revision moderation setting of this node.  }
126        drupal_write_record('revision_moderation', $node);  
127        break;  /**
128     * Implement hook_node_update().
129      case 'update':   */
130        // Update revision moderation setting of this node.  function revision_moderation_node_update($node) {
131        drupal_write_record('revision_moderation', $node, 'nid');    // Update revision moderation setting of this node.
132        break;    drupal_write_record('revision_moderation', $node, 'nid');
133      if ($node->nid && $node->revision_moderation == 1 && arg(2) != 'revisions'
134      case 'delete':      && (!user_access('administer nodes') || !variable_get('revision_moderation_exempt', 1))) {
135        // Delete record from revision_moderation table when node is deleted.      if (isset($node->original_node)) {
136        db_query('DELETE FROM {revision_moderation} WHERE nid = %d', $node->nid);        // Update node table's vid to the original value.
137        break;        db_update('node')
138            -> fields(array('vid'       => $node->original_node->vid,
139      case 'load':                          'title'     => $node->original_node->title['zxx'][0]['value'],
140        // Set a revision_moderation property which can be checked later.                          'status'    => $node->original_node->status,
141        $node->revision_moderation = db_result(db_query('SELECT revision_moderation FROM {revision_moderation} WHERE nid = %d', $node->nid));                          'moderate'  => $node->original_node->moderate,
142        break;                          ))
143            ->condition('nid', $node->nid)
144      case 'view':          ->execute();
145        // Cannot use _node_revision_access() here, it's static cached with 1 op        drupal_set_message(t('Your changes have been submitted for moderation.'));
146        $access_update = user_access('revert revisions');      }
147        $access_delete = user_access('delete revisions');    }
148        // Display more descriptive message at the top of node revision views, including operations  }
149        // that the current user has available to them.  
150        $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));  /**
151        if ($node->vid != $current_vid) {   * Implement hook_node_delete().
152          $links = array(); // Array of links to show along with the message.   */
153          if ($access_update) {  function revision_moderation_node_delete($node) {
154            // Add a link directly to the diff if we have Diff module installed.    // Delete record from revision_moderation table when node is deleted.
155            if (module_exists('diff')) {    db_delete('revision_moderation')
156              if ($node->vid > $current_vid) {      ->condition('nid', $node->nid)
157               $difflink = "node/$node->nid/revisions/view/$current_vid/$node->vid";      ->execute();
158              }  }
159              else {  
160               $difflink = "node/$node->nid/revisions/view/$node->vid/$current_vid";  /**
161              }   * Implement hook_node_load().
162              $links[] = l(t('Compare revisions'), $difflink);   */
163            }  function revision_moderation_node_load($nodes, $types) {
164            $links[] = l(t('Edit revision'), "node/$node->nid/revisions/$node->vid/edit");     // Set a revision_moderation property which can be checked later.
165            // If this revision is old, show an option to revert to it.    $results = db_query('SELECT revision_moderation, nid FROM {revision_moderation} WHERE nid IN(:nids)', array(':nids' => array_keys($nodes), ));
166            // Otherwise, show an option to publish it.    foreach ($results as $record) {
167            if ($node->vid < $current_vid) {      $nodes[$record->nid]->revision_moderation = $record->revision_moderation;
168              $links[] = l(t('Revert to revision'), "node/$node->nid/revisions/$node->vid/revert");    }
169            }  }
170            else {  
171              $links[] = l(t('Publish revision'), "node/$node->nid/revisions/$node->vid/publish");  /**
172            }   * Implement hook_node_view().
173     */
174    function revision_moderation_node_view($node) {
175      // Cannot use _node_revision_access() here, it's static cached with 1 op
176      $access_update = user_access('revert revisions');
177      $access_delete = user_access('delete revisions');
178      // Display more descriptive message at the top of node revision views, including operations
179      // that the current user has available to them.
180      $current_vid = db_query_range('SELECT vid FROM {node} WHERE nid = :nid', 0, 1,  array(':nid' => $node->nid, ))->fetchField();
181      if ($node->vid != $current_vid) {
182        $links = array(); // Array of links to show along with the message.
183        if ($access_update) {
184          // Add a link directly to the diff if we have Diff module installed.
185          if (module_exists('diff')) {
186            if ($node->vid > $current_vid) {
187              $difflink = "node/$node->nid/revisions/view/$current_vid/$node->vid";
188          }          }
189          if ($access_delete) {          else {
190            $links[] = l(t('Delete revision'), "node/$node->nid/revisions/$node->vid/delete");            $difflink = "node/$node->nid/revisions/view/$node->vid/$current_vid";
191          }          }
192          // Get username for the revision rather than the original node.          $links[] = l(t('Compare revisions'), $difflink);
         $revision_author = user_load($node->revision_uid);  
         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));  
193        }        }
194        elseif ($node->revision_moderation == 1 && !$teaser) {        $links[] = l(t('Edit revision'), "node/$node->nid/revisions/$node->vid/edit");
195          // Notify admin if a node has pending revisions.        // If this revision is old, show an option to revert to it.
196          if ($access_update && arg(2) != 'revisions' && revision_moderation_get_node_pending_revisions($node->nid)) {        // Otherwise, show an option to publish it.
197            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"))));        if ($node->vid < $current_vid) {
198          }          $links[] = l(t('Revert to revision'), "node/$node->nid/revisions/$node->vid/revert");
199          }
200          else {
201            $links[] = l(t('Publish revision'), "node/$node->nid/revisions/$node->vid/publish");
202        }        }
203        break;      }
204        if ($access_delete) {
205          $links[] = l(t('Delete revision'), "node/$node->nid/revisions/$node->vid/delete");
206        }
207        // Get username for the revision rather than the original node.
208        $author = user_load($node->revision_uid);
209        $revision_author = array('account' => $author,
210                                 'name' => check_plain($author->name),
211                                 );
212        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));
213    }    }
214      elseif (isset($node->revision_moderation) && $node->revision_moderation == 1 && $node->build_mode != 'teaser') {
215        // Notify admin if a node has pending revisions.
216        if ($access_update && arg(2) != 'revisions' && revision_moderation_get_node_pending_revisions($node->nid)) {
217          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"))));
218        }
219      }
220    }
221    
222    // Only do this logic for non-admin users on nodes with revision moderation  /**
223    // turned on.   * Implement hook_node_prepare().
224    // And not editing a chose revision   */
225    if ($node->nid && $node->revision_moderation == 1 && arg(2) != 'revisions'  function revision_moderation_node_prepare($node) {
226      && (!user_access('administer nodes') || !variable_get('revision_moderation_exempt', 1))) {    if (isset($node->nid)) {
227      switch ($op) {      if (isset($node->revision_moderation) && $node->nid && $node->revision_moderation == 1 && arg(2) != 'revisions'
228        case 'prepare':        && (!user_access('administer nodes') || !variable_get('revision_moderation_exempt', 1))) {
229          // If user has a pending revision for this node, load the latest version of        // If user has a pending revision for this node, load the latest version of
230          // it instead.        // it instead.
231          if ($revisions = revision_moderation_get_node_pending_revisions($node->nid)) {        if ($revisions = revision_moderation_get_node_pending_revisions($node->nid)) {
232            global $user;          global $user;
233            foreach ($revisions as $revision) {          foreach ($revisions as $revision) {
234              if ($revision->uid == $user->uid) {            if ($revision->uid == $user->uid) {
235                drupal_set_message(t('Editing your latest revision, which is still pending moderation.'));              drupal_set_message(t('Editing your latest revision, which is still pending moderation.'));
236                $node = node_load($node->nid, $revision->vid);              $node = node_load($node->nid, $revision->vid);
               break;  
             }  
237            }            }
238          }          }
239          break;        }
   
       case 'presave':  
         $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));  
         $node->original_node = node_load($node->nid, $current_vid);  
         break;  
   
       case 'update':  
         if (isset($node->original_node)) {  
           // Update node table's vid to the original value.  
   
           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);  
           drupal_set_message(t('Your changes have been submitted for moderation.'));  
         }  
         break;  
240      }      }
241    }    }
242  }  }
243    
244  /**  /**
245   * Implementation of hook_block().   * Implement hook_node_presave().
246     */
247    function revision_moderation_node_presave($node) {
248      if ($node->nid && $node->revision_moderation == 1 && arg(2) != 'revisions'
249        && (!user_access('administer nodes') || !variable_get('revision_moderation_exempt', 1))) {
250        $current_vid = db_query_range('SELECT vid FROM {node} WHERE nid = :nid', 0, 1, array(':nid' => $node->nid, ))->fetchField();
251        $node->original_node = node_load($node->nid, $current_vid);
252      }
253    }
254    
255    
256    /**
257     * Implement hook_block().
258   */   */
259  function revision_moderation_block($op = 'list', $delta = 0, $edit = array()) {  function revision_moderation_block($op = 'list', $delta = 0, $edit = array()) {
260    if ($op == 'list') {    if ($op == 'list') {
# Line 247  function revision_moderation_block($op = Line 275  function revision_moderation_block($op =
275            $list[] = l($node->title, "node/$node->nid/revisions/$node->vid/view");            $list[] = l($node->title, "node/$node->nid/revisions/$node->vid/view");
276          }          }
277          $output .= theme('item_list', $list);          $output .= theme('item_list', $list);
278          $output .= '<p>'. l(t('View all pending revisions'), 'admin/content/node/revisions') .'</p>';          $output .= '<p>' . l(t('View all pending revisions'), 'admin/content/node/revisions') . '</p>';
279        }        }
280        else {        else {
281          $output .= t('No pending revisions found.');          $output .= t('No pending revisions found.');
# Line 269  function revision_moderation_pending_rev Line 297  function revision_moderation_pending_rev
297  }  }
298    
299  /**  /**
300   * Implementation of hook_theme().   * Implement hook_theme().
301   */   */
302  function revision_moderation_theme() {  function revision_moderation_theme() {
303    return array(    return array(
# Line 286  function theme_revision_moderation_pendi Line 314  function theme_revision_moderation_pendi
314    $nodes = revision_moderation_get_all_pending_revisions(50);    $nodes = revision_moderation_get_all_pending_revisions(50);
315    if (count($nodes)) {    if (count($nodes)) {
316      $header = array(      $header = array(
317        t('Title'),        t('Title', array(), array('context' => 'Node title', )),
318        t('Type'),        t('Type', array(), array('context' => 'Node types', )),
319        t('Updated by'),        t('Updated by'),
320        t('Last updated'),        t('Last updated'),
321      );      );
322      $rows = array();      $rows = array();
323      foreach ($nodes as $node) {      foreach ($nodes as $node) {
324        $rows[] = array(        $rows[] = array(
325          l($node->title, "node/$node->nid/revisions"),          l($node->title['zxx'][0]['value'], "node/$node->nid/revisions"),
326          check_plain(node_get_types('name', $node)),          check_plain(node_get_type_name($node)),
327          theme('username', user_load(array('uid' => $node->uid))),          theme('username', user_load(array('uid' => $node->uid))),
328          format_date($node->timestamp),          format_date($node->timestamp),
329        );        );
330      }      }
331      return theme('table', $header, $rows);      return theme('table', array('header' => $header, 'rows' => $rows));
332    }    }
333    else {    else {
334      return '<p>'. t('No pending revisions found.') .'</p>';      return '<p>' . t('No pending revisions found.') . '</p>';
335    }    }
336  }  }
337    
# Line 315  function theme_revision_moderation_pendi Line 343  function theme_revision_moderation_pendi
343   */   */
344  function revision_moderation_get_all_pending_revisions($limit) {  function revision_moderation_get_all_pending_revisions($limit) {
345    // Obtain a list of nodes with revisions higher than current published revision.    // Obtain a list of nodes with revisions higher than current published revision.
346    $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";    $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 :limit";
347    $result = db_query($sql, $limit);    $result = db_query($sql, array(':limit' => $limit, ));
348    $revisions = array();    $revisions = array();
349    while ($revision = db_fetch_object($result)) {    foreach ($result as $revision) {
350      $revisions[$revision->nid] = $revision;      $revisions[$revision->nid] = $revision;
351    }    }
352    
# Line 333  function revision_moderation_get_all_pen Line 361  function revision_moderation_get_all_pen
361   */   */
362  function revision_moderation_get_node_pending_revisions($nid) {  function revision_moderation_get_node_pending_revisions($nid) {
363    // Obtain a list of revisions higher than current published revision for a given node.    // Obtain a list of revisions higher than current published revision for a given node.
364    $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";    $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 = :nid ORDER BY r.vid DESC";
365    $result = db_query($sql, $nid);    $result = db_query($sql, array(':nid' => $nid, ));
366    $revisions = array();    $revisions = array();
367    while ($revision = db_fetch_object($result)) {    while ($revision = db_fetch_object($result)) {
368      $revisions[$revision->vid] = $revision;      $revisions[$revision->vid] = $revision;
# Line 350  function revision_moderation_edit($node) Line 378  function revision_moderation_edit($node)
378    // Get username for the revision rather than the original node.    // Get username for the revision rather than the original node.
379    $revision_author = user_load($node->revision_uid);    $revision_author = user_load($node->revision_uid);
380    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))));    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))));
381    return drupal_get_form($node->type .'_node_form', $node);    return drupal_get_form($node->type . '_node_form', $node);
382  }  }
383    
384  /**  /**
# Line 365  function revision_moderation_publish_con Line 393  function revision_moderation_publish_con
393    $form['revision'] = array('#type' => 'value', '#value' => $node->vid);    $form['revision'] = array('#type' => 'value', '#value' => $node->vid);
394    $form['type'] = array('#type' => 'value', '#value' => $node->type);    $form['type'] = array('#type' => 'value', '#value' => $node->type);
395    
396    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'));    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'));
397  }  }
398    
399  /**  /**
# Line 378  function revision_moderation_publish_con Line 406  function revision_moderation_publish_con
406    $vid = $form_state['values']['revision'];    $vid = $form_state['values']['revision'];
407    $type = $form_state['values']['type'];    $type = $form_state['values']['type'];
408    
409    db_query("UPDATE {node} SET vid = %d, title = '%s' WHERE nid = %d", $vid, $title, $nid);    db_update('node')
410        ->fields(array('vid' => $vid, 'title' => $title, ))
411        ->condition(array('nid' => $nid))
412        ->execute();
413    
414    // Clear the cache so an anonymous poster can see the changes    // Clear the cache so an anonymous poster can see the changes
415    cache_clear_all();    cache_clear_all();
416    drupal_set_message('The selected revision has been published.');    drupal_set_message(t('The selected revision has been published.'));
417    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"));    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"));
418    $form_state['redirect'] = 'node/'. $nid;    $form_state['redirect'] = 'node/' . $nid;
419    }
420    
421    function revision_moderation_schema_alter(&$schema) {
422      $schema['node']['fields']['moderate'] = array(
423          'description' => 'A boolean indicating whether the node "in moderation" used by Revision Moderation.',
424          'type' => 'int',
425          'not null' => TRUE,
426          'default' => 0,
427          );
428  }  }

Legend:
Removed from v.1.49  
changed lines
  Added in v.1.49.2.1

  ViewVC Help
Powered by ViewVC 1.1.2