Issue #1201858: add reset buttons to text string forms.
[project/print.git] / print.pages.inc
1 <?php
2
3 /**
4 * @file
5 * Contains the functions to generate Printer-friendly pages.
6 *
7 * This file is included by the core PF module, and includes all the
8 * functions necessary to generate a PF version of the original page
9 * in HTML format.
10 *
11 * @ingroup print
12 */
13
14 $_print_urls = PRINT_URLS_DEFAULT;
15
16 /**
17 * Generate an HTML version of the printer-friendly page
18 *
19 * @see print_controller()
20 */
21 function print_controller_html() {
22 $args = func_get_args();
23 $path = implode('/', $args);
24 $cid = isset($_GET['comment']) ? (int)$_GET['comment'] : NULL;
25
26 $print = print_controller($path, $cid, PRINT_HTML_FORMAT);
27 if ($print !== FALSE) {
28 $node = $print['node'];
29 $html = theme('print', array('print' => $print, 'type' => PRINT_HTML_FORMAT, 'node' => $node));
30 print $html;
31
32 $nodepath = (isset($node->path)) ? drupal_get_normal_path($node->path) : 'node/' . $path;
33 db_merge('print_page_counter')
34 ->key(array('path' => $nodepath))
35 ->fields(array(
36 'totalcount' => 1,
37 'timestamp' => REQUEST_TIME,
38 ))
39 ->expression('totalcount', 'totalcount + :inc', array(':inc' => 1))
40 ->execute();
41 }
42 }
43
44 /**
45 * Select the print generator function based on the page type
46 *
47 * Depending on the type of node, this functions chooses the appropriate
48 * generator function.
49 *
50 * @param $path
51 * path of the original page
52 * @param $cid
53 * comment ID of the individual comment to be rendered
54 * @param $format
55 * format of the page being generated
56 * @param $teaser
57 * if set to TRUE, outputs only the node's teaser
58 * @param $message
59 * optional sender's message (used by the send e-mail module)
60 * @return
61 * array with the fields to be used in the template
62 * @see _print_generate_node()
63 * @see _print_generate_path()
64 * @see _print_generate_book()
65 */
66 function print_controller($path, $cid = NULL, $format = PRINT_HTML_FORMAT, $teaser = FALSE, $message = NULL) {
67 if (empty($path)) {
68 // If no path was provided, let's try to generate a page for the referer
69 global $base_url;
70
71 $ref = $_SERVER['HTTP_REFERER'];
72 $path = preg_replace("!^$base_url/!", '', $ref);
73 if ($path === $ref) {
74 $path = '';
75 }
76 }
77 if (!ctype_digit($path)) {
78 // Indirect call with print/alias
79 // If there is a path alias with these arguments, generate a printer-friendly version for it
80 $path = drupal_get_normal_path($path);
81 $ret = preg_match('!^node/(.*)!i', $path, $matches);
82 if ($ret == 1) {
83 $path = $matches[1];
84 }
85 }
86 $parts = explode('/', $path);
87 if (ctype_digit($parts[0]) && (count($parts) == 1)) {
88 $print = _print_generate_node($path, $cid, $format, $teaser, $message);
89 }
90 else {
91 $ret = preg_match('!^book/export/html/(.*)!i', $path, $matches);
92 if ($ret == 1) {
93 // This is a book PF page link, handle trough the book handling functions
94 $print = _print_generate_book($matches[1], $format, $teaser, $message);
95 }
96 else {
97 // If no content node was found, handle the page printing with the 'printable' engine
98 $print = _print_generate_path($path, $format, $teaser, $message);
99 }
100 }
101
102 return $print;
103 }
104
105 /**
106 * Generates a robots meta tag to tell them what they may index
107 *
108 * @return
109 * string with the meta robots tag
110 */
111 function _print_robots_meta_generator() {
112 $print_robots_noindex = variable_get('print_robots_noindex', PRINT_ROBOTS_NOINDEX_DEFAULT);
113 $print_robots_nofollow = variable_get('print_robots_nofollow', PRINT_ROBOTS_NOFOLLOW_DEFAULT);
114 $print_robots_noarchive = variable_get('print_robots_noarchive', PRINT_ROBOTS_NOARCHIVE_DEFAULT);
115 $robots_meta = array();
116
117 if (!empty($print_robots_noindex)) {
118 $robots_meta[] = 'noindex';
119 }
120 if (!empty($print_robots_nofollow)) {
121 $robots_meta[] = 'nofollow';
122 }
123 if (!empty($print_robots_noarchive)) {
124 $robots_meta[] = 'noarchive';
125 }
126
127 if (count($robots_meta) > 0) {
128 $robots_meta = implode(', ', $robots_meta);
129 $robots_meta = "<meta name='robots' content='$robots_meta' />\n";
130 }
131 else {
132 $robots_meta = '';
133 }
134
135 return $robots_meta;
136 }
137
138 /**
139 * Post-processor that fills the array for the template with common details
140 *
141 * @param $node
142 * generated node with a printer-friendly node body
143 * @param $message
144 * optional sender's message (used by the send e-mail module)
145 * @param $cid
146 * id of current comment being generated (NULL when not generating
147 * an individual comment)
148 * @return
149 * array with the fields to be used in the template
150 */
151 function _print_var_generator($node, $message = NULL, $cid = NULL) {
152 global $base_url, $language, $_print_urls;
153
154 $path = empty($node->nid) ? $node->path : "node/$node->nid";
155
156 // print module settings
157 $print_css = variable_get('print_css', PRINT_CSS_DEFAULT);
158 $print_logo_options = variable_get('print_logo_options', PRINT_LOGO_OPTIONS_DEFAULT);
159 $print_logo_url = variable_get('print_logo_url', PRINT_LOGO_URL_DEFAULT);
160 $print_html_new_window = variable_get('print_html_new_window', PRINT_HTML_NEW_WINDOW_DEFAULT);
161 $print_html_sendtoprinter = variable_get('print_html_sendtoprinter', PRINT_HTML_SENDTOPRINTER_DEFAULT);
162 $print_html_windowclose = variable_get('print_html_windowclose', PRINT_HTML_WINDOWCLOSE_DEFAULT);
163 $print_sourceurl_enabled = variable_get('print_sourceurl_enabled', PRINT_SOURCEURL_ENABLED_DEFAULT);
164 $print_sourceurl_forcenode = variable_get('print_sourceurl_forcenode', PRINT_SOURCEURL_FORCENODE_DEFAULT);
165 $print_sourceurl_date = variable_get('print_sourceurl_date', PRINT_SOURCEURL_DATE_DEFAULT);
166 $print_footer_options = variable_get('print_footer_options', PRINT_FOOTER_OPTIONS_DEFAULT);
167 $print_footer_user = variable_get('print_footer_user', PRINT_FOOTER_USER_DEFAULT);
168
169 $print['language'] = $language->language;
170 $print['title'] = check_plain($node->title);
171 $print['head'] = drupal_get_html_head();
172 if ($print_html_sendtoprinter) {
173 drupal_add_js('misc/drupal.js', array('weight' => JS_LIBRARY));
174 }
175 $print['scripts'] = drupal_get_js();
176 $print['robots_meta'] = _print_robots_meta_generator();
177 $print['url'] = url($path, array('absolute' => TRUE));
178 $print['base_href'] = "<base href='" . $print['url'] . "' />\n";
179 $print['favicon'] = theme_get_setting('toggle_favicon') ? "<link rel='shortcut icon' href='" . theme_get_setting('favicon') . "' type='image/x-icon' />\n" : '';
180
181 if (!empty($print_css)) {
182 drupal_add_css(strtr($print_css, array('%t' => path_to_theme())));
183 }
184 else {
185 drupal_add_css(drupal_get_path('module', 'print') . '/css/print.css');
186 }
187 $drupal_css = drupal_add_css();
188 foreach ($drupal_css as $key => $css_file) {
189 if ($css_file['group'] == CSS_THEME) {
190 // Unset the theme's CSS
191 unset($drupal_css[$key]);
192 }
193 }
194
195 // If we are sending a message via e-mail, the CSS must be embedded
196 if (!empty($message)) {
197 $style = '';
198 $css_files = array_keys($drupal_css);
199 foreach ($css_files as $filename) {
200 $res = file_exists($filename) ? file_get_contents($filename, TRUE) : FALSE;
201 if ($res != FALSE) {
202 $style .= $res;
203 }
204 }
205 $print['css'] = "<style type='text/css' media='all'>$style</style>\n";
206 }
207 else {
208 $print['css'] = drupal_get_css($drupal_css);
209 }
210
211 $window_close = ($print_html_new_window && $print_html_windowclose) ? 'window.close();' : '';
212 $print['sendtoprinter'] = $print_html_sendtoprinter ? "<script type='text/javascript'>(function ($) { Drupal.behaviors.print = { attach: function(context) {window.print();$window_close}};}(jQuery));</script>" : '';
213
214 switch ($print_logo_options) {
215 case 0: // none
216 $logo_url = 0;
217 break;
218 case 1: // theme's
219 $logo_url = theme_get_setting('logo');
220 break;
221 case 2: // user-specifed
222 $logo_url = strip_tags($print_logo_url);
223 break;
224 }
225 $site_name = variable_get('site_name', 'Drupal');
226 $print['logo'] = $logo_url ? "<img class='print-logo' src='" . check_url($logo_url) . "' alt='$site_name' id='logo' />\n" : '';
227
228 switch ($print_footer_options) {
229 case 0: // none
230 $footer = '';
231 break;
232 case 1: // theme's
233 $footer = variable_get('site_footer', FALSE) . "\n" . theme('blocks', 'footer');
234 break;
235 case 2: // user-specifed
236 $footer = $print_footer_user;
237 break;
238 }
239 $print['footer_message'] = filter_xss_admin($footer);
240
241 $published_site = variable_get('site_name', 0);
242 if ($published_site) {
243 $print_text_published = filter_xss(variable_get('print_text_published', t('Published on %site_name')));
244 $published = t($print_text_published, array('%site_name' => $published_site));
245 $print['site_name'] = $published . ' (' . l($base_url, $base_url) . ')';
246 }
247 else {
248 $print['site_name'] = '';
249 }
250
251 if ($print_sourceurl_enabled == 1) {
252 /* Grab and format the src URL */
253 if (empty($print_sourceurl_forcenode)) {
254 $url = $print['url'];
255 }
256 else {
257 $url = $base_url . '/' . (((bool)variable_get('clean_url', '0')) ? '' : '?q=') . $path;
258 }
259 if (is_int($cid)) {
260 $url .= '#comment-$cid';
261 }
262 $retrieved_date = format_date(REQUEST_TIME, 'short');
263 $print_text_retrieved = filter_xss(variable_get('print_text_retrieved', t('retrieved on %date')));
264 $retrieved = t($print_text_retrieved, array('%date' => $retrieved_date));
265 $print['printdate'] = $print_sourceurl_date ? " ($retrieved)" : '';
266
267 $source_url = filter_xss(variable_get('print_text_source_url', t('Source URL')));
268 $print['source_url'] = '<strong>' . $source_url . $print['printdate'] . ':</strong> ' . l($url, $url);
269 }
270 else {
271 $print['source_url'] = '';
272 }
273
274 $print['type'] = (isset($node->type)) ? $node->type : '';
275
276 menu_set_active_item($path);
277 $breadcrumb = drupal_get_breadcrumb();
278 if (!empty($breadcrumb)) {
279 $breadcrumb[] = menu_get_active_title();
280 $print['breadcrumb'] = filter_xss(implode(' > ', $breadcrumb));
281 }
282 else {
283 $print['breadcrumb'] = '';
284 }
285
286 // Display the collected links at the bottom of the page. Code once taken from Kjartan Mannes' project.module
287 $print['pfp_links'] = '';
288 if (!empty($_print_urls)) {
289 $urls = _print_friendly_urls();
290 $max = count($urls);
291 $pfp_links = '';
292 if ($max) {
293 for ($i = 0; $i < $max; $i++) {
294 $pfp_links .= '[' . ($i + 1) . '] ' . check_plain($urls[$i]) . "<br />\n";
295 }
296 $links = filter_xss(variable_get('print_text_links', t('Links')));
297 $print['pfp_links'] = "<p><strong>$links:</strong><br />$pfp_links</p>";
298 }
299 }
300
301 $print['node'] = $node;
302 $print['message'] = $message;
303
304 return $print;
305 }
306
307 /**
308 * Callback function for the preg_replace_callback for URL-capable patterns
309 *
310 * Manipulate URLs to make them absolute in the URLs list, and to add a
311 * [n] footnote marker.
312 *
313 * @param $matches
314 * array with the matched tag patterns, usually <a...>+text+</a>
315 * @return
316 * tag with re-written URL and when appropriate the [n] index to the
317 * URL list
318 */
319 function _print_rewrite_urls($matches) {
320 global $base_url, $base_root, $_print_urls;
321
322 $include_anchors = variable_get('print_urls_anchors', PRINT_URLS_ANCHORS_DEFAULT);
323
324 // first, split the html into the different tag attributes
325 $pattern = '!\s*(\w+\s*=\s*"(?:\\\"|[^"])*")\s*|\s*(\w+\s*=\s*\'(?:\\\\\'|[^\'])*\')\s*|\s*(\w+\s*=\s*\w+)\s*|\s+!';
326 $attribs = preg_split($pattern, $matches[1], -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
327 foreach ($attribs as $key => $value) {
328 $attribs[$key] = preg_replace('!(\w)\s*=\s*(.*)!', '$1=$2', $value);
329 }
330
331 $size = count($attribs);
332 for ($i=1; $i < $size; $i++) {
333 // If the attribute is href or src, we may need to rewrite the URL in the value
334 if (preg_match('!^(?:href|src)\s*?=(.*)!i', $attribs[$i], $urls) > 0) {
335 $url = trim($urls[1], " \t\n\r\0\x0B\"'");
336
337 if (strpos(html_entity_decode($url), '://') || preg_match('!^mailto:.*?@.*?\..*?$!iu', html_entity_decode($url))) {
338 // URL is absolute, do nothing
339 $newurl = $url;
340 }
341 else {
342 if ($url[0] == '#') {
343 // URL is an anchor tag
344 if ($include_anchors && (!empty($_print_urls))) {
345 $path = explode('/', $_GET['q']);
346 unset($path[0]);
347 $path = implode('/', $path);
348 if (ctype_digit($path)) {
349 $path = "node/$path";
350 }
351 // Printer-friendly URLs is on, so we need to make it absolute
352 $newurl = url($path, array('fragment' => substr($url, 1), 'absolute' => TRUE));
353 }
354 // Because base href is the original page, change the link to
355 // still be usable inside the print page
356 $matches[1] = str_replace($url, base_path() . $_GET['q'] . $url, $matches[1]);
357 }
358 else {
359 // URL is relative, convert it into absolute URL
360 if ($url[0] == '/') {
361 // If it starts with '/' just append it to the server name
362 $newurl = $base_root . '/' . trim($url, '/');
363 }
364 elseif (preg_match('!^(?:index.php)?\?q=!i', $url)) {
365 // If it starts with ?q=, just prepend with the base URL
366 $newurl = $base_url . '/' . trim($url, '/');
367 }
368 else {
369 $newurl = url(trim($url, '/'), array('absolute' => TRUE));
370 }
371 $matches[1] = str_replace($url, $newurl, $matches[1]);
372 }
373 }
374 }
375 }
376
377 $ret = '<' . $matches[1] . '>';
378 if (count($matches) == 4) {
379 $ret .= $matches[2] . $matches[3];
380 if ((!empty($_print_urls)) && (isset($newurl))) {
381 $ret .= ' <span class="print-footnote">[' . _print_friendly_urls(trim($newurl)) . ']</span>';
382 }
383 }
384
385 return $ret;
386 }
387
388 /**
389 * Auxiliary function to store the Printer-friendly URLs list as static.
390 *
391 * @param $url
392 * absolute URL to be inserted in the list
393 * @return
394 * list of URLs previously stored if $url is 0, or the current count
395 * otherwise.
396 */
397 function _print_friendly_urls($url = 0) {
398 static $urls = array();
399 if ($url) {
400 $url_idx = array_search($url, $urls);
401 if ($url_idx !== FALSE) {
402 return ($url_idx + 1);
403 }
404 else {
405 $urls[] = $url;
406 return count($urls);
407 }
408 }
409 $ret = $urls;
410 $urls = array();
411 return $ret;
412 }
413
414 /**
415 * Check URL list settings for this node
416 *
417 * @param node
418 * node object
419 * @param $format
420 * format of the page being generated
421 * @return
422 * TRUE if URL list should be displayed, FALSE otherwise
423 */
424 function _print_url_list_enabled($node, $format = PRINT_HTML_FORMAT) {
425 if (!isset($node->type)) {
426 return variable_get('print_urls', PRINT_URLS_DEFAULT);
427 }
428
429 switch ($format) {
430 case PRINT_HTML_FORMAT:
431 $node_urllist = isset($node->print_display_urllist) ? $node->print_display_urllist : variable_get('print_display_urllist_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT);
432 $fmt = '';
433 break;
434 case PRINT_MAIL_FORMAT:
435 $node_urllist = isset($node->print_mail_display_urllist) ? $node->print_mail_display_urllist : variable_get('print_mail_display_urllist_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT);
436 $fmt = $format . '_';
437 break;
438 case PRINT_PDF_FORMAT:
439 $node_urllist = isset($node->print_pdf_display_urllist) ? $node->print_pdf_display_urllist : variable_get('print_pdf_display_urllist_' . $node->type, PRINT_TYPE_URLLIST_DEFAULT);
440 $fmt = $format . '_';
441 break;
442 }
443 if (!isset($node_urllist)) $node_urllist = PRINT_TYPE_URLLIST_DEFAULT;
444
445 // Get value of Printer-friendly URLs setting
446 return (variable_get('print_urls', PRINT_URLS_DEFAULT) && ($node_urllist));
447 }
448
449 /**
450 * Prepare a Printer-friendly-ready node body for content nodes
451 *
452 * @param $nid
453 * node ID of the node to be rendered into a printer-friendly page
454 * @param $cid
455 * comment ID of the individual comment to be rendered
456 * @param $format
457 * format of the page being generated
458 * @param $teaser
459 * if set to TRUE, outputs only the node's teaser
460 * @param $message
461 * optional sender's message (used by the send e-mail module)
462 * @return
463 * filled array ready to be used in the template
464 */
465 function _print_generate_node($nid, $cid = NULL, $format = PRINT_HTML_FORMAT, $teaser = FALSE, $message = NULL) {
466 global $_print_urls;
467
468 if (!isset($langcode)) {
469 $langcode = $GLOBALS['language_content']->language;
470 }
471
472 // We can take a node id
473 $node = node_load($nid);
474 if (!$node) {
475 // Node not found
476 drupal_not_found();
477 return FALSE;
478 }
479 elseif (!node_access('view', $node)) {
480 // Access is denied
481 drupal_access_denied();
482 return FALSE;
483 }
484 drupal_set_title($node->title);
485
486 $view_mode = $teaser ? 'teaser' : 'print';
487
488 // Turn off Pagination by the Paging module
489 unset($node->pages);
490 unset($node->page_count);
491
492 // Make this page a member of the original page's organic group
493 if (function_exists('og_set_group_context') && isset($node->og_groups)) {
494 og_set_group_context($node->og_groups);
495 }
496
497 if ($cid === NULL) {
498 // Adapted (simplified) version of node_view
499 //Render the node content
500 node_build_content($node, $view_mode);
501
502 // Disable the links area
503 unset($node->content['links']);
504 // Disable fivestar widget output
505 unset($node->content['fivestar_widget']);
506 // Disable service links module output
507 unset($node->content['service_links']);
508
509 $build = $node->content;
510 unset($node->content);
511
512 // Disable the AdSense module ads
513 // $content = preg_replace('!<div class=[\'"]adsense[\'"].*?</div>!sim', '', $content);
514 }
515
516 $print_comments = variable_get('print_comments', PRINT_COMMENTS_DEFAULT);
517
518 if (function_exists('comment_render') && (($cid != NULL) || ($print_comments))) {
519 //Print only the requested comment (or if $cid is NULL, all of them)
520 $comments = comment_render($node, $cid);
521
522 //Remove the comment forms
523 $comments = preg_replace('!<form.*?id="comment-.*?">.*?</form>!sim', '', $comments);
524 //Remove the 'Post new comment' title
525 $comments = preg_replace('!<h2.*?>' . t('Post new comment') . '</h2>!', '', $comments);
526 //Remove the comment title hyperlink
527 $comments = preg_replace('!(<h3.*?>.*?)<a.*?>(.*?)</a>(.*?</h3>)!i', '$1$2$3', $comments);
528 //Remove the comment author link
529 $pattern = '!(<(?:span|div) class="submitted">.*?)<a.*?>(.*?)</a>(.*?</(?:span|div)>)!sim';
530 if (preg_match($pattern, $comments)) {
531 $comments = preg_replace($pattern , '$1$2$3', $comments);
532 }
533 //Remove the comment links
534 $comments = preg_replace('!\s*<ul class="links">.*?</ul>!sim', '', $comments);
535 if ($cid != NULL) {
536 // Single comment requested, output only the comment
537 unset($node->body);
538 }
539 $node->body .= $comments;
540 }
541
542 $build += array(
543 '#theme' => 'node',
544 '#node' => $node,
545 '#view_mode' => $view_mode,
546 '#language' => $langcode,
547 );
548
549 drupal_alter('node_view', $build);
550
551 $content = render($build);
552
553 //Get rid of the annoying D7 title link
554 $pattern = '!(<h2 property="dc:title" datatype="">)\s*<a [^>]*?>(.*?)</a>\s*(</h2>)!mis';
555 $content = preg_replace($pattern, '$1$2$3', $content);
556
557 //Check URL list settings
558 $_print_urls = _print_url_list_enabled($node, $format);
559
560 // Convert the a href elements
561 $pattern = '!<(a\s[^>]*?)>(.*?)(</a>)!is';
562 $content = preg_replace_callback($pattern, '_print_rewrite_urls', $content);
563
564 $print = _print_var_generator($node, $message, $cid);
565 $print['content'] = $content;
566
567 return $print;
568 }
569
570 /**
571 * Prepare a Printer-friendly-ready node body for non-content pages
572 *
573 * @param $path
574 * path of the node to be rendered into a printer-friendly page
575 * @param $format
576 * format of the page being generated
577 * @param $teaser
578 * if set to TRUE, outputs only the node's teaser
579 * @param $message
580 * optional sender's message (used by the send e-mail module)
581 * @return
582 * filled array ready to be used in the template
583 */
584 function _print_generate_path($path, $format = PRINT_HTML_FORMAT, $teaser = FALSE, $message = NULL) {
585 global $_print_urls;
586
587 // Handle node tabs
588 $parts = explode('/', $path);
589 if (ctype_digit($parts[0]) && (count($parts) > 1)) {
590 $path = 'node/' . $path;
591 }
592
593 $path = drupal_get_normal_path($path);
594
595 menu_set_active_item($path);
596 // Adapted from index.php.
597 $node = new stdClass();
598 $node->body = menu_execute_active_handler($path, FALSE);
599 if (is_array($node->body)) {
600 $node->body = drupal_render($node->body);
601 }
602
603 if (is_int($node->body)) {
604 switch ($node->body) {
605 case MENU_NOT_FOUND:
606 drupal_not_found();
607 return FALSE;
608 break;
609 case MENU_ACCESS_DENIED:
610 drupal_access_denied();
611 return FALSE;
612 break;
613 }
614 }
615
616 $node->title = drupal_get_title();
617 $node->path = $path;
618 $node->changed = 0;
619
620 // Delete any links area
621 $node->body = preg_replace('!\s*<div class="links">.*?</div>!sim', '', $node->body);
622
623 //Check URL list settings
624 $_print_urls = _print_url_list_enabled($node, $format);
625
626 // Convert the a href elements
627 $pattern = '!<(a\s[^>]*?)>(.*?)(</a>)!is';
628 $node->body = preg_replace_callback($pattern, '_print_rewrite_urls', $node->body);
629
630 $print = _print_var_generator($node, $message);
631 $print['content'] = $node->body;
632
633 return $print;
634 }
635
636
637 /**
638 * Prepare a Printer-friendly-ready node body for book pages
639 *
640 * @param $nid
641 * node ID of the node to be rendered into a printer-friendly page
642 * @param $format
643 * format of the page being generated
644 * @param $teaser
645 * if set to TRUE, outputs only the node's teaser
646 * @param $message
647 * optional sender's message (used by the send e-mail module)
648 * @return
649 * filled array ready to be used in the template
650 */
651 function _print_generate_book($nid, $format = PRINT_HTML_FORMAT, $teaser = FALSE, $message = NULL) {
652 global $_print_urls;
653
654 $node = node_load($nid);
655 if (!$node) {
656 // Node not found
657 drupal_not_found();
658 return FALSE;
659 }
660 elseif (!node_access('view', $node) || (!user_access('access printer-friendly version'))) {
661 // Access is denied
662 drupal_access_denied();
663 return FALSE;
664 }
665
666 $tree = book_menu_subtree_data($node->book);
667 $node->body = book_export_traverse($tree, 'book_node_export');
668
669 //Check URL list settings
670 $_print_urls = _print_url_list_enabled($node, $format);
671
672 // Convert the a href elements
673 $pattern = '!<(a\s[^>]*?)>(.*?)(</a>)!is';
674 $node->body = preg_replace_callback($pattern, '_print_rewrite_urls', $node->body);
675
676 $print = _print_var_generator($node, $message);
677 $print['content'] = $node->body;
678
679 // The title is already displayed by the book_recurse, so avoid duplication
680 $print['title'] = '';
681
682 return $print;
683 }