| Commit | Line | Data |
|---|---|---|
| b09f08f7 | 1 | <?php |
| 3483245d JV |
2 | // $Id$ |
| 3 | ||
| 4 | /** | |
| 5 | * @file | |
| 6 | * Generates the PDF versions of the pages | |
| 7 | * | |
| 8 | * This file is included by the print_pdf module and includes the | |
| 9 | * functions that interface with the PDF generation packages. | |
| d08475b8 JV |
10 | * |
| 11 | * @ingroup print | |
| 3483245d | 12 | */ |
| b09f08f7 | 13 | |
| fe25f54b | 14 | require_once(DRUPAL_ROOT . '/' . drupal_get_path('module', 'print') . '/print.pages.inc'); |
| b09f08f7 | 15 | |
| 6a4c89f9 JV |
16 | /** |
| 17 | * Generate a PDF version of the printer-friendly page | |
| 18 | * | |
| 19 | * @see print_controller() | |
| 20 | * @see _print_get_template() | |
| 21 | * @see _print_pdf_dompdf() | |
| 22 | * @see _print_pdf_tcpdf() | |
| 23 | */ | |
| b09f08f7 | 24 | function print_pdf_controller() { |
| dd0fda21 | 25 | global $base_url, $language; |
| e60934b7 | 26 | |
| 606acc3b JV |
27 | // Disable caching for generated PDFs, as Drupal doesn't ouput the proper headers from the cache |
| 28 | $GLOBALS['conf']['cache'] = FALSE; | |
| 29 | ||
| 5b1b9562 | 30 | $args = func_get_args(); |
| 5b1b9562 | 31 | $path = implode('/', $args); |
| 20ab24e6 | 32 | $cid = isset($_GET['comment']) ? (int)$_GET['comment'] : NULL; |
| 3c90dace | 33 | |
| 7d62e7c4 | 34 | $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT); |
| b09f08f7 | 35 | |
| 855b243a | 36 | $print = print_controller($path, $cid, PRINT_PDF_FORMAT); |
| 5c9469df JV |
37 | if ($print === FALSE) { |
| 38 | return; | |
| 39 | } | |
| 40 | ||
| b09f08f7 | 41 | // Img elements must be set to absolute |
| 7d62e7c4 JV |
42 | $pattern = '!<(img\s[^>]*?)>!is'; |
| 43 | $print['content'] = preg_replace_callback($pattern, '_print_rewrite_urls', $print['content']); | |
| 44 | $print['logo'] = preg_replace_callback($pattern, '_print_rewrite_urls', $print['logo']); | |
| 45 | $print['footer_message'] = preg_replace_callback($pattern, '_print_rewrite_urls', $print['footer_message']); | |
| e60934b7 JV |
46 | // And converted from private to public paths |
| 47 | $file_downloads = variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC); | |
| 48 | if ($file_downloads == FILE_DOWNLOADS_PRIVATE) { | |
| dd0fda21 JV |
49 | switch (variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE)) { |
| 50 | case LANGUAGE_NEGOTIATION_PATH_DEFAULT: | |
| 51 | case LANGUAGE_NEGOTIATION_PATH: | |
| 52 | $lang = $language->language; | |
| 53 | break; | |
| 54 | default: | |
| 55 | $lang = ''; | |
| 56 | break; | |
| 57 | } | |
| 58 | $pattern = "!(<img\s[^>]*?src\s*?=\s*?['\"]?)${base_url}/(?:(?:index.php)?\?q=)?(?:${lang}/)?system/files(/[^>]*?>)!is"; | |
| fe25f54b | 59 | $replacement = '$1file://' . realpath(file_directory_path()) . '$2'; |
| e60934b7 JV |
60 | $print['content'] = preg_replace($pattern, $replacement, $print['content']); |
| 61 | $print['logo'] = preg_replace($pattern, $replacement, $print['logo']); | |
| 62 | $print['footer_message'] = preg_replace($pattern, $replacement, $print['footer_message']); | |
| 63 | } | |
| b09f08f7 | 64 | |
| 7d62e7c4 | 65 | $node = $print['node']; |
| 1caf9f9d | 66 | ob_start(); |
| fe25f54b | 67 | include_once(DRUPAL_ROOT . '/' . _print_get_template(PRINT_PDF_FORMAT, $print['type'])); |
| 1caf9f9d JV |
68 | $html = ob_get_contents(); |
| 69 | ob_end_clean(); | |
| 70 | ||
| 361ee8f2 | 71 | // Convert the a href elements, to make sure no relative links remain |
| f4236c76 JV |
72 | $pattern = '!<(a\s[^>]*?)>!is'; |
| 73 | $html = preg_replace_callback($pattern, '_print_rewrite_urls', $html); | |
| 361ee8f2 JV |
74 | // And make anchor links relative again, to permit in-PDF navigation |
| 75 | $html = preg_replace("!${base_url}/" . PRINTPDF_PATH . "/.*?%2523!", '#', $html); | |
| f4236c76 | 76 | |
| 40db8370 JV |
77 | $pdf_filename = variable_get('print_pdf_filename', PRINT_PDF_FILENAME_DEFAULT); |
| 78 | if (function_exists('token_replace') && !empty($pdf_filename)) { | |
| fe25f54b | 79 | $pdf_filename = token_replace($pdf_filename, 'node', $node) . '.pdf'; |
| 40db8370 JV |
80 | } |
| 81 | else { | |
| fe25f54b | 82 | $pdf_filename = str_replace('/', '_', $path) . '.pdf'; |
| 40db8370 | 83 | } |
| 7d62e7c4 | 84 | if (basename($print_pdf_pdf_tool) == 'dompdf_config.inc.php') { |
| 40db8370 | 85 | _print_pdf_dompdf($print, $html, $pdf_filename); |
| b09f08f7 | 86 | } |
| 7d62e7c4 | 87 | elseif (basename($print_pdf_pdf_tool) == 'tcpdf.php') { |
| 40db8370 | 88 | _print_pdf_tcpdf($print, $html, $pdf_filename); |
| b09f08f7 | 89 | } |
| 0956bdfb JV |
90 | elseif (basename($print_pdf_pdf_tool) == 'wkhtmltopdf') { |
| 91 | _print_pdf_wkhtmltopdf($print, $html, $pdf_filename); | |
| 92 | } | |
| b09f08f7 JV |
93 | else { |
| 94 | return drupal_not_found(); | |
| 95 | } | |
| 855b243a | 96 | |
| c8aee091 | 97 | $nodepath = (isset($node->path)) ? drupal_get_normal_path($node->path) : 'node/' . $path; |
| 855b243a JV |
98 | db_merge('print_pdf_page_counter') |
| 99 | ->key(array('path' => $nodepath)) | |
| 100 | ->fields(array( | |
| 101 | 'totalcount' => 1, | |
| 102 | 'timestamp' => REQUEST_TIME, | |
| 103 | )) | |
| 104 | ->expression('totalcount', 'totalcount + :inc', array(':inc' => 1)) | |
| 105 | ->execute(); | |
| b09f08f7 JV |
106 | } |
| 107 | ||
| 6a4c89f9 JV |
108 | /** |
| 109 | * Generate the PDF file using the dompdf library | |
| 110 | * | |
| 111 | * @param $print | |
| 112 | * array containing the configured data | |
| 113 | * @param $html | |
| 114 | * contents of the post-processed template already with the node data | |
| 115 | * @param $filename | |
| 116 | * name of the PDF file to be generated | |
| 117 | * @see print_pdf_controller() | |
| 118 | */ | |
| 1caf9f9d | 119 | function _print_pdf_dompdf($print, $html, $filename) { |
| 7d62e7c4 JV |
120 | $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT); |
| 121 | $print_pdf_paper_size = variable_get('print_pdf_paper_size', PRINT_PDF_PAPER_SIZE_DEFAULT); | |
| 122 | $print_pdf_page_orientation = variable_get('print_pdf_page_orientation', PRINT_PDF_PAGE_ORIENTATION_DEFAULT); | |
| 123 | $print_pdf_content_disposition = variable_get('print_pdf_content_disposition', PRINT_PDF_CONTENT_DISPOSITION_DEFAULT); | |
| fe25f54b | 124 | require_once(DRUPAL_ROOT . '/' . $print_pdf_pdf_tool); |
| b09f08f7 | 125 | |
| 893ee70f JV |
126 | // dompdf seems to have problems with something in system.css so let's not use it |
| 127 | $html = preg_replace('!<link.*?modules/system/system.css.*?/>!', '', $html); | |
| 128 | ||
| 56bdd124 JV |
129 | $url_array = parse_url($print['url']); |
| 130 | ||
| fe25f54b | 131 | $protocol = $url_array['scheme'] . '://'; |
| 56bdd124 | 132 | $host = $url_array['host']; |
| fe25f54b | 133 | $path = dirname($url_array['path']) . '/'; |
| b09f08f7 JV |
134 | |
| 135 | $dompdf = new DOMPDF(); | |
| 56bdd124 JV |
136 | $dompdf->set_base_path($path); |
| 137 | $dompdf->set_host($host); | |
| 6a4c89f9 | 138 | $dompdf->set_paper(drupal_strtolower($print_pdf_paper_size), $print_pdf_page_orientation); |
| 56bdd124 JV |
139 | $dompdf->set_protocol($protocol); |
| 140 | ||
| cc511103 JV |
141 | // dompdf can't handle footers cleanly, so disable the following |
| 142 | // $html = theme('print_pdf_dompdf_footer', $html); | |
| b97f7b85 | 143 | |
| f76a10f2 JV |
144 | // Convert from UTF-8 to ISO 8859-1 and then to HTML entities |
| 145 | if (function_exists('utf8_decode')) { | |
| 146 | $html = utf8_decode($html); | |
| 147 | } | |
| 148 | // iconv fails silently when it encounters something that it doesn't know, so don't use it | |
| 149 | // else if (function_exists('iconv')) { | |
| 150 | // $html = iconv('UTF-8', 'ISO-8859-1', $html); | |
| 151 | // } | |
| ff2fdaa2 | 152 | elseif (function_exists('mb_convert_encoding')) { |
| f76a10f2 JV |
153 | $html = mb_convert_encoding($html, 'ISO-8859-1', 'UTF-8'); |
| 154 | } | |
| ff2fdaa2 | 155 | elseif (function_exists('recode_string')) { |
| f76a10f2 JV |
156 | $html = recode_string('UTF-8..ISO_8859-1', $html); |
| 157 | } | |
| 158 | $html = htmlspecialchars_decode(htmlentities($html, ENT_NOQUOTES, 'ISO-8859-1'), ENT_NOQUOTES); | |
| d356106f | 159 | |
| dfb35930 | 160 | //must get rid of tbody (dompdf goes into recursion) |
| d54079c6 | 161 | $html = preg_replace('!<tbody[^>]*?>|</tbody>!i', '', $html); |
| dfb35930 | 162 | |
| d356106f | 163 | $dompdf->load_html($html); |
| 3483245d | 164 | |
| b09f08f7 | 165 | $dompdf->render(); |
| 7d62e7c4 | 166 | $dompdf->stream($filename, array('Attachment' => ($print_pdf_content_disposition == 2))); |
| b09f08f7 JV |
167 | } |
| 168 | ||
| 6a4c89f9 JV |
169 | /** |
| 170 | * Generate the PDF file using the TCPDF library | |
| 171 | * | |
| 172 | * @param $print | |
| 173 | * array containing the configured data | |
| 174 | * @param $html | |
| 175 | * contents of the post-processed template already with the node data | |
| 176 | * @param $filename | |
| 177 | * name of the PDF file to be generated | |
| 178 | * @see print_pdf_controller() | |
| 179 | */ | |
| 1caf9f9d | 180 | function _print_pdf_tcpdf($print, $html, $filename) { |
| 85cce36d JV |
181 | global $base_url, $language; |
| 182 | ||
| 7d62e7c4 JV |
183 | $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT); |
| 184 | $print_pdf_paper_size = variable_get('print_pdf_paper_size', PRINT_PDF_PAPER_SIZE_DEFAULT); | |
| 185 | $print_pdf_page_orientation = variable_get('print_pdf_page_orientation', PRINT_PDF_PAGE_ORIENTATION_DEFAULT); | |
| 186 | $print_pdf_content_disposition = variable_get('print_pdf_content_disposition', PRINT_PDF_CONTENT_DISPOSITION_DEFAULT); | |
| 187 | ||
| 4817021f JV |
188 | $pdf_tool_path = realpath(dirname($print_pdf_pdf_tool)); |
| 189 | ||
| b658d760 JV |
190 | if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) { |
| 191 | define('K_TCPDF_EXTERNAL_CONFIG', TRUE); | |
| 192 | define('K_PATH_MAIN', dirname($_SERVER['SCRIPT_FILENAME'])); | |
| 193 | define('K_PATH_URL', $base_url); | |
| 194 | define('K_PATH_FONTS', $pdf_tool_path . '/fonts/'); | |
| 195 | define('K_PATH_CACHE', $pdf_tool_path . '/cache/'); | |
| 196 | define('K_PATH_IMAGES', ''); | |
| 197 | define('K_BLANK_IMAGE', $pdf_tool_path . '/images/_blank.png'); | |
| 198 | define('K_CELL_HEIGHT_RATIO', 1.25); | |
| 199 | define('K_SMALL_RATIO', 2/3); | |
| 200 | } | |
| 7d62e7c4 | 201 | |
| 903b9638 | 202 | // Decode HTML entities in image filenames |
| b658d760 | 203 | $pattern = "!<img\s[^>]*?src\s*?=\s*?['\"]?${base_url}[^>]*?>!is"; |
| ff2fdaa2 | 204 | $html = preg_replace_callback($pattern, create_function('$matches', 'return html_entity_decode($matches[0], ENT_QUOTES);'), $html); |
| 5c4a2f7f | 205 | // Remove queries from the image URL |
| b658d760 | 206 | $pattern = "!(<img\s[^>]*?src\s*?=\s*?['\"]?${base_url}.*?)(?:%3F|\?)[\w=&]+([^>]*?>)!is"; |
| 903b9638 | 207 | $html = preg_replace($pattern, '$1$2', $html); |
| cdb13c56 | 208 | |
| fe25f54b | 209 | require_once(DRUPAL_ROOT . '/' . $print_pdf_pdf_tool); |
| e03112ed | 210 | if (strpos(PDF_PRODUCER, 'PHP4') === FALSE) { |
| fe25f54b | 211 | require_once(DRUPAL_ROOT . '/' . drupal_get_path('module', 'print_pdf') . '/print_pdf.class.inc'); |
| 90263e69 JV |
212 | } |
| 213 | else { | |
| 6936e5f6 JV |
214 | drupal_set_message(t("The PHP4 version of TCPDF is not supported. Please upgrade it."), 'error', FALSE); |
| 215 | drupal_goto($_GET['q']); | |
| 90263e69 | 216 | } |
| 7d62e7c4 | 217 | |
| 455e82fd JV |
218 | $font = Array( |
| 219 | variable_get('print_pdf_font_family', PRINT_PDF_FONT_FAMILY_DEFAULT), | |
| b2a85b2b | 220 | '', |
| 455e82fd JV |
221 | variable_get('print_pdf_font_size', PRINT_PDF_FONT_SIZE_DEFAULT), |
| 222 | ); | |
| 6a4c89f9 | 223 | $orientation = drupal_strtoupper($print_pdf_page_orientation[0]); |
| 56bdd124 JV |
224 | |
| 225 | // create new PDF document | |
| 3da84173 | 226 | $pdf = new PrintTCPDF($orientation , 'mm', $print_pdf_paper_size, TRUE); |
| b09f08f7 | 227 | |
| 56bdd124 | 228 | // set document information |
| 7d62e7c4 JV |
229 | $pdf->SetAuthor(strip_tags($print['submitted'])); |
| 230 | $pdf->SetCreator(variable_get('site_name', 'Drupal')); | |
| e522c3f2 | 231 | $pdf->SetTitle(html_entity_decode($print['title'], ENT_QUOTES, 'UTF-8')); |
| 7d62e7c4 | 232 | $keys = implode(' ', explode("\n", trim(strip_tags($print['taxonomy'])))); |
| 56bdd124 | 233 | $pdf->SetKeywords($keys); |
| 7d62e7c4 | 234 | $pdf->setPDFVersion('1.6'); |
| 56bdd124 | 235 | |
| 85cce36d JV |
236 | if (defined('LANGUAGE_RTL') && $language->direction == LANGUAGE_RTL) { |
| 237 | $pdf->setRTL(TRUE); | |
| 238 | } | |
| 239 | ||
| 1024f54b JV |
240 | $pdf = theme('print_pdf_tcpdf_header', $pdf, $html, $font); |
| 241 | $pdf = theme('print_pdf_tcpdf_footer', $pdf, $html, $font); | |
| 242 | $pdf = theme('print_pdf_tcpdf_page', $pdf); | |
| 4817021f JV |
243 | |
| 244 | //initialize document | |
| 245 | $pdf->AliasNbPages(); | |
| 246 | ||
| 247 | // add a page | |
| 248 | $pdf->AddPage(); | |
| 249 | ||
| 1024f54b | 250 | $pdf = theme('print_pdf_tcpdf_content', $pdf, $html, $font); |
| 4817021f JV |
251 | |
| 252 | // reset pointer to the last page | |
| 253 | $pdf->lastPage(); | |
| 254 | ||
| 29c45af0 JV |
255 | // try to recover from any warning/error |
| 256 | ob_clean(); | |
| 257 | ||
| 4817021f JV |
258 | //Close and output PDF document |
| 259 | $output_dest = ($print_pdf_content_disposition == 2) ? 'D' : 'I'; | |
| 260 | $pdf->Output($filename, $output_dest); | |
| 261 | } | |
| 262 | ||
| 6a4c89f9 | 263 | /** |
| 0956bdfb JV |
264 | * Generate the PDF file using wkhtmltopdf |
| 265 | * | |
| 266 | * @param $print | |
| 267 | * array containing the configured data | |
| 268 | * @param $html | |
| 269 | * contents of the post-processed template already with the node data | |
| 270 | * @param $filename | |
| 271 | * name of the PDF file to be generated | |
| 272 | * @see print_pdf_controller() | |
| 273 | */ | |
| 274 | function _print_pdf_wkhtmltopdf($print, $html, $filename) { | |
| 275 | $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT); | |
| 730917d3 | 276 | $print_pdf_paper_size = drupal_strtolower(variable_get('print_pdf_paper_size', PRINT_PDF_PAPER_SIZE_DEFAULT)); |
| 0956bdfb JV |
277 | $print_pdf_page_orientation = variable_get('print_pdf_page_orientation', PRINT_PDF_PAGE_ORIENTATION_DEFAULT); |
| 278 | $print_pdf_content_disposition = variable_get('print_pdf_content_disposition', PRINT_PDF_CONTENT_DISPOSITION_DEFAULT); | |
| d9a43552 JV |
279 | $print_pdf_wkhtmltopdf_options = variable_get('print_pdf_wkhtmltopdf_options', PRINT_PDF_WKHTMLTOPDF_OPTIONS); |
| 280 | $print_pdf_xvfb_options = variable_get('print_pdf_xvfb_options', PRINT_PDF_XVFB_OPTIONS); | |
| 0956bdfb JV |
281 | |
| 282 | $xvfb_binary = key(file_scan_directory(drupal_get_path('module', 'print'), '!^Xvfb$!')); | |
| d9a43552 | 283 | $dpi = 96; |
| 0956bdfb | 284 | |
| 04742a90 | 285 | // If available, launch a temporary X server |
| 0956bdfb | 286 | if (isset($xvfb_binary)) { |
| a8ffbc1f JV |
287 | $xdisplay = variable_get('print_pdf_wkhtmltopdf_xdisplay', 10); |
| 288 | variable_set('print_pdf_wkhtmltopdf_xdisplay', ($xdisplay == 4990) ? 10 : $xdisplay + 10); | |
| 289 | $xdisplay += mt_rand(0, 9); | |
| 290 | ||
| d9a43552 | 291 | $xcmd = realpath($xvfb_binary) . " :$xdisplay -screen 0 320x200x24 -dpi $dpi -terminate -nolisten tcp -tst $print_pdf_xvfb_options"; |
| 730917d3 JV |
292 | |
| 293 | $xdescriptor = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')); | |
| 294 | $xprocess = proc_open($xcmd, $xdescriptor, $xpipes, NULL, NULL); | |
| 0956bdfb JV |
295 | } |
| 296 | ||
| 730917d3 | 297 | $descriptor = array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')); |
| d9a43552 | 298 | $cmd = realpath($print_pdf_pdf_tool) . " --page-size $print_pdf_paper_size --orientation $print_pdf_page_orientation --dpi $dpi $print_pdf_wkhtmltopdf_options - -"; |
| 0956bdfb | 299 | |
| ff2fdaa2 | 300 | $process = proc_open($cmd, $descriptor, $pipes, NULL, isset($xvfb_binary) ? array('DISPLAY' => ':' . $xdisplay) : NULL); |
| 0956bdfb JV |
301 | |
| 302 | if (is_resource($process)) { | |
| 303 | fwrite($pipes[0], $html); | |
| 304 | fclose($pipes[0]); | |
| 305 | ||
| 306 | $pdf = stream_get_contents($pipes[1]); | |
| 307 | fclose($pipes[1]); | |
| 308 | ||
| 04742a90 JV |
309 | stream_set_blocking($xpipes[2], 0); |
| 310 | $error = stream_get_contents($pipes[2]); | |
| 311 | if (!empty($error)) { | |
| 312 | watchdog('print_pdf', 'wkhtmltopdf: ' . $error); | |
| 730917d3 | 313 | } |
| 04742a90 | 314 | fclose($pipes[2]); |
| 730917d3 | 315 | |
| 04742a90 | 316 | $retval = proc_terminate($process); |
| 0956bdfb JV |
317 | } |
| 318 | if (isset($xvfb_binary)) { | |
| 04742a90 JV |
319 | fclose($xpipes[0]); |
| 320 | fclose($xpipes[1]); | |
| 321 | stream_set_blocking($xpipes[2], 0); | |
| 322 | $xerror = stream_get_contents($xpipes[2]); | |
| 323 | if (!empty($xerror)) { | |
| 324 | watchdog('print_pdf', 'wkhtmltopdf Xvfb: ' . $xerror); | |
| 730917d3 | 325 | } |
| 04742a90 JV |
326 | fclose($xpipes[2]); |
| 327 | ||
| 328 | proc_terminate($xprocess); | |
| 0956bdfb JV |
329 | } |
| 330 | ||
| a8ffbc1f | 331 | if (!empty($pdf)) { |
| 0956bdfb JV |
332 | if (headers_sent()) { |
| 333 | die("Unable to stream pdf: headers already sent"); | |
| 334 | } | |
| 335 | header("Cache-Control: private"); | |
| 336 | header("Content-Type: application/pdf"); | |
| 337 | ||
| 338 | $attachment = ($print_pdf_content_disposition == 2) ? "attachment" : "inline"; | |
| 339 | ||
| 340 | header("Content-Disposition: $attachment; filename=\"$filename\""); | |
| 341 | ||
| 342 | echo $pdf; | |
| 343 | flush(); | |
| 344 | } | |
| 730917d3 JV |
345 | else { |
| 346 | drupal_goto($print['url']); | |
| 347 | exit; | |
| 348 | } | |
| 0956bdfb JV |
349 | } |
| 350 | ||
| 351 | /** | |
| b97f7b85 JV |
352 | * Format the dompdf footer contents |
| 353 | * | |
| 354 | * @param $html | |
| 355 | * contents of the body of the HTML from the original node | |
| 356 | * @see theme_print_pdf_tcpdf_footer() | |
| 357 | */ | |
| 3a1f33ce | 358 | function theme_print_pdf_dompdf_footer(&$html) { |
| b97f7b85 JV |
359 | preg_match('!<div class="print-footer">(.*?)</div>!si', $html, $tpl_footer); |
| 360 | $html = str_replace($tpl_footer[0], '', $html); | |
| 361 | ||
| 362 | $text = '<script type="text/php"> | |
| 363 | if (isset($pdf)) { | |
| 364 | $font = Font_Metrics::get_font("verdana");; | |
| 365 | $size = 10; | |
| 366 | $color = array(0,0,0); | |
| 367 | $text_height = Font_Metrics::get_font_height($font, $size); | |
| 368 | ||
| 369 | $w = $pdf->get_width(); | |
| 370 | $h = $pdf->get_height(); | |
| 371 | ||
| 372 | $footer = $pdf->open_object(); | |
| 373 | ||
| 374 | // Draw a line along the bottom | |
| 375 | $y = $h - 25; | |
| 376 | $pdf->line(15, $y, $w - 15, $y, $color, 1); | |
| 377 | ||
| 378 | $y += $text_height / 2; | |
| fe25f54b | 379 | $pdf->page_text(15, $y, \'' . addslashes(strip_tags($tpl_footer[1])) . '\', $font, $size, $color); |
| b97f7b85 JV |
380 | |
| 381 | $pdf->close_object(); | |
| 382 | $pdf->add_object($footer, "all"); | |
| 383 | ||
| 384 | // Center the text | |
| 385 | $width = Font_Metrics::get_text_width("Page 1 of 2", $font, $size); | |
| 386 | $pagenumtxt = t("Page !n of !total", array("!n" => "{PAGE_NUM}", "!total" => "{PAGE_COUNT}")); | |
| 387 | $pdf->page_text($w - 15 - $width, $y, $pagenumtxt, $font, $size, $color); | |
| 388 | } | |
| 389 | </script>'; | |
| 390 | ||
| 391 | return str_replace("<body>", "<body>" . $text, $html); | |
| 392 | } | |
| 393 | ||
| 394 | /** | |
| 6a4c89f9 JV |
395 | * Format the TCPDF header |
| 396 | * | |
| 397 | * @param $pdf | |
| 398 | * current TCPDF object | |
| 399 | * @param $html | |
| 400 | * contents of the body of the HTML from the original node | |
| 401 | * @param $font | |
| 402 | * array with the font definition (font name, styles and size) | |
| 403 | * @see theme_print_pdf_tcpdf_header() | |
| 404 | */ | |
| 3a1f33ce | 405 | function theme_print_pdf_tcpdf_header(&$pdf, &$html, $font) { |
| 4817021f JV |
406 | preg_match('!<div class="print-logo">(.*?)</div>!si', $html, $tpl_logo); |
| 407 | preg_match('!<h1 class="print-title">(.*?)</h1>!si', $html, $tpl_title); | |
| 408 | preg_match('!<div class="print-site_name">(.*?)</div>!si', $html, $tpl_site_name); | |
| 409 | ||
| 74df721a | 410 | $ratio = 0; |
| 4817021f JV |
411 | $logo = ''; |
| 412 | $logo_ret = preg_match('!src\s*=\s*(\'.*?\'|".*?"|[^\s]*)!i', $tpl_logo[1], $matches); | |
| 3da84173 JV |
413 | if ($logo_ret) { |
| 414 | $logo = trim($matches[1], '\'"'); | |
| 4817021f | 415 | $size = getimagesize($logo); |
| c64555f4 | 416 | $ratio = $size ? ($size[0] / $size[1]) : 0; |
| 3da84173 JV |
417 | } |
| 418 | ||
| 4817021f JV |
419 | // set header font |
| 420 | $pdf->setHeaderFont($font); | |
| 421 | // set header margin | |
| 422 | $pdf->SetHeaderMargin(5); | |
| 56bdd124 | 423 | // set header data |
| bd02b7ac | 424 | $pdf->SetHeaderData($logo, 10 * $ratio, html_entity_decode($tpl_title[1], ENT_QUOTES, 'UTF-8'), strip_tags($tpl_site_name[1])); |
| 1024f54b JV |
425 | |
| 426 | return $pdf; | |
| 4817021f | 427 | } |
| 3da84173 | 428 | |
| 6a4c89f9 JV |
429 | /** |
| 430 | * Format the TCPDF page settings (margins, etc) | |
| 431 | * | |
| 432 | * @param $pdf | |
| 433 | * current TCPDF object | |
| 434 | * @see theme_print_pdf_tcpdf_page() | |
| 435 | */ | |
| 3a1f33ce | 436 | function theme_print_pdf_tcpdf_page(&$pdf) { |
| b09f08f7 | 437 | // set margins |
| 4817021f | 438 | $pdf->SetMargins(15, 20, 15); |
| c67b9ed4 | 439 | // set auto page breaks |
| 4817021f | 440 | $pdf->SetAutoPageBreak(TRUE, 15); |
| b09f08f7 | 441 | // set image scale factor |
| 3a24b895 JV |
442 | sscanf(PDF_PRODUCER, "TCPDF %d.%d.%d", $major, $minor, $build); |
| 443 | $imagescale = (($major >= 4) && ($minor >= 6) && ($build >= 2)) ? 1 : 4; | |
| 444 | $pdf->setImageScale($imagescale); | |
| 973f5b72 JV |
445 | // set image compression quality |
| 446 | $pdf->setJPEGQuality(100); | |
| 1024f54b JV |
447 | |
| 448 | return $pdf; | |
| 4817021f | 449 | } |
| 973f5b72 | 450 | |
| 6a4c89f9 JV |
451 | /** |
| 452 | * Format the TCPDF page content | |
| 453 | * | |
| 454 | * @param $pdf | |
| 455 | * current TCPDF object | |
| 456 | * @param $html | |
| 457 | * contents of the body of the HTML from the original node | |
| 458 | * @param $font | |
| 459 | * array with the font definition (font name, styles and size) | |
| 460 | * @see theme_print_pdf_tcpdf_content() | |
| 461 | */ | |
| 3a1f33ce | 462 | function theme_print_pdf_tcpdf_content(&$pdf, &$html, $font) { |
| 4817021f JV |
463 | // set content font |
| 464 | $pdf->setFont($font[0], $font[1], $font[2]); | |
| b09f08f7 | 465 | |
| 26673803 | 466 | preg_match('!<body.*?>(.*)</body>!sim', $html, $matches); |
| 4817021f | 467 | $pattern = '!(?:<div class="print-(?:logo|site_name|breadcrumb|footer)">.*?</div>|<hr class="print-hr" />)!si'; |
| 3da84173 JV |
468 | $matches[1] = preg_replace($pattern, '', $matches[1]); |
| 469 | ||
| f76a10f2 JV |
470 | // Make CCK fields look better |
| 471 | $matches[1] = preg_replace('!(<div class="field.*?>)\s*!sm', '$1', $matches[1]); | |
| 472 | $matches[1] = preg_replace('!(<div class="field.*?>.*?</div>)\s*!sm', '$1', $matches[1]); | |
| 473 | $matches[1] = preg_replace('!<div( class="field-label.*?>.*?)</div>!sm', '<strong$1</strong>', $matches[1]); | |
| 474 | ||
| 4817021f | 475 | // Since TCPDF's writeHTML is so bad with <p>, do everything possible to make it look nice |
| 57b1d44f | 476 | $matches[1] = preg_replace('!<(?:p(|\s+.*?)/?|/p)>!i', '<br$1 />', $matches[1]); |
| e83e4f36 | 477 | $matches[1] = str_replace(array('<div', 'div>'), array('<span', 'span><br />'), $matches[1]); |
| f76a10f2 JV |
478 | do { |
| 479 | $prev = $matches[1]; | |
| 480 | $matches[1] = preg_replace('!(</span>)<br />(\s*?</span><br />)!s', '$1$2', $matches[1]); | |
| 481 | } while ($prev != $matches[1]); | |
| e83e4f36 | 482 | |
| a01ab7bd | 483 | @$pdf->writeHTML($matches[1]); |
| 1024f54b JV |
484 | |
| 485 | return $pdf; | |
| 4817021f | 486 | } |
| b09f08f7 | 487 | |
| 6a4c89f9 JV |
488 | /** |
| 489 | * Format the TCPDF footer contents | |
| 490 | * | |
| 491 | * @param $pdf | |
| 492 | * current TCPDF object | |
| 493 | * @param $html | |
| 494 | * contents of the body of the HTML from the original node | |
| 495 | * @param $font | |
| 496 | * array with the font definition (font name, styles and size) | |
| 497 | * @see theme_print_pdf_tcpdf_footer() | |
| 498 | */ | |
| 3a1f33ce | 499 | function theme_print_pdf_tcpdf_footer(&$pdf, &$html, $font) { |
| b97f7b85 JV |
500 | preg_match('!<div class="print-footer">(.*?)</div>!si', $html, $tpl_footer); |
| 501 | $footer = trim(preg_replace('!</?div[^>]*?>!i', '', $tpl_footer[1])); | |
| 2c779f90 | 502 | |
| 4817021f JV |
503 | // set footer font |
| 504 | $font[2] *= 0.8; | |
| 505 | $pdf->setFooterFont($font); | |
| 506 | // set footer margin | |
| 507 | $pdf->SetFooterMargin(10); | |
| 508 | // set footer data | |
| b97f7b85 | 509 | $pdf->SetFooterData($footer); |
| 1024f54b JV |
510 | |
| 511 | return $pdf; | |
| b09f08f7 | 512 | } |
| 6a4c89f9 JV |
513 | |
| 514 | /** | |
| 515 | * Format the TCPDF footer layout | |
| 516 | * | |
| 517 | * @param $pdf | |
| 518 | * current TCPDF object | |
| 519 | * @see theme_print_pdf_tcpdf_footer2() | |
| 520 | */ | |
| 3a1f33ce | 521 | function theme_print_pdf_tcpdf_footer2(&$pdf) { |
| 6a4c89f9 | 522 | //Position at 1.5 cm from bottom |
| 4eb16937 | 523 | $pdf->writeHTMLCell(0, 15, 15, -10, $pdf->footer, 0, 0, 0, TRUE, ''); |
| 6a4c89f9 JV |
524 | |
| 525 | $ormargins = $pdf->getOriginalMargins(); | |
| b97f7b85 | 526 | $pagenumtxt = t('Page !n of !total', array('!n' => $pdf->PageNo(), '!total' => $pdf->getAliasNbPages())); |
| 6a4c89f9 JV |
527 | //Print page number |
| 528 | if ($pdf->getRTL()) { | |
| 529 | $pdf->SetX($ormargins['right']); | |
| 530 | $pdf->Cell(0, 10, $pagenumtxt, 'T', 0, 'L'); | |
| 531 | } | |
| 532 | else { | |
| 533 | $pdf->SetX($ormargins['left']); | |
| 534 | $pdf->Cell(0, 10, $pagenumtxt, 'T', 0, 'R'); | |
| 535 | } | |
| 1024f54b JV |
536 | |
| 537 | return $pdf; | |
| 6a4c89f9 | 538 | } |