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

Contents of /contributions/modules/save_as_draft/save_as_draft.module

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


Revision 1.4 - (show annotations) (download) (as text)
Thu May 21 13:57:41 2009 UTC (6 months, 1 week ago) by realityloop
Branch: MAIN
CVS Tags: DRUPAL-6--1-0-BETA1, HEAD
Changes since 1.3: +19 -8 lines
File MIME type: text/x-php
Added:
Disable Save as Draft checkbox on node creation
Save revision automatically when Save as Draft selected

Fixed:
notice: Undefined property: stdClass::$nid
notice: Undefined property: stdClass::$save_as_draft
1 <?php
2 // $Id: save_as_draft.module,v 1.2.2.3 2008/05/20 23:24:55 peligrorice Exp $
3
4 /**
5 * @file
6 * Allows saving of new node revisions(drafts) while existing revisions stay visible.
7 */
8
9 /**
10 * Implementation of hook_help().
11 */
12
13 function save_as_draft_help($path, $arg) {
14 switch ($path) {
15 case 'admin/help/save_as_draft':
16 $output = '<p>'. t('Administrators, make sure you have:
17 <ol>
18 <li>Enabled the \'Save As Draft\' setting on the appropriate content type</li>
19 <li>Set the appropriate permissions at: Administer > User Management > Access Control</li>
20 </ol>
21 Users:
22 <ol>
23 <li>When modifying a node the user may decide not to publish their current changes
24 they can then check the Save As Draft checkbox, and then submit the node.</li>
25 <li>The changes will be stored in a future revision, draft, that can be published at a later date.</li>
26 <li>Every time the node is saved with the Save As Draft checkbox checked, a new \'future\' revision will be created.</li>
27 <li>Each time the user edits the node the most current revision will be used (even if this is not the \'active\' revision)</li>
28 <li>To release a draft the user can simply edit the node, uncheck the Save As Draft checkbox and submit the node. They may also use the Secondary Method below.</li>
29 </ol>') .'</p>';
30 $output .= '<p>'. t('Secondary Method:<br />
31 <ol><li>
32 Through either the Pending drafts block, or the "Drafts" tab at Administer >> Content >> Content, click on the title of a node with pending drafts. This will take you to a page showing all the revisions, including drafts, for that node.
33 </li><li>
34 Click on the title of any revision, or draft, to view its contents and check it over.
35 </li><li>
36 If the changes are found acceptable, click "Publish revision" at the top of the post. This will be made the new active revision.
37 </li></ol>') .'</p>';
38 return $output;
39 }
40 }
41
42 /**
43 * Implementation of hook_menu().
44 */
45 function save_as_draft_menu() {
46 $items = array();
47
48 // An admin page listing all nodes with draft revisions.
49 $items['admin/content/node/drafts'] = array(
50 'title' => 'Drafts',
51 'page callback' => 'save_as_draft_pending_drafts_admin',
52 'type' => MENU_LOCAL_TASK,
53 'access arguments' => array('administer nodes'),
54 );
55
56 /* if (arg(0) == 'node' && is_numeric(arg(1))) {
57 $node = node_load(arg(1));
58 $access = array('administer nodes') || (user_access('view revisions') && node_access('update', $node));*/
59
60 // Callback to allow users to edit revisions.
61 $items['node/%/revisions/%/edit'] = array(
62 'title' => 'Edit revision',
63 'page callback' => 'save_as_draft_edit',
64 'page arguments' => array(1, 3),
65 'access arguments' => TRUE,
66 'type' => MENU_CALLBACK,
67 );
68
69 // Callback to allow users to publish revisions directly.
70 $items['node/%/revisions/%/publish'] = array(
71 'title' => 'Publish revision',
72 'page callback' => 'save_as_draft_publish',
73 'page arguments' => array(1, 3),
74 'access arguments' => TRUE,
75 'type' => MENU_CALLBACK,
76 );
77 // }
78
79
80 return $items;
81 }
82
83 /**
84 * Implementation of hook_perm().
85 */
86 function save_as_draft_perm() {
87 return array('access save as draft');
88 }
89
90
91 /**
92 * Implementation of hook_form_alter().
93 */
94 function save_as_draft_form_alter(&$form, &$form_state, $form_id) {
95 // Only show the checkbox if user has 'access save as draft' privileges and the function is enabled for this content type.
96 if (isset($form['type'])) {
97 $node = $form['#node'];
98 if (user_access('access save as draft') && $form['type']['#value'] .'_node_form' == $form_id && variable_get("save_as_draft_$node->type", FALSE)) {
99 $form['options']['save_as_draft'] = array(
100 '#type' => 'checkbox',
101 '#title' => t('Save this node as a draft'),
102 '#disabled' => TRUE,
103 '#description' => t('Check this box to save your changes without making them visible to site visitors.<br />(Leave "Published" checked)'),
104 '#required' => FALSE,
105 '#weight' => -1,
106 );
107 // Disable save as draft on node creation
108 if ($form['nid']['#value'] != NULL) {
109 $form['options']['save_as_draft']['#disabled'] = FALSE;
110 $form['options']['save_as_draft']['#default_value'] = $node->save_as_draft;
111 }
112 }
113 }
114
115 // Also add option to node settings form.
116 if ($form_id == 'node_type_form' && isset($form['identity']['type'])) {
117 $form['workflow']['save_as_draft'] = array(
118 '#type' => 'radios',
119 '#title' => t('Save As Draft Options'),
120 '#default_value' => variable_get('save_as_draft_'. $form['#node_type']->type, 0),
121 '#options' => array(t('Disabled'), t('Enabled')),
122 );
123 }
124 }
125
126 /**
127 * Implementation of hook_nodeapi().
128 */
129 function save_as_draft_nodeapi(&$node, $op, $teaser = NULL, $page = NULL) {
130 switch ($op) {
131 case 'presave':
132 // Auto enable revision on nodes when Save as Draft is checked.
133 if ($node->save_as_draft == TRUE) {
134 $node->revision = TRUE;
135 }
136 break;
137 case 'insert':
138 // Store save as draft setting of this node.
139 db_query('INSERT INTO {save_as_draft} (nid, save_as_draft) VALUES (%d, %d)', $node->nid, $node->save_as_draft);
140 break;
141 case 'update':
142 // Update save as draft setting of this node.
143 db_query('DELETE FROM {save_as_draft} WHERE nid = %d', $node->nid);
144 db_query('INSERT INTO {save_as_draft} (nid, save_as_draft) VALUES (%d, %d)', $node->nid, $node->save_as_draft);
145 break;
146 case 'delete':
147 // Delete record from save_as_draft table when node is deleted.
148 db_query('DELETE FROM {save_as_draft} WHERE nid = %d', $node->nid);
149 break;
150 case 'load':
151 // Set a save_as_draft property which can be checked later.
152 $node->save_as_draft = db_result(db_query('SELECT save_as_draft FROM {save_as_draft} WHERE nid = %d', $node->nid));
153 break;
154 case 'view':
155 // Display more descriptive message at the top of node revision views, including operations
156 // that the current user has available to them.
157 $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));
158 if ($node->vid != $current_vid) {
159 drupal_set_message(t('You are currently viewing a revision of this post created on @date by @author.', array('@date' => format_date($node->changed, 'small'), '@author' => $node->name)));
160 if (node_access('update', $node)) {
161 drupal_set_message(l(t('Edit revision'), "node/$node->nid/revisions/$node->vid/edit"));
162 }
163 if (user_access('revert revisions')) {
164 // If this revision is old, show an option to revert to it.
165 // Otherwise, show an option to publish it.
166 if ($node->vid < $current_vid) {
167 drupal_set_message(l(t('Revert to revision'), "node/$node->nid/revisions/$node->vid/revert"));
168 }
169 else {
170 drupal_set_message(l(t('Publish revision'), "node/$node->nid/revisions/$node->vid/publish"));
171 }
172 drupal_set_message(l(t('Delete revision'), "node/$node->nid/revisions/$node->vid/delete"));
173 }
174 }
175 elseif ($node->save_as_draft == 1) {
176 // Notify admin if a node has pending revisions.
177 if (user_access('view revisions') && arg(2) != 'revisions' && save_as_draft_get_node_pending_drafts($node->nid)) {
178 drupal_set_message(t('This post has one or more draft revisions: <a href="@list">view list of revisions</a>.', array('@list' => url("node/$node->nid/revisions"))));
179 }
180 }
181 break;
182 }
183
184 // Only do this logic for non-admin users on nodes with save as draft
185 // turned on.
186 if (isset($node->nid) && $node->save_as_draft == 1 && (user_access('access save as draft'))) {
187 switch ($op) {
188 case 'prepare':
189 // If user has a pending revision for this node, load the latest version of
190 // it instead.
191 if ($revisions = save_as_draft_get_node_pending_drafts($node->nid)) {
192 global $user;
193 foreach ($revisions as $revision) {
194 if ($revision->uid == $user->uid) {
195 drupal_set_message(t('Editing your latest revision, which is still in draft \'mode\'.'));
196 $node = node_load($node->nid, $revision->vid);
197 break;
198 }
199 }
200 }
201 break;
202 case 'presave':
203 $current_vid = db_result(db_query('SELECT vid FROM {node} WHERE nid = %d', $node->nid));
204 $node->original_node = node_load($node->nid, $current_vid);
205 break;
206 case 'update':
207 if (isset($node->original_node)) {
208 // Update node table's vid to the original value.
209 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);
210 drupal_set_message(t('Your changes have been saved as a draft.'));
211 }
212 break;
213 }
214 }
215 }
216
217 /**
218 * Implementation of hook_block().
219 */
220 function save_as_draft_block($op = 'list', $delta = 0, $edit = array()) {
221 if ($op == 'list') {
222 $blocks[0]['info'] = t('Pending drafts');
223
224 return $blocks;
225 }
226 elseif ($op == 'view') {
227 $block = array();
228
229 if (user_access('access save as draft')) {
230 $output = '';
231 $list = array();
232
233 $nodes = save_as_draft_get_all_pending_drafts(10);
234 if (count($nodes)) {
235 foreach ($nodes as $node) {
236 if (node_access('update', $node)) {
237 $list[] = l($node->title, "node/$node->nid/revisions/$node->vid/view");
238 }
239 }
240 $output .= theme('item_list', $list);
241 $output .= '<p>'. l(t('View all pending drafts'), 'admin/content/node/drafts') .'</p>';
242 }
243 else {
244 $output .= t('No pending drafts found.');
245 }
246
247 $block['subject'] = t('Pending drafts');
248 $block['content'] = $output;
249 }
250
251 return $block;
252 }
253 }
254
255 /**
256 * Menu callback; displays list of nodes with pending revisions.
257 */
258 function save_as_draft_pending_drafts_admin() {
259 $nodes = save_as_draft_get_all_pending_drafts(50);
260 if (count($nodes)) {
261 $header = array(
262 t('Title'),
263 t('Type'),
264 t('Updated by'),
265 t('Last updated'),
266 );
267 $rows = array();
268 foreach ($nodes as $node) {
269 $rows[] = array(
270 l($node->title, "node/$node->nid/revisions/$node->vid/view"),
271 $node->type,
272 theme('username', user_load(array('uid' => $node->uid))),
273 format_date($node->timestamp),
274 );
275 }
276 return theme('table', $header, $rows);
277 }
278 else {
279 return t('No pending revisions found.');
280 }
281 }
282
283 /**
284 * Retrieve list of all pending revisions.
285 *
286 * @param $limit
287 * The number of pending revisions to retrieve.
288 */
289 function save_as_draft_get_all_pending_drafts($limit) {
290 // Obtain a list of nodes with revisions higher than current published revision.
291 $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 LIMIT %d";
292 $result = db_query($sql, $limit);
293 $revisions = array();
294 while ($revision = db_fetch_object($result)) {
295 $revisions[$revision->nid] = $revision;
296 }
297
298 return $revisions;
299 }
300
301 /**
302 * Retrieve list of all pending revisions for a given node.
303 *
304 * @param $nid
305 * The node ID to retrieve.
306 */
307 function save_as_draft_get_node_pending_drafts($nid) {
308 // Obtain a list of revisions higher than current published revision for a given node.
309 $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";
310 $result = db_query($sql, $nid);
311 $revisions = array();
312 while ($revision = db_fetch_object($result)) {
313 $revisions[$revision->vid] = $revision;
314 }
315
316 return $revisions;
317 }
318
319 /**
320 * Menu callback; edit revision.
321 */
322 function save_as_draft_edit($nid, $vid) {
323 $node = node_load($nid, $vid);
324 drupal_set_message(t('You are currently editing a revision of this post created on @date by @author.', array('@date' => format_date($node->changed, 'small'), '@author' => $node->name)));
325 return drupal_get_form($node->type .'_node_form', $node);
326 }
327
328 /**
329 * Menu callback; publish revision directly.
330 */
331 function save_as_draft_publish($nid, $vid) {
332 $node = node_load($nid, $vid);
333 db_query("UPDATE {node} SET vid = %d, title = '%s' WHERE nid = %d", $vid, $node->title, $nid);
334 drupal_set_message('The selected revision has been published.');
335 watchdog('content', '@type: published %title revision %revision', array('@type' => t($node->type), '%title' => $node->title, '%revision' => $vid), WATCHDOG_NOTICE, l(t('view'), "node/$nid/revisions/$vid/view"));
336 drupal_goto("node/$nid");
337 }
338
339 /**
340 * Implementation of hook_token_values().
341 */
342 function save_as_draft_token_values($entity_type, $object = NULL) {
343 $values = array();
344 if ($entity_type == 'node') {
345 $values['vid'] = $object->vid;
346 $values['save_as_draft'] = $object->save_as_draft ? t('on') : t('off');
347 $values['revision'] = $object->revision ? t('on') : t('off');
348 }
349 return $values;
350 }
351
352 /**
353 * Implementation of hook_token_list().
354 */
355 function save_as_draft_token_list($entity_type = 'all') {
356 if ($entity_type == 'node') {
357 $tokens = array();
358 $tokens['node']['vid'] = t('Node revision ID');
359 $tokens['node']['save_as_draft'] = t('Whether save as draft is on. (@on/@off)', array('@on' => t('on'), '@off' => t('off')));
360 $tokens['node']['revision'] = t('Whether a new revision is to be created. (@on/@off)', array('@on' => t('on'), '@off' => t('off')));
361 return $tokens;
362 }
363 }

  ViewVC Help
Powered by ViewVC 1.1.2