print.pages.inc 24 KB

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