| 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. | |
| 10 | */ | |
| b09f08f7 | 11 | |
| 2c3f06f7 | 12 | require_once(DRUPAL_ROOT .'/'. drupal_get_path('module', 'print') .'/print.pages.inc'); |
| b09f08f7 | 13 | |
| 6a4c89f9 JV |
14 | /** |
| 15 | * Generate a PDF version of the printer-friendly page | |
| 16 | * | |
| 17 | * @see print_controller() | |
| 18 | * @see _print_get_template() | |
| 19 | * @see _print_pdf_dompdf() | |
| 20 | * @see _print_pdf_tcpdf() | |
| 21 | */ | |
| b09f08f7 | 22 | function print_pdf_controller() { |
| e60934b7 JV |
23 | global $base_url; |
| 24 | ||
| 5b1b9562 | 25 | $args = func_get_args(); |
| 3c90dace | 26 | // Remove the printpdf/ prefix |
| 5b1b9562 | 27 | $path = implode('/', $args); |
| 20ab24e6 | 28 | $cid = isset($_GET['comment']) ? (int)$_GET['comment'] : NULL; |
| 3c90dace | 29 | |
| 7d62e7c4 | 30 | $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT); |
| b09f08f7 | 31 | |
| 0706a465 | 32 | $print = print_controller($path, $cid); |
| 5c9469df JV |
33 | if ($print === FALSE) { |
| 34 | return; | |
| 35 | } | |
| 36 | ||
| b09f08f7 | 37 | // Img elements must be set to absolute |
| 7d62e7c4 JV |
38 | $pattern = '!<(img\s[^>]*?)>!is'; |
| 39 | $print['content'] = preg_replace_callback($pattern, '_print_rewrite_urls', $print['content']); | |
| 40 | $print['logo'] = preg_replace_callback($pattern, '_print_rewrite_urls', $print['logo']); | |
| 41 | $print['footer_message'] = preg_replace_callback($pattern, '_print_rewrite_urls', $print['footer_message']); | |
| e60934b7 JV |
42 | // And converted from private to public paths |
| 43 | $file_downloads = variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC); | |
| 44 | if ($file_downloads == FILE_DOWNLOADS_PRIVATE) { | |
| 968f9c90 | 45 | $pattern = "!(<img\s[^>]*?src\s*?=\s*?['\"]?)${base_url}/(?:(?:index.php)?\?q=)?system/files(/[^>]*?>)!is"; |
| 44d16177 | 46 | $replacement = '$1file://'. realpath(file_directory_path()) .'$2'; |
| e60934b7 JV |
47 | $print['content'] = preg_replace($pattern, $replacement, $print['content']); |
| 48 | $print['logo'] = preg_replace($pattern, $replacement, $print['logo']); | |
| 49 | $print['footer_message'] = preg_replace($pattern, $replacement, $print['footer_message']); | |
| 50 | } | |
| b09f08f7 | 51 | |
| 7d62e7c4 | 52 | $node = $print['node']; |
| 1caf9f9d | 53 | ob_start(); |
| 2c3f06f7 | 54 | include_once(DRUPAL_ROOT .'/'. _print_get_template('pdf', $print['type'])); |
| 1caf9f9d JV |
55 | $html = ob_get_contents(); |
| 56 | ob_end_clean(); | |
| 57 | ||
| 7d62e7c4 JV |
58 | if (basename($print_pdf_pdf_tool) == 'dompdf_config.inc.php') { |
| 59 | _print_pdf_dompdf($print, $html, $path .'.pdf'); | |
| b09f08f7 | 60 | } |
| 7d62e7c4 JV |
61 | elseif (basename($print_pdf_pdf_tool) == 'tcpdf.php') { |
| 62 | _print_pdf_tcpdf($print, $html, $path .'.pdf'); | |
| b09f08f7 JV |
63 | } |
| 64 | else { | |
| 65 | return drupal_not_found(); | |
| 66 | } | |
| 67 | } | |
| 68 | ||
| 6a4c89f9 JV |
69 | /** |
| 70 | * Generate the PDF file using the dompdf library | |
| 71 | * | |
| 72 | * @param $print | |
| 73 | * array containing the configured data | |
| 74 | * @param $html | |
| 75 | * contents of the post-processed template already with the node data | |
| 76 | * @param $filename | |
| 77 | * name of the PDF file to be generated | |
| 78 | * @see print_pdf_controller() | |
| 79 | */ | |
| 1caf9f9d | 80 | function _print_pdf_dompdf($print, $html, $filename) { |
| 7d62e7c4 JV |
81 | $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT); |
| 82 | $print_pdf_paper_size = variable_get('print_pdf_paper_size', PRINT_PDF_PAPER_SIZE_DEFAULT); | |
| 83 | $print_pdf_page_orientation = variable_get('print_pdf_page_orientation', PRINT_PDF_PAGE_ORIENTATION_DEFAULT); | |
| 84 | $print_pdf_content_disposition = variable_get('print_pdf_content_disposition', PRINT_PDF_CONTENT_DISPOSITION_DEFAULT); | |
| 2c3f06f7 | 85 | require_once(DRUPAL_ROOT .'/'. $print_pdf_pdf_tool); |
| b09f08f7 | 86 | |
| 893ee70f JV |
87 | // dompdf seems to have problems with something in system.css so let's not use it |
| 88 | $html = preg_replace('!<link.*?modules/system/system.css.*?/>!', '', $html); | |
| 89 | ||
| 56bdd124 JV |
90 | $url_array = parse_url($print['url']); |
| 91 | ||
| 3483245d | 92 | $protocol = $url_array['scheme'] .'://'; |
| 56bdd124 | 93 | $host = $url_array['host']; |
| 3483245d | 94 | $path = dirname($url_array['path']) .'/'; |
| b09f08f7 JV |
95 | |
| 96 | $dompdf = new DOMPDF(); | |
| 56bdd124 JV |
97 | $dompdf->set_base_path($path); |
| 98 | $dompdf->set_host($host); | |
| 6a4c89f9 | 99 | $dompdf->set_paper(drupal_strtolower($print_pdf_paper_size), $print_pdf_page_orientation); |
| 56bdd124 JV |
100 | $dompdf->set_protocol($protocol); |
| 101 | ||
| b97f7b85 JV |
102 | $html = theme('print_pdf_dompdf_footer', $html); |
| 103 | ||
| d356106f | 104 | // Convert from UTF-8 to ISO-8859-1 and then to HTML entities |
| 571e2ce9 JV |
105 | $all_entities = get_html_translation_table(HTML_ENTITIES, ENT_NOQUOTES); |
| 106 | $special_entities = get_html_translation_table(HTML_SPECIALCHARS, ENT_NOQUOTES); | |
| 107 | $no_tags = array_diff($all_entities, $special_entities); | |
| 108 | $html = strtr(utf8_decode($html), $no_tags); | |
| d356106f JV |
109 | |
| 110 | $dompdf->load_html($html); | |
| 3483245d | 111 | |
| b09f08f7 | 112 | $dompdf->render(); |
| 7d62e7c4 | 113 | $dompdf->stream($filename, array('Attachment' => ($print_pdf_content_disposition == 2))); |
| b09f08f7 JV |
114 | } |
| 115 | ||
| 6a4c89f9 JV |
116 | /** |
| 117 | * Generate the PDF file using the TCPDF library | |
| 118 | * | |
| 119 | * @param $print | |
| 120 | * array containing the configured data | |
| 121 | * @param $html | |
| 122 | * contents of the post-processed template already with the node data | |
| 123 | * @param $filename | |
| 124 | * name of the PDF file to be generated | |
| 125 | * @see print_pdf_controller() | |
| 126 | */ | |
| 1caf9f9d | 127 | function _print_pdf_tcpdf($print, $html, $filename) { |
| dc300af6 | 128 | global $base_url; |
| 7d62e7c4 JV |
129 | $print_pdf_pdf_tool = variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT); |
| 130 | $print_pdf_paper_size = variable_get('print_pdf_paper_size', PRINT_PDF_PAPER_SIZE_DEFAULT); | |
| 131 | $print_pdf_page_orientation = variable_get('print_pdf_page_orientation', PRINT_PDF_PAGE_ORIENTATION_DEFAULT); | |
| 132 | $print_pdf_content_disposition = variable_get('print_pdf_content_disposition', PRINT_PDF_CONTENT_DISPOSITION_DEFAULT); | |
| 133 | ||
| 4817021f JV |
134 | $pdf_tool_path = realpath(dirname($print_pdf_pdf_tool)); |
| 135 | ||
| 7d62e7c4 | 136 | define('K_TCPDF_EXTERNAL_CONFIG', TRUE); |
| dc300af6 JV |
137 | define('K_PATH_MAIN', dirname($_SERVER['SCRIPT_FILENAME'])); |
| 138 | define('K_PATH_URL', $base_url); | |
| 4817021f JV |
139 | define('K_PATH_FONTS', $pdf_tool_path .'/fonts/'); |
| 140 | define('K_PATH_CACHE', $pdf_tool_path .'/cache/'); | |
| 141 | define('K_PATH_IMAGES', ''); | |
| 142 | define('K_BLANK_IMAGE', $pdf_tool_path .'/images/_blank.png'); | |
| 7d62e7c4 JV |
143 | define('K_CELL_HEIGHT_RATIO', 1.25); |
| 144 | define('K_SMALL_RATIO', 2/3); | |
| 145 | ||
| 2c3f06f7 | 146 | require_once(DRUPAL_ROOT .'/'. $print_pdf_pdf_tool); |
| e03112ed | 147 | if (strpos(PDF_PRODUCER, 'PHP4') === FALSE) { |
| 2c3f06f7 | 148 | require_once(DRUPAL_ROOT .'/'. drupal_get_path('module', 'print_pdf') .'/print_pdf.class.inc'); |
| 90263e69 JV |
149 | } |
| 150 | else { | |
| 6936e5f6 JV |
151 | drupal_set_message(t("The PHP4 version of TCPDF is not supported. Please upgrade it."), 'error', FALSE); |
| 152 | drupal_goto($_GET['q']); | |
| 90263e69 | 153 | } |
| 7d62e7c4 | 154 | |
| 455e82fd JV |
155 | $font = Array( |
| 156 | variable_get('print_pdf_font_family', PRINT_PDF_FONT_FAMILY_DEFAULT), | |
| b2a85b2b | 157 | '', |
| 455e82fd JV |
158 | variable_get('print_pdf_font_size', PRINT_PDF_FONT_SIZE_DEFAULT), |
| 159 | ); | |
| 6a4c89f9 | 160 | $orientation = drupal_strtoupper($print_pdf_page_orientation[0]); |
| 56bdd124 JV |
161 | |
| 162 | // create new PDF document | |
| 3da84173 | 163 | $pdf = new PrintTCPDF($orientation , 'mm', $print_pdf_paper_size, TRUE); |
| b09f08f7 | 164 | |
| 56bdd124 | 165 | // set document information |
| 7d62e7c4 JV |
166 | $pdf->SetAuthor(strip_tags($print['submitted'])); |
| 167 | $pdf->SetCreator(variable_get('site_name', 'Drupal')); | |
| 168 | $pdf->SetTitle($print['title']); | |
| 169 | $keys = implode(' ', explode("\n", trim(strip_tags($print['taxonomy'])))); | |
| 56bdd124 | 170 | $pdf->SetKeywords($keys); |
| 7d62e7c4 | 171 | $pdf->setPDFVersion('1.6'); |
| 56bdd124 | 172 | |
| 1024f54b JV |
173 | $pdf = theme('print_pdf_tcpdf_header', $pdf, $html, $font); |
| 174 | $pdf = theme('print_pdf_tcpdf_footer', $pdf, $html, $font); | |
| 175 | $pdf = theme('print_pdf_tcpdf_page', $pdf); | |
| 4817021f JV |
176 | |
| 177 | //initialize document | |
| 178 | $pdf->AliasNbPages(); | |
| 179 | ||
| 180 | // add a page | |
| 181 | $pdf->AddPage(); | |
| 182 | ||
| 1024f54b | 183 | $pdf = theme('print_pdf_tcpdf_content', $pdf, $html, $font); |
| 4817021f JV |
184 | |
| 185 | // reset pointer to the last page | |
| 186 | $pdf->lastPage(); | |
| 187 | ||
| 188 | //Close and output PDF document | |
| 189 | $output_dest = ($print_pdf_content_disposition == 2) ? 'D' : 'I'; | |
| 190 | $pdf->Output($filename, $output_dest); | |
| 191 | } | |
| 192 | ||
| 6a4c89f9 | 193 | /** |
| b97f7b85 JV |
194 | * Format the dompdf footer contents |
| 195 | * | |
| 196 | * @param $html | |
| 197 | * contents of the body of the HTML from the original node | |
| 198 | * @see theme_print_pdf_tcpdf_footer() | |
| 199 | */ | |
| 3a1f33ce | 200 | function theme_print_pdf_dompdf_footer(&$html) { |
| b97f7b85 JV |
201 | preg_match('!<div class="print-footer">(.*?)</div>!si', $html, $tpl_footer); |
| 202 | $html = str_replace($tpl_footer[0], '', $html); | |
| 203 | ||
| 204 | $text = '<script type="text/php"> | |
| 205 | if (isset($pdf)) { | |
| 206 | $font = Font_Metrics::get_font("verdana");; | |
| 207 | $size = 10; | |
| 208 | $color = array(0,0,0); | |
| 209 | $text_height = Font_Metrics::get_font_height($font, $size); | |
| 210 | ||
| 211 | $w = $pdf->get_width(); | |
| 212 | $h = $pdf->get_height(); | |
| 213 | ||
| 214 | $footer = $pdf->open_object(); | |
| 215 | ||
| 216 | // Draw a line along the bottom | |
| 217 | $y = $h - 25; | |
| 218 | $pdf->line(15, $y, $w - 15, $y, $color, 1); | |
| 219 | ||
| 220 | $y += $text_height / 2; | |
| 38b1c723 | 221 | $pdf->page_text(15, $y, \''. addslashes(strip_tags($tpl_footer[1])) .'\', $font, $size, $color); |
| b97f7b85 JV |
222 | |
| 223 | $pdf->close_object(); | |
| 224 | $pdf->add_object($footer, "all"); | |
| 225 | ||
| 226 | // Center the text | |
| 227 | $width = Font_Metrics::get_text_width("Page 1 of 2", $font, $size); | |
| 228 | $pagenumtxt = t("Page !n of !total", array("!n" => "{PAGE_NUM}", "!total" => "{PAGE_COUNT}")); | |
| 229 | $pdf->page_text($w - 15 - $width, $y, $pagenumtxt, $font, $size, $color); | |
| 230 | } | |
| 231 | </script>'; | |
| 232 | ||
| 233 | return str_replace("<body>", "<body>" . $text, $html); | |
| 234 | } | |
| 235 | ||
| 236 | /** | |
| 6a4c89f9 JV |
237 | * Format the TCPDF header |
| 238 | * | |
| 239 | * @param $pdf | |
| 240 | * current TCPDF object | |
| 241 | * @param $html | |
| 242 | * contents of the body of the HTML from the original node | |
| 243 | * @param $font | |
| 244 | * array with the font definition (font name, styles and size) | |
| 245 | * @see theme_print_pdf_tcpdf_header() | |
| 246 | */ | |
| 3a1f33ce | 247 | function theme_print_pdf_tcpdf_header(&$pdf, &$html, $font) { |
| 4817021f JV |
248 | preg_match('!<div class="print-logo">(.*?)</div>!si', $html, $tpl_logo); |
| 249 | preg_match('!<h1 class="print-title">(.*?)</h1>!si', $html, $tpl_title); | |
| 250 | preg_match('!<div class="print-site_name">(.*?)</div>!si', $html, $tpl_site_name); | |
| 251 | ||
| 74df721a | 252 | $ratio = 0; |
| 4817021f JV |
253 | $logo = ''; |
| 254 | $logo_ret = preg_match('!src\s*=\s*(\'.*?\'|".*?"|[^\s]*)!i', $tpl_logo[1], $matches); | |
| 3da84173 JV |
255 | if ($logo_ret) { |
| 256 | $logo = trim($matches[1], '\'"'); | |
| 4817021f | 257 | $size = getimagesize($logo); |
| c64555f4 | 258 | $ratio = $size ? ($size[0] / $size[1]) : 0; |
| 3da84173 JV |
259 | } |
| 260 | ||
| 4817021f JV |
261 | // set header font |
| 262 | $pdf->setHeaderFont($font); | |
| 263 | // set header margin | |
| 264 | $pdf->SetHeaderMargin(5); | |
| 56bdd124 | 265 | // set header data |
| 4817021f | 266 | $pdf->SetHeaderData($logo, 10 * $ratio, $tpl_title[1], strip_tags($tpl_site_name[1])); |
| 1024f54b JV |
267 | |
| 268 | return $pdf; | |
| 4817021f | 269 | } |
| 3da84173 | 270 | |
| 6a4c89f9 JV |
271 | /** |
| 272 | * Format the TCPDF page settings (margins, etc) | |
| 273 | * | |
| 274 | * @param $pdf | |
| 275 | * current TCPDF object | |
| 276 | * @see theme_print_pdf_tcpdf_page() | |
| 277 | */ | |
| 3a1f33ce | 278 | function theme_print_pdf_tcpdf_page(&$pdf) { |
| b09f08f7 | 279 | // set margins |
| 4817021f | 280 | $pdf->SetMargins(15, 20, 15); |
| c67b9ed4 | 281 | // set auto page breaks |
| 4817021f | 282 | $pdf->SetAutoPageBreak(TRUE, 15); |
| b09f08f7 | 283 | // set image scale factor |
| 75628d9a | 284 | $pdf->setImageScale(4); |
| 973f5b72 JV |
285 | // set image compression quality |
| 286 | $pdf->setJPEGQuality(100); | |
| 1024f54b JV |
287 | |
| 288 | return $pdf; | |
| 4817021f | 289 | } |
| 973f5b72 | 290 | |
| 6a4c89f9 JV |
291 | /** |
| 292 | * Format the TCPDF page content | |
| 293 | * | |
| 294 | * @param $pdf | |
| 295 | * current TCPDF object | |
| 296 | * @param $html | |
| 297 | * contents of the body of the HTML from the original node | |
| 298 | * @param $font | |
| 299 | * array with the font definition (font name, styles and size) | |
| 300 | * @see theme_print_pdf_tcpdf_content() | |
| 301 | */ | |
| 3a1f33ce | 302 | function theme_print_pdf_tcpdf_content(&$pdf, &$html, $font) { |
| 4817021f JV |
303 | // set content font |
| 304 | $pdf->setFont($font[0], $font[1], $font[2]); | |
| b09f08f7 | 305 | |
| 26673803 | 306 | preg_match('!<body.*?>(.*)</body>!sim', $html, $matches); |
| 4817021f | 307 | $pattern = '!(?:<div class="print-(?:logo|site_name|breadcrumb|footer)">.*?</div>|<hr class="print-hr" />)!si'; |
| 3da84173 JV |
308 | $matches[1] = preg_replace($pattern, '', $matches[1]); |
| 309 | ||
| 4817021f JV |
310 | // Since TCPDF's writeHTML is so bad with <p>, do everything possible to make it look nice |
| 311 | $matches[1] = preg_replace('!(<p\s*/>|</p>)!i', '<br />', $matches[1]); | |
| e83e4f36 JV |
312 | $matches[1] = str_replace(array('<div', 'div>'), array('<span', 'span><br />'), $matches[1]); |
| 313 | ||
| 314 | $pdf->writeHTML($matches[1]); | |
| 1024f54b JV |
315 | |
| 316 | return $pdf; | |
| 4817021f | 317 | } |
| b09f08f7 | 318 | |
| 6a4c89f9 JV |
319 | /** |
| 320 | * Format the TCPDF footer contents | |
| 321 | * | |
| 322 | * @param $pdf | |
| 323 | * current TCPDF object | |
| 324 | * @param $html | |
| 325 | * contents of the body of the HTML from the original node | |
| 326 | * @param $font | |
| 327 | * array with the font definition (font name, styles and size) | |
| 328 | * @see theme_print_pdf_tcpdf_footer() | |
| 329 | */ | |
| 3a1f33ce | 330 | function theme_print_pdf_tcpdf_footer(&$pdf, &$html, $font) { |
| b97f7b85 JV |
331 | preg_match('!<div class="print-footer">(.*?)</div>!si', $html, $tpl_footer); |
| 332 | $footer = trim(preg_replace('!</?div[^>]*?>!i', '', $tpl_footer[1])); | |
| 2c779f90 | 333 | |
| 4817021f JV |
334 | // set footer font |
| 335 | $font[2] *= 0.8; | |
| 336 | $pdf->setFooterFont($font); | |
| 337 | // set footer margin | |
| 338 | $pdf->SetFooterMargin(10); | |
| 339 | // set footer data | |
| b97f7b85 | 340 | $pdf->SetFooterData($footer); |
| 1024f54b JV |
341 | |
| 342 | return $pdf; | |
| b09f08f7 | 343 | } |
| 6a4c89f9 JV |
344 | |
| 345 | /** | |
| 346 | * Format the TCPDF footer layout | |
| 347 | * | |
| 348 | * @param $pdf | |
| 349 | * current TCPDF object | |
| 350 | * @see theme_print_pdf_tcpdf_footer2() | |
| 351 | */ | |
| 3a1f33ce | 352 | function theme_print_pdf_tcpdf_footer2(&$pdf) { |
| 6a4c89f9 | 353 | //Position at 1.5 cm from bottom |
| 90263e69 | 354 | $pdf->writeHTMLCell(0, 15, 15, 0, $pdf->footer, 0, 0, 0, TRUE, ''); |
| 6a4c89f9 JV |
355 | |
| 356 | $ormargins = $pdf->getOriginalMargins(); | |
| b97f7b85 | 357 | $pagenumtxt = t('Page !n of !total', array('!n' => $pdf->PageNo(), '!total' => $pdf->getAliasNbPages())); |
| 6a4c89f9 JV |
358 | //Print page number |
| 359 | if ($pdf->getRTL()) { | |
| 360 | $pdf->SetX($ormargins['right']); | |
| 361 | $pdf->Cell(0, 10, $pagenumtxt, 'T', 0, 'L'); | |
| 362 | } | |
| 363 | else { | |
| 364 | $pdf->SetX($ormargins['left']); | |
| 365 | $pdf->Cell(0, 10, $pagenumtxt, 'T', 0, 'R'); | |
| 366 | } | |
| 1024f54b JV |
367 | |
| 368 | return $pdf; | |
| 6a4c89f9 | 369 | } |