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

Contents of /contributions/modules/epublish/epublish.module

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


Revision 1.17 - (show annotations) (download) (as text)
Mon Sep 14 16:43:08 2009 UTC (2 months, 1 week ago) by jerdiggity
Branch: MAIN
CVS Tags: HEAD
Changes since 1.16: +1 -1 lines
File MIME type: text/x-php
Bug fix [#575556]
1 <?php
2 // $Id$
3
4 /**
5 * @file
6 * This module helps organize a group of nodes into a publication, such as
7 * a newspaper, magazine or newsletter. Each publication can have multiple
8 * editions. Within each edition, the epublish module also makes it
9 * possible to organize content by topic, similar to the way news websites
10 * such as the New York Times categorize their content using topics such
11 * as "international," "national," "sports," etc.
12 *
13 * @note
14 * See the module help for usage and administration information.
15 */
16
17 /**
18 * Implementation of hook_init().
19 * Special thanks to Stefan Engstrom.
20 */
21 function epublish_init() {
22 $path = drupal_get_path('module', 'epublish');
23 if (variable_get('epublish_css', 1)) {
24 drupal_add_css($path .'/epublish.css');
25 }
26 drupal_add_js($path .'/epublish.js');
27 }
28
29 /**
30 * Implementation of hook_theme().
31 */
32 function epublish_theme() {
33 $filename = array();
34 $dyn_arr = array();
35 $files = file_scan_directory(drupal_get_path('module', 'epublish'), '^epublish_layout_.*\.inc$');
36 foreach ($files as $fname) {
37 $dyn_arr[$fname->name] = array(
38 'file' => $fname->basename,
39 'arguments' => array('topics' => NULL, 'params' => NULL),
40 );
41 }
42 $static_arr = array(
43 'epublish_edition_reference' => array(
44 'arguments' => array('edition' => 0),
45 ),
46 'epublish_abstract' => array(
47 'arguments' => array('abstract' => NULL),
48 ),
49 'epublish_topics' => array(
50 'arguments' => array('topics' => 0, 'sid' => NULL, 'edition' => 0, 'context' => NULL),
51 ),
52 'epublish_volume_reference' => array(
53 'arguments' => array('pid' => NULL, 'volume' => NULL),
54 ),
55 'epublish_pub_page' => array(
56 'arguments' => array('output' => 0, 'publication' => 0, 'edition' => 0, 'volume' => NULL),
57 ),
58 'epublish_format_volume' => array(
59 'arguments' => array('volume' => NULL, 'pid' => NULL, 'edition_blocks' => array()),
60 ),
61 'epublish_format_edition' => array(
62 'arguments' => array('edition' => 0),
63 ),
64 'epublish_format_pub' => array(
65 'arguments' => array(),
66 ),
67 'epublish_form_section' => array(
68 'arguments' => array('form' => NULL),
69 ),
70 'epublish_form_edition' => array(
71 'arguments' => array('form' => NULL),
72 ),
73 'epublish_admin_node' => array(
74 'arguments' => array('form' => NULL),
75 ),
76 'epublish_navigation' => array(
77 'arguments' => array('node' => NULL, 'eid' => NULL),
78 ),
79 );
80 return (array_merge($static_arr, $dyn_arr));
81 }
82
83 /**
84 * Implementation of hook_help().
85 */
86 function epublish_help($path, $arg) {
87 switch ($path) {
88 case 'admin/modules#description':
89 $output = t('<p>Enables users to organize the contents of their site into publications with multiple editions, like a magazine or newspaper.</p>');
90 break;
91 case 'admin/settings/epublish':
92 $output = t('<p>Settings for periodically-issued publications.</p>');
93 break;
94 case 'admin/node/configure/defaults':
95 $output = t('<p>If you want users to be able to enter brief abstracts of postings for displays on headlines and publication pages, check the <em>has abstract</em> box.</p>');
96 break;
97 case 'admin/help#epublish':
98 $output = t("<p>This module helps organize a publication or group of publications, each with multiple editions.</p>".
99 "<h3>Configuration</h3><p>To use this module, you have to take a few steps:</p>".
100 "<ul><li>Install and enable the module.</li>".
101 "<li>Enable the taxonomy module in !modules.<br />If the taxonomy module is not enabled, you can not use this module.</li>".
102 "<li>Create a taxonomy vocabulary in !taxonomy.</li>".
103 "<li>Create in !taxcreate at least one term in your new taxonomy. Each posting can be associated with a taxonomy term and grouped by topic within a headlines \"section\" (see below).</li>".
104 "<li>Set the appropriate access right in !access<br />The access right is <b>administer publications</b>.</li></ul>",
105 array('!modules' => l(t("administer &raquo; modules"), "admin/modules", array(), NULL, NULL, FALSE, TRUE),
106 '!taxonomy' => l(t("administer &raquo; topics &raquo; add vocabulary"), "admin/taxonomy/add/vocabulary", array(), NULL, NULL, FALSE, TRUE),
107 '!taxcreate' => l(t("administer &raquo; topics"), "admin/taxonomy", array(), NULL, NULL, FALSE, TRUE),
108 '!access' => l(t("administer &raquo; access"), "admin/access", array(), NULL, NULL, FALSE, TRUE))) .
109 t("<h3>Creating and administering publications</h3>".
110 "<p>The epublish module deals with three objects, which can be created or edited using !admin:</p>".
111 "<ul><li>A \"<b>publication</b>\" could be a newsletter or magazine -- something that appears in multiple editions, either on a regular or sporadic basis, according to a publication schedule that you specify.</li>".
112 "<li>Each publication can have multiple \"<b>editions</b>,\" typically labeled with a dateline, volume and number. A monthly magazine, for example, might be labeled \"November 2004, volume 3, no. 11.\"".
113 "(The volume and number fields are optional.) Each publication can have a designated \"current\" edition. The current edition will display in all places where a publication is specified but no specific edition number has otherwise been indicated.</li>".
114 "<li>Within each edition, content can be organized using a headlines \"<b>section</b>.\" Headlines sections organize postings by topic using taxonomy terms, similar to the way that news websites such as the New York Times categorize their content using ".
115 "topics such as \"international,\" \"national,\" \"sports,\" etc. In addition to topics based on taxonomy terms, two special, non-taxonomy-based topic groupings exist: \"top stories\" , \"advertisement\" and \"miscellaneous.\"</li></ul>\n".
116 "<p>You can add or organize headlines to a specific edition of a publication by using !admin to specify the edition that you want to edit. You can also use weighting to control the order in which headlines appear.</p>\n".
117 "<h3>Viewing publications</h3>".
118 "<p>A list of publications can be viewed at path !epublish. Each publication has a numeric publication ID (pid). An individual publication can be viewed using the path \"epublish/{pid}\" where ".
119 "{pid} is the publication's ID number, or \"epublish\{name}\" where {name} is the publication name. An individual edition can be viewed using the path \"epublish/{pid}/{eid}\" or \"epublish/{name}/{eid}\" ".
120 "where {eid} is the edition ID number. As an alternative to {eid}, the path can also specify editions by their volume and number using the syntax \"v{volume}n{number}\". For example, the path ".
121 "\"epublish/Monthly%20News/v3n14\" would show volume 3, number 14 of the publication named \"Monthly News.\" Or, the path \"epublish/4/v3\" would show all editions of volume 3 of the publication ".
122 "with {pid} 4. The path \"epublish/{pid}/current\" specifies a publication's current edition.</p>\n",
123 array('!admin' => l(t("administer &raquo; epublish"), "admin/epublish", array(), NULL, NULL, FALSE, TRUE),
124 '!epublish' => l(t('epublish'), "epublish"),
125 '!nodes' => l(t("administer &raquo; epublish &raquo; edition contents"), "admin/epublish/", array(), NULL, NULL, FALSE, TRUE))) .
126 t("<h3>URL Aliases for publication edition</h3>".
127 "<p>The Publication edition can have custom URL aliases. To enable the URL aliases, one must enable the 'path' module from the !modules.</p>",
128 array('!modules' => l(t("module list"), "admin/build/modules", array(), NULL, NULL, FALSE, TRUE))) .
129 t("<h3>Viewing latest headlines</h3>".
130 "<p>In addition to displaying postings that have been collected into specific editions of a publication, you can also view a list of the most recent postings in each topic section ".
131 "at \"epublish/headlines/{sid}\" where {sid} is a numeric section ID. \"Topics\" use taxonomy terms to organize content according to the following rules:</p>\n".
132 "<li>When editing the topics in each section, you can set an \"automatically-included headlines limit\" specifying the maximum number of headlines that should be included for that topic and also set a time frame that limits the search. For example, a time ".
133 "frame of \"30 days\" means that postings older than that will be ignored. You can also specify which node types are eligible for inclusion.</li>\n".
134 "<li>Most topics refer to a taxonomy term and all of its descendants. For example, a taxonomy might include the term \"music,\" with child terms \"rock,\" \"classical,\" \"jazz.\" Only nodes that have been tagged with one or more of these terms would be included in the topic \"music.\"</li>\n".
135 "<li>In addition, there are three special topics, named \"top stories\" \"advertisement\" and \"miscellaneous,\" which do not filter for taxonomy terms at all. \"Top stories\" are taken from stories that have been marked as \"sticky at top of lists\. ".
136 "The \"miscellaneous\" topic appears at the bottom of each section. (If, however, you set its \"automatically-included headlines limit\" to zero, no miscellanous headlines will be displayed.)</li>\n") .
137 t("<h3>Publications and headlines blocks</h3>".
138 "<p>The epublish module creates a sidebar block for each section, as well as an \"epublish\" block that lists all publications. To make blocks visible on your pages, use !blocks.</p>",
139 array('!blocks' => l(t("administer &raquo; blocks"), "admin/block", array(), NULL, NULL, FALSE, TRUE))) .
140 t("<h3>Customizing layouts</h3>\n".
141 "<p>The epublish module comes with several standard \"layouts\" that make it possible to customize the layout of publication pages. The \"node views,\" \"one- and two-column\" and \"regular\" layouts are different ".
142 "page layouts for displaying nodes from a single edition. The \"simple list of headlines only\" layout is used on pages that list multiple editions of a publication.</p>\n".
143 "<p>You can use !settings to select a headlines <b>layout</b> and <b>section</b> that apply to all publications and their editions. If you check the \"custom layouts\" or \"custom sections\" boxes, ".
144 "individual publications and editions can also be assigned their own separate layouts and sections that override the global settings, according to the following order of precedence:</p>\n".
145 "<h4>Section selection</h4>".
146 "<ul><li>If the <i>edition</i> specifies a custom section, it takes precedence.</li>\n".
147 "<li>Otherwise, if the <i>publication</i> specifies a custom section, it takes precedence.</li>\n".
148 "<li>Otherwise, the globally-specified section is used.</li></ul>\n".
149 "<h4>Layout selection</h4>".
150 "<ul><li>If the <i>section</i> specifies a custom layout, it takes precedence.</li>\n".
151 "<li>Otherwise, if the <i>edition</i> specifies a custom layout, it takes precedence.</li>\n".
152 "<li>Otherwise, if the <i>publication</i> specifies a custom layout, it takes precedence.</li>\n".
153 "<li>Otherwise, the globally-specified layout is used.</li></ul>\n".
154 "<p>The ability to customize layouts and sections provides considerable flexibility for design purposes, but it can can also make administration of publications more complicated. Most users will probably ".
155 "want to leave the \"custom layouts\" option turned off.</p>\n" .
156 "<p>Layouts are also themeable, and additional layouts can be can be added as needed. For an explanation of how to do this, see the README.txt TImes of India
157 times desc
158 Volume 54
159 TImes of India
160 times desc
161 Volume 54
162
163 *
164 1 edition, Volume 54, No. 534TImes of India
165 times desc
166 Volume 54
167
168 *
169 1 edition, Volume 54, No. 534
170 435TImes of India
171 times desc
172 Volume 54
173
174 *
175 1 edition, Volume 54, No. 534
176 435
177
178 Volume 22
179
180 *
181 2nd edition, Volume 22, No. 22
182 22
183
184 Volume 22
185
186 *
187 2nd edition, Volume 22, No. 22
188 22
189 435
190
191 Volume 22
192
193 *
194 2nd edition, Volume 22, No. 22
195 22
196 *
197 1 edition, Volume 54, No. 534
198 435
199
200 Volume 22
201
202 *
203 2nd edition, Volume 22, No. 22
204 22file that comes included with this module.</p>",
205 array('!settings' => l(t("epublish settings"), "admin/settings/epublish")));
206 break;
207 }
208 return $output;
209 }
210
211 /**
212 * Implementation of hook_perm().
213 */
214 function epublish_perm() {
215 return array('administer publications');
216 }
217
218 /**
219 * Implementation of hook_menu().
220 */
221 function epublish_menu() {
222 $items['epublish'] = array(
223 'title' => 'Publications',
224 'page callback' => 'epublish_pub_page',
225 'access callback' => 'user_access',
226 'access arguments' => array('access content'),
227 'type' => MENU_SUGGESTED_ITEM,
228 );
229 $items['headlines'] = array(
230 'title' => 'Headlines',
231 'page callback' => 'epublish_headlines_page',
232 'access callback' => 'user_access',
233 'access arguments' => array('access content'),
234 'type' => MENU_CALLBACK
235 );
236 $items['admin/epublish'] = array(
237 'title' => 'Epublish',
238 'page callback' => 'epublish_pub_list',
239 'access callback' => 'user_access',
240 'access arguments' => array('administer publications'),
241 );
242 $items['admin/epublish/list'] = array(
243 'title' => 'List publications',
244 'type' => MENU_DEFAULT_LOCAL_TASK,
245 'weight' => -10
246 );
247 $items['admin/epublish/add/publication'] = array(
248 'title' => 'Add publication',
249 'page callback' => 'epublish_admin_publication_edit',
250 'access callback' => 'user_access',
251 'access arguments' => array('administer publications'),
252 'type' => MENU_LOCAL_TASK
253 );
254 $items['admin/epublish/edit/publication'] = array(
255 'title' => 'Edit publication',
256 'page callback' => 'epublish_admin_publication_edit',
257 'access callback' => 'user_access',
258 'access arguments' => array('administer publications'),
259 'type' => MENU_CALLBACK
260 );
261 $items['admin/epublish/add/edition'] = array(
262 'title' => 'Add edition',
263 'page callback' => 'epublish_admin_edition_add',
264 'access callback' => 'user_access',
265 'access arguments' => array('administer publications'),
266 'type' => MENU_CALLBACK
267 );
268 $items['admin/epublish/edit/edition'] = array(
269 'title' => 'Edit edition',
270 'page callback' => 'epublish_admin_edition_edit',
271 'access callback' => 'user_access',
272 'access arguments' => array('administer publications'),
273 'type' => MENU_CALLBACK
274 );
275 $items['admin/epublish/sections'] = array(
276 'title' => 'Sections and Topics',
277 'page callback' => 'epublish_sections_table',
278 'access callback' => 'user_access',
279 'access arguments' => array('administer publications'),
280 'type' => MENU_LOCAL_TASK
281 );
282 $items['admin/epublish/add/section'] = array(
283 'title' => 'Add section',
284 'page callback' => 'epublish_admin_section_edit',
285 'access callback' => 'user_access',
286 'access arguments' => array('administer publications'),
287 'type' => MENU_CALLBACK
288 );
289 $items['admin/epublish/edit/section'] = array(
290 'title' => 'Edit section',
291 'page callback' => 'epublish_admin_section_edit',
292 'access callback' => 'user_access',
293 'access arguments' => array('administer publications'),
294 'type' => MENU_CALLBACK
295 );
296 $items['admin/epublish/add/topic'] = array(
297 'title' => 'Add topic',
298 'page callback' => 'epublish_admin_topic_add',
299 'access callback' => 'user_access',
300 'access arguments' => array('administer publications'),
301 'type' => MENU_CALLBACK
302 );
303 $items['admin/epublish/edit/topic'] = array(
304 'title' => 'Edit topic',
305 'page callback' => 'epublish_admin_topic_edit',
306 'access callback' => 'user_access',
307 'access arguments' => array('administer publications'),
308 'type' => MENU_CALLBACK
309 );
310 $items['admin/epublish/headlines'] = array(
311 'title' => 'Add headlines',
312 'page callback' => 'epublish_admin_node_head',
313 'access callback' => 'user_access',
314 'access arguments' => array('administer publications'),
315 'type' => MENU_CALLBACK
316 );
317 $items['admin/epublish/edit/volume'] = array(
318 'title' => 'Edit volume name',
319 'page callback' => 'epublish_admin_volume_edit',
320 'access callback' => 'user_access',
321 'access arguments' => array('administer publications'),
322 'type' => MENU_CALLBACK
323 );
324 $items['admin/settings/epublish'] = array(
325 'title' => 'Epublish',
326 'description' => 'Describes what the settings generally do.',
327 'page callback' => 'drupal_get_form',
328 'page arguments' => array('epublish_admin_settings'),
329 'access callback' => 'user_access',
330 'access arguments' => array('administer site configuration'),
331 'type' => MENU_NORMAL_ITEM,
332 );
333 $path = drupal_get_path('module', 'epublish');
334 if (variable_get('epublish_css', 1)) {
335 drupal_add_css($path .'/epublish.css');
336 }
337 drupal_add_js($path .'/epublish.js');
338 return $items;
339 }
340
341 /**
342 * Implementation of hook_settings().
343 */
344 function epublish_admin_settings() {
345 $form['display'] = array(
346 '#type' => 'fieldset',
347 '#title' => t('Display'),
348 '#collapsible' => TRUE,
349 '#collapsed' => FALSE,
350 );
351 $order = array('ASC' => 'ascending', 'DESC' => 'descending');
352 $form['display']['epublish_edition_order'] = array(
353 '#type' => 'select',
354 '#title' => t("Display order for listing editions"),
355 '#default_value' => variable_get('epublish_edition_order', 'DESC'),
356 '#options' => $order,
357 '#description' => t("Descending order means that the most recent editions will appear at the top of the list."),
358 );
359 $form['display']['epublish_top_stories'] = array(
360 '#type' => 'textfield',
361 '#title' => t('Top stories'),
362 '#default_value' => variable_get('epublish_top_stories', t('top stories')),
363 '#size' => 50,
364 '#maxlength' => 128,
365 '#description' => t('The subtitle used for top stories in a headlines section.'),
366 );
367 $form['display']['epublish_miscellaneous'] = array(
368 '#type' => 'textfield',
369 '#title' => t('Miscellaneous stories'),
370 '#default_value' => variable_get('epublish_miscellaneous', t('miscellaneous')),
371 '#size' => 50,
372 '#maxlength' => 128,
373 '#description' => t('The subtitle used for miscellaneous stories in a headlines section.'),
374 );
375 $form['display']['epublish_advertisement'] = array(
376 '#type' => 'textfield',
377 '#title' => t('Advertisement stories'),
378 '#default_value' => variable_get('epublish_advertisement', t('advertisement')),
379 '#size' => 50,
380 '#maxlength' => 128,
381 '#description' => t('The subtitle used for advertisement stories in a headlines section.'),
382 );
383 $form['display']['epublish_css'] = array(
384 '#type' => 'select',
385 '#title' => t("Include ePublish CSS file"),
386 '#default_value' => variable_get('epublish_css', 1),
387 '#options' => array(1 => t('enabled'), 0 => t('disabled')),
388 '#description' => t("You may want disable the ePublish CSS file and add all necessary styles to your theme."),
389 );
390 // layouts
391 $layouts = epublish_layouts('page');
392 $form['layouts'] = array(
393 '#type' => 'fieldset',
394 '#title' => t('Layouts'),
395 '#collapsible' => TRUE,
396 '#collapsed' => FALSE,
397 );
398 $form['layouts']['epublish_global_layout_page'] = array(
399 '#type' => 'select',
400 '#title' => t("Page layout"),
401 '#default_value' => variable_get('epublish_global_layout_page', 'regular'),
402 '#options' => $layouts,
403 '#description' => t("Select a page layout."),
404 );
405 $layouts = epublish_layouts('list');
406 $form['layouts']['epublish_global_layout_list'] = array(
407 '#type' => 'select',
408 '#title' => t("Listing layout"),
409 '#default_value' => variable_get('epublish_global_layout_list', 'list'),
410 '#options' => $layouts,
411 '#description' => t("Select a layout to control the display of headline listings."),
412 );
413 $form['layouts']['epublish_custom_layouts'] = array(
414 '#type' => 'checkbox',
415 '#title' => t('Custom layouts?'),
416 '#return_value' => 1,
417 '#default_value' => variable_get('epublish_custom_layouts', '0'),
418 '#description' => t('If this option is checked, publications, sections and editions can each have their own own layouts that override the global layouts selected above.'),
419 );
420 // sections
421 $sids = epublish_sections();
422 $array_keys = array_keys($sids);
423 $form['sections'] = array(
424 '#type' => 'fieldset',
425 '#title' => t('Sections'),
426 '#collapsible' => TRUE,
427 '#collapsed' => FALSE,
428 );
429 $form['sections']['epublish_global_sid'] = array(
430 '#type' => 'select',
431 '#title' => t("Headlines section"),
432 '#default_value' => variable_get('epublish_global_sid', array_shift($array_keys)),
433 '#options' => $sids,
434 '#description' => t("Select a section to control which topics are headlined in each publication."),
435 );
436 $form['sections']['epublish_custom_sections'] = array(
437 '#type' => 'checkbox',
438 '#title' => t('Custom sections?'),
439 '#return_value' => 1,
440 '#default_value' => variable_get('epublish_custom_sections', '0'),
441 '#description' => t('If checked, each publication and edition can have its own section that overrides the global section selected above.'),
442 );
443 return system_settings_form($form);
444 }
445
446 /**
447 * Implementation of hook_form_alter().
448 */
449 function epublish_form_alter(&$form, $form_state, $form_id) {
450 if ($form_id == 'node_type_form') {
451 $form['submission']['epublish_abstract'] = array(
452 '#type' => 'checkbox',
453 '#title' => t('Has abstract'),
454 '#return_value' => 1,
455 '#default_value' => variable_get('epublish_abstract_'. $form['#node_type']->type, TRUE),
456 '#description' => t('Users can enter a brief abstract summarizing the content of each node.'),
457 );
458 }
459 else if (isset($form['type']) && $form['type']['#value'] .'_node_form' == $form_id) {
460 if (variable_get('epublish_abstract_'. $form['type']['#value'], TRUE)) {
461 $node = $form['#node'];
462 $form['epublish_abstract'] = array(
463 '#type' => 'textarea',
464 '#title' => t('Abstract'),
465 '#default_value' => $node->epublish_abstract,
466 '#cols' => 70,
467 '#rows' => 4,
468 '#description' => t('A brief summary of this item.'),
469 );
470 }
471 }
472 }
473
474 /**
475 * Implementation of hook_nodeapi().
476 */
477 function epublish_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
478 switch ($op) {
479 case 'insert':
480 if (variable_get('epublish_abstract_'. $node->type, TRUE)) {
481 db_query("INSERT INTO {epublish_abstract} (nid, epublish_abstract) VALUES ('%d', '%s')", $node->nid, $node->epublish_abstract);
482 }
483 break;
484 case 'update':
485 if (variable_get('epublish_abstract_'. $node->type, TRUE)) {
486 db_query("DELETE FROM {epublish_abstract} WHERE nid = '%d'", $node->nid);
487 if ($node->epublish_abstract) {
488 db_query("INSERT INTO {epublish_abstract} (nid, epublish_abstract) VALUES ('%d', '%s')", $node->nid, $node->epublish_abstract);
489 }
490 }
491 break;
492 case 'delete':
493 db_query("DELETE FROM {epublish_edition_node} WHERE nid = '%d'", $node->nid);
494 if (variable_get('epublish_abstract_'. $node->type, TRUE)) {
495 db_query("DELETE FROM {epublish_abstract} WHERE nid = '%d'", $node->nid);
496 }
497 break;
498 case 'load':
499 if (variable_get('epublish_abstract_'. $node->type, TRUE)) {
500 $object = db_fetch_object(db_query("SELECT epublish_abstract FROM {epublish_abstract} WHERE nid = '%d'", $node->nid));
501 return array('epublish_abstract' => $object->epublish_abstract);
502 }
503 break;
504 case 'view':
505 // append epublish navigation to all nodes that belong to an edition
506 if (!$a3) {
507 $eid = db_result(db_query('SELECT eid FROM {epublish_edition_node} een WHERE nid = %d', $node->nid));
508 if ($eid) {
509 $node = theme('epublish_navigation', $node, $eid);
510 }
511 }
512 break;
513 }
514 }
515
516 /**
517 * Implementation of hook_block().
518 */
519 function epublish_block($op = 'list', $delta = 0) {
520 if ($op == 'list') {
521 $blocks = array();
522 $blocks[0]['info'] = t('E-Publish');
523 foreach (epublish_sections() as $sid => $title) {
524 $blocks[$sid]['info'] = t('E-publish section: ') . t($title);
525 }
526 $publications = db_query("SELECT * FROM {epublish_publication}");
527 while ($publication = db_fetch_object($publications)) {
528 $blocks['pub_'. $publication->pid]['info'] = t($publication->name);
529 $blocks['cur_edition_'. $publication->pid]['info'] = t("Current edition of @pub", array('@pub' => $publication->name));
530 }
531 return $blocks;
532 }
533 else if ($op == 'view') {
534 // publication blocks
535 if (substr($delta, 0, 12) == 'cur_edition_') {
536 $pid = substr($delta, 12);
537 $publication = epublish_get_pub($pid);
538 $data['subject'] = t($publication->name);
539 $eid = epublish_current_edition($pid);
540 $edition = epublish_get_edition($eid);
541 $sid = epublish_assign_section($edition);
542 $topics = epublish_section_topics($sid, $edition->eid);
543 $items = array();
544 foreach ($topics as $topic) {
545 foreach ($topic->nodes as $nid) {
546 $node = node_load($nid);
547 $items[] = l($node->title, "node/$nid");
548 }
549 }
550 $data['content'] = theme('item_list', $items);
551 return $data;
552 }
553 else if (substr($delta, 0, 4) == 'pub_') {
554 $pid = substr($delta, 4);
555 $publication = epublish_get_pub($pid);
556 $data['subject'] = t($publication->name);
557 $items = array();
558 $order = variable_get('epublish_edition_order', 'DESC');
559 $result = db_query("SELECT * FROM {epublish_edition} WHERE published=1 AND pid='%d' ORDER BY volume $order, number $order, pubdate $order, eid $order LIMIT 10", $publication->pid);
560 while (($edition = db_fetch_object($result)) && $i++ < 10) {
561 $items[] = l(theme('epublish_edition_reference', $edition), "epublish/$publication->pid/$edition->eid");
562 }
563 $data['content'] = theme('item_list', $items);
564 if ($i == 10) {
565 $data['content'] .= '<div class="more-link">'. l(t('more'), "epublish/$publication->pid", array('title' => t('More editions.'))) .'</div>';
566 }
567 return $data;
568 // section blocks
569 }
570 else if ($delta) {
571 $section = epublish_get_section($delta);
572 $topics = epublish_topic_selection_list($delta);
573 $data['subject'] = l(t($section->title), "headlines/$delta");
574 $items = array();
575 foreach ($topics as $tid => $name) {
576 if ($tid > 0) {
577 $items[] = l(t($name), "taxonomy/term/$tid");
578 }
579 }
580 $data['content'] = theme('item_list', $items);
581 return $data;
582 }
583 else {
584 $data['subject'] = t('Publications');
585 $result = db_query("SELECT * from {epublish_publication}");
586 $items = array();
587 while ($publication = db_fetch_object($result)) {
588 $items[] = l($publication->name, "epublish/$publication->pid");
589 }
590 $data['content'] .= theme('item_list', $items);
591 return $data;
592 }
593 }
594 }
595
596 /*******************************************
597 * LISTINGS
598 ******************************************/
599
600 /**
601 * epublish_sections: lists all publication sections.
602 *
603 * @param $include_default
604 * A Boolean value indicating whether a "default" option should be included
605 *
606 * @return
607 * An array of sections and their titles, suitable for use as the $options in a form_select call, e.g.,
608 * form_select($title, $name, $value, epublish_sections(), $description)
609 */
610 function epublish_sections($include_default = FALSE) {
611 $result = db_query("SELECT COUNT(*) FROM {epublish_section}");
612 $sections = array();
613 // if no sections exist, create a default section
614 if (!db_result($result)) {
615 $nodetype = array();
616 foreach (node_get_types() as $type => $name) {
617 $nodetypes[$type] = $name;
618 }
619 $array_keys = array_keys(module_invoke('taxonomy', 'get_vocabularies'));
620 $vid = array_pop($array_keys);
621 $form_state = array(
622 'title' => t('default'),
623 'vid' => $vid,
624 'node_types' => $nodetypes,
625 'timeframe' => '',
626 'layout_list' => '',
627 'layout_page' => ''
628 );
629 epublish_form_section_submit(NULL, $form_state);
630 $result = db_query("SELECT * FROM {epublish_section}");
631 }
632 if ($include_default) {
633 $sections[0] = t('<default>');
634 }
635 $result = db_query("SELECT * FROM {epublish_section}");
636 while ($section = db_fetch_object($result)) {
637 $sections[$section->sid] = $section->title;
638 }
639 return $sections;
640 }
641
642 /**
643 * epublish_layouts: Loads and lists all installed publication layouts.
644 *
645 * Layouts are loaded from files in the epublish directory. Each layout file should have the filename
646 * layout_{name}.inc
647 * Its content should set the variable $description = a short description of the layout (for display in a form_select pulldown menu)
648 * It should also include a function with the filename and parameters
649 * theme_epublish_layout_{name}($section, $params=NULL)
650 *
651 * @param $context_selection
652 * A text string indicating the context in which the layout should appear. Possible contexts include:
653 * --> 'list' => a listing (for example, a list of headlines within an edition)
654 * --> 'page' => the entire contents of a page
655 * --> 'email' => the text of an email (currently not used)
656 * --> 'rss' => an RSS feed (currently not used)
657 *
658 * @return
659 * An array of layouts and their descriptions, suitable for use as the $options in a form_select call, e.g.,
660 * form_select($title, $name, $value, epublish_layouts(), $description)
661 */
662 function epublish_layouts($context_selection=NULL, $include_default=FALSE) {
663 static $layouts, $contexts;
664 if (!isset($layouts)) {
665 $layouts = array();
666 $files = file_scan_directory(drupal_get_path('module', 'epublish'), '^epublish_layout_.*\.inc$');
667 foreach ($files as $filename => $file) {
668 include_once($filename);
669 $layouts[drupal_substr($file->name, 16)] = $description;
670 if ($context) {
671 $contexts[$context][drupal_substr($file->name, 16)] = $description;
672 }
673 }
674 }
675 if ($context_selection) {
676 if ($include_default) {
677 return array_merge(array(0 => t('<default>')), $contexts[$context_selection]);
678 }
679 else {
680 return $contexts[$context_selection];
681 }
682 }
683 else {
684 if ($include_default) {
685 return array_merge(array(0 => t('<default>')), $layouts);
686 }
687 else {
688 return $layouts;
689 }
690 }
691 }
692
693 // Load all layouts.
694 epublish_layouts();
695
696
697 /*******************************************
698 * DISPLAY FUNCTIONS
699 ******************************************/
700
701
702 /**
703 * theme_epublish_abstract: A themeable function to display the abstract for an article.
704 */
705 function theme_epublish_abstract($abstract) {
706 return '<div class="epublish_abstract">'. $abstract .'</div>';
707 }
708
709 /**
710 * theme_epublish_topics: A themeable function to display the headlines from an array of topics.
711 *
712 * @param $topics
713 * An array of topics
714 * @param $sid
715 * A headlines section ID number
716 * @param $eid
717 * An edition ID number
718 * @param $context
719 * The context in which the headlines will appear. Possibilities include:
720 * --> 'list' => a list of items (i.e., "<li>item1</li><li>item2</li>..."
721 * --> 'page' => the result will be the main content of a page
722 *
723 * @return
724 * An HTML-formatted list of headlines.
725 */
726 function theme_epublish_topics(&$topics, $sid, &$edition, $context='page') {
727 $params = array();
728 if ($edition->description) {
729 $params['description'] = $edition->description;
730 }
731 $layout = epublish_assign_layout($sid, $edition, $context);
732 $function = "theme_epublish_layout_$layout";
733 if (function_exists($function)) {
734 return theme("epublish_layout_$layout", $topics, $params);
735 }
736 }
737
738 /**
739 * theme_epublish_volume_reference: Themeable function that returns the reference string for an edition of a publication.
740 *
741 * @param $pid
742 * A publication ID.
743 * @param $volume
744 * A volume number
745 *
746 * @return
747 * A text string describing the volume.
748 */
749 function theme_epublish_volume_reference($pid, $volume) {
750 $dateline = db_result(db_query("SELECT dateline FROM {epublish_volume} WHERE pid='%d' AND volume='%d'", $pid, $volume));
751 if ($dateline) {
752 return $dateline;
753 }
754 if ($volume) {
755 return t('Volume') ." $volume";
756 }
757 return t('<none>');
758 }
759
760 /**
761 * theme_epublish_edition_reference: Themeable function that returns the reference string for an edition of a publication.
762 *
763 * @param $edition
764 * An edition object.
765 *
766 * @return
767 * A text string describing the edition.
768 */
769 function theme_epublish_edition_reference(&$edition) {
770 $reference = array();
771 if ($edition->dateline) {
772 $reference[] = t($edition->dateline);
773 }
774 if ($edition->volume) {
775 $reference[] = t('Volume') ." $edition->volume";
776 }
777 if ($edition->number) {
778 $reference[] = t('No.') ." $edition->number";
779 }
780 return implode(', ', $reference);
781 }
782
783 /**
784 * epublish_pub_page: Display the publication(s).
785 */
786 function epublish_pub_page() {
787 $pub = arg(1);
788 $ed = arg(2); //) ? arg(2) : 'current';
789 if (is_numeric($pub)) {
790 $publication = epublish_get_pub($pub);
791 }
792 else if ($pub) {
793 $publication = epublish_get_pub_by_name($pub);
794 }
795 if ($publication) {
796 if ($ed == t('current')) {
797 $ed = epublish_current_edition($publication->pid);
798 }
799 }
800 else {
801 return theme('epublish_format_pub');
802 }
803 if (is_numeric($ed)) {
804 $edition = epublish_get_edition($ed);
805 $sid = epublish_assign_section($edition);
806 $topics = epublish_section_topics($sid, $edition->eid);
807 $output = theme('epublish_topics', $topics, $sid, $edition, 'page');
808 }
809 else {
810 $order = variable_get('epublish_edition_order', 'DESC');
811 preg_match('/(v([0-9]+))?(n([0-9]+))?/i', $ed, $match);
812 $volume = $match[2] ? (" AND volume=" . $match[2]) : '';
813 $number = $match[4] ? (" AND number=" . $match[4]) : '';
814 //$num_editions = db_result(db_query("SELECT COUNT(*) FROM {epublish_edition} WHERE published=1 AND pid='%d'$volume$number", $publication->pid));
815 $num_editions = db_result(db_query("SELECT COUNT(*) FROM {epublish_edition} WHERE published=1 AND pid='%d'$volume$number ORDER BY volume $order, number $order, pubdate $order, eid $order", $publication->pid));
816 $editions = db_query("SELECT * FROM {epublish_edition} WHERE published=1 AND pid='%d'$volume$number ORDER BY volume $order, number $order, pubdate $order, eid $order", $publication->pid);
817 if ($num_editions == 1) {
818 $edition = db_fetch_object($editions);
819 $sid = epublish_assign_section($edition);
820 $topics = epublish_section_topics($sid, $edition->eid);
821 $output = theme('epublish_topics', $topics, $sid, $edition, 'page');
822 }
823 else {
824 $edition = NULL;
825 if (!$ed) {
826 $output .= '<div class="content">'. $publication->description .'</div>';
827 }
828 $editions = db_query("SELECT * FROM {epublish_edition} WHERE published=1 AND pid='%d'$volume$number ORDER BY volume $order, number $order, pubdate $order, eid $order", $publication->pid);
829 while ($ed = db_fetch_object($editions)) {
830 if ($previous_volume && ($ed->volume != $previous_volume)) {
831 $output .= theme('epublish_format_volume', $previous_volume, $publication->pid, $edition_blocks);
832 $edition_blocks = array();
833 }
834 $edition_blocks[] = theme('epublish_format_edition', $ed);
835 $previous_volume = $ed->volume;
836 }
837 if ($edition_blocks) {
838 $output .= theme('epublish_format_volume', $previous_volume, $publication->pid, $edition_blocks);
839 }
840 $output = '<div class="node"><div class="epublish">'. $output .'</div></div>';
841 }
842 }
843 return theme('epublish_pub_page', $output, $publication, $edition, $match[2]);
844 }
845
846 /**
847 * theme_epublish_pub_page: Display the page.
848 *
849 * @param $output
850 * A publication ID.
851 * @param $publication
852 * A publication object
853 * @param $edition
854 * An edition object
855 * @param $volume
856 * A volume number (used only if a single edition is not specified)
857 */
858 function theme_epublish_pub_page(&$output, &$publication, &$edition, $volume=NULL) {
859 if ($publication) {
860 $breadcrumb[] = l(t('Home'), NULL);
861 $breadcrumb[] = l(t($publication->name), "epublish/$publication->pid");
862 $title = $publication->name;
863 }
864 if ($edition->volume) {
865 $breadcrumb[] = l(theme('epublish_volume_reference', $edition->pid, $edition->volume), "epublish/$edition->pid/v$edition->volume");
866 $title = "$publication->name, " . theme('epublish_volume_reference', $edition->pid, $edition->volume);
867 }
868 else if ($volume) {
869 $breadcrumb[] = l(t(theme('epublish_volume_reference', $publication->pid, $volume)), "epublish/$publication->pid/v$volume");
870 $title = "$publication->name, " . theme('epublish_volume_reference', $publication->pid, $volume);
871 }
872 if ($edition) {
873 $title = "$publication->name, " . theme('epublish_edition_reference', $edition);
874 }
875 if ($output) {
876 drupal_set_breadcrumb($breadcrumb);
877 }
878 drupal_set_title(check_plain($title));
879 return $output;
880 }
881
882
883 /**
884 * epublish_headlines_page: Display the headlines.
885 */
886 function epublish_headlines_page() {
887 $sid = arg(1);
888 $sids = epublish_sections();
889 if (!$sid) {
890 $array_keys = array_keys($sids);
891 $sid = variable_get('epublish_global_sid', array_shift($array_keys));
892 }
893 $section = epublish_get_section($sid);
894 if ($section->timeframe) {
895 $timeframe = " AND (n.created >= '". strtotime('-'. $section->timeframe) ."' OR n.sticky=1)";
896 }
897 $result = db_query("SELECT et.tid, et.count, et.node_types, td.name FROM {epublish_topic} et LEFT JOIN {term_data} td USING (tid) WHERE et.sid='%d' ORDER BY et.weight", $sid);
898 $all_nodes = array();
899 $topics = array();
900 while ($topic = db_fetch_object($result)) {
901 $included_node_types = _epublish_build_node_inclusions(array_unique(array_merge(explode(',', $section->node_types), explode(',', $topic->node_types))));
902 $exclusions = _epublish_build_node_exclusions($all_nodes);
903 // Condition to handle another default section
904 if ($topic->tid == -2) {
905 $topic->name = variable_get('epublish_advertisement', t('advertisement'));
906 $result2 = db_query("SELECT DISTINCT(n.nid) FROM {node} n WHERE ($exclusions) AND ($included_node_types) AND n.promote = 1 AND n.status = 1$timeframe AND n.sticky = 1 ORDER by n.created DESC LIMIT $topic->count");
907 }
908 else if ($topic->tid == -1) {
909 $topic->name = variable_get('epublish_top_stories', t('top stories'));
910 $result2 = db_query("SELECT DISTINCT(n.nid) FROM {node} n WHERE ($exclusions) AND ($included_node_types) AND n.promote = 1 AND n.status = 1$timeframe AND n.sticky = 1 ORDER by n.created DESC LIMIT $topic->count");
911 }
912 else if ($topic->tid == 0) {
913 $topic->name = variable_get('epublish_miscellaneous', t('miscellaneous'));
914 $result2 = db_query("SELECT DISTINCT(n.nid) FROM {node} n WHERE ($exclusions) AND ($included_node_types) AND n.promote = 1 AND n.status = 1$timeframe ORDER by n.sticky DESC, n.created DESC LIMIT $topic->count");
915 }
916 else {
917 $included_terms = _epublish_topic_term_inclusions($topic->tid, $sid);
918 $result2 = db_query("SELECT DISTINCT(n.nid) FROM {node} n INNER JOIN {term_node} tn ON n.nid=tn.nid WHERE ($exclusions) AND ($included_node_types) AND ($included_terms) AND n.promote = 1 AND n.status = 1$timeframe ORDER by n.sticky DESC, n.created DESC LIMIT $topic->count");
919 }
920 $topic->nodes = array();
921 while ($node = db_fetch_object($result2)) {
922 $topic->nodes[] = $node->nid;
923 $all_nodes[] = $node->nid;
924 }
925 if (count($topic->nodes)) {
926 $topics[] = $topic;
927 }
928 }
929 drupal_set_title(check_plain($section->title));
930 $edition = NULL;
931 return theme('epublish_topics', $topics, $sid, $edition, 'page');
932 }
933
934 /**
935 * theme_epublish_format_volume: A themeable function that lists the issues
936 * of a single volume of a publication.
937 *
938 * @param $volume
939 * A volume number.
940 * @param $pid
941 * A publication ID number
942 * @param $edition_blocks
943 * A list of blocks of HTML text, one for each edition of a volume.
944 *
945 * @return
946 * An HTML-formatted display showing the reference name of the volume and a list of its editions.
947 */
948 function theme_epublish_format_volume($volume, $pid, $edition_blocks = array()) {
949 if ($volume) {
950 $output = '<h3>'. l(theme('epublish_volume_reference', $pid, $volume), "epublish/$pid/v$volume") ."</h3>\n";
951 }
952 $output .= '<ul>'. implode('', $edition_blocks) ."</ul>\n";
953 return '<div class="volume">'."$output</div>\n";
954 }
955
956 /**
957 * theme_epublish_format_edition: A themeable layout that lists the nodes in a single edition of a publication.
958 *
959 * @param $edition
960 * An edition object.
961 *
962 * @return
963 * An HTML-formatted display showing the reference name of the edition and a list of its headlines.
964 */
965 function theme_epublish_format_edition(&$edition) {
966 $sid = epublish_assign_section($edition);
967 $topics = epublish_section_topics($sid, $edition->eid);
968 if (is_numeric($edition->volume) && is_numeric($edition->number) && $edition->volume > 0 && $edition->number > 0) {
969 $output = "<li><div class=\"reference\">". l(theme('epublish_edition_reference', $edition), "epublish/$edition->pid/v$edition->volume" ."n$edition->number") ."</div></li>\n";
970 }
971 else {
972 $output = "<li><div class=\"reference\">". l(theme('epublish_edition_reference', $edition), "epublish/$edition->pid/$edition->eid") ."</div></li>\n";
973 }
974 $output .= theme('epublish_topics', $topics, $sid, $edition, 'list');
975 return '<div class="edition">'."$output</div>\n";
976 }
977
978 /**
979 * theme_epublish_format_pub: A themeable function that lists all of the publications on the site.
980 *
981 * @return
982 * An HTML-formatted display showing the name of each publication and its description.
983 */
984 function theme_epublish_format_pub() {
985 $result = db_query("SELECT * from {epublish_publication}");
986 $output = '<dl>';
987 while ($publication = db_fetch_object($result)) {
988 $output .= '<dt>'. l($publication->name, "epublish/$publication->pid") ."</dt>\n";
989 if ($publication->description) {
990 $output .= "<dd>$publication->description</dd>\n";
991 }
992 }
993 $output .= "</dl>\n";
994 drupal_set_title(t('publications'));
995 return "<div class=\"epublish\">$output</div>";
996 }
997
998 /*******************************************
999 * SELECTORS
1000 ******************************************/
1001
1002 /**
1003 * epublish_assign_layout: chooses the right layout to use in displaying an array of topics.
1004 * If the "custom layouts" option is turned on, this function looks for a layout in the following
1005 * order and chooses the first one it finds:
1006 * --> section
1007 * --> edition
1008 * --> publication
1009 * --> global settings
1010 *
1011 * @param $sid
1012 * A headlines section ID number
1013 * @param $eid
1014 * An edition ID number
1015 * @param $context
1016 * The context in which the layout is designed to appear. Possibilities include:
1017 * --> 'list' => a list of items (i.e., "<li>item1</li><li>item2</li>..."
1018 * --> 'page' => the result will be the main content of a page
1019 *
1020 * @return
1021 * the name of the layout to use
1022 */
1023 function epublish_assign_layout($sid, &$edition, $context) {
1024 $layout = "layout_$context";
1025 if (variable_get('epublish_custom_layouts', '0')) {
1026 $section = epublish_get_section($sid);
1027 if ($section->$layout) {
1028 return $section->$layout;
1029 }
1030 if ($edition->$layout) {
1031 return $edition->$layout;
1032 }
1033 $publication = epublish_get_pub($edition->pid);
1034 if ($publication->$layout) {
1035 return $publication->$layout;
1036 }
1037 }
1038 if ($context == 'page') {
1039 return variable_get('epublish_global_layout_page', 'regular');
1040 }
1041 else {
1042 return variable_get('epublish_global_layout_list', 'list');
1043 }
1044 }
1045
1046 /**
1047 * epublish_assign_section: chooses the right headlines section to use for organizing
1048 * topics and their headlines. If the "custom sections" option is turned on, this
1049 * function looks for a layout in the following order and chooses the first one it finds:
1050 * --> edition
1051 * --> publication
1052 * --> global settings
1053 *
1054 * @param $edition
1055 * An edition object
1056 *
1057 * @return
1058 * the headlines section ID number
1059 */
1060 function epublish_assign_section(&$edition) {
1061 $sids = epublish_sections();
1062 if (variable_get('epublish_custom_sections', FALSE)) {
1063 if ($sids[$edition->sid]) {
1064 return $edition->sid;
1065 }
1066 $publication = epublish_get_pub($edition->pid);
1067 if ($sids[$publication->sid]) {
1068 return $publication->sid;
1069 }
1070 }
1071 $array_keys = array_keys($sids);
1072 $auto_sid = array_shift($array_keys);
1073 $sid = variable_get('epublish_global_sid', $auto_sid);
1074 if ($sids[$sid]) {
1075 return $sid;
1076 }
1077 else {
1078 return $auto_sid;
1079 }
1080 }
1081
1082 /**
1083 * epublish_topic_selection_list: returns the topics associated with a specific section ID
1084 *
1085 * @param $sid
1086 * A section ID.
1087 *
1088 * @return
1089 * An associative array of topic IDs and their reference names, for use as the $options parameter in form_select function calls
1090 */