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

Contents of /contributions/modules/publishing/publishing.module

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


Revision 1.3 - (show annotations) (download) (as text)
Sat Nov 11 06:38:14 2006 UTC (3 years ago) by merlinofchaos
Branch: MAIN
CVS Tags: DRUPAL-4-7--1-0, HEAD
Branch point for: DRUPAL-4-7
Changes since 1.2: +2 -2 lines
File MIME type: text/x-php
Fix stupid typos x2
1 <?php
2
3 /**
4 * @file
5 *
6 * This module provides support for an article publishing engine. It requires
7 * a whole host of tools, and this module itself requires some user customization
8 * that can range from very light to Very Serious.
9 *
10 * This module requires the workflow, views and dashboard modules.
11 */
12
13 /**
14 * Implementation of hook_help
15 */
16 function publishing_help($section = NULL) {
17 if ($section == 'admin/modules#description') {
18 return t('Creates a framework to ease content publishing workflow.');
19 }
20 }
21
22 /**
23 * Implementation of hook_perm. This module provides a couple of permission
24 * flags so that we don't have to actually know much about the roles in
25 * use; workflow is mostly roles based, though, so what you need to do
26 * here is to add the permission flag to the proper role so that the
27 * module can utilize it.
28 */
29 function publishing_perm() {
30 return array('publishing author', 'publishing editor');
31 }
32
33 /**
34 * Implementation of hook_menu.
35 */
36 function publishing_menu($may_cache) {
37 // In the future these pages will be much more user customizable,
38 // but that's going to wait for panels 2.
39 $items = array();
40 if ($may_cache) {
41 $items[] = array(
42 'path' => 'publishing/author',
43 'title' => t('author dashboard'),
44 'callback' => 'publishing_author_page',
45 'access' => user_access('publishing author'),
46 );
47 $items[] = array(
48 'path' => 'publishing/editor',
49 'title' => t('editor dashboard'),
50 'callback' => 'publishing_editor_page',
51 'access' => user_access('publishing editor'),
52 );
53 }
54 return $items;
55 }
56
57 /**
58 * implementation of hook_settings
59 */
60 function publishing_settings() {
61 $result = db_query("SELECT s.sid, s.state, w.name FROM {workflow_states} s INNER JOIN {workflows} w ON w.wid = s.wid ORDER BY w.name");
62 while ($state = db_fetch_object($result)) {
63 $options[$state->name][$state->sid] = $state->state;
64 }
65 $options[-1] = t('No state');
66
67 $result = db_query("SELECT wid, name FROM {workflows} ORDER BY name");
68 while ($workflow = db_fetch_object($result)) {
69 $workflows[$workflow->wid] = $workflow->name;
70 }
71 $workflows[-1] = t('No workflow');
72
73 $result = db_query("SELECT type FROM {workflow_type_map} WHERE wid = %d", variable_get('publishing_workflow_wid', -1));
74 while ($workflow = db_fetch_object($result)) {
75 $node_types .= ($node_types ? ', ' : '') . $workflow->type;
76 }
77
78 $result = db_query("SELECT r.rid, r.name FROM {role} r ORDER BY r.name");
79 while ($obj = db_fetch_object($result)) {
80 $rids[$obj->rid] = $obj->name;
81 }
82
83 $rids[-1] = t('No role');
84
85 $form['markup'] = array(
86 '#value' => t('<p>The publishing module needs a workflow with some minimum settings, and at least two roles. If you already have these in your system, simply select them below. Or click the appropriate buttons to have the publishing module create them for you.</p>'),
87 );
88
89 $form['roles'] = array(
90 '#type' => 'fieldset',
91 '#title' => t('Roles'),
92 );
93 $form['roles']['publishing_role_editor'] = array(
94 '#type' => 'select',
95 '#title' => t('Editor role'),
96 '#description' => t('Select the role to which you have assigned the editor permission.'),
97 '#default_value' => variable_get('publishing_role_editor', -1),
98 '#options' => $rids,
99 );
100
101 $form['roles']['publishing_role_author'] = array(
102 '#type' => 'select',
103 '#title' => t('Author role'),
104 '#description' => t('Select the role to which you have assigned the author permission.'),
105 '#default_value' => variable_get('publishing_role_author', -1),
106 '#options' => $rids,
107 );
108
109 $form['roles']['role_text'] = array(
110 '#value' => t('<p>Click here to create roles for this purpose if they do not already exist on your system. Do not click this just to save changes; click save configuration, below, for that.</p>'),
111 );
112
113 $form['roles']['role_button'] = array(
114 '#type' => 'button',
115 '#value' => t('Create roles'),
116 );
117
118 if (in_array('article editor', $rids)) {
119 $form['roles']['role_button']['#attributes'] = array('disabled' => TRUE);
120 $form['roles']['role_explanation'] = array('#value' => t('<p>The create button is disabled because you appear to already have these roles; if this is not true, you will need to remove or rename the "article editor" role that already exists.</p>'));
121 }
122
123 $form['workflow'] = array(
124 '#type' => 'fieldset',
125 '#title' => t('Workflow'),
126 );
127
128 $form['workflow']['text'] = array(
129 '#value' => t('<p>The basic workflow creates documents along the following path:</p><ol><li><b>Draft</b> -- Drafts are created by users but not submitted to the system. Their primary value is for letting authors start content and continue it later if they need to. When an author is ready, the author can change the state to <b>Review</b></li><li><b>Review</b> -- When an article has been submitted for review, editors are allowed to peruse the document, make changes if necessary, and either send it back for rework or publish it.</li><li><b>Rework</b> -- Articles in rework have been essentially rejected and remain this way until the author once again submits the article for review.</li><li><b>Published</b> -- Published articles are now ready to be given to consumers. You should use Views to ensure that content available on the system respects the workflow published field.</li></ol><p>Please be sure that the roles listed above have been created.'),
130 );
131
132 $form['workflow']['publishing_workflow_wid'] = array(
133 '#type' => 'select',
134 '#title' => t('Publishing workflow'),
135 '#description' => t('Select the workflow that the publishing module will use.'),
136 '#default_value' => variable_get('publishing_workflow_wid', -1),
137 '#options' => $workflows,
138 );
139
140 if ($node_types) {
141 $form['workflow']['node_types'] = array(
142 '#value' => t('This workflow is currently used on the following node types: %nodes', array('%nodes' => $node_types)),
143 );
144 }
145 else {
146 $form['workflow']['node_types'] = array(
147 '#value' => t('This workflow is currently not used on any node types.'),
148 );
149 }
150 $form['workflow']['publishing_workflow_draft'] = array(
151 '#type' => 'select',
152 '#title' => t('Draft state'),
153 '#description' => t('Select the workflow state that corresponds to the draft state.'),
154 '#default_value' => variable_get('publishing_workflow_draft', -1),
155 '#options' => $options,
156 );
157
158 $form['workflow']['publishing_workflow_review'] = array(
159 '#type' => 'select',
160 '#title' => t('Review state'),
161 '#description' => t('Select the workflow state that corresponds to the review state.'),
162 '#default_value' => variable_get('publishing_workflow_review', -1),
163 '#options' => $options,
164 );
165
166 $form['workflow']['publishing_workflow_rework'] = array(
167 '#type' => 'select',
168 '#title' => t('Rework state'),
169 '#description' => t('Select the workflow state that corresponds to the rework state.'),
170 '#default_value' => variable_get('publishing_workflow_rework', -1),
171 '#options' => $options,
172 );
173
174 $form['workflow']['publishing_workflow_published'] = array(
175 '#type' => 'select',
176 '#title' => t('Published state'),
177 '#description' => t('Select the workflow state that corresponds to the published state.'),
178 '#default_value' => variable_get('publishing_workflow_published', -1),
179 '#options' => $options,
180 );
181
182 $form['workflow']['workflow_text'] = array(
183 '#value' => t('<p>Click here to create a basic workflow for this purpose it does not already exist on your system. Do not click this just to save changes; click save configuration, below, for that.</p>'),
184 );
185
186 $form['workflow']['workflow_button'] = array(
187 '#type' => 'button',
188 '#value' => t('Create workflow'),
189 );
190
191 $wid = db_result(db_query("SELECT wid FROM {workflows} WHERE name = '%s'", t('Publishing Module Workflow')));
192 if ($wid) {
193 $form['workflow']['workflow_button']['#attributes'] = array('disabled' => TRUE);
194 $form['workflow']['workflow_explanation'] = array('#value' => t('<p>The create button is disabled because you appear to already have the proper workflow; if this is not true, you will need to remove or rename the "Publishing Module Workflow" workflow that already exists.</p>'));
195
196 }
197 $form['#process'] = array('publishing_create' => array());
198
199 return $form;
200 }
201
202 function publishing_create($form) {
203 if ($_POST['op'] == t('Create roles')) {
204 publishing_create_roles();
205 }
206 elseif ($_POST['op'] == t('Create workflow')) {
207 publishing_create_workflow();
208 }
209
210 return $form;
211 }
212
213 function publishing_create_roles() {
214 $result = db_result(db_query("SELECT MAX(rid) FROM {role}"));
215 $editor = ++$result;
216 variable_set('publishing_role_editor', $editor);
217 $author = ++$result;
218 variable_set('publishing_role_author', $author);
219 db_query("INSERT INTO {role} (name, rid) VALUES ('%s', %d), ('%s', %d)", t('article editor'), $editor, t('article author'), $author);
220 db_query("INSERT INTO {permission} (rid, perm) VALUES (%d, 'publishing editor'), (%d, 'publishing author')", $editor, $author);
221 drupal_set_message('New roles created.');
222 drupal_goto($_GET['q']);
223 }
224
225 function publishing_create_workflow() {
226 // Note: This should just be workflow_create() but workflow_create()
227 // does not return the $wid.
228 $wid = db_next_id('{workflows}_wid');
229 $name = t('Publishing Module Workflow');
230
231 $editor = variable_get('publishing_role_editor', -1);
232 $author = variable_get('publishing_role_author', -1);
233 if ($editor == -1 || $author == -1) {
234 drupal_set_message(t('Please be sure editor and author roles are set up before creating a workflow.'));
235 }
236
237 db_query("INSERT INTO {workflows} (wid, name, tab_roles) VALUES (%d, '%s', '%s')", $wid, $name, $author . ',' . $editor);
238 db_query("INSERT INTO {workflow_states} (sid, wid, state, sysid) VALUES (%d, %d, '%s', %d)",
239 $creation = db_next_id('{workflow_states}_sid'), $wid, t('(creation)'), WORKFLOW_CREATION);
240
241 variable_set('publishing_workflow_wid', $wid);
242
243 variable_set('publishing_workflow_draft', $draft = workflow_state_create($wid, t('Draft')));
244 variable_set('publishing_workflow_review', $review = workflow_state_create($wid, t('Review')));
245 variable_set('publishing_workflow_rework', $rework = workflow_state_create($wid, t('Rework')));
246 variable_set('publishing_workflow_published', $published = workflow_state_create($wid, t('Published')));
247
248 workflow_transition_add_role($creation, $draft, $author);
249 workflow_transition_add_role($draft, $review, $author);
250 workflow_transition_add_role($review, $rework, $editor);
251 workflow_transition_add_role($review, $published, $editor);
252 workflow_transition_add_role($published, $review, $editor);
253 workflow_transition_add_role($rework, $review, $author);
254
255 drupal_set_message('Workflow created');
256 }
257
258 function theme_publishing_box($content, $title = NULL, $id = NULL) {
259 if ($id) {
260 $id = "id=\"$id\"";
261 }
262 $output = "<div class=\"publishing-box\" $id>";
263 if ($title) {
264 $output .= "<h2>$title</h2>";
265 }
266 $output .= $content;
267 $output .= '</div>';
268 return $output;
269 }
270
271 /**
272 * Help authors and editors out by adding some information to the node
273 * views
274 */
275 function publishing_nodeapi(&$node, $op, $teaser, $page) {
276 if ($op == 'view' && $page) {
277 switch ($node->_workflow) {
278 case variable_get('publishing_workflow_draft', -1):
279 $node->body = theme('publishing_text_draft', $node) . $node->body;
280 break;
281 case variable_get('publishing_workflow_review', -1):
282 $node->body = theme('publishing_text_review', $node) . $node->body;
283 break;
284 case variable_get('publishing_workflow_rework', -1):
285 $node->body = theme('publishing_text_rework', $node) . $node->body;
286 break;
287 }
288 }
289 }
290
291 function theme_publishing_text_draft($node) {
292 theme_add_style(drupal_get_path('module', 'publishing') . '/publishing.css');
293 $output = '<div class="publishing-node-box">';
294 $output .= t('This %type submission is currently a <b>draft</b>. In order to submit this for review, go to the %link tab, set the state to <b>Review</b> and click Submit!', array('%type' => $node->type, '%link' => l('workflow', "node/$node->nid/workflow")));
295 $output .= '</div>';
296
297 return $output;
298 }
299
300 function theme_publishing_text_review($node) {
301 theme_add_style(drupal_get_path('module', 'publishing') . '/publishing.css');
302 $output = '<div class="publishing-node-box">';
303 $output .= t('This %type submission is currently up for review. From the %link tab, you may set <b>publish</b> this post or send it back for <b>rework</b>! If you send it back for rework, please provide a comment!', array('%type' => $node->type, '%link' => l('workflow', "node/$node->nid/workflow")));
304 $output .= '</div>';
305
306 return $output;
307 }
308
309 function theme_publishing_text_rework($node) {
310 theme_add_style(drupal_get_path('module', 'publishing') . '/publishing.css');
311 $output = '<div class="publishing-node-box">';
312 $output .= t('This %type submission has been sent back for <b>rework</b>. In order to submit this for review, go to the %link tab, set the state to <b>Review</b> and click Submit! From this tab you can also see any comments the editor made when sending this post back for rework', array('%type' => $node->type, '%link' => l('workflow', "node/$node->nid/workflow")));
313 $output .= '</div>';
314
315 return $output;
316 }
317
318 /**
319 * Provide a page for an author to see a list of drafts, a list of articles
320 * back for review. The panel is highly customizable and should be
321 * tailored to your individual needs. Task lists are a good one, and
322 * links to an author forum for collaboration are another good one.
323 */
324 function publishing_author_page() {
325 // get all node types that can be added. You probably want to just
326 // tailor this list to things that matter to authors, since this
327 // will get crud like project issues and forums and other stuff
328 // if you have that.
329
330 $result = db_query("SELECT type FROM {workflow_type_map} WHERE wid = %d", variable_get('publishing_workflow_wid', 0));
331 while ($workflow = db_fetch_object($result)) {
332 $node_types[$workflow->type] = $workflow->type;
333 }
334
335 foreach (node_get_types() as $type => $name) {
336 if ($node_types[$type] && module_invoke(node_get_base($type), 'access', 'create', $type)) {
337 $menu_items[] = l("Submit $name", "node/add/$type", array('title' => t('Add a new %s.', array('%s' => $name))));
338 }
339 }
340
341 $menu = theme('publishing_box', theme('item_list', $menu_items), t('Author Menu'), 'author-menu');
342 $drafts = views_build_view('block', views_get_view('publishing_bystate_mine'), array(variable_get('publishing_workflow_draft', -1)), false, 10);
343
344 $rework = views_build_view('block', views_get_view('publishing_bystate_mine'), array(variable_get('publishing_workflow_rework', -1)), false, 10);
345 $review = views_build_view('block', views_get_view('publishing_bystate_mine'), array(variable_get('publishing_workflow_review', -1)), false, 10);
346 $left = $menu . theme('publishing_box', $drafts, t('My Drafts'), 'drafts');
347
348 $right = theme('publishing_box', $rework, t('Back for Rework'), 'rework');
349 $right .= theme('publishing_box', $review, t('Up for Review'), 'review');
350
351 return panels_print_layout('twocol', array('left' => $left, 'right' => $right));
352 // return theme('dashboard', 'author', $left, $right);
353 }
354
355 function publishing_editor_page() {
356 $menu = theme('publishing_box', theme('item_list', $menu_items), t('Author Menu'), 'menu');
357 $drafts = views_build_view('block', views_get_view('publishing_bystate'), array(variable_get('publishing_workflow_draft', -1)), false, 10);
358
359 $rework = views_build_view('block', views_get_view('publishing_bystate'), array(variable_get('publishing_workflow_rework', 4)), false, 10);
360 $review = views_build_view('block', views_get_view('publishing_bystate'), array(variable_get('publishing_workflow_review', 3)), false, 20);
361
362 $right = theme('publishing_box', $drafts, t('All Drafts'), 'drafts');
363
364 $right .= theme('publishing_box', $rework, t('Back for Rework'), 'rework');
365 $left = theme('publishing_box', $review, t('Up for Review'), 'review');
366
367 return panels_print_layout('twocol', array('left' => $left, 'right' => $right));
368 // return theme('dashboard', 'author', $left, $right);
369 }
370
371 /**
372 * hunmonk's module dependency check: see http://drupal.org/node/54463
373 */
374 function publishing_form_alter($form_id, &$form) {
375 if ($form_id == 'system_modules' && !$_POST) {
376 publishing_system_module_validate($form);
377 }
378 }
379
380 /**
381 * hunmonk's module dependency check: see http://drupal.org/node/54463
382 */
383 function publishing_system_module_validate(&$form) {
384 $module = 'publishing';
385 $dependencies = array('views', 'workflow', 'panels');
386 foreach ($dependencies as $dependency) {
387 if (!in_array($dependency, $form['status']['#default_value'])) {
388 $missing_dependency = TRUE;
389 $missing_dependency_list[] = $dependency;
390 }
391 }
392 if (in_array($module, $form['status']['#default_value']) && isset($missing_dependency)) {
393 db_query("UPDATE {system} SET status = 0 WHERE type = 'module' AND name = '%s'", $module);
394 $key = array_search($module, $form['status']['#default_value']);
395 unset($form['status']['#default_value'][$key]);
396 drupal_set_message(t('The module %module was deactivated--it requires the following disabled/non-existant modules to function properly: %dependencies', array('%module' => $module, '%dependencies' => implode(', ', $missing_dependency_list))), 'error');
397 }
398 }
399
400 /**
401 * Provide our default views.
402 */
403
404 function publishing_views_default_views() {
405 $view = new stdClass();
406 $view->name = 'publishing_bystate_mine';
407 $view->description = t('Lists nodes in the given workflow state for the logged in user.');
408 $view->page = TRUE;
409 $view->page_title = 'Publishing by state';
410 $view->page_header = '';
411 $view->page_header_format = '1';
412 $view->page_empty = t('No articles.');
413 $view->page_empty_format = '1';
414 $view->page_type = 'teaser';
415 $view->url = 'publishing/mine';
416 $view->use_pager = TRUE;
417 $view->nodes_per_page = '10';
418 $view->block = TRUE;
419 $view->block_title = t('Workflow states');
420 $view->block_header = '';
421 $view->block_header_format = '1';
422 $view->block_type = 'list';
423 $view->nodes_per_block = '10';
424 $view->block_more = '1';
425 $view->block_use_page_header = FALSE;
426 $view->block_use_page_empty = TRUE;
427 $view->menu_title = t('My workflows');
428
429 $view->sort = array (
430 array (
431 'tablename' => 'node',
432 'field' => 'created',
433 'sortorder' => 'DESC',
434 'options' => '',
435 ),
436 );
437 $view->argument = array (
438 array (
439 'type' => 'workflow_state',
440 'argdefault' => '4',
441 'title' => t('Publishing: %1'),
442 'options' => '',
443 ),
444 );
445 $view->field = array (
446 array (
447 'tablename' => 'node',
448 'field' => 'title',
449 'label' => '',
450 'handler' => 'views_handler_field_nodelink',
451 ),
452 array (
453 'tablename' => 'node',
454 'field' => 'created',
455 'label' => '',
456 'handler' => 'views_handler_field_date_small',
457 ),
458 );
459 $view->filter = array (
460 array (
461 'tablename' => 'node',
462 'field' => 'currentuid',
463 'operator' => '=',
464 'options' => '',
465 'value' => '***CURRENT_USER***',
466 ),
467 );
468 $view->requires = array(node);
469 $views[$view->name] = $view;
470
471 $view = new stdClass();
472 $view->name = 'publishing_bystate';
473 $view->description = t('Lists nodes in the given workflow state.');
474 $view->access = array (
475 );
476 $view->page = TRUE;
477 $view->page_title = t('Workflow states');
478 $view->page_header = '';
479 $view->page_header_format = '1';
480 $view->page_empty = t('No articles.');
481 $view->page_empty_format = '1';
482 $view->page_type = 'teaser';
483 $view->url = 'publishing/all';
484 $view->use_pager = TRUE;
485 $view->nodes_per_page = '10';
486 $view->block = TRUE;
487 $view->block_title = t('Workflow states');
488 $view->block_header = '';
489 $view->block_header_format = '1';
490 $view->block_type = 'list';
491 $view->nodes_per_block = '10';
492 $view->block_more = '1';
493 $view->block_use_page_header = FALSE;
494 $view->block_use_page_empty = TRUE;
495 $view->menu_title = t('workflows');
496 $view->sort = array (
497 array (
498 'tablename' => 'node',
499 'field' => 'created',
500 'sortorder' => 'DESC',
501 'options' => '',
502 ),
503 );
504 $view->argument = array (
505 array (
506 'type' => 'workflow_state',
507 'argdefault' => '4',
508 'title' => t('Publishing: %1'),
509 'options' => '',
510 ),
511 );
512 $view->field = array (
513 array (
514 'tablename' => 'node',
515 'field' => 'title',
516 'label' => '',
517 'handler' => 'views_handler_field_nodelink',
518 ),
519 array (
520 'tablename' => 'node',
521 'field' => 'created',
522 'label' => '',
523 'handler' => 'views_handler_field_date_small',
524 ),
525 array (
526 'tablename' => 'users',
527 'field' => 'name',
528 'label' => '',
529 ),
530 );
531 $view->filter = array (
532 );
533 $view->requires = array(node, users);
534 $views[$view->name] = $view;
535
536 return $views;
537 }

  ViewVC Help
Powered by ViewVC 1.1.2