noalyss Version-9
document_export.class.php
Go to the documentation of this file.
1<?php
2/*
3 * This file is part of NOALYSS.
4 *
5 * NOALYSS is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * NOALYSS is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with NOALYSS; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18*/
19
20// Copyright Author Dany De Bontridder danydb@aevalys.eu
21/**
22 * @brief Export DOCUMENT from Analytic accountancy, can transform into PDF
23 * and add a stamp on each pages
24 *
25 * It depends on PDFTK and CONVERT_GIF_PDF
26 */
28{
29 /**
30 *@brief create 2 temporary folders, store_pdf and store_convert, initialize
31 * an array feedback containing messages
32 *
33 */
34 function __construct()
35 {
36 // Create 2 temporary folders 1. convert to PDF + stamp
37 // 2. store result
38 $this->feedback = array();
39 $this->store_convert = tempnam($_ENV['TMP'], 'convert_');
40 $this->store_pdf = tempnam($_ENV['TMP'], 'pdf_');
41 unlink($this->store_convert);
42 unlink($this->store_pdf);
43 $this->progress=NULL;
44 umask(0);
45 if ( mkdir($this->store_convert) == FALSE )
46 throw new Exception(sprintf("Create %s failed",$this->store_onvert));
47 if ( mkdir($this->store_pdf)== FALSE )
48 throw new Exception(sprintf("Create %s failed",$this->store_pdf));
49 }
50 /**
51 * @brief concatenate all PDF into a single one and save it into the
52 * store_pdf folder.
53 * If an error occurs then it is added to feedback
54 */
55 function concatenate_pdf()
56 {
57 try
58 {
59 $this->check_file();
60 $stmt=PDFTK." ".$this->store_pdf.'/*pdf output '.$this->store_pdf.'/result.pdf';
61 $status=0;
62 echo $stmt;
63 passthru($stmt, $status);
64
65 if ($status<>0)
66 {
67 $cnt_feedback=count($this->feedback);
68 $this->feedback[$cnt_feedback]['file']='result.pdf';
69 $this->feedback[$cnt_feedback]['message']=' cannot concatenate PDF';
70 $this->feedback[$cnt_feedback]['error']=$status;
71 }
72 }
73 catch (Exception $exc)
74 {
75 $cnt_feedback=count($this->feedback);
76 $this->feedback[$cnt_feedback]['file']=' ';
77 $this->feedback[$cnt_feedback]['message']=$exc->getMessage();
78 $this->feedback[$cnt_feedback]['error']=0;
79 }
80 }
81
82 /**
83 * Make a zip file
84 */
85 function make_zip()
86 {
87 $zip=new Zip_Extended();
88 $res=$zip->open("{$this->store_pdf}/result.zip",ZipArchive::CREATE);
89 if ($res !== true) {
90 error_log("ERR-DE89 cannot create zip file");
91 throw new Exception ( __FILE__.":".__LINE__."cannot recreate zip");
92 }
93 chdir($this->store_pdf);
94 // addGmpn
95 $res=$zip->add_file_pattern($this->store_pdf,"/.*.pdf/");
96 if ($res == 0) {
97 error_log("ERR-DE96 aucun fichier trouvé");
98 throw new Exception ( __FILE__.":".__LINE__."cannot recreate zip");
99 }
100 $zip->close();
101
102 }
103 /**
104 * copy the file
105 * @param $p_source
106 * @param $target
107 * @throws Exception
108 */
109
110 function move_file($p_source, $p_target)
111 {
112 $this->check_file();
113 $i=1;
114 $target=$p_target;
115 // do not overwrite a document already present
116 while (file_exists($target)) {
117 $target = sprintf("%d-%s",$i,$p_target);
118 $i++;
119 }
120 copy($p_source, $this->store_pdf . '/' . $target);
121 }
122 /**
123 * @brief send the resulting PDF to the browser
124 */
125 function send_pdf()
126 {
127 header('Content-Type: application/x-download');
128 header('Content-Disposition: attachment; filename="result.pdf"');
129 header('Cache-Control: private, max-age=0, must-revalidate');
130 header('Pragma: public');
131 echo file_get_contents($this->store_pdf . '/result.pdf');
132 }
133 /**
134 * @brief send the resulting PDF to the browser
135 */
136 function send_zip()
137 {
138 header('Content-Type: application/zip');
139 header('Content-Disposition: attachment; filename="result.zip"');
140 header('Cache-Control: private, max-age=0, must-revalidate');
141 header('Pragma: public');
142 echo file_get_contents($this->store_pdf . '/result.zip');
143 }
144 /**
145 * @brief remove folder and its content
146 */
147 function clean_folder()
148 {
149 $files= scandir($this->store_convert);
150 $nb_file=count($files);
151 for ($i=0;$i < $nb_file;$i++) {
152 if (is_file($this->store_convert."/".$files[$i])) unlink($this->store_convert."/".$files[$i]);
153 }
154 rmdir($this->store_convert);
155 $files= scandir($this->store_pdf);
156 $nb_file=count($files);
157 for ($i=0;$i < $nb_file;$i++) {
158 if (is_file($this->store_pdf."/".$files[$i])) unlink($this->store_pdf."/".$files[$i]);
159 }
160 rmdir($this->store_pdf);
161
162 }
163
164 /**
165 * @brief export all the pieces in PDF and transform them into a PDF with
166 * a stamp. If an error occurs then $this->feedback won't be empty
167 * @param $p_array contents all the jr_id
168 * @param Progress_Bar $progress is the progress bar
169 * @param int $p_separate 1 everything in a single PDF or a ZIP with all PDF
170 * @param int $reconcilied_operation 1 with receipt of reconcilied operation 2 without them
171 *
172 */
174 {
175 $this->progress=$progress;
176
177 $this->check_file();
178 if (count($p_array)==0)
179 return;
180 ob_start();
181 $cnt_feedback=0;
182 global $cn;
183
185 $order=0;
186 // follow progress
187 $step=round(16/count($p_array), 2);
188
189 foreach ($p_array as $value)
190 {
191 $progress->increment($step);
192
193 $output_receipt=$this->export_receipt($value, $progress, $step);
194
195 if ($output_receipt==NULL)
196 {
197 continue;
198 }
199 $output=$output_receipt['output'];
200 $file_pdf=$output_receipt['filepdf'];
201
202 // export also the receipt of reconcilied operation
203 $a_reconcilied_operation=[];
204 if ( $reconcilied_document == 1 ) {
205 $a_reconcilied_operation=$cn->get_array("select jr_id,jra_concerned
206 from jrn_rapt where jra_concerned=$1 or jr_id=$1", [$value]);
207 }
208
209 // for each reconcilied operation , export the receipt and concantenate
210 foreach ($a_reconcilied_operation as $reconcilied_operation)
211 {
212 $op=($reconcilied_operation['jr_id']==$value)?$reconcilied_operation['jra_concerned']:$reconcilied_operation['jr_id'];
213
214 $output_rec=$this->export_receipt($op, $progress, $step);
215 if ($output_rec==NULL)
216 {
217 continue;
218 }
219 // concatenate detail operation with the output
220 $output3=$this->store_convert.'/tmp_operation_'.$file_pdf;
221
222 $stmt=PDFTK." ".$output." ".$output_rec['output'].
223 ' output '.$output3;
224
225 passthru($stmt, $status);
226 if ($status<>0)
227 {
228 $cnt_feedback=count($this->feedback);
229 $this->feedback[$cnt_feedback]['file']=$output3;
230 $this->feedback[$cnt_feedback]['message']=_('Echec ');
231 $this->feedback[$cnt_feedback]['error']=$status;
232 $cnt_feedback++;
233 continue;
234 }
235 unlink($output_rec['output']);
236 rename($output3, $output);
237 }
238 $progress->increment($step);
239
240 // create the pdf with the detail of operation
241 $detail_operation=new PDF_Operation($cn, $value);
242 $detail_operation->export_pdf(array("acc", "anc"));
243
244 // output 2
245 $output2=$this->store_convert.'/operation_'.$file_pdf;
246
247 // concatenate detail operation with the output
248 $stmt=PDFTK." ".$detail_operation->get_pdf_filename()." ".$output.
249 ' output '.$output2;
250
251 $progress->increment($step);
252 passthru($stmt, $status);
253 if ($status<>0)
254 {
255 $cnt_feedback=count($this->feedback);
256 $this->feedback[$cnt_feedback]['file']=$output2;
257 $this->feedback[$cnt_feedback]['message']=_('Echec Ajout detail ');
258 $this->feedback[$cnt_feedback]['error']=$status;
259 $cnt_feedback++;
260 continue;
261 }
262 // remove doc with detail
263 $detail_operation->unlink();
264
265 // overwrite old with new PDF
266 rename($output2, $output);
267
268 // Move the PDF into another temp directory
269 $this->move_file($output, $file_pdf);
270 $order++;
271 }
272
273 $progress->set_value(93);
274
275 if ($p_separate==1)
276 {
277 // concatenate all pdf into one
278 $this->concatenate_pdf();
279
280 ob_clean();
281 $this->send_pdf();
282 }
283 else
284 {
285 // Put all PDF In a zip file
286 $this->make_zip();
287 ob_clean();
288 $this->send_zip();
289 }
290
291 $progress->set_value(100);
292 // remove files from "conversion folder"
293 // $this->clean_folder();
294 }
295
296 /**
297 * @brief check that the files are installed
298 * throw a exception if one is missing
299 */
300 function check_file()
301 {
302 try
303 {
304 if (CONVERT_GIF_PDF == 'NOT') throw new Exception(_("CONVERT_GIF_PDF n'est pas installé"));
305 if (PDFTK == 'NOT') throw new Exception(_("TKPDF n'est pas installé"));
306 if ( FIX_BROKEN_PDF == 'YES') {
307 if (PS2PDF == 'NOT') throw new Exception(_('PS2PDF non installé'));
308 if (PDF2PS == 'NOT') throw new Exception(_('PDF2PS non installé'));
309 }
310 } catch (Exception $ex)
311 {
312 throw ($ex);
313 }
314 }
315
316 /**
317 * @brief export a file (
318 * @param type $p_jrn_id
319 * @param $progress
320 * @return string
321 */
323 {
324 global $cn;
325 $cnt_feedback=count($this->feedback);
326
327 // For each file save it into the temp folder,
328 $file=$cn->get_array('select jr_pj,jr_pj_name,jr_pj_number,jr_pj_type from jrn '
329 .' where jr_id=$1', array($p_jrn_id));
330
331
332 if ($file[0]['jr_pj']=='')
333 {
334 return null;
335 }
336
337
338 $filename=clean_filename($file[0]['jr_pj_name']);
339 $receipt=clean_filename($file[0]['jr_pj_number']);
341 $filename=$receipt.'-'.$filename;
342
343 $cn->start();
344 $cn->lo_export($file[0]['jr_pj'], $this->store_convert.'/'.$filename);
345 $cn->commit();
346
347 if ( ! file_exists( $this->store_convert.'/'.$filename) ){
348 throw new \Exception("ERR:DE342 Ne peut pas exporter le fichier $filename");
349 }
350
351 // Convert this file into PDF
352 if ($file[0]['jr_pj_type']!='application/pdf')
353 {
354 $status=0;
355 $arg=" ".escapeshellarg($this->store_convert.DIRECTORY_SEPARATOR.$filename);
356 echo "arg = [".$arg."]";
357 passthru(OFFICE." ".$arg, $status);
358 if ($status<>0)
359 {
360 $this->feedback[$cnt_feedback]['file']=$filename;
361 $this->feedback[$cnt_feedback]['message']=' cannot convert to PDF';
362 $this->feedback[$cnt_feedback]['error']=$status;
363 return null;
364 }
365 }
366 // Create a image with the stamp + formula
367 $img=imagecreatefromgif(NOALYSS_INCLUDE.'/template/template.gif');
368 $font=imagecolorallocatealpha($img, 100, 100, 100, 110);
369 imagettftext($img, 40, 25, 500, 1000, $font,
370 NOALYSS_INCLUDE.'/tfpdf/font/unifont/DejaVuSans.ttf'
371 , _("Copie certifiée conforme à l'original"));
372 imagettftext($img, 40, 25, 550, 1100, $font,
373 NOALYSS_INCLUDE.'/tfpdf/font/unifont/DejaVuSans.ttf'
374 , $file[0]['jr_pj_number']);
375 imagettftext($img, 40, 25, 600, 1200, $font,
376 NOALYSS_INCLUDE.'/tfpdf/font/unifont/DejaVuSans.ttf'
377 , $file[0]['jr_pj_name']);
378 imagegif($img, $this->store_convert.'/'.'stamp.gif');
379
380 // transform gif file to pdf with convert tool
381 $stmt=CONVERT_GIF_PDF." ".escapeshellarg($this->store_convert.'/'.'stamp.gif')." "
382 .escapeshellarg($this->store_convert.'/stamp.pdf');
383 passthru($stmt, $status);
384 if ($status<>0)
385 {
386 $this->feedback[$cnt_feedback]['file']='stamp.pdf';
387 $this->feedback[$cnt_feedback]['message']=' cannot convert to PDF';
388 $this->feedback[$cnt_feedback]['error']=$status;
389 return null;
390 }
391
392
393 $progress->increment($step);
394 //
395 // remove extension
396 $ext=strrpos($filename, ".");
397 $file_pdf=substr($filename, 0, $ext);
398 $file_pdf.=".pdf";
399
400 //-----------------------------------
401 // Fix broken PDF , actually pdftk can not handle all the PDF
402 if (FIX_BROKEN_PDF=='YES'&&PDF2PS!='NOT'&&PS2PDF!='NOT')
403 {
404
405 $stmpt=PDF2PS." ".escapeshellarg($this->store_convert.'/'.$file_pdf).
406 " ".escapeshellarg($this->store_convert.'/'.$file_pdf.'.ps');
407
408 passthru($stmpt, $status);
409
410 if ($status<>0)
411 {
412 $this->feedback[$cnt_feedback]['file']=$this->store_convert.'/'.$file_pdf;
413 $this->feedback[$cnt_feedback]['message']=' cannot force to PDF';
414 $this->feedback[$cnt_feedback]['error']=$status;
415 $cnt_feedback++;
416 return null;
417 }
418 $stmpt=PS2PDF." ".escapeshellarg($this->store_convert.'/'.$file_pdf.'.ps').
419 " ".escapeshellarg($this->store_convert.'/'.$file_pdf.'.2');
420
421 passthru($stmpt, $status);
422
423 if ($status<>0)
424 {
425 $this->feedback[$cnt_feedback]['file']=$this->store_convert.'/'.$file_pdf;
426 $this->feedback[$cnt_feedback]['message']=' cannot force to PDF';
427 $this->feedback[$cnt_feedback]['error']=$status;
428 $cnt_feedback++;
429 return null;
430 }
431 rename($this->store_convert.'/'.$file_pdf.'.2', $this->store_convert.'/'.$file_pdf);
432 }
433 $progress->increment($step);
434 // output
435 $output=$this->store_convert.'/stamp_'.$file_pdf;
436
437 // Concatenate stamp + file
438 $stmt=PDFTK." ".escapeshellarg($this->store_convert.'/'.$file_pdf)
439 .' stamp '.$this->store_convert.
440 '/stamp.pdf output '.$output;
441
442 passthru($stmt, $status);
443 if ($status<>0)
444 {
445
446 $this->feedback[$cnt_feedback]['file']=$file_pdf;
447 $this->feedback[$cnt_feedback]['message']=_(' ne peut pas convertir en PDF');
448 $this->feedback[$cnt_feedback]['error']=$status;
449 return null;
450 }
451 return array("output"=>$output,"filepdf"=>$file_pdf);
452 }
453 /**
454 * @brief Order the array with the date
455 * @param array $p_array array of jrn.jr_id
456 */
458 {
459 global $cn;
460 if (empty($p_array)) {return array();}
461
462 $list_jrn_id=join(',', $p_array);
463
464 $array=$cn->get_array("select jr_id ,jr_date from jrn where jr_id in ($list_jrn_id) order by jr_date");
465 $array=array_column($array, 'jr_id');
466 return $array;
467 }
468}
noalyss_str_replace($search, $replace, $string)
Definition: ac_common.php:1553
$op
Definition: ajax_admin.php:38
$ex
Definition: balance.inc.php:45
Export DOCUMENT from Analytic accountancy, can transform into PDF and add a stamp on each pages.
send_pdf()
send the resulting PDF to the browser
concatenate_pdf()
concatenate all PDF into a single one and save it into the store_pdf folder.
move_file($p_source, $p_target)
copy the file
__construct()
create 2 temporary folders, store_pdf and store_convert, initialize an array feedback containing mess...
export_receipt($p_jrn_id, Progress_Bar $progress, $step)
export a file (
make_zip()
Make a zip file.
send_zip()
send the resulting PDF to the browser
reorder_array($p_array)
Order the array with the date.
export_all($p_array, Progress_Bar $progress, $p_separate=1, $reconcilied_document=2)
export all the pieces in PDF and transform them into a PDF with a stamp.
clean_folder()
remove folder and its content
check_file()
check that the files are installed throw a exception if one is missing
Detail Operation ACC + ANC , it will use Acc_Operation and Anc_Operation.
Use one db for tracking progress bar value, the task id must be unique and let you follow the progres...
set_value($p_value)
Store the progress value into the db.
extends the Zip object
const PDF2PS
Definition: constant.php:291
const PS2PDF
Definition: constant.php:300
$img
clean_filename($p_filename)
sanitize the filename remove character which could be a problem,