Project

General

Profile

Paste
Download (9.65 KB) Statistics
| Branch: | Revision:

root / drupal7 / sites / all / modules / print / print_pdf / lib_handlers / print_pdf_tcpdf / print_pdf_tcpdf.pages.inc @ 76bdcd04

1
<?php
2

    
3
/**
4
 * @file
5
 * Generates the PDF version using TCPDF.
6
 *
7
 * This file is included by the print_pdf_tcpdf module and includes the
8
 * functions that interface with the TCPDF library.
9
 *
10
 * @ingroup print
11
 */
12

    
13
/**
14
 * Implements hook_print_pdf_generate().
15
 */
16
function print_pdf_tcpdf_print_pdf_generate($html, $meta, $paper_size = NULL, $page_orientation = NULL) {
17
  global $base_url, $language;
18

    
19
  module_load_include('inc', 'print', 'includes/print');
20

    
21
  $pdf_tool = explode('|', variable_get('print_pdf_pdf_tool', PRINT_PDF_PDF_TOOL_DEFAULT));
22
  if (empty($paper_size)) {
23
    $paper_size = variable_get('print_pdf_paper_size', PRINT_PDF_PAPER_SIZE_DEFAULT);
24
  }
25
  if (empty($page_orientation)) {
26
    $page_orientation = variable_get('print_pdf_page_orientation', PRINT_PDF_PAGE_ORIENTATION_DEFAULT);
27
  }
28
  $images_via_file = variable_get('print_pdf_images_via_file', PRINT_PDF_IMAGES_VIA_FILE_DEFAULT);
29

    
30
  if (variable_get('print_pdf_autoconfig', PRINT_PDF_AUTOCONFIG_DEFAULT)) {
31
    $pdf_tool_path = realpath(dirname($pdf_tool[1]));
32

    
33
    if (!defined('K_TCPDF_EXTERNAL_CONFIG')) {
34
      define('K_TCPDF_EXTERNAL_CONFIG', TRUE);
35
    }
36
    if (!defined('K_PATH_MAIN')) {
37
      define('K_PATH_MAIN', DRUPAL_ROOT);
38
    }
39
    if (!defined('K_PATH_URL')) {
40
      define('K_PATH_URL', $base_url);
41
    }
42
    if (!defined('K_PATH_FONTS')) {
43
      define('K_PATH_FONTS', $pdf_tool_path . '/fonts/');
44
    }
45
    if (!defined('K_PATH_CACHE')) {
46
      define('K_PATH_CACHE', drupal_realpath('public://print_pdf/print_pdf_tcpdf/cache') . '/');
47
    }
48
    if (!defined('K_PATH_IMAGES')) {
49
      define('K_PATH_IMAGES', '');
50
    }
51
    if (!defined('K_BLANK_IMAGE')) {
52
      define('K_BLANK_IMAGE', $pdf_tool_path . '/images/_blank.png');
53
    }
54
    if (!defined('K_CELL_HEIGHT_RATIO')) {
55
      define('K_CELL_HEIGHT_RATIO', 1.25);
56
    }
57
    if (!defined('K_SMALL_RATIO')) {
58
      define('K_SMALL_RATIO', 2 / 3);
59
    }
60
  }
61

    
62
  // Try to use local file access for image files.
63
  $html = _print_access_images_via_file($html, $images_via_file);
64

    
65
  // Decode HTML entities in image filenames.
66
  $pattern = "!<img\s[^>]*?src\s*?=\s*?['\"]?{$base_url}[^>]*?>!is";
67
  $html = preg_replace_callback($pattern, create_function('$matches', 'return html_entity_decode($matches[0], ENT_QUOTES);'), $html);
68
  // Remove queries from the image URL.
69
  $pattern = "!(<img\s[^>]*?src\s*?=\s*?['\"]?{$base_url}[^>]*?)(?:%3F|\?)[^\s'\"]+([^>]*?>)!is";
70
  $html = preg_replace($pattern, '$1$2', $html);
71

    
72
  $tool_path = DRUPAL_ROOT . '/' . $pdf_tool[1];
73
  if (file_exists($tool_path)) {
74
    require_once $tool_path;
75
  }
76
  else {
77
    watchdog('print_pdf', 'Configured PDF tool does not exist at path: %path', array('%path' => $tool_path), WATCHDOG_ERROR);
78
    throw new Exception("Configured PDF tool does not exist, unable to generate PDF.");
79
  }
80
  module_load_include('inc', 'print_pdf_tcpdf', 'print_pdf_tcpdf.class');
81

    
82
  $font = array(
83
    check_plain(variable_get('print_pdf_font_family', PRINT_PDF_TCPDF_FONT_FAMILY_DEFAULT)),
84
    '',
85
    check_plain(variable_get('print_pdf_font_size', PRINT_PDF_TCPDF_FONT_SIZE_DEFAULT)),
86
  );
87
  $orientation = drupal_strtoupper($page_orientation[0]);
88

    
89
  // Create new PDF document.
90
  $pdf = new PrintTCPDF($orientation, 'mm', $paper_size, TRUE);
91

    
92
  // Set document information.
93
  if (isset($meta['name'])) {
94
    $pdf->SetAuthor(strip_tags($meta['name']));
95
  }
96
  $pdf->SetCreator(variable_get('site_name', 'Drupal'));
97
  $pdf->SetTitle(html_entity_decode($meta['title'], ENT_QUOTES, 'UTF-8'));
98
  $pdf->setPDFVersion('1.6');
99
  $pdf->setFontSubsetting(variable_get('print_pdf_font_subsetting', PRINT_PDF_TCPDF_FONT_SUBSETTING_DEFAULT));
100
  $pdf->setTcpdfLink(FALSE);
101

    
102
  if ($language->direction == LANGUAGE_RTL) {
103
    $pdf->setRTL(TRUE);
104
  }
105

    
106
  $pdf = theme('print_pdf_tcpdf_header', array(
107
    'pdf' => $pdf,
108
    'html' => $html,
109
    'font' => $font,
110
  ));
111
  $pdf = theme('print_pdf_tcpdf_footer', array(
112
    'pdf' => $pdf,
113
    'html' => $html,
114
    'font' => $font,
115
  ));
116
  $pdf = theme('print_pdf_tcpdf_page', array('pdf' => $pdf));
117

    
118
  // Enable third-party module to alter the pdf object, via
119
  // hook_print_pdf_tcpdf_alter().
120
  drupal_alter('print_pdf_tcpdf', $pdf, $html, $meta);
121

    
122
  // Add a page.
123
  $pdf->AddPage();
124

    
125
  $pdf = theme('print_pdf_tcpdf_content', array(
126
    'pdf' => $pdf,
127
    'html' => $html,
128
    'font' => $font,
129
  ));
130

    
131
  // Reset pointer to the last page.
132
  $pdf->lastPage();
133

    
134
  // Try to recover from any warning/error.
135
  ob_clean();
136

    
137
  return $pdf = $pdf->Output('', 'S');
138
}
139

    
140
/**
141
 * Format the TCPDF header.
142
 *
143
 * @param array $vars
144
 *   An associative array containing:
145
 *   - $pdf: current TCPDF object
146
 *   - $html: contents of the body of the HTML from the original node
147
 *   - $font: array with the font definition (font name, styles and size)
148
 *
149
 * @return object
150
 *   modified PDF object
151
 *
152
 * @ingroup themeable
153
 * @ingroup print_themeable
154
 */
155
function theme_print_pdf_tcpdf_header($vars) {
156
  global $base_url;
157

    
158
  $pdf = $vars['pdf'];
159
  preg_match('!<div class="print-logo">(.*?)</div>!si', $vars['html'], $tpl_logo);
160
  preg_match('!<title>(.*?)</title>!si', $vars['html'], $tpl_title);
161
  preg_match('!<div class="print-site_name">(.*?)</div>!si', $vars['html'], $tpl_site_name);
162

    
163
  $ratio = 0;
164
  $logo = '';
165
  if (isset($tpl_logo[1]) && preg_match('!src\s*=\s*(?:"(.*?)"|\'(.*?)\'|([^\s]*))!i', $tpl_logo[1], $logo_url)) {
166
    $logo = $logo_url[1];
167

    
168
    // Make logo relative again.
169
    $logo = preg_replace("!^$base_url(.*)!sm", DRUPAL_ROOT . '$1', $logo);
170

    
171
    if (!empty($logo)) {
172
      $size = getimagesize($logo);
173
      $ratio = $size ? ($size[0] / $size[1]) : 0;
174
    }
175
  }
176

    
177
  // Set header font.
178
  $pdf->setHeaderFont($vars['font']);
179
  // Set header margin.
180
  $pdf->setHeaderMargin(5);
181
  // Set header data.
182
  $pdf->setHeaderData($logo, 10 * $ratio, html_entity_decode($tpl_title[1], ENT_QUOTES, 'UTF-8'), html_entity_decode(strip_tags($tpl_site_name[1]), ENT_QUOTES, 'UTF-8'));
183

    
184
  return $pdf;
185
}
186

    
187
/**
188
 * Format the TCPDF page settings (margins, etc).
189
 *
190
 * @param array $vars
191
 *   An associative array containing:
192
 *   - $pdf: current TCPDF object.
193
 *
194
 * @return object
195
 *   modified PDF object
196
 *
197
 * @ingroup themeable
198
 * @ingroup print_themeable
199
 */
200
function theme_print_pdf_tcpdf_page($vars) {
201
  $pdf = $vars['pdf'];
202
  // Set margins.
203
  $pdf->SetMargins(15, 20, 15);
204
  // Set auto page breaks.
205
  $pdf->SetAutoPageBreak(TRUE, 15);
206
  // Set image scale factor.
207
  $pdf->setImageScale(1);
208
  // Set image compression quality.
209
  $pdf->setJPEGQuality(100);
210

    
211
  return $pdf;
212
}
213

    
214
/**
215
 * Format the TCPDF page content.
216
 *
217
 * @param array $vars
218
 *   An associative array containing:
219
 *   - $pdf: current TCPDF object
220
 *   - $html: contents of the body of the HTML from the original node
221
 *   - $font: array with the font definition (font name, styles and size)
222
 *
223
 * @return object
224
 *   modified PDF object
225
 *
226
 * @ingroup themeable
227
 * @ingroup print_themeable
228
 */
229
function theme_print_pdf_tcpdf_content($vars) {
230
  $pdf = $vars['pdf'];
231
  // Set content font.
232
  $pdf->setFont($vars['font'][0], $vars['font'][1], $vars['font'][2]);
233

    
234
  // Remove the logo, published, breadcrumb and footer from the main content.
235
  preg_match('!<body.*?>(.*)</body>!sim', $vars['html'], $matches);
236
  $pattern = '!(?:<div class="print-(?:logo|site_name|breadcrumb|footer)">.*?</div>|<hr class="print-hr" />)!si';
237
  $matches[1] = preg_replace($pattern, '', $matches[1]);
238

    
239
  // Make CCK fields look better.
240
  $matches[1] = preg_replace('!(<div class="field.*?>)\s*!sm', '$1', $matches[1]);
241
  $matches[1] = preg_replace('!(<div class="field.*?>.*?</div>)\s*!sm', '$1', $matches[1]);
242
  $matches[1] = preg_replace('!<div( class="field-label.*?>.*?)</div>!sm', '<strong$1</strong>', $matches[1]);
243

    
244
  // Since TCPDF's writeHTML is so bad with <p>, try to make it look nice.
245
  $matches[1] = preg_replace('!<(?:p(|\s+.*?)/?|/p)>!i', '<br$1 />', $matches[1]);
246
  $matches[1] = str_replace(array('<div', 'div>'), array('<span', 'span><br />'), $matches[1]);
247
  do {
248
    $prev = $matches[1];
249
    $matches[1] = preg_replace('!(</span>)<br />(\s*?</span><br />)!s', '$1$2', $matches[1]);
250
  } while ($prev != $matches[1]);
251

    
252
  @$pdf->writeHTML($matches[1]);
253

    
254
  return $pdf;
255
}
256

    
257
/**
258
 * Format the TCPDF footer contents.
259
 *
260
 * @param array $vars
261
 *   An associative array containing:
262
 *   - $pdf: current TCPDF object
263
 *   - $html: contents of the body of the HTML from the original node
264
 *   - $font: array with the font definition (font name, styles and size)
265
 *
266
 * @return object
267
 *   modified PDF object
268
 *
269
 * @ingroup themeable
270
 * @ingroup print_themeable
271
 */
272
function theme_print_pdf_tcpdf_footer($vars) {
273
  $pdf = $vars['pdf'];
274
  preg_match('!<div class="print-footer">(.*?)</div>!si', $vars['html'], $tpl_footer);
275

    
276
  if (isset($tpl_footer[1])) {
277
    $footer = trim(preg_replace('!</?div[^>]*?>!i', '', $tpl_footer[1]));
278

    
279
    // Set footer font.
280
    $vars['font'][2] *= 0.8;
281
    $pdf->setFooterFont($vars['font']);
282
    // Set footer margin.
283
    $pdf->SetFooterMargin(10);
284
    // Set footer data.
285
    $pdf->setFooterContent($footer);
286
  }
287

    
288
  return $pdf;
289
}
290

    
291
/**
292
 * Format the TCPDF footer layout.
293
 *
294
 * @param array $vars
295
 *   An associative array containing:
296
 *   - $pdf: current TCPDF object.
297
 *
298
 * @return object
299
 *   modified PDF object
300
 *
301
 * @ingroup themeable
302
 * @ingroup print_themeable
303
 */
304
function theme_print_pdf_tcpdf_footer2($vars) {
305
  $pdf = $vars['pdf'];
306
  // Position at 1.5 cm from bottom.
307
  $pdf->writeHTMLCell(0, 15, 15, $pdf->getPageHeight() - 15, $pdf->footer);
308

    
309
  $ormargins = $pdf->getOriginalMargins();
310
  $pagenumtxt = t('Page !n of !total', array('!n' => $pdf->PageNo(), '!total' => $pdf->getAliasNbPages()));
311
  // Print page number.
312
  if ($pdf->getRTL()) {
313
    $pdf->SetX($ormargins['right']);
314
    $pdf->Cell(0, 10, $pagenumtxt, 'T', 0, 'L');
315
  }
316
  else {
317
    $pdf->SetX($ormargins['left']);
318
    $pdf->Cell(0, 10, $pagenumtxt, 'T', 0, 'R');
319
  }
320

    
321
  return $pdf;
322
}