copyright and version fixes
[civicrm-core.git] / CRM / Utils / PDF / Utils.php
CommitLineData
6a488035
TO
1<?php
2/*
3 +--------------------------------------------------------------------+
232624b1 4 | CiviCRM version 4.4 |
6a488035
TO
5 +--------------------------------------------------------------------+
6 | Copyright CiviCRM LLC (c) 2004-2013 |
7 +--------------------------------------------------------------------+
8 | This file is a part of CiviCRM. |
9 | |
10 | CiviCRM is free software; you can copy, modify, and distribute it |
11 | under the terms of the GNU Affero General Public License |
12 | Version 3, 19 November 2007 and the CiviCRM Licensing Exception. |
13 | |
14 | CiviCRM is distributed in the hope that it will be useful, but |
15 | WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
17 | See the GNU Affero General Public License for more details. |
18 | |
19 | You should have received a copy of the GNU Affero General Public |
20 | License and the CiviCRM Licensing Exception along |
21 | with this program; if not, contact CiviCRM LLC |
22 | at info[AT]civicrm[DOT]org. If you have questions about the |
23 | GNU Affero General Public License or the licensing of CiviCRM, |
24 | see the CiviCRM license FAQ at http://civicrm.org/licensing |
25 +--------------------------------------------------------------------+
26*/
27
28/**
29 *
30 * @package CRM
31 * @copyright CiviCRM LLC (c) 2004-2013
32 * $Id$
33 *
34 */
35class CRM_Utils_PDF_Utils {
36
37 static function html2pdf(&$text, $fileName = 'civicrm.pdf', $output = FALSE, $pdfFormat = NULL) {
38 if (is_array($text)) {
39 $pages = &$text;
40 }
41 else {
42 $pages = array($text);
43 }
44 // Get PDF Page Format
45 $format = CRM_Core_BAO_PdfFormat::getDefaultValues();
46 if (is_array($pdfFormat)) {
47 // PDF Page Format parameters passed in
48 $format = array_merge($format, $pdfFormat);
49 }
50 else {
51 // PDF Page Format ID passed in
52 $format = CRM_Core_BAO_PdfFormat::getById($pdfFormat);
53 }
54 $paperSize = CRM_Core_BAO_PaperSize::getByName($format['paper_size']);
55 $paper_width = self::convertMetric($paperSize['width'], $paperSize['metric'], 'pt');
56 $paper_height = self::convertMetric($paperSize['height'], $paperSize['metric'], 'pt');
57 // dompdf requires dimensions in points
58 $paper_size = array(0, 0, $paper_width, $paper_height);
59 $orientation = CRM_Core_BAO_PdfFormat::getValue('orientation', $format);
60 $metric = CRM_Core_BAO_PdfFormat::getValue('metric', $format);
61 $t = CRM_Core_BAO_PdfFormat::getValue('margin_top', $format);
62 $r = CRM_Core_BAO_PdfFormat::getValue('margin_right', $format);
63 $b = CRM_Core_BAO_PdfFormat::getValue('margin_bottom', $format);
64 $l = CRM_Core_BAO_PdfFormat::getValue('margin_left', $format);
65 $margins = array($metric,$t,$r,$b,$l);
66
67 $config = CRM_Core_Config::singleton();
68 $html = "
69<html>
70 <head>
71 <meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"/>
72 <style>@page { margin: {$t}{$metric} {$r}{$metric} {$b}{$metric} {$l}{$metric}; }</style>
73 <style type=\"text/css\">@import url({$config->userFrameworkResourceURL}css/print.css);</style>
74 </head>
75 <body>
76 <div id=\"crm-container\">\n";
77
78 // Strip <html>, <header>, and <body> tags from each page
79 $htmlElementstoStrip = array(
80 '@<head[^>]*?>.*?</head>@siu',
81 '@<body>@siu',
82 '@</body>@siu',
83 '@<html[^>]*?>@siu',
84 '@</html>@siu',
85 '@<!DOCTYPE[^>]*?>@siu',
86 );
87 $htmlElementsInstead = array('', '', '', '', '', '');
88 foreach ($pages as & $page) {
89 $page = preg_replace($htmlElementstoStrip,
90 $htmlElementsInstead,
91 $page
92 );
93 }
94 // Glue the pages together
95 $html .= implode("\n<div style=\"page-break-after: always\"></div>\n", $pages);
96 $html .= "
97 </div>
98 </body>
99</html>";
100 if ($config->wkhtmltopdfPath) {
101 return self::_html2pdf_wkhtmltopdf($paper_size, $orientation, $margins, $html, $output, $fileName);
102 }
103 else {
104 return self::_html2pdf_dompdf($paper_size, $orientation, $html, $output, $fileName);
105 }
106 }
107
108 static function _html2pdf_dompdf($paper_size, $orientation, $html, $output, $fileName) {
109 require_once 'packages/dompdf/dompdf_config.inc.php';
110 spl_autoload_register('DOMPDF_autoload');
111 $dompdf = new DOMPDF();
112 $dompdf->set_paper($paper_size, $orientation);
113 $dompdf->load_html($html);
114 $dompdf->render();
115
116 if ($output) {
117 return $dompdf->output();
118 }
119 else {
120 $dompdf->stream($fileName);
121 }
122 }
123
124 static function _html2pdf_wkhtmltopdf($paper_size, $orientation, $margins, $html, $output, $fileName) {
125 require_once 'packages/snappy/src/autoload.php';
126 $config = CRM_Core_Config::singleton();
127 $snappy = new Knp\Snappy\Pdf($config->wkhtmltopdfPath);
128 $snappy->setOption("page-width", $paper_size[2] . "pt");
129 $snappy->setOption("page-height", $paper_size[3] . "pt");
130 $snappy->setOption("orientation", $orientation);
131 $snappy->setOption("margin-top", $margins[1] . $margins[0]);
132 $snappy->setOption("margin-right", $margins[2] . $margins[0]);
133 $snappy->setOption("margin-bottom", $margins[3] . $margins[0]);
134 $snappy->setOption("margin-left", $margins[4] . $margins[0]);
135 $pdf = $snappy->getOutputFromHtml($html);
136 if ($output) {
137 return $pdf;
138 }
139 else {
140 header('Content-Type: application/pdf');
141 header('Content-Disposition: attachment; filename="' . $fileName . '"');
142 echo $pdf;
143 }
144 }
145
146 /*
147 * function to convert value from one metric to another
148 */
149 static function convertMetric($value, $from, $to, $precision = NULL) {
150 switch ($from . $to) {
151 case 'incm':
152 $value *= 2.54;
153 break;
154
155 case 'inmm':
156 $value *= 25.4;
157 break;
158
159 case 'inpt':
160 $value *= 72;
161 break;
162
163 case 'cmin':
164 $value /= 2.54;
165 break;
166
167 case 'cmmm':
168 $value *= 10;
169 break;
170
171 case 'cmpt':
172 $value *= 72 / 2.54;
173 break;
174
175 case 'mmin':
176 $value /= 25.4;
177 break;
178
179 case 'mmcm':
180 $value /= 10;
181 break;
182
183 case 'mmpt':
184 $value *= 72 / 25.4;
185 break;
186
187 case 'ptin':
188 $value /= 72;
189 break;
190
191 case 'ptcm':
192 $value *= 2.54 / 72;
193 break;
194
195 case 'ptmm':
196 $value *= 25.4 / 72;
197 break;
198 }
199 if (!is_null($precision)) {
200 $value = round($value, $precision);
201 }
202 return $value;
203 }
204
205 static function &pdflib($fileName,
206 $searchPath,
207 &$values,
208 $numPages = 1,
209 $echo = TRUE,
210 $output = 'College_Match_App',
211 $creator = 'CiviCRM',
212 $author = 'http://www.civicrm.org/',
213 $title = '2006 College Match Scholarship Application'
214 ) {
215 try {
216 $pdf = new PDFlib();
217 $pdf->set_parameter("compatibility", "1.6");
218 $pdf->set_parameter("licensefile", "/home/paras/bin/license/pdflib.txt");
219
220 if ($pdf->begin_document('', '') == 0) {
221 CRM_Core_Error::statusBounce("PDFlib Error: " . $pdf->get_errmsg());
222 }
223
224 $config = CRM_Core_Config::singleton();
225 $pdf->set_parameter('resourcefile', $config->templateDir . '/Quest/pdf/pdflib.upr');
226 $pdf->set_parameter('textformat', 'utf8');
227
228 /* Set the search path for fonts and PDF files */
229
230 $pdf->set_parameter('SearchPath', $searchPath);
231
232 /* This line is required to avoid problems on Japanese systems */
233
234 $pdf->set_parameter('hypertextencoding', 'winansi');
235
236 $pdf->set_info('Creator', $creator);
237 $pdf->set_info('Author', $author);
238 $pdf->set_info('Title', $title);
239
240 $blockContainer = $pdf->open_pdi($fileName, '', 0);
241 if ($blockContainer == 0) {
242 CRM_Core_Error::statusBounce('PDFlib Error: ' . $pdf->get_errmsg());
243 }
244
245 for ($i = 1; $i <= $numPages; $i++) {
246 $page = $pdf->open_pdi_page($blockContainer, $i, '');
247 if ($page == 0) {
248 CRM_Core_Error::statusBounce('PDFlib Error: ' . $pdf->get_errmsg());
249 }
250
251 /* dummy page size */
252 $pdf->begin_page_ext(20, 20, '');
253
254 /* This will adjust the page size to the block container's size. */
255
256 $pdf->fit_pdi_page($page, 0, 0, 'adjustpage');
257
258
259 $status = array();
260 /* Fill all text blocks with dynamic data */
261
262 foreach ($values as $key => $value) {
263 if (is_array($value)) {
264 continue;
265 }
266
267 // pdflib does like the forward slash character, hence convert
268 $value = str_replace('/', '_', $value);
269
270 $res = $pdf->fill_textblock($page,
271 $key,
272 $value,
273 'embedding encoding=winansi'
274 );
275
276 /**
277 if ( $res == 0 ) {
278 CRM_Core_Error::debug( "$key, $value: $res", $pdf->get_errmsg( ) );
279 } else {
280 CRM_Core_Error::debug( "SUCCESS: $key, $value", null );
281 }
282 **/
283 }
284
285 $pdf->end_page_ext('');
286 $pdf->close_pdi_page($page);
287 }
288
289 $pdf->end_document('');
290 $pdf->close_pdi($blockContainer);
291
292 $buf = $pdf->get_buffer();
293 $len = strlen($buf);
294
295 if ($echo) {
296 header('Content-type: application/pdf');
297 header("Content-Length: $len");
298 header("Content-Disposition: inline; filename={$output}.pdf");
299 echo $buf;
300 CRM_Utils_System::civiExit();
301 }
302 else {
303 return $buf;
304 }
305 }
306 catch(PDFlibException$excp) {
307 CRM_Core_Error::statusBounce('PDFlib Error: Exception' .
308 "[" . $excp->get_errnum() . "] " . $excp->get_apiname() . ": " .
309 $excp->get_errmsg()
310 );
311 }
312 catch(Exception$excp) {
313 CRM_Core_Error::statusBounce("PDFlib Error: " . $excp->get_errmsg());
314 }
315 }
316}
317