]> Raphaël G. Git Repositories - cdn/blob - public/ausweis.php
Add ausweis generator
[cdn] / public / ausweis.php
1 <?php
2 /**
3 * Ausweis generator
4 */
5
6 //Set default timezone
7 date_default_timezone_set('Europe/Paris');
8
9 //XXX: Append FPDF paths and qrlib to include_path
10 ini_set('include_path', ini_get('include_path') . PATH_SEPARATOR . '/usr/share/php/fpdf' . PATH_SEPARATOR . '/usr/share/php/fpdf/font' . PATH_SEPARATOR . '../vendor/phpqrcode');
11
12 //XXX: Set font path
13 define('FPDF_FONTPATH', '../vendor/font');
14
15 //Load FPDF
16 require 'fpdf.php';
17
18 //Require qrcode
19 //XXX: need php-gd
20 require 'qrlib.php';
21
22 //Set reasons
23 $reasons = ['travail', 'achats', 'sante', 'famille', 'handicap', 'sport_animaux', 'convocation', 'missions', 'enfants'];
24
25 //Display form
26 if (
27 empty($_REQUEST['type']) ||
28 empty($_REQUEST['lastname']) ||
29 empty($_REQUEST['firstname']) ||
30 empty($_REQUEST['birthdate']) ||
31 empty($_REQUEST['birthplace']) ||
32 empty($_REQUEST['address']) ||
33 empty($_REQUEST['function']) ||
34 empty($_REQUEST['location']) ||
35 empty($_REQUEST['date']) ||
36 empty($_REQUEST['time'])
37 ) {
38 //Set time
39 //XXX: round it to previous 5 minute
40 $time = floor(strtotime('now')/300)*300;
41
42 //Set selected
43 $selected = null;
44
45 //Set selected
46 if (empty($_REQUEST['type'])) {
47 if (!empty($_SERVER['SCRIPT_URL'])) {
48 if ($_SERVER['SCRIPT_URL'] == '/bnp') {
49 $selected = 'bnp';
50 } elseif ($_SERVER['SCRIPT_URL'] == '/poltrone') {
51 $selected = 'poltrone';
52 } elseif ($_SERVER['SCRIPT_URL'] == '/convoc') {
53 $selected = 'convocation';
54 } elseif ($_SERVER['SCRIPT_URL'] == '/achat') {
55 $selected = 'achats';
56 } elseif ($_SERVER['SCRIPT_URL'] == '/sport') {
57 $selected = 'sport_animaux';
58 } elseif ($_SERVER['SCRIPT_URL'] == '/travail') {
59 $selected = 'travail';
60 }
61 }
62 } else {
63 if ($_REQUEST['type'] == 'bnp' || $_REQUEST['type'] == 'poltrone' || in_array($_REQUEST['type'], $reasons)) {
64 $selected = $_REQUEST['type'];
65 }
66 }
67 ?>
68 <html>
69 <head>
70 <title>Ausweis generator</title>
71 <style>
72 p {
73 color: red;
74 font-weight: bold;
75 }
76 section {
77 margin: 1rem auto;
78 text-align: center;
79 }
80 div {
81 display: flex;
82 width: 25rem;
83 margin: 0 auto;
84 justify-content: space-between;
85 }
86 span {
87 font-style: italic;
88 color: #ccc;
89 }
90 select,
91 input {
92 border: .1rem solid black;
93 border-radius: .2rem;
94 width: 12rem;
95 }
96 input.date {
97 width: 5rem;
98 }
99 input.time {
100 width: 3rem;
101 }
102 input[type="submit"] {
103 margin: 0 .5rem;
104 }
105 input[type="submit"]:first-child,
106 input[type="submit"]:last-child {
107 margin: 0;
108 }
109 </style>
110 </head>
111 <body>
112 <section>
113 <h1>Generateur d'attestation</h1>
114 <p>Tous les champs sont obligatoires, format de date jj/mm/aaaa, format horaire hh:mm</p>
115 <form action="<?php echo htmlspecialchars($_SERVER['REQUEST_URI']); ?>" method="post">
116 <section>
117 <div>
118 <label for="type">Type</label>
119 <select name="type">
120 <optgroup label="Professional">
121 <option value="bnp"<?php echo empty($selected)||$selected=='bnp'?' selected="selected"':''; ?>>Bnp</option>
122 <option value="poltrone"<?php echo !empty($selected)&&$selected=='poltrone'?' selected="selected"':''; ?>>Poltrone</option>
123 </optgroup>
124 <optgroup label="Personnal">
125 <option value="travail"<?php echo !empty($selected)&&$selected=='travail'?' selected="selected"':''; ?>>Travail</option>
126 <option value="achats"<?php echo !empty($selected)&&$selected=='achats'?' selected="selected"':''; ?>>Achat</option>
127 <option value="sante"<?php echo !empty($selected)&&$selected=='sante'?' selected="selected"':''; ?>>Sante</option>
128 <option value="famille"<?php echo !empty($selected)&&$selected=='famille'?' selected="selected"':''; ?>>Famille</option>
129 <option value="handicap"<?php echo !empty($selected)&&$selected=='handicap'?' selected="selected"':''; ?>>Handicap</option>
130 <option value="sport_animaux"<?php echo !empty($selected)&&$selected=='sport_animaux'?' selected="selected"':''; ?>>Sport</option>
131 <option value="convocation"<?php echo !empty($selected)&&$selected=='convocation'?' selected="selected"':''; ?>>Convocation</option>
132 <option value="missions"<?php echo !empty($selected)&&$selected=='missions'?' selected="selected"':''; ?>>Mission</option>
133 <option value="enfants"<?php echo !empty($selected)&&$selected=='enfants'?' selected="selected"':''; ?>>Enfant</option>
134 </optgroup>
135 </select>
136 </div>
137 </section>
138 <section>
139 <div>
140 <label for="firstname">Prénom</label>
141 <input type="text" name="firstname" value="<?php echo htmlspecialchars($_REQUEST['firstname']??''); ?>" />
142 </div>
143 <div>
144 <span>Jean</span>
145 </div>
146 </section>
147 <section>
148 <div>
149 <label for="lastname">Nom</label>
150 <input type="text" name="lastname" value="<?php echo htmlspecialchars($_REQUEST['lastname']??''); ?>" />
151 </div>
152 <div>
153 <span>Dupont</span>
154 </div>
155 </section>
156 <section>
157 <div>
158 <label for="birthdate">Date de naissance</label>
159 <input class="date" type="text" name="birthdate" value="<?php echo htmlspecialchars($_REQUEST['birthdate']??''); ?>" />
160 </div>
161 <div>
162 <span>01/01/1970</span>
163 </div>
164 </section>
165 <section>
166 <div>
167 <label for="birthplace">Lieu de naissance</label>
168 <input type="text" name="birthplace" value="<?php echo htmlspecialchars($_REQUEST['birthplace']??''); ?>" />
169 </div>
170 <div>
171 <span>Lyon</span>
172 </div>
173 </section>
174 <section>
175 <div>
176 <label for="address">Adresse</label>
177 <input type="text" name="address" value="<?php echo htmlspecialchars($_REQUEST['address']??''); ?>" />
178 </div>
179 <div>
180 <span>30 rue des boulets 75011 Paris</span>
181 </div>
182 </section>
183 <section>
184 <div>
185 <label for="function">Fonction</label>
186 <input type="text" name="function" value="<?php echo htmlspecialchars($_REQUEST['function']??'Technicien(e) d\'astreint(e)'); ?>" />
187 </div>
188 <div>
189 <span>Technicien(e) d'astreint(e)</span>
190 </div>
191 </section>
192 <section>
193 <div>
194 <label for="location">Fait à</label>
195 <input type="text" name="location" value="<?php echo htmlspecialchars($_REQUEST['location']??'Paris'); ?>" />
196 </div>
197 <div>
198 <span>Paris</span>
199 </div>
200 </section>
201 <section>
202 <div>
203 <label for="date">Sortie</label>
204 <input class="date" type="text" name="date" value="<?php echo htmlspecialchars($_REQUEST['date']??date('d/m/Y', $time)); ?>" />
205 <label for="time">a</label>
206 <input class="time" type="text" name="time" value="<?php echo htmlspecialchars($_REQUEST['time']??date('H:i', $time)); ?>" />
207 </div>
208 </section>
209 <section>
210 <div>
211 <input type="submit" value="Afficher" />
212 <input type="submit" name="download" value="Télécharger" />
213 <input type="submit" name="download" value="iBug" />
214 </div>
215 </form>
216 </section>
217 </body>
218 </html>
219 <?php
220 exit;
221 }
222
223 if (!empty($_SERVER['REQUEST_METHOD']) && $_SERVER['REQUEST_METHOD'] != 'GET' && !empty($_REQUEST['download']) && $_REQUEST['download'] == 'iBug') {
224 header('Location: '.$_SERVER['REQUEST_URI'].'?'.http_build_query($_REQUEST));
225 exit;
226 }
227
228 /**
229 * Ausweis class
230 */
231 class Ausweis {
232 /**
233 * Fix date
234 */
235 static function fixDate($date) {
236 $return = preg_replace(
237 [
238 '%^([0-9]{2})/([0-9]{2})/([0-9]{4})$%',
239 '%^([0-9]{2})/([0-9]{2})/([0-9]{2})$%',
240 '%^([0-9]{2})([0-9]{2})([0-9]{4})$%',
241 '%^([0-9]{2})([0-9]{2})([0-9]{2})$%'
242 ],
243 [
244 '\3-\2-\1',
245 '20\3-\2-\1',
246 '\3-\2-\1',
247 '20\3-\2-\1'
248 ],
249 $date
250 );
251 if (!preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2}$/', $return)) {
252 die('Unable to fix date "'.$date.'" please use dd/mm/aaaa format');
253 }
254 return $return;
255 }
256
257 /**
258 * Fix time
259 */
260 static function fixTime($time) {
261 $return = preg_replace(
262 [
263 '%^([0-9]{2}):([0-9]{2})%',
264 '%^([0-9]{2})h([0-9]{2})%',
265 '%^([0-9]{2})([0-9]{2})%'
266 ],
267 [
268 '\1:\2',
269 '\1:\2',
270 '\1:\2'
271 ],
272 $time
273 );
274 if (!preg_match('/^[0-9]{2}:[0-9]{2}$/', $return)) {
275 die('Unable to fix time "'.$time.'" please use HH:ii format');
276 }
277 return $return;
278 }
279
280 /**
281 * Add ausweis attestation
282 */
283 static function addAttestation($p, $reason, $firstname, $lastname, $birthdate, $birthplace, $address, $location, $date, $time) {
284 //Set positions
285 $pos = [];
286
287 //Add page
288 $p->AddPage();
289
290 //Set label length
291 $labelLength = 30;
292
293 //Set line height
294 $lineHeight = 7.9;
295
296 //Set title height
297 $titleHeight = 15;
298
299 //Disable auto page break
300 $p->SetAutoPageBreak(false, 0);
301
302 //Set margins
303 $p->SetMargins(23.8, 0);
304
305 //Set y
306 $p->SetY(12);
307
308 //Set font
309 $p->setFont('LiberationSerif', 'B', 17);
310
311 //Addd title
312 $p->Cell(0, 20, utf8_decode('ATTESTATION DE DÉPLACEMENT DÉROGATOIRE'), 0, 0, 'C');
313
314 //Set y
315 $p->SetY(28.5);
316
317 //Set font
318 $p->setFont('MicrosoftSansSerif', '', 10.5);
319
320 //Add legal mention
321 $p->Cell(0, 4, utf8_decode('En application du décret n°2020-1310 du 29 octobre 2020 prescrivant les mesures générales'), 0, 1, 'C');
322 $p->Cell(0, 4, utf8_decode('nécessaires pour faire face à l\'épidémie de Covid19 dans le cadre de l\'état d\'urgence sanitaire'), 0, 1, 'C');
323
324 //Set y
325 $p->setY(40.25);
326
327 //Add formal
328 $p->Cell(0, 4, utf8_decode('Je soussigné(e),'), 0, 1, 'L');
329
330 //Set y
331 $p->setY(46.25);
332
333 //Save name pos
334 $posName = $p->getY();
335
336 //Add employee
337 $p->Cell(0, 8, utf8_decode('Mme/M. :'), 0, 1, 'L');
338
339 //Save birth pos
340 $posBirth = $p->getY();
341
342 //Add birth
343 $p->Cell(75, 8, utf8_decode('Né(e) le :'), 0, 0, 'L');
344 $p->Cell(0, 8, utf8_decode('à :'), 0, 1, 'L');
345
346 //Save address pos
347 $posAddress = $p->getY();
348
349 //Add address
350 $p->Cell(0, 8, utf8_decode('Demeurant :'), 0, 1, 'L');
351
352 //Set y
353 $p->setY(71);
354
355 //Add certification
356 $p->Cell(0, 4.2, utf8_decode('certifie que mon déplacement est lié au motif suivant (cocher la case) autorisé par le décret'), 0, 1, 'L');
357 $p->Cell(0, 4.2, utf8_decode('n°2020-1310 du 29 octobre 2020 prescrivant les mesures générales nécessaires pour faire face à'), 0, 1, 'L');
358 $p->Cell(0, 4.2, utf8_decode('l\'épidémie de Covid19 dans le cadre de l\'état d\'urgence sanitaire¹ :'), 0, 1, 'L');
359
360 //Jump line
361 $p->Ln(3.5);
362
363 //Set box size
364 $boxSize = 5.85;
365
366 //Save y
367 $y = $p->getY();
368
369 //Set margins
370 $p->SetLeftMargin(37.5, 0);
371
372 //Add travail
373 $p->MultiCell(148, 4.25, utf8_decode('Déplacements entre le domicile et le lieu d\'exercice de l\'activité professionnelle ou un établissement d\'enseignement ou de formation, déplacements professionnels ne pouvant être différés², déplacements pour un concours ou un examen'), 0, 'J');
374
375 //Save travail position
376 $pos['travail'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
377
378 //Jump line
379 $p->Ln(6.5);
380
381 //Save y
382 $y = $p->getY();
383
384 //Add achats
385 $p->MultiCell(148, 4.25, utf8_decode('Déplacements pour effectuer des achats de fournitures nécessaires à l\'activité professionnelle, des achats de première nécessité³ dans des établissements dont les activités demeurent autorisées, le retrait de commande et les livraisons à domicile'), 0, 'J');
386
387 //Save achats position
388 $pos['achats'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
389
390 //Jump line
391 $p->Ln(6.5);
392
393 //Save y
394 $y = $p->getY();
395
396 //Add sante
397 $p->MultiCell(148, 4.25, utf8_decode('Consultations, examens et soins ne pouvant être ni assurés à distance et l\'achat de médicaments'), 0, 'J');
398
399 //Save sante position
400 $pos['sante'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
401
402 //Jump line
403 $p->Ln(6.5);
404
405 //Save y
406 $y = $p->getY();
407
408 //Add famille
409 $p->MultiCell(148, 4.25, utf8_decode('Déplacements pour motif familial impérieux, pour l\'assistance aux personnes vulnérables et précaires ou la garde d\'enfants'), 0, 'J');
410
411 //Save famille position
412 $pos['famille'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
413
414 //Jump line
415 $p->Ln(6.5);
416
417 //Save y
418 $y = $p->getY();
419
420 //Add handicap
421 $p->MultiCell(148, 4.25, utf8_decode('Déplacement des personnes en situation de handicap et leur accompagnant'), 0, 'J');
422
423 //Save handicap position
424 $pos['handicap'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
425
426 //Jump line
427 $p->Ln(6.5);
428
429 //Save y
430 $y = $p->getY();
431
432 //Add sport_animaux
433 $p->MultiCell(148, 4.25, utf8_decode('Déplacements brefs, dans la limite d\'une heure quotidienne et dans un rayon maximal d\'un kilomètre autour du domicile, liés soit à l\'activité physique individuelle des personnes, à l\'exclusion de toute pratique sportive collective et de toute proximité avec d\'autres personnes, soit à la promenade avec les seules personnes regroupées dans un même domicile, soit aux besoins des animaux de compagnie'), 0, 'J');
434
435 //Save sport_animaux position
436 $pos['sport_animaux'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
437
438 //Jump line
439 $p->Ln(6.5);
440
441 //Save y
442 $y = $p->getY();
443
444 //Add convocation
445 $p->MultiCell(148, 4.25, utf8_decode('Convocation judiciaire ou administrative et pour se rendre dans un service public'), 0, 'J');
446
447 //Save convocation position
448 $pos['convocation'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
449
450 //Jump line
451 $p->Ln(6.5);
452
453 //Save y
454 $y = $p->getY();
455
456 //Add missions
457 $p->MultiCell(148, 4.25, utf8_decode('Participation à des missions d\'intérêt général sur demande de l\'autorité administrative'), 0, 'J');
458
459 //Save missions position
460 $pos['missions'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
461
462 //Jump line
463 $p->Ln(6.5);
464
465 //Save y
466 $y = $p->getY();
467
468 //Add enfants
469 $p->MultiCell(148, 4.25, utf8_decode('Déplacement pour chercher les enfants à l\'école et à l\'occasion de leurs activités périscolaires'), 0, 'J');
470
471 //Save enfants position
472 $pos['enfants'] = $y + ($p->getY() - $y) / 2 - $boxSize / 2;
473
474 //Set line width
475 $p->SetLineWidth(0.5);
476
477 //Add boxes
478 foreach($pos as $k => $v) {
479 $p->Rect(27.75, $v, 5.85, 5.85);
480 }
481
482 //Set margins
483 $p->SetLeftMargin(23.9, 0);
484
485 //Set y
486 $p->SetY('-64.9', true);
487
488 //Save location pos
489 $posLocation = $p->getY();
490
491 //Add creation location
492 $p->Cell(0, 4, utf8_decode('Fait à :'), 0, 1, 'L');
493
494 //Set y
495 $p->SetY('-56.9', true);
496
497 //Save date pos
498 $posDate = $p->getY();
499
500 //Add creation date
501 $p->Cell(60.1, 4, utf8_decode('Le :'), 0, 0, 'L');
502 $p->Cell(0, 4, utf8_decode('à :'), 0, 1, 'L');
503
504 //Set y
505 $p->SetY('-51', true);
506
507 //Set font
508 $p->setFont('MicrosoftSansSerif', '', 10);
509
510 //Add creation mentions
511 $p->Cell(0, 4, utf8_decode('(Date et heure de début de sortie à mentionner obligatoirement)'), 0, 1, 'L');
512
513 //Set font
514 $p->setFont('MicrosoftSansSerif', '', 10.5);
515
516 //Set y
517 $p->SetY('-45.3', true);
518
519 //Add signature
520 $p->Cell(12, 4, utf8_decode('Signature :'), 0, 0, 'L');
521 $p->Ln($lineHeight);
522
523 //Place footer
524 $p->SetY('-33.25', true);
525
526 //Set font
527 $p->setFont('MicrosoftSansSerif', '', 8);
528
529 //Add notice
530 $p->Cell(12.5, 3.5, utf8_decode('¹'), 0, 0, 'C');
531 $p->MultiCell(0, 3.5, utf8_decode('Les personnes souhaitant bénéficier de l\'une de ces exceptions doivent se munir s\'il y a lieu, lors de leurs'."\n".'déplacements hors de leur domicile, d\'un document leur permettant de justifier que le déplacement considéré entre'."\n".'dans le champ de l\'une de ces exceptions'), 0, 'L');
532 $p->Ln(0);
533 $p->Cell(12.5, 3.5, utf8_decode('²'), 0, 0, 'C');
534 $p->MultiCell(0, 3.5, utf8_decode('A utiliser par les travailleurs non-salariés, lorsqu\'ils ne peuvent disposer d\'un justificatif de déplacement établi par leur'."\n".'employeur'), 0, 'L');
535 $p->Ln(0);
536 $p->Cell(12.5, 3.5, utf8_decode('³'), 0, 0, 'C');
537 $p->MultiCell(0, 3.5, utf8_decode('Y compris les acquisitions à titre gratuit (distribution de denrées alimentaires...) et les déplacements liés à la'."\n".'perception de prestations sociales et au retrait d\'espèces'), 0, 'L');
538 $p->Ln(0);
539
540 //Set font
541 $p->setFont('Helvetica', '', 11);
542
543 //Set y
544 $p->setXY(41, $posName);
545
546 //Add name
547 $p->Cell(0, 8, utf8_decode($firstname.' '.$lastname), 0, 0, 'L');
548
549 //Set y
550 $p->setXY(41, $posBirth);
551
552 //Fix birthdate
553 $birthdate = self::fixDate($birthdate);
554
555 //Add birth
556 $p->Cell(63, 8, utf8_decode($birthdate), 0, 0, 'L');
557 $p->Cell(0, 8, utf8_decode($birthplace), 0, 0, 'L');
558
559 //Set y
560 $p->setXY(46, $posAddress);
561
562 //Add address
563 $p->Cell(0, 7, utf8_decode($address), 0, 0, 'L');
564
565 //Set xy
566 $p->setXY(27.75, $pos[$reason]);
567
568 //Set y
569 $p->setXY(36, $posLocation);
570
571 //Add location
572 $p->Cell(0, 4, utf8_decode($location), 0, 0, 'L');
573
574 //Set y
575 $p->setXY(31, $posDate);
576
577 //Fix date
578 $date = self::fixDate($date);
579
580 //Fix time
581 $time = self::fixTime($time);
582
583 //Add date
584 $p->Cell(58, 4, utf8_decode($date), 0, 0, 'L');
585 $p->Cell(0, 4, utf8_decode($time), 0, 0, 'L');
586
587 //Set xy
588 $p->setXY(27.75, $pos[$reason]);
589
590 //Set font
591 $p->setFont('Helvetica', '', 16);
592
593 //Add cross
594 $p->Cell(0, 6.5, 'X', 0, 0, 'L');
595
596 //Set delay
597 $delay = rand(30, 60);
598
599 //Set qrdata
600 $qrData = [
601 'Cree le: '.date('d/m/Y \a H:i', strtotime('-'.$delay.' minutes', strtotime($date.' '.$time))),
602 'Nom: '.$lastname,
603 'Prenom: '.$firstname,
604 'Naissance: '.date('d/m/Y', strtotime($birthdate)).' a '.$birthplace,
605 'Adresse: '.$address,
606 'Sortie: '.date('d/m/Y \a H:i', strtotime($date.' '.$time)),
607 'Motifs: '.$reason
608 ];
609
610 //Set qr text
611 $qrText = implode(";\n ", $qrData);
612
613 //Set qr file
614 $qrFile = tmpfile();
615
616 //Set qr path
617 $qrPath = stream_get_meta_data($qrFile)['uri'];
618
619 //Output in png
620 #ob_start();
621 QRcode::png($qrText, $qrPath, QR_ECLEVEL_M, 6, 4, false);
622 #$qrPng = ob_get_contents();
623 #ob_end_clean();
624
625 //Add qrPng
626 $p->Image($qrPath, 146, 221, 40, 40, 'PNG');
627
628 //Add page
629 //XXX: add the attestation de déplacement dérogatoire page
630 $p->AddPage();
631
632 //Add qrPng
633 $p->Image($qrPath, 12.5, 12.5, 117, 0, 'PNG');
634 $p->Ln();
635 }
636
637 /**
638 * Add ausweis quittance
639 */
640 static function addQuittance($p, $firstname, $lastname, $address, $titleowner, $firstowner, $lastowner, $addressowner, $sign, $loyer, $charge) {
641 //Add employer page
642 $p->AddPage();
643
644 //Set label length
645 $labelLength = 80;
646
647 //Set line height
648 $lineHeight = 15;
649
650 //Set margins
651 $p->SetMargins(30, 0);
652
653 //Disable auto page break
654 $p->SetAutoPageBreak(false, 0);
655
656 //Jump line
657 $p->SetY($lineHeight);
658
659 //Set font
660 $p->setFont('Helvetica', 'B', 18);
661
662 //Addd title
663 $p->Cell(0, 20, utf8_decode('QUITTANCE DE LOYER'), 0, 0, 'C');
664
665 //Jump line
666 $p->Ln($titleHeight);
667
668 //Set font
669 $p->setFont('Times', '', 9);
670
671 //Add legal mention
672 $p->Cell(0, 5, utf8_decode('Quittance de loyer pour la période du '.date('01/m/Y', strtotime('-1 month')).' au '.date('d/m/Y', strtotime('-1 day', strtotime('first day of now')))), 0, 0, 'C');
673 $p->Ln();
674
675 //Jump line
676 $p->Ln($lineHeight);
677
678 //Set font
679 $p->setFont('Times', 'BU', 10);
680
681 //Add formal
682 $p->Cell($labelLength, 5, utf8_decode('Bailleur :'), 0, 0, 'L');
683 $p->Cell(0, 5, utf8_decode('Colocataire :'), 0, 0, 'L');
684
685 //Jump line
686 $p->Ln();
687
688 //Set font
689 $p->setFont('Times', '', 9);
690
691 //Add names
692 $p->Cell($labelLength, 5, utf8_decode($titleowner.' '.$firstowner.' '.$lastowner), 0, 0, 'L');
693 $p->Cell(0, 5, utf8_decode($firstname.' '.$lastname), 0, 0, 'L');
694 $p->Ln();
695 $p->Cell($labelLength, 5, utf8_decode($addressowner), 0, 0, 'L');
696 $p->Cell(0, 5, utf8_decode($address), 0, 0, 'L');
697
698 //Add formal
699 $p->Ln($lineHeight*1.5);
700
701 //Add date
702 $p->Cell(0, 5, utf8_decode('Angers le '.date('07/m/Y', strtotime('-1 month'))), 0, 0, 'R');
703
704 //Jump line
705 $p->Ln($lineHeight);
706
707 //Set font
708 $p->setFont('Times', 'BU', 10);
709
710 //Add formal
711 $p->Cell(0, 5, utf8_decode('Adresse de location :'), 0, 0, 'L');
712 $p->Ln();
713
714 //Set font
715 $p->setFont('Times', 'B', 9);
716
717 //Add address
718 $p->Cell(0, 5, utf8_decode($address), 0, 0, 'L');
719
720 //Add formal
721 $p->Ln($lineHeight);
722
723 //Set font
724 $p->setFont('Times', '', 10);
725
726 //Set total
727 $total = $loyer + $charge;
728
729 //Add mention
730 $p->MultiCell(0, 5, utf8_decode('Je soussigné '.$titleowner.' '.$firstowner.' '.$lastowner.', usufruitier du logement situé au '.$address.', déclare avoir reçu de '.$firstname.' '.$lastname.', colocataire de ce logement, la somme de '.str_replace('.', ',', sprintf('%.2f', $total)).' euros correspondant au loyer et aux charges dus pour la période allant du '.date('01/m/Y', strtotime('-1 month')).' au '.date('d/m/Y', strtotime('-1 day', strtotime('first day of now'))).'. Cette somme correspond aux montants suivants :'), 0, 'J');
731
732 //Add formal
733 $p->Ln($lineHeight);
734
735 //Add formal
736 $p->Cell(0, 5, utf8_decode('Loyer hors charge :'), 0, 0, 'L');
737 $p->Ln();
738
739 //Set font
740 $p->setFont('Times', '', 9);
741
742 $p->Cell(0, 5, utf8_decode(str_replace('.', ',', sprintf('%.2f', $loyer)).' euros'), 0, 0, 'L');
743
744 //Add formal
745 $p->Ln($lineHeight);
746
747 //Set font
748 $p->setFont('Times', '', 10);
749
750 //Add formal
751 $p->Cell(0, 5, utf8_decode('Provision pour charges :'), 0, 0, 'L');
752 $p->Ln();
753
754 //Set font
755 $p->setFont('Times', '', 9);
756
757 $p->Cell(0, 5, utf8_decode(str_replace('.', ',', sprintf('%.2f', $charge)).' euros'), 0, 0, 'L');
758
759 //Add formal
760 $p->Ln($lineHeight);
761
762 //Set font
763 $p->setFont('Times', 'BU', 10);
764
765 //Add formal
766 $p->Cell(0, 5, utf8_decode('Somme totale reçue :'), 0, 0, 'L');
767 $p->Ln();
768
769 //Set font
770 $p->setFont('Times', 'B', 9);
771
772 $p->Cell(0, 5, utf8_decode(str_replace('.', ',', sprintf('%.2f', $total)).' euros'), 0, 0, 'L');
773
774 //Add formal
775 $p->Ln($lineHeight);
776
777 //Set font
778 $p->setFont('Times', '', 10);
779
780 //Add formal
781 $p->Cell(0, 5, utf8_decode('Date du paiement :'), 0, 0, 'L');
782 $p->Ln();
783
784 //Set font
785 $p->setFont('Times', '', 9);
786 $p->Cell(0, 5, utf8_decode(date('05/m/Y', strtotime('-1 month')).' par virement'), 0, 0, 'L');
787
788 //Add formal
789 $p->Ln($lineHeight);
790
791 //Set Y
792 $p->setY(-60);
793
794 //Set font
795 $p->setFont('Times', '', 10);
796
797 //Add creation location
798 $p->Cell(0, 5, utf8_decode('Fait à Angers le '.date('07/m/Y', strtotime('-1 month'))), 0, 0, 'L');
799 $p->Ln();
800
801 //Add signature
802 $p->Cell(12, 5, utf8_decode('Signature :'), 0, 0, 'L');
803 $p->Ln();
804
805 //Add sign
806 $p->Image($sign, 45, 245, 30, 0, 'PNG');
807
808 //Set font
809 $p->setFont('Times', '', 10);
810
811 //Set Y
812 $p->setY(-30);
813
814 //Add legal
815 $p->MultiCell(0, 5, utf8_decode('La présente quittance est valable sous réserve d\'encaissement des sommes indiquées et de tous droits ou instances en cours. Elle n\'est libératoire que pour la période indiquée et n\'implique pas présomption de paiement des échéances antérieures qui pourraient rester dues.'), 0, 'J');
816 }
817
818 /**
819 * Add ausweis employer
820 */
821 static function addEmployer($p, $employerTitle, $employerFunction, $employerCompany, $employerCity, $logo, $stamp, $sign, $workplaces, $firstname, $lastname, $birthdate, $birthplace, $address, $function) {
822 //Add conveyances
823 $conveyances = [
824 'Bicyclette',
825 'Cyclomoteur',
826 'Marche',
827 'Transport en commun',
828 'Voiture'
829 ];
830
831 //Add employer page
832 $p->AddPage();
833
834 //Set label length
835 $labelLength = 51.75;
836
837 //Set line height
838 $lineHeight = 7.5;
839
840 //Set title height
841 $titleHeight = 18.5;
842
843 //Set margins
844 $p->SetMargins(25, 0);
845
846 //Disable auto page break
847 $p->SetAutoPageBreak(false, 0);
848
849 //Jump line
850 #$p->Ln($titleHeight);
851 $p->SetY($titleHeight);
852
853 //Set font
854 $p->setFont('TrebuchetMS', 'B', 16);
855
856 //Addd title
857 $p->Cell(0, 20, utf8_decode('JUSTIFICATIF DE DÉPLACEMENT PROFESSIONNEL'), 0, 0, 'C');
858
859 //Jump line
860 $p->Ln();
861
862 //Set font
863 $p->setFont('Times', '', 10);
864
865 //Add legal mention
866 $p->Cell(0, 5, utf8_decode('En application du décret n°2020-1310 du 29 octobre 2020 prescrivant les mesures générales nécessaires pour'), 0, 1, 'C');
867 $p->Cell(0, 5, utf8_decode('faire face à l\'épidémie de Covid19 dans le cadre de l\'état d\'urgence sanitaire'), 0, 1, 'C');
868
869 //Jump line
870 $p->Ln($lineHeight);
871
872 //Add formal
873 $p->Cell(0, 5, utf8_decode('Je soussigné(e),'), 0, 0, 'L');
874
875 //Jump line
876 $p->Ln($lineHeight);
877
878 //Add name
879 $p->Cell($labelLength, 5, utf8_decode('Nom et prénom de l\'employeur :'), 0, 0, 'L');
880 $p->Cell(0, 5, utf8_decode($employerTitle), 0, 0, 'L');
881
882 //Jump line
883 $p->Ln($lineHeight);
884
885 //Add functions
886 $p->Cell($labelLength, 5, utf8_decode('Fonctions :'), 0, 0, 'L');
887 $p->Cell(0, 5, utf8_decode($employerFunction), 0, 0, 'L');
888
889 //Jump line
890 $p->Ln($lineHeight);
891
892 //Add certification
893 $p->MultiCell(0, 5, utf8_decode('Certifie que les déplacements de la personne ci-après, entre son domicile et le ou les lieux d\'exercice de son activité professionnelle ou à l\'occasion de l\'exercice de ses fonctions, ne peuvent être différés ou sont indispensables à l\'exercice d\'activités ne pouvant être organisées sous forme de télétravail :'), 0, 'J');
894
895 //Jump line
896 $p->Ln($lineHeight-5);
897
898 //Add employee
899 $p->Cell($labelLength, 5, utf8_decode('Nom :'), 0, 0, 'L');
900 $p->Cell(0, 5, utf8_decode($lastname), 0, 0, 'L');
901 $p->Ln($lineHeight);
902 $p->Cell($labelLength, 5, utf8_decode('Prénom :'), 0, 0, 'L');
903 $p->Cell(0, 5, utf8_decode($firstname), 0, 0, 'L');
904 $p->Ln($lineHeight);
905 $p->Cell($labelLength, 5, utf8_decode('Date de naissance :'), 0, 0, 'L');
906 $p->Cell(0, 5, utf8_decode($birthdate), 0, 0, 'L');
907 $p->Ln($lineHeight);
908 $p->Cell($labelLength, 5, utf8_decode('Lieu de naissance :'), 0, 0, 'L');
909 $p->Cell(0, 5, utf8_decode($birthplace), 0, 0, 'L');
910 $p->Ln($lineHeight);
911 $p->Cell($labelLength, 5, utf8_decode('Adresse du domicile :'), 0, 0, 'L');
912 $p->Cell(0, 5, utf8_decode($address), 0, 0, 'L');
913 $p->Ln($lineHeight);
914 $p->Cell($labelLength, 5, utf8_decode('Nature de l\'activité professionnelle :'), 0, 0, 'L');
915 $p->Cell(0, 5, utf8_decode($function), 0, 0, 'L');
916 $p->Ln($lineHeight);
917
918 //Add conveyances
919 $p->Cell($labelLength, 5, utf8_decode('Moyens de déplacement :'), 0, 0, 'L');
920 $p->Cell(0, 5, /*' '.*/implode(', ', $conveyances), 0, 0, 'L');
921
922 //Jump line
923 $p->Ln($lineHeight);
924
925 //Add validity
926 $p->Cell($labelLength, 5, utf8_decode('Durée de validité :'), 0, 0, 'L');
927 $p->Cell(0, 5, utf8_decode('6 mois'), 0, 0, 'L');
928
929 //Jump line
930 $p->Ln($lineHeight);
931
932 //Add workplaces
933 $p->Cell(0, 5, utf8_decode('Lieux d\'exercice de l\'activité professionnelle :'), 0, 0, 'L');
934 foreach($workplaces as $siret => $location) {
935 $p->Ln(4);
936 #$p->cell($labelLength/1.5, 5, ' '.$siret.' :', 0, 0, 'l');
937 $p->cell(0, 5, ' '.utf8_decode($location), 0, 0, 'l');
938 }
939
940 //Jump line
941 #$p->Ln($lineHeight*2);
942
943 //Place footer
944 $p->SetY('-65', true);
945
946 //Add employer name
947 $p->Cell($labelLength, 5, utf8_decode('Nom et cachet de l\'employeur :'), 0, 0, 'L');
948 $p->Cell(0, 5, utf8_decode($employerCompany), 0, 0, 'L');
949
950 //Jump line
951 $p->Ln($lineHeight);
952
953 //Add sign location
954 $p->Cell($labelLength, 5, utf8_decode('Fait à :'), 0, 0, 'L');
955 $p->Cell(0, 5, utf8_decode($employerCity), 0, 0, 'L');
956
957 //Jump line
958 $p->Ln($lineHeight);
959
960 //Add sign date
961 $p->Cell($labelLength, 5, utf8_decode('Le :'), 0, 0, 'L');
962 $p->Cell(0, 5, utf8_decode('02 novembre 2020'), 0, 0, 'L');
963
964 //Jump line
965 $p->Ln($lineHeight);
966
967 //Place footer
968 $p->SetY('-40', true);
969
970 //Set font
971 $p->setFont('MicrosoftSansSerif', '', 7);
972
973 //Add notice
974 $p->Cell(0, 4, utf8_decode('Ce document, établi par l\'employeur, est suffisant pour justifier les déplacements professionnels d\'un salarié, qu\'il s\'agisse :'), 0, 0, 'L');
975 $p->Ln($lineHeight/2);
976 $p->Cell(0, 4, utf8_decode('- du trajet habituel entre le domicile et le lieu de travail du salarié ou des déplacements entre les différents lieux de travail lorsque la nature'), 0, 0, 'L');
977 $p->Ln($lineHeight/2);
978 $p->Cell(0, 4, utf8_decode('de ses fonctions l\'exige'), 0, 0, 'L');
979 $p->Ln($lineHeight/2);
980 $p->Cell(0, 4, utf8_decode('- des déplacements de nature professionnelle qui ne peuvent pas être différés, à la demande de l\'employeur.'), 0, 0, 'L');
981 $p->Ln($lineHeight/2);
982 $p->Cell(0, 4, utf8_decode('Il n\'est donc pas nécessaire que le salarié se munisse, en plus de ce justificatif, de l\'attestation de déplacement dérogatoire.'), 0, 0, 'L');
983 $p->Ln($lineHeight/2);
984 $p->Cell(0, 4, utf8_decode('Les travailleurs non-salariés, pour lesquels ce justificatif ne peut être établi, doivent en revanche se munir de l\'attestation de déplacement'), 0, 0, 'L');
985 $p->Ln($lineHeight/2);
986 $p->Cell(0, 4, utf8_decode('dérogatoire en cochant le premier motif de déplacement'), 0, 0, 'L');
987
988 //Add pictures
989 $p->Image($logo, 10, 8, 40, 0, 'PNG');
990 $p->Image($stamp, 130, 210, 60, 0, 'PNG');
991 $p->Image($sign, 110, 215, 25, 0, 'PNG');
992 }
993 }
994
995 /**
996 * Prefilled data
997 */
998 $data = [];
999
1000 /**
1001 * Bnp
1002 */
1003 if ($_REQUEST['type'] == 'bnp') {
1004 //Set employer
1005 $data['employer'] = [
1006 'title' => 'Jean-Laurent Bonnafé',
1007 'function' => 'Administrateur Directeur Général de BNP Paribas',
1008 'company' => 'BNP PARIBAS',
1009 'address' => '16 Boulevard des Italiens 75009 Paris',
1010 'city' => 'Paris',
1011 'vat' => 'FR76662042449'
1012 ];
1013
1014 //Set workplaces
1015 $data['workplaces'] = [
1016 //TODO: add others...
1017 66204244932405 => '37 place du Marché St Honoré 75001 Paris',
1018 66204244932355 => '36b avenue de l\'Opéra 75002 Paris',
1019 66204244920376 => '67 rue de Bretagne 75003 Paris',
1020 66204244919998 => '48 rue des Archives 75004 Paris',
1021 66204244915558 => '50 boulevard de Saint Marcel 75005 Paris',
1022 66204244920368 => '1 rue de Medicis 75006 Paris',
1023 66204244941596 => '64 rue de Sèvres 75007 Paris',
1024 66204244943238 => '10 boulevard Malesherbes 75008 Paris',
1025 66204244900014 => '16 boulevard des Italiens 75009 Paris',
1026 66204244932454 => '150 rue du fbg Poissonniere 75010 Paris',
1027 66204244941539 => '41 rue Basfroi 75011 Paris',
1028 66204244943733 => '47 boulevard Diderot 75012 Paris',
1029 66204244920897 => '109 rue de Tolbiac 75013 Paris',
1030 66204244941265 => '160 boulevard Macdonald 75019 Paris',
1031 66204244925110 => '4 place Saint Fargeau 75020 Paris',
1032 00000000000000 => 'Île-de-France',
1033 99999999999999 => 'France',
1034 ];
1035
1036 //Set pictures
1037 $data['sign'] = '../picture/ausweis/bnp/sign.png';
1038 $data['stamp'] = '../picture/ausweis/bnp/stamp.png';
1039 $data['logo'] = '../picture/ausweis/bnp/logo.png';
1040
1041 //Set reason
1042 $data['reason'] = 'travail';
1043 /**
1044 * Poltronesofa
1045 */
1046 } elseif ($_REQUEST['type'] == 'poltrone') {
1047 //Set employer
1048 $data['employer'] = [
1049 'title' => 'M Renzo Ricci',
1050 'function' => 'Président',
1051 'company' => 'POLTRONESOFA \'FRANCE',
1052 'address' => '6 Rue Jean Jaures 92800 Puteaux',
1053 'city' => 'Puteaux',
1054 'vat' => 'FR88422036905'
1055 ];
1056
1057 //Set workplaces
1058 $data['workplaces'] = [
1059 42203690500020 => 'Place du Marché St Honoré 75001 Paris',
1060 42203690500558 => '72 Boulevard de Sébastopol 75003 Paris',
1061 42203690500756 => 'Avenue de Fontainebleau 94320 Thiais',
1062 //42203690500749 => 'Cc Opensky Lot A03 78200 Buchelay',
1063 //42203690500681 => 'L\'oseraie 95520 Osny',
1064 42203690500533 => '1 rue de la Mare au Chanvre 91700 Sainte-Geneviève-des-Bois',
1065 42203690500483 => '23 rue Alexandre Chatrian 77410 Claye-Souilly',
1066 42203690500434 => 'Route Nationale 10 78210 Coignières',
1067 42203690500186 => 'Avenue Henri Barbusse 78340 Les Clayes-sous-Bois',
1068 42203690500152 => 'La Saussaie Beauclair 93110 Rosny-sous-Bois',
1069 42203690500095 => '234 Boulevard du Havre 95220 Pierrelaye'
1070 ];
1071
1072 //Set pictures
1073 $data['sign'] = '../picture/ausweis/poltrone/sign.png';
1074 $data['stamp'] = '../picture/ausweis/poltrone/stamp.png';
1075 $data['logo'] = '../picture/ausweis/poltrone/logo.png';
1076
1077 //Set reason
1078 $data['reason'] = 'travail';
1079 /**
1080 * Sport
1081 */
1082 } elseif ($_REQUEST['type'] == 'sport_animaux') {
1083 //Set reason
1084 $data['reason'] = 'sport_animaux';
1085 $data['sign'] = '../picture/ausweis/bnp/sign.png';
1086 /**
1087 * Achats
1088 */
1089 } elseif ($_REQUEST['type'] == 'achats') {
1090 //Set reason
1091 $data['reason'] = 'achats';
1092 $data['sign'] = '../picture/ausweis/bnp/sign.png';
1093 /**
1094 * Others:
1095 * - travail: 578,
1096 * - achats: 533,
1097 * - sante: 477,
1098 * - famille: 435,
1099 * - handicap: 396,
1100 * - sport_animaux: 358,
1101 * - convocation: 295,
1102 * - missions: 255,
1103 * - enfants: 211,
1104 */
1105 } elseif (in_array($_REQUEST['type'], $reasons)) {
1106 //Set reason
1107 $data['reason'] = $_REQUEST['type'];
1108 /**
1109 * Unknown
1110 */
1111 } else {
1112 die('TODO');
1113 }
1114
1115 //Set filename
1116 //XXX: was Ausweis_ now we use Travail_firstname_lastname.pdf
1117 $fileName = ucfirst($data['reason']).'_'.preg_replace(['/[^a-zA-Z0-9]/', '/__+/'], ['_', '_'], $_REQUEST['firstname'].'_'.$_REQUEST['lastname']).'_'.date('Ymd_Hi', strtotime(Ausweis::fixDate($_REQUEST['date']).' '.Ausweis::fixTime($_REQUEST['time']))).'.pdf';
1118
1119 //Create pdf object
1120 $p = new FPDF('P', 'mm', 'A4');
1121
1122 //Add marianne bold
1123 #$p->AddFont('Marianne-Bold', '', 'marianne-bold.php');
1124 #$p->AddFont('Marianne-Bold', 'B', 'marianne-bold.php');
1125 #$p->AddFont('Marianne-Bold', 'BI', 'marianne-bold.php');
1126 #$p->AddFont('Marianne-Bold', 'I', 'marianne-bold.php');
1127
1128 //Add mariane regular
1129 #$p->AddFont('Marianne-Regular', '', 'marianne-regular.php');
1130 #$p->AddFont('Marianne-Regular', 'B', 'marianne-regular.php');
1131 #$p->AddFont('Marianne-Regular', 'BI', 'marianne-regular.php');
1132 #$p->AddFont('Marianne-Regular', 'I', 'marianne-regular.php');
1133
1134 //Add trebuchet ms
1135 $p->AddFont('TrebuchetMS', '', 'trebuc.php');
1136 $p->AddFont('TrebuchetMS', 'B', 'trebucb.php');
1137 $p->AddFont('TrebuchetMS', 'BI', 'trebucbi.php');
1138 $p->AddFont('TrebuchetMS', 'I', 'trebuci.php');
1139
1140 //Add liberation serif
1141 $p->AddFont('LiberationSerif', '', 'liberationserif.php');
1142 $p->AddFont('LiberationSerif', 'B', 'liberationserifb.php');
1143 $p->AddFont('LiberationSerif', 'BI', 'liberationserifbi.php');
1144 $p->AddFont('LiberationSerif', 'I', 'liberationserifi.php');
1145
1146 //Add microsoft sans serif
1147 $p->AddFont('MicrosoftSansSerif', '', 'micross.php');
1148 $p->AddFont('MicrosoftSansSerif', 'B', 'micross.php');
1149 $p->AddFont('MicrosoftSansSerif', 'BI', 'micross.php');
1150 $p->AddFont('MicrosoftSansSerif', 'I', 'micross.php');
1151
1152 //Set creator
1153 $p->SetTitle('Justificatif de déplacement professionnel', true);
1154 $p->SetCreator($_SERVER['PHP_SELF'], true);
1155 $p->SetAuthor('Französischer Kommandantur', true);
1156 $p->SetSubject('Verkehrsausweis', true);
1157
1158 /**
1159 * Add attestation
1160 */
1161 Ausweis::addAttestation(
1162 $p,
1163 $data['reason'],
1164 $_REQUEST['firstname'],
1165 $_REQUEST['lastname'],
1166 $_REQUEST['birthdate'],
1167 $_REQUEST['birthplace'],
1168 $_REQUEST['address'],
1169 $_REQUEST['location'],
1170 $_REQUEST['date'],
1171 $_REQUEST['time']
1172 );
1173
1174 /**
1175 * Employer attestation type
1176 */
1177 //XXX: add the justificatif de déplacement professionnel page
1178 if (!empty($data['employer'])) {
1179 /**
1180 * Add employer attestation
1181 */
1182 Ausweis::addEmployer(
1183 $p,
1184 $data['employer']['title'],
1185 $data['employer']['function'],
1186 $data['employer']['company'],
1187 $data['employer']['city'],
1188 $data['logo'],
1189 $data['stamp'],
1190 $data['sign'],
1191 $data['workplaces'],
1192 $_REQUEST['firstname'],
1193 $_REQUEST['lastname'],
1194 $_REQUEST['birthdate'],
1195 $_REQUEST['birthplace'],
1196 $_REQUEST['address'],
1197 $_REQUEST['function']
1198 );
1199 }
1200
1201 /**
1202 * Personnal sport and buy attestation type
1203 */
1204 if ($data['reason'] == 'sport_animaux' || $data['reason'] == 'achats') {
1205 /**
1206 * Add quittance attestation
1207 */
1208 Ausweis::addQuittance(
1209 $p,
1210 $_REQUEST['firstname'],
1211 $_REQUEST['lastname'],
1212 $_REQUEST['address'],
1213 'M.',
1214 'Jean',
1215 'Larivière',
1216 '6 chemin Bas des Plaines 49000 Angers',
1217 '../picture/ausweis/bnp/sign.png',
1218 705.55,
1219 125.00,
1220 );
1221 }
1222
1223 //Close document
1224 $p->Close();
1225
1226 //Send common headers
1227 header('Content-Type: application/pdf');
1228
1229 //Send download headers
1230 if (!empty($_REQUEST['download'])) {
1231 if ($_REQUEST['download'] == 'iBug') {
1232 header('Content-Type: application/octet-stream');
1233 }
1234 header('Content-Disposition: attachment; filename="'.rawurlencode($fileName).'"');
1235 //Send display headers
1236 } else {
1237 header('Content-Disposition: inline; filename="'.rawurlencode($fileName).'"');
1238 }
1239
1240 //Send remaining headers
1241 header('Cache-Control: private, max-age=0, must-revalidate');
1242 header('Pragma: public');
1243
1244 //Save output
1245 $output = $p->Output('S');
1246
1247 //Send content-length
1248 header('Content-Length: '.strlen($output));
1249
1250 //Display the pdf
1251 echo $output;