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

Contents of /contributions/modules/revision_moderation/revision_moderation.module

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


Revision 1.49 - (show annotations) (download) (as text)
Sat Dec 27 22:27:36 2008 UTC (11 months ago) by add1sun
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-7--1
Changes since 1.48: +2 -2 lines
File MIME type: text/x-php
Ugh, last patch removed the new  for listing actions in the dsm.
1 <?php
2 // $Id: revision_moderation.module,v 1.48 2008/12/24 15:24:01 add1sun Exp $
3
4 /**
5 * @file
6 * Allows moderation of node revisions while existing revisions stay visible.
7 */
8
9 // Actions module support.
10 include_once drupal_get_path('module', 'revision_moderation') .'/revision_moderation_actions.inc';
11
12 /**
13 * Implementation of hook_menu().
14 */
15 function 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 */
65 function 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 */
74 function 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 */
88 function 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 */
122 function revision_moderation_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
123 switch ($op) {
124 case 'insert':
125 // Store revision moderation setting of this node.
126 drupal_write_record('revision_moderation', $node);
127 break;
128
129 case 'update':
130 // Update revision moderation setting of this node.
131 drupal_write_record('revision_moderation', $node, 'nid');
132 break;
133
134 case 'delete':
135 // Delete record from revision_moderation table when node is deleted.
136 db_query('DELETE FROM {revision_moderation} WHERE nid = %d', $node->nid);
137 break;
138
139 case 'load':
140 // Set a revision_moderation property which can be checked later.
141 $node->revision_moderation = db_result(db_query('SELECT revision_moderation FROM {revision_moderation} WHERE nid = %d', $node->nid));
142 break;
143
144 case 'view':
145 // Cannot use _node_revision_access() here, it's static cached with 1 op
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) {
152 $links = array(); // Array of links to show along with the message.
153 if ($access_update) {
154 // Add a link directly to the diff if we have Diff module installed.
155 if (module_exists('diff')) {
156 if ($node->vid > $current_vid) {
157 $difflink = "node/$node->nid/revisions/view/$current_vid/$node->vid";
158 }
159 else {
160 $difflink = "node/$node->nid/revisions/view/$node->vid/$current_vid";
161 }
162 $links[] = l(t('Compare revisions'), $difflink);
163 }
164 $links[] = l(t('Edit revision'), "node/$node->nid/revisions/$node->vid/edit");
165 // If this revision is old, show an option to revert to it.
166 // Otherwise, show an option to publish it.
167 if ($node->vid < $current_vid) {
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 }
173 }
174 if ($access_delete) {
175 $links[] = l(t('Delete revision'), "node/$node->nid/revisions/$node->vid/delete");
176 }
177 // Get username for the revision rather than the original node.
178 $revision_author = user_load($node->revision_uid);
179 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));
180 }
181 elseif ($node->revision_moderation == 1 && !$teaser) {
182 // Notify admin if a node has pending revisions.
183 if ($access_update && arg(2) != 'revisions' && revision_moderation_get_node_pending_revisions($node->nid)) {
184 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"))));
185 }
186 }
187 break;
188 }
189
190 // Only do this logic for non-admin users on nodes with revision moderation
191 // turned on.
192 // And not editing a chose revision
193 if ($node->nid && $node->revision_moderation == 1 && arg(2) != 'revisions'
194 && (!user_access('administer nodes') || !variable_get('revision_moderation_exempt', 1))) {
195 switch ($op) {
196 case 'prepare':
197 // If user has a pending revision for this node, load the latest version of
198 // it instead.
199 if ($revisions = revision_moderation_get_node_pending_revisions($node->nid)) {
200 global $user;
201 foreach ($revisions as $revision) {
202 if ($revision->uid == $user->uid) {
203 drupal_set_message(t('Editing your latest revision, which is still pending moderation.'));
204 $node = node_load($node->nid, $revision->vid);
205 break;
206 }
207 }
208 }
209 break;
210
211 case 'presave':
212 $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));
213 $node->original_node = node_load($node->nid, $current_vid);
214 break;
215
216 case 'update':
217 if (isset($node->original_node)) {
218 // Update node table's vid to the original value.
219
220 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);
221 drupal_set_message(t('Your changes have been submitted for moderation.'));
222 }
223 break;
224 }
225 }
226 }
227
228 /**
229 * Implementation of hook_block().
230 */
231 function revision_moderation_block($op = 'list', $delta = 0, $edit = array()) {
232 if ($op == 'list') {
233 $blocks[0]['info'] = t('Pending revisions');
234
235 return $blocks;
236 }
237 elseif ($op == 'view') {
238 $block = array();
239
240 if (user_access('administer nodes')) {
241 $output = '';
242 $list = array();
243
244 $nodes = revision_moderation_get_all_pending_revisions(10);
245 if (count($nodes)) {
246 foreach ($nodes as $node) {
247 $list[] = l($node->title, "node/$node->nid/revisions/$node->vid/view");
248 }
249 $output .= theme('item_list', $list);
250 $output .= '<p>'. l(t('View all pending revisions'), 'admin/content/node/revisions') .'</p>';
251 }
252 else {
253 $output .= t('No pending revisions found.');
254 }
255
256 $block['subject'] = t('Pending revisions');
257 $block['content'] = $output;
258 }
259
260 return $block;
261 }
262 }
263
264 /**
265 * Menu callback to display list of nodes with pending revisions.
266 */
267 function revision_moderation_pending_revisions_admin() {
268 return theme('revision_moderation_pending_revisions_admin');
269 }
270
271 /**
272 * Implementation of hook_theme().
273 */
274 function revision_moderation_theme() {
275 return array(
276 'revision_moderation_pending_revisions_admin' => array(
277 'arguments' => array(),
278 ),
279 );
280 }
281
282 /**
283 * Displays list of nodes with pending revisions.
284 */
285 function theme_revision_moderation_pending_revisions_admin() {
286 $nodes = revision_moderation_get_all_pending_revisions(50);
287 if (count($nodes)) {
288 $header = array(
289 t('Title'),
290 t('Type'),
291 t('Updated by'),
292 t('Last updated'),
293 );
294 $rows = array();
295 foreach ($nodes as $node) {
296 $rows[] = array(
297 l($node->title, "node/$node->nid/revisions"),
298 check_plain(node_get_types('name', $node)),
299 theme('username', user_load(array('uid' => $node->uid))),
300 format_date($node->timestamp),
301 );
302 }
303 return theme('table', $header, $rows);
304 }
305 else {
306 return '<p>'. t('No pending revisions found.') .'</p>';
307 }
308 }
309
310 /**
311 * Retrieve list of all pending revisions.
312 *
313 * @param $limit
314 * The number of pending revisions to retrieve.
315 */
316 function revision_moderation_get_all_pending_revisions($limit) {
317 // Obtain a list of nodes with revisions higher than current published revision.
318 $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";
319 $result = db_query($sql, $limit);
320 $revisions = array();
321 while ($revision = db_fetch_object($result)) {
322 $revisions[$revision->nid] = $revision;
323 }
324
325 return $revisions;
326 }
327
328 /**
329 * Retrieve list of all pending revisions for a given node.
330 *
331 * @param $nid
332 * The node ID to retrieve.
333 */
334 function revision_moderation_get_node_pending_revisions($nid) {
335 // Obtain a list of revisions higher than current published revision for a given node.
336 $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";
337 $result = db_query($sql, $nid);
338 $revisions = array();
339 while ($revision = db_fetch_object($result)) {
340 $revisions[$revision->vid] = $revision;
341 }
342
343 return $revisions;
344 }
345
346 /**
347 * Menu callback; edit revision.
348 */
349 function revision_moderation_edit($node) {
350 // Get username for the revision rather than the original node.
351 $revision_author = user_load($node->revision_uid);
352 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))));
353 return drupal_get_form($node->type .'_node_form', $node);
354 }
355
356 /**
357 * Returns a confirmation page for publishing a revision.
358 *
359 * @param $node
360 * The node object for which revision is to be published.
361 */
362 function revision_moderation_publish_confirm($form_state, $node) {
363 $form['node_id'] = array('#type' => 'value', '#value' => $node->nid);
364 $form['title'] = array('#type' => 'value', '#value' => $node->title);
365 $form['revision'] = array('#type' => 'value', '#value' => $node->vid);
366 $form['type'] = array('#type' => 'value', '#value' => $node->type);
367
368 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'));
369 }
370
371 /**
372 * Submission handler for the publish confirm form.
373 * Publishes a revision directly.
374 */
375 function revision_moderation_publish_confirm_submit($form, &$form_state) {
376 $nid = $form_state['values']['node_id'];
377 $title = $form_state['values']['title'];
378 $vid = $form_state['values']['revision'];
379 $type = $form_state['values']['type'];
380
381 db_query("UPDATE {node} SET vid = %d, title = '%s' WHERE nid = %d", $vid, $title, $nid);
382 // Clear the cache so an anonymous poster can see the changes
383 cache_clear_all();
384 drupal_set_message('The selected revision has been published.');
385 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"));
386 $form_state['redirect'] = 'node/'. $nid;
387 }

  ViewVC Help
Powered by ViewVC 1.1.2