1
|
<?php
|
2
|
|
3
|
/**
|
4
|
* @file
|
5
|
* Generates the PDF version using dompdf.
|
6
|
*
|
7
|
* This file is included by the print_pdf_dompdf module and includes the
|
8
|
* functions that interface with the dompdf library.
|
9
|
*
|
10
|
* @ingroup print
|
11
|
*/
|
12
|
|
13
|
/**
|
14
|
* Implements hook_print_pdf_generate().
|
15
|
*/
|
16
|
function print_pdf_dompdf_print_pdf_generate($html, $meta, $paper_size = NULL, $page_orientation = NULL) {
|
17
|
module_load_include('inc', 'print', 'includes/print');
|
18
|
|
19
|
$pdf_tool = explode('|', variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT));
|
20
|
if (empty($paper_size)) {
|
21
|
$paper_size = variable_get('print_pdf_paper_size', PRINT_PDF_PAPER_SIZE_DEFAULT);
|
22
|
}
|
23
|
if (empty($page_orientation)) {
|
24
|
$page_orientation = variable_get('print_pdf_page_orientation', PRINT_PDF_PAGE_ORIENTATION_DEFAULT);
|
25
|
}
|
26
|
$images_via_file = variable_get('print_pdf_images_via_file', PRINT_PDF_IMAGES_VIA_FILE_DEFAULT);
|
27
|
$unicode = TRUE;
|
28
|
|
29
|
if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
|
30
|
$font_subsetting = variable_get('print_pdf_dompdf_font_subsetting', PRINT_PDF_DOMPDF_FONT_SUBSETTING_DEFAULT);
|
31
|
$unicode = variable_get('print_pdf_dompdf_unicode', PRINT_PDF_DOMPDF_UNICODE_DEFAULT);
|
32
|
|
33
|
if (!defined('DOMPDF_ENABLE_PHP')) {
|
34
|
define('DOMPDF_ENABLE_PHP', FALSE);
|
35
|
}
|
36
|
if (!defined('DOMPDF_ENABLE_REMOTE')) {
|
37
|
define('DOMPDF_ENABLE_REMOTE', TRUE);
|
38
|
}
|
39
|
if (!defined('DOMPDF_TEMP_DIR')) {
|
40
|
define('DOMPDF_TEMP_DIR', file_directory_temp());
|
41
|
}
|
42
|
if (!defined('DOMPDF_UNICODE_ENABLED')) {
|
43
|
define('DOMPDF_UNICODE_ENABLED', $unicode);
|
44
|
}
|
45
|
if (!defined('DOMPDF_ENABLE_FONTSUBSETTING')) {
|
46
|
define('DOMPDF_ENABLE_FONTSUBSETTING', $font_subsetting);
|
47
|
}
|
48
|
if (!defined('DOMPDF_FONT_CACHE')) {
|
49
|
define('DOMPDF_FONT_CACHE', drupal_realpath('public://print_pdf/print_pdf_dompdf/fonts/'));
|
50
|
}
|
51
|
}
|
52
|
|
53
|
$version = print_pdf_dompdf_pdf_tool_version($pdf_tool[1]);
|
54
|
if (version_compare($version, '0.7', '<')) {
|
55
|
// Version of dompdf is 0.6.* or 0.5.*.
|
56
|
if (version_compare($version, '0.6', '<')) {
|
57
|
// Version of dompdf is 0.5.
|
58
|
spl_autoload_register('DOMPDF_autoload');
|
59
|
}
|
60
|
// Earlier dompdf versions could generate xml errors. Tell libxml to
|
61
|
// hide them.
|
62
|
libxml_use_internal_errors(TRUE);
|
63
|
$dompdf = new DOMPDF();
|
64
|
}
|
65
|
else {
|
66
|
// Version of dompdf is >= 0.7.
|
67
|
$tool_path = dirname($pdf_tool[1]) . '/../autoload.inc.php';
|
68
|
if (file_exists($tool_path)) {
|
69
|
require_once $tool_path;
|
70
|
}
|
71
|
else {
|
72
|
watchdog('print_pdf', 'Configured PDF tool does not exist at path: %path', array('%path' => $tool_path), WATCHDOG_ERROR);
|
73
|
throw new Exception("Configured PDF tool does not exist, unable to generate PDF.");
|
74
|
}
|
75
|
|
76
|
$dompdf = new \Dompdf\Dompdf();
|
77
|
$unicode = TRUE;
|
78
|
|
79
|
if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
|
80
|
$dompdf->set_option('enable_php', FALSE);
|
81
|
$dompdf->set_option('enable_remote', TRUE);
|
82
|
$dompdf->set_option('temp_dir', file_directory_temp());
|
83
|
$dompdf->set_option('enable_font_subsetting', $font_subsetting);
|
84
|
$dompdf->set_option('font_cache', drupal_realpath('public://print_pdf/print_pdf_dompdf/fonts/'));
|
85
|
}
|
86
|
}
|
87
|
|
88
|
// Try to use local file access for image files.
|
89
|
$html = _print_access_images_via_file($html, $images_via_file);
|
90
|
// Remove all scripts due to security concerns.
|
91
|
$html = preg_replace('!<script(.*?)>(.*?)</script>!is', '', $html);
|
92
|
|
93
|
// Spaces in img URLs must be replaced with %20, when using external access.
|
94
|
if (!$images_via_file) {
|
95
|
$pattern = '!<(img\s[^>]*?)>!is';
|
96
|
$html = preg_replace_callback($pattern, '_print_replace_spaces', $html);
|
97
|
}
|
98
|
|
99
|
// It seems dompdf has problems with something in system.css, don't use it.
|
100
|
$html = preg_replace('!<link.*?modules/system/system.css.*?/>!', '', $html);
|
101
|
|
102
|
$url_array = parse_url($meta['url']);
|
103
|
|
104
|
$protocol = $url_array['scheme'] . '://';
|
105
|
$host = $url_array['host'];
|
106
|
$path = dirname($url_array['path']) . '/';
|
107
|
|
108
|
$dompdf->set_base_path($path);
|
109
|
$dompdf->set_host($host);
|
110
|
$dompdf->set_paper(drupal_strtolower($paper_size), $page_orientation);
|
111
|
$dompdf->set_protocol($protocol);
|
112
|
|
113
|
// It seems dompdf can't handle footers cleanly, so disable the following.
|
114
|
/* $html = theme('print_pdf_dompdf_footer', array('html' => $html)); */
|
115
|
|
116
|
// If dompdf Unicode support is disabled, try to convert to ISO-8859-1 and
|
117
|
// then to HTML entities.
|
118
|
if (!$unicode) {
|
119
|
// Convert the euro sign to an HTML entity.
|
120
|
$html = str_replace('€', '€', $html);
|
121
|
|
122
|
// Convert from UTF-8 to ISO 8859-1 and then to HTML entities.
|
123
|
if (function_exists('utf8_decode')) {
|
124
|
$html = utf8_decode($html);
|
125
|
}
|
126
|
// iconv fails silently when it encounters something that it doesn't know,
|
127
|
// so don't use it.
|
128
|
/*
|
129
|
else if (function_exists('iconv')) {
|
130
|
$html = iconv('UTF-8', 'ISO-8859-1', $html);
|
131
|
}
|
132
|
*/
|
133
|
elseif (function_exists('mb_convert_encoding')) {
|
134
|
$html = mb_convert_encoding($html, 'ISO-8859-1', 'UTF-8');
|
135
|
}
|
136
|
elseif (function_exists('recode_string')) {
|
137
|
$html = recode_string('UTF-8..ISO_8859-1', $html);
|
138
|
}
|
139
|
$html = htmlspecialchars_decode(htmlentities($html, ENT_NOQUOTES, 'ISO-8859-1'), ENT_NOQUOTES);
|
140
|
}
|
141
|
else {
|
142
|
// Otherwise, ensure the content is properly formatted Unicode.
|
143
|
$html = mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8');
|
144
|
}
|
145
|
|
146
|
// Must get rid of tbody (dompdf goes into recursion).
|
147
|
$html = preg_replace('!<tbody[^>]*?>|</tbody>!i', '', $html);
|
148
|
|
149
|
$dompdf->load_html($html);
|
150
|
|
151
|
$dompdf->render();
|
152
|
return $dompdf->output();
|
153
|
}
|
154
|
|
155
|
/**
|
156
|
* Format the dompdf footer contents.
|
157
|
*
|
158
|
* @param array $vars
|
159
|
* An associative array containing:
|
160
|
* - $html: contents of the body of the HTML from the original node.
|
161
|
*
|
162
|
* @return string
|
163
|
* customized HTML text
|
164
|
*
|
165
|
* @ingroup themeable
|
166
|
* @ingroup print_themeable
|
167
|
*/
|
168
|
function theme_print_pdf_dompdf_footer($vars) {
|
169
|
preg_match('!<div class="print-footer">(.*?)</div>!si', $vars['html'], $tpl_footer);
|
170
|
if (isset($tpl_footer[1])) {
|
171
|
$html = str_replace($tpl_footer[0], '', $vars['html']);
|
172
|
|
173
|
$text = '<script type="text/php">
|
174
|
if (isset($pdf)) {
|
175
|
$font = Font_Metrics::get_font("verdana");;
|
176
|
$size = 10;
|
177
|
$color = array(0,0,0);
|
178
|
$text_height = Font_Metrics::get_font_height($font, $size);
|
179
|
|
180
|
$w = $pdf->get_width();
|
181
|
$h = $pdf->get_height();
|
182
|
|
183
|
$footer = $pdf->open_object();
|
184
|
|
185
|
// Draw a line along the bottom
|
186
|
$y = $h - 25;
|
187
|
$pdf->line(15, $y, $w - 15, $y, $color, 1);
|
188
|
|
189
|
$y += $text_height / 2;
|
190
|
$pdf->page_text(15, $y, \'' . addslashes(strip_tags($tpl_footer[1])) . '\', $font, $size, $color);
|
191
|
|
192
|
$pdf->close_object();
|
193
|
$pdf->add_object($footer, "all");
|
194
|
|
195
|
// Center the text
|
196
|
$width = Font_Metrics::get_text_width("Page 1 of 2", $font, $size);
|
197
|
$pagenumtxt = t("Page !n of !total", array("!n" => "{PAGE_NUM}", "!total" => "{PAGE_COUNT}"));
|
198
|
$pdf->page_text($w - 15 - $width, $y, $pagenumtxt, $font, $size, $color);
|
199
|
}
|
200
|
</script>';
|
201
|
|
202
|
return str_replace("<body>", "<body>" . $text, $html);
|
203
|
}
|
204
|
else {
|
205
|
return $vars['html'];
|
206
|
}
|
207
|
}
|