print_pdf.pages.inc 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. <?php
  2. /**
  3. * @file
  4. * Generates the PDF versions of the pages
  5. *
  6. * This file is included by the print_pdf module and includes the
  7. * functions that interface with the PDF generation packages.
  8. *
  9. * @ingroup print
  10. */
  11. module_load_include('inc', 'print', 'print.pages');
  12. /**
  13. * Generate a PDF version of the printer-friendly page
  14. *
  15. * @see print_controller()
  16. * @see _print_pdf_dompdf()
  17. * @see _print_pdf_tcpdf()
  18. */
  19. function print_pdf_controller() {
  20. // Disable caching for generated PDFs, as Drupal doesn't ouput the proper headers from the cache
  21. $GLOBALS['conf']['cache'] = FALSE;
  22. $args = func_get_args();
  23. $path = filter_xss(implode('/', $args));
  24. $cid = isset($_GET['comment']) ? (int)$_GET['comment'] : NULL;
  25. // Handle the query
  26. $query = $_GET;
  27. unset($query['q']);
  28. if (!empty($path)) {
  29. if ($alias = drupal_lookup_path('source', $path)) {
  30. // Alias
  31. $path_arr = explode('/', $alias);
  32. $node = node_load($path_arr[1]);
  33. }
  34. elseif (ctype_digit($args[0])) {
  35. // normal nid
  36. $node = node_load($args[0]);
  37. }
  38. $pdf_filename = variable_get('print_pdf_filename', PRINT_PDF_FILENAME_DEFAULT);
  39. if (!empty($pdf_filename) && !empty($node)) {
  40. $pdf_filename = token_replace($pdf_filename, array('node' => $node), array('clear' => TRUE));
  41. }
  42. else {
  43. $pdf_filename = token_replace($pdf_filename, array('site'), array('clear' => TRUE));
  44. if (empty($pdf_filename)) {
  45. // If empty, use a fallback solution
  46. $pdf_filename = str_replace('/', '_', $path);
  47. }
  48. }
  49. }
  50. else {
  51. $pdf_filename = 'page';
  52. }
  53. if (function_exists('transliteration_clean_filename')) {
  54. $pdf_filename = transliteration_clean_filename($pdf_filename, language_default('language'));
  55. }
  56. drupal_alter('print_pdf_filename', $pdf_filename, $path);
  57. $pdf = print_pdf_generate_path($path, $query, $cid, $pdf_filename . '.pdf');
  58. if ($pdf == NULL) {
  59. drupal_goto($path);
  60. exit;
  61. }
  62. $nodepath = (isset($node->nid)) ? 'node/' . $node->nid : drupal_get_normal_path($path);
  63. db_merge('print_pdf_page_counter')
  64. ->key(array('path' => $nodepath))
  65. ->fields(array(
  66. 'totalcount' => 1,
  67. 'timestamp' => REQUEST_TIME,
  68. ))
  69. ->expression('totalcount', 'totalcount + 1')
  70. ->execute();
  71. drupal_exit();
  72. }
  73. /**
  74. * Gennerate a PDF for a given Drupal path.
  75. *
  76. * @param string $path
  77. * path of the page to convert to PDF
  78. * @param array $query
  79. * (optional) array of key/value pairs as used in the url() function for the
  80. * query
  81. * @param int $cid
  82. * (optional) comment ID of the comment to render.
  83. * @param string $pdf_filename
  84. * (optional) filename of the generated PDF
  85. * @param string $view_mode
  86. * (optional) view mode to be used when rendering the content
  87. *
  88. * @return
  89. * generated PDF page, or NULL in case of error
  90. *
  91. * @see print_pdf_controller()
  92. */
  93. function print_pdf_generate_path($path, $query = NULL, $cid = NULL, $pdf_filename = NULL, $view_mode = PRINT_VIEW_MODE) {
  94. global $base_url;
  95. $link = print_pdf_print_link();
  96. $node = print_controller($path, $link['format'], $cid, $view_mode);
  97. if ($node) {
  98. // Call the current tool's hook_pdf_tool_info(), to see if we need to expand CSS
  99. $pdf_tool = explode('|', variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT));
  100. $cache_enabled = variable_get('print_pdf_cache_enabled', PRINT_PDF_CACHE_ENABLED_DEFAULT);
  101. $function = $pdf_tool[0] . '_pdf_tool_info';
  102. if (function_exists($function)) {
  103. $info = $function();
  104. }
  105. $expand = isset($info['expand_css']) ? $info['expand_css'] : FALSE;
  106. $html = theme('print', array('node' => $node, 'query' => $query, $expand, 'format' => $link['format']));
  107. // Img elements must be set to absolute
  108. $pattern = '!<(img\s[^>]*?)>!is';
  109. $html = preg_replace_callback($pattern, '_print_rewrite_urls', $html);
  110. // Convert the a href elements, to make sure no relative links remain
  111. $pattern = '!<(a\s[^>]*?)>!is';
  112. $html = preg_replace_callback($pattern, '_print_rewrite_urls', $html);
  113. // And make anchor links relative again, to permit in-PDF navigation
  114. $html = preg_replace("!${base_url}/" . $link['path'] . '/.*?#!', '#', $html);
  115. $meta = array(
  116. 'node' => $node,
  117. 'url' => url(drupal_get_path_alias(empty($node->nid) ? $node->path : "node/$node->nid"), array('absolute' => TRUE)),
  118. );
  119. if (isset($node->name)) $meta['name'] = $node->name;
  120. if (isset($node->title)) $meta['title'] = $node->title;
  121. $paper_size = isset($node->print_pdf_size) ? $node->print_pdf_size : NULL;
  122. $page_orientation = isset($node->print_pdf_orientation) ? $node->print_pdf_orientation : NULL;
  123. $pdf = '';
  124. $cachemiss = FALSE;
  125. if ($cache_enabled && isset($node->nid)) {
  126. // See if the file exists in the cache
  127. $cachefile = drupal_realpath(print_pdf_cache_dir()) . '/' . $node->nid . '.pdf';
  128. if (is_readable($cachefile)) {
  129. // Get the PDF content from the cached file
  130. $pdf = file_get_contents($cachefile);
  131. if ($pdf === FALSE) {
  132. watchdog('print_pdf', 'Failed to read from cached file %file', array('%file' => $cached), WATCHDOG_ERROR);
  133. }
  134. }
  135. else {
  136. $cachemiss = TRUE;
  137. }
  138. }
  139. // If cache is off or file is not cached, generate one from scratch
  140. if (empty($pdf)) {
  141. $pdf = print_pdf_generate_html($html, $meta, NULL, $paper_size, $page_orientation);
  142. }
  143. if (!empty($pdf)) {
  144. // A PDF was created, save it to cache if configured
  145. if ($cachemiss) {
  146. if (file_unmanaged_save_data($pdf, $cachefile, FILE_EXISTS_REPLACE) == FALSE) {
  147. watchdog('print_pdf', 'Failed to write to "%f".', array('%f' => $filename), WATCHDOG_ERROR);
  148. }
  149. }
  150. return $pdf_filename ? print_pdf_dispose_content($pdf, $pdf_filename) : $pdf;
  151. }
  152. }
  153. else {
  154. return NULL;
  155. }
  156. }