9
9
* binary is preferred but this class should also work with the non static version,
10
10
* even though a lot of features will be missing.
11
11
*
12
- * Basic use:
12
+ * Basic use
13
+ * ---------
13
14
*
14
15
* $pdf = new WkHtmlToPdf;
16
+ *
17
+ * // Add a HTML file, a HTML string, a page from URL or a PDF file
18
+ * $pdf->addPage('/home/joe/page.html');
19
+ * $pdf->addPage('<html>....</html>');
15
20
* $pdf->addPage('http://google.com');
16
21
* $pdf->addPage('/home/joe/my.pdf');
22
+ *
23
+ * // Add a cover (same sources as above are possible)
17
24
* $pdf->addCover('mycover.pdf');
25
+ *
26
+ * // Add a Table of contents
18
27
* $pdf->addToc();
19
28
*
20
- * // Save the PDF
29
+ * // Save the PDF, or ...
21
30
* $pdf->saveAs('/tmp/new.pdf');
22
31
*
23
- * // Send to client for inline display
32
+ * // ... send to client for inline display or ...
24
33
* $pdf->send();
25
34
*
26
- * // Send to client as file download
35
+ * // ... send to client as file download
27
36
* $pdf->send('test.pdf');
28
37
*
29
- * Setting options:
38
+ *
39
+ * Setting options
40
+ * ---------------
41
+ *
42
+ * The wkhtmltopdf binary has some global options (e.g. to set the document's DPI) and options
43
+ * for each PDF page (e.g. to supply a custom CSS file). Please see "wkhtmltopdf -H" to get a
44
+ * list of all available options.
45
+ *
46
+ * In addition this class also supports global page options: You can set default page options
47
+ * that will be applied to every page you add. You can also override these defaults per page:
30
48
*
31
49
* $pdf = new WkHtmlToPdf($options); // Set global PDF options
32
50
* $pdf->setOptions($options); // Set global PDF options (alternative)
33
- * $pdf->setPageOptions($options); // Set global default page options
34
- * $pdf->addPage($page, $options); // Set page options (overrides default page options)
51
+ * $pdf->setPageOptions($options); // Set default page options
52
+ * $pdf->addPage($page, $options); // Add page with options (overrides default page options)
35
53
*
36
- * Example options:
37
54
*
38
- * // See "wkhtmltopdf -H" for all available options
39
- * $options=array(
40
- * 'no-outline',
41
- * 'margin-top' =>0,
42
- * 'margin-right' =>0,
43
- * );
55
+ * Special global options
56
+ * ----------------------
44
57
*
45
- * Extra global options:
58
+ * You can use these special global options to set up some file paths :
46
59
*
47
60
* bin: path to the wkhtmltopdf binary. Defaults to /usr/bin/wkhtmltopdf.
48
61
* tmp: path to tmp directory. Defaults to PHP temp dir.
49
62
*
50
- * Error handling:
51
63
*
52
- * saveAs() and save() will return false on error. In this case the detailed error message
53
- * from wkhtmltopdf can be obtained through getError().
64
+ * Error handling
65
+ * --------------
66
+ *
67
+ * saveAs() and save() will return false on error. In this case the detailed error message
68
+ * from wkhtmltopdf can be obtained through getError().
54
69
*
55
70
* @author Michael Härtl <haertl.mike@gmail.com> (sponsored by PeoplePerHour.com)
56
- * @version 1.0 .0
71
+ * @version 1.1 .0
57
72
* @license http://www.opensource.org/licenses/MIT
58
73
*/
59
74
class WkHtmlToPdf
60
75
{
61
- protected $ bin= '/usr/bin/wkhtmltopdf ' ;
76
+ protected $ bin = '/usr/bin/wkhtmltopdf ' ;
62
77
63
- protected $ options= array ();
64
- protected $ pageOptions= array ();
65
- protected $ objects= array ();
78
+ protected $ options = array ();
79
+ protected $ pageOptions = array ();
80
+ protected $ objects = array ();
66
81
67
82
protected $ tmp ;
68
83
protected $ tmpFile ;
84
+ protected $ tmpFiles = array ();
69
85
70
86
protected $ error ;
71
87
88
+ // Regular expression to detect HTML strings
89
+ const REGEX_HTML = '/<html>/i ' ;
90
+
72
91
/**
73
92
* @param array $options global options for wkhtmltopdf (optional)
74
93
*/
@@ -79,24 +98,27 @@ public function __construct($options=array())
79
98
}
80
99
81
100
/**
82
- * Remove temporary PDF file when script completes
101
+ * Remove temporary PDF file and pages when script completes
83
102
*/
84
103
public function __destruct ()
85
104
{
86
105
if ($ this ->tmpFile !==null )
87
106
unlink ($ this ->tmpFile );
107
+
108
+ foreach ($ this ->tmpFiles as $ tmp )
109
+ unlink ($ tmp );
88
110
}
89
111
90
112
/**
91
113
* Add a page object to the output
92
114
*
93
- * @param string $input either a URL or a PDF filename
115
+ * @param string $input either a URL, a HTML string or a PDF/HTML filename
94
116
* @param array $options optional options for this page
95
117
*/
96
118
public function addPage ($ input ,$ options =array ())
97
119
{
98
- $ options ['input ' ]= $ input ;
99
- $ this ->objects []= array_merge ($ this ->pageOptions ,$ options );
120
+ $ options ['input ' ] = preg_match ( self :: REGEX_HTML , $ input ) ? $ this -> createTmpFile ( $ input ) : $ input ;
121
+ $ this ->objects [] = array_merge ($ this ->pageOptions ,$ options );
100
122
}
101
123
102
124
/**
@@ -107,20 +129,19 @@ public function addPage($input,$options=array())
107
129
*/
108
130
public function addCover ($ input ,$ options =array ())
109
131
{
110
- $ options ['input ' ]= "cover $ input " ;
111
- $ this ->objects []= array_merge ($ this ->pageOptions ,$ options );
132
+ $ options ['input ' ] = "cover $ input " ;
133
+ $ this ->objects [] = array_merge ($ this ->pageOptions ,$ options );
112
134
}
113
135
114
136
/**
115
137
* Add a TOC object to the output
116
138
*
117
- * @param string $input either a URL or a PDF filename
118
- * @param array $options optional options for this page
139
+ * @param array $options optional options for the table of contents
119
140
*/
120
141
public function addToc ($ options =array ())
121
142
{
122
- $ options ['input ' ]= "toc " ;
123
- $ this ->objects []= $ options ;
143
+ $ options ['input ' ] = "toc " ;
144
+ $ this ->objects [] = $ options ;
124
145
}
125
146
126
147
/**
@@ -131,7 +152,7 @@ public function addToc($options=array())
131
152
*/
132
153
public function saveAs ($ filename )
133
154
{
134
- if (($ pdfFile= $ this ->getPdfFilename ())===false )
155
+ if (($ pdfFile = $ this ->getPdfFilename ())===false )
135
156
return false ;
136
157
137
158
copy ($ pdfFile ,$ filename );
@@ -146,7 +167,7 @@ public function saveAs($filename)
146
167
*/
147
168
public function send ($ filename =null )
148
169
{
149
- if (($ pdfFile= $ this ->getPdfFilename ())===false )
170
+ if (($ pdfFile = $ this ->getPdfFilename ())===false )
150
171
return false ;
151
172
152
173
header ('Pragma: public ' );
@@ -172,21 +193,21 @@ public function setOptions($options)
172
193
{
173
194
foreach ($ options as $ key =>$ val )
174
195
if ($ key ==='bin ' )
175
- $ this ->bin = $ val ;
196
+ $ this ->bin = $ val ;
176
197
elseif ($ key ==='tmp ' )
177
- $ this ->tmp = $ val ;
198
+ $ this ->tmp = $ val ;
178
199
elseif (is_int ($ key ))
179
- $ this ->options []= $ val ;
200
+ $ this ->options [] = $ val ;
180
201
else
181
- $ this ->options [$ key ]= $ val ;
202
+ $ this ->options [$ key ] = $ val ;
182
203
}
183
204
184
205
/**
185
206
* @param array $options that should be applied to all pages as name/value pairs
186
207
*/
187
208
public function setPageOptions ($ options =array ())
188
209
{
189
- $ this ->pageOptions = $ options ;
210
+ $ this ->pageOptions = $ options ;
190
211
}
191
212
192
213
/**
@@ -197,20 +218,28 @@ public function getError()
197
218
return $ this ->error ;
198
219
}
199
220
221
+ /**
222
+ * @return string path to temp directory
223
+ */
224
+ public function getTmpDir ()
225
+ {
226
+ if ($ this ->tmp ===null )
227
+ $ this ->tmp = sys_get_temp_dir ();
228
+
229
+ return $ this ->tmp ;
230
+ }
231
+
200
232
/**
201
233
* @return mixed the temporary PDF filename or false on error (triggers PDf creation)
202
234
*/
203
235
protected function getPdfFilename ()
204
236
{
205
237
if ($ this ->tmpFile ===null )
206
238
{
207
- if ($ this ->tmp ===null )
208
- $ this ->tmp =sys_get_temp_dir ();
209
-
210
- $ tmpFile =tempnam ($ this ->tmp ,'tmp_WkHtmlToPdf_ ' );
239
+ $ tmpFile = tempnam ($ this ->getTmpDir (),'tmp_WkHtmlToPdf_ ' );
211
240
212
241
if ($ this ->createPdf ($ tmpFile )===true )
213
- $ this ->tmpFile = $ tmpFile ;
242
+ $ this ->tmpFile = $ tmpFile ;
214
243
else
215
244
return false ;
216
245
}
@@ -224,15 +253,15 @@ protected function getPdfFilename()
224
253
*/
225
254
protected function getCommand ($ filename )
226
255
{
227
- $ command= $ this ->bin ;
256
+ $ command = $ this ->bin ;
228
257
229
- $ command.= $ this ->renderOptions ($ this ->options );
258
+ $ command .= $ this ->renderOptions ($ this ->options );
230
259
231
260
foreach ($ this ->objects as $ object )
232
261
{
233
- $ command.= ' ' .$ object ['input ' ];
262
+ $ command .= ' ' .$ object ['input ' ];
234
263
unset($ object ['input ' ]);
235
- $ command.= $ this ->renderOptions ($ object );
264
+ $ command .= $ this ->renderOptions ($ object );
236
265
}
237
266
238
267
return $ command .' ' .$ filename ;
@@ -243,44 +272,61 @@ protected function getCommand($filename)
243
272
*/
244
273
protected function createPdf ($ fileName )
245
274
{
246
- $ command= $ this ->getCommand ($ fileName );
275
+ $ command = $ this ->getCommand ($ fileName );
247
276
248
277
// we use proc_open with pipes to fetch error output
249
- $ descriptors= array (
250
- 1 => array ('pipe ' ,'w ' ),
251
- 2 => array ('pipe ' ,'w ' ),
278
+ $ descriptors = array (
279
+ 1 => array ('pipe ' ,'w ' ),
280
+ 2 => array ('pipe ' ,'w ' ),
252
281
);
253
- $ process= proc_open ($ command , $ descriptors , $ pipes );
282
+ $ process = proc_open ($ command , $ descriptors , $ pipes );
254
283
255
284
if (is_resource ($ process )) {
256
285
257
- $ stdout= stream_get_contents ($ pipes [1 ]);
258
- $ stderr= stream_get_contents ($ pipes [2 ]);
286
+ $ stdout = stream_get_contents ($ pipes [1 ]);
287
+ $ stderr = stream_get_contents ($ pipes [2 ]);
259
288
fclose ($ pipes [1 ]);
260
289
fclose ($ pipes [2 ]);
261
290
262
- $ result= proc_close ($ process );
291
+ $ result = proc_close ($ process );
263
292
264
293
if ($ result !==0 )
265
- $ this ->error = "Could not run command $ command: \n$ stderr " ;
294
+ $ this ->error = "Could not run command $ command: \n$ stderr " ;
266
295
} else
267
- $ this ->error = "Could not run command $ command " ;
296
+ $ this ->error = "Could not run command $ command " ;
268
297
269
298
return $ this ->error ===null ;
270
299
}
271
300
301
+ /**
302
+ * Create a tmp file with given content
303
+ *
304
+ * @param string $content the file content
305
+ * @return string the path to the created file
306
+ */
307
+ protected function createTmpFile ($ content )
308
+ {
309
+ $ tmpFile = tempnam ($ this ->getTmpDir (),'tmp_WkHtmlToPdf_ ' );
310
+ rename ($ tmpFile , ($ tmpFile .='.html ' ));
311
+ file_put_contents ($ tmpFile , $ content );
312
+
313
+ $ this ->tmpFiles [] = $ tmpFile ;
314
+
315
+ return $ tmpFile ;
316
+ }
317
+
272
318
/**
273
319
* @param array $options for a wkhtml, either global or for an object
274
320
* @return string the string with options
275
321
*/
276
322
protected function renderOptions ($ options )
277
323
{
278
- $ out= '' ;
324
+ $ out = '' ;
279
325
foreach ($ options as $ key =>$ val )
280
326
if (is_numeric ($ key ))
281
- $ out.= " -- $ val " ;
327
+ $ out .= " -- $ val " ;
282
328
else
283
- $ out.= " -- $ key $ val " ;
329
+ $ out .= " -- $ key $ val " ;
284
330
285
331
return $ out ;
286
332
}
0 commit comments