1<?php
2/**
3 * Copyright since 2007 PrestaShop SA and Contributors
4 * PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5 *
6 * NOTICE OF LICENSE
7 *
8 * This source file is subject to the Open Software License (OSL 3.0)
9 * that is bundled with this package in the file LICENSE.md.
10 * It is also available through the world-wide-web at this URL:
11 * https://opensource.org/licenses/OSL-3.0
12 * If you did not receive a copy of the license and are unable to
13 * obtain it through the world-wide-web, please send an email
14 * to license@prestashop.com so we can send you a copy immediately.
15 *
16 * DISCLAIMER
17 *
18 * Do not edit or add to this file if you wish to upgrade PrestaShop to newer
19 * versions in the future. If you wish to customize PrestaShop for your
20 * needs please refer to https://devdocs.prestashop.com/ for more information.
21 *
22 * @author    PrestaShop SA and Contributors <contact@prestashop.com>
23 * @copyright Since 2007 PrestaShop SA and Contributors
24 * @license   https://opensource.org/licenses/OSL-3.0 Open Software License (OSL 3.0)
25 */
26
27/**
28 * @since 1.5
29 */
30class PDFGeneratorCore extends TCPDF
31{
32    const DEFAULT_FONT = 'helvetica';
33
34    /**
35     * @var string
36     */
37    public $header;
38
39    /**
40     * @var string
41     */
42    public $footer;
43
44    /**
45     * @var string
46     */
47    public $pagination;
48
49    /**
50     * @var string
51     */
52    public $content;
53
54    /**
55     * @var string
56     */
57    public $font;
58
59    /**
60     * @var array
61     */
62    public $font_by_lang = [
63        'ja' => 'cid0jp',
64        'bg' => 'freeserif',
65        'ru' => 'freeserif',
66        'uk' => 'freeserif',
67        'mk' => 'freeserif',
68        'el' => 'freeserif',
69        'en' => 'dejavusans',
70        'vn' => 'dejavusans',
71        'pl' => 'dejavusans',
72        'ar' => 'dejavusans',
73        'fa' => 'dejavusans',
74        'ur' => 'dejavusans',
75        'az' => 'dejavusans',
76        'ca' => 'dejavusans',
77        'gl' => 'dejavusans',
78        'hr' => 'dejavusans',
79        'sr' => 'dejavusans',
80        'si' => 'dejavusans',
81        'cs' => 'dejavusans',
82        'sk' => 'dejavusans',
83        'ka' => 'dejavusans',
84        'he' => 'dejavusans',
85        'lo' => 'dejavusans',
86        'lt' => 'dejavusans',
87        'lv' => 'dejavusans',
88        'tr' => 'dejavusans',
89        'ko' => 'cid0kr',
90        'zh' => 'cid0cs',
91        'tw' => 'cid0cs',
92        'th' => 'freeserif',
93    ];
94
95    /**
96     * @param bool $use_cache
97     * @param string $orientation
98     */
99    public function __construct($use_cache = false, $orientation = 'P')
100    {
101        parent::__construct($orientation, 'mm', 'A4', true, 'UTF-8', $use_cache, false);
102        $this->setRTL(Context::getContext()->language->is_rtl);
103    }
104
105    /**
106     * set the PDF encoding.
107     *
108     * @param string $encoding
109     */
110    public function setEncoding($encoding)
111    {
112        $this->encoding = $encoding;
113    }
114
115    /**
116     * set the PDF header.
117     *
118     * @param string $header HTML
119     */
120    public function createHeader($header)
121    {
122        $this->header = $header;
123    }
124
125    /**
126     * set the PDF footer.
127     *
128     * @param string $footer HTML
129     */
130    public function createFooter($footer)
131    {
132        $this->footer = $footer;
133    }
134
135    /**
136     * create the PDF content.
137     *
138     * @param string $content HTML
139     */
140    public function createContent($content)
141    {
142        $this->content = $content;
143    }
144
145    /**
146     * create the PDF pagination.
147     *
148     * @param string $pagination HTML
149     */
150    public function createPagination($pagination)
151    {
152        $this->pagination = $pagination;
153    }
154
155    /**
156     * Change the font.
157     *
158     * @param string $iso_lang
159     */
160    public function setFontForLang($iso_lang)
161    {
162        if (array_key_exists($iso_lang, $this->font_by_lang)) {
163            $this->font = $this->font_by_lang[$iso_lang];
164        } else {
165            $this->font = self::DEFAULT_FONT;
166        }
167
168        $this->setHeaderFont([$this->font, '', PDF_FONT_SIZE_MAIN, '', false]);
169        $this->setFooterFont([$this->font, '', PDF_FONT_SIZE_MAIN, '', false]);
170
171        $this->setFont($this->font, '', PDF_FONT_SIZE_MAIN, '', false);
172    }
173
174    /**
175     * @see TCPDF::Header()
176     */
177    public function Header()
178    {
179        $this->writeHTML($this->header);
180    }
181
182    /**
183     * @see TCPDF::Footer()
184     */
185    public function Footer()
186    {
187        $this->writeHTML($this->footer);
188        $this->FontFamily = self::DEFAULT_FONT;
189        $this->writeHTML($this->pagination);
190    }
191
192    /**
193     * Render HTML template.
194     *
195     * @param string $filename
196     * @param bool $display true:display to user, false:save, 'I','D','S' as fpdf display
197     *
198     * @throws PrestaShopException
199     *
200     * @return string HTML rendered
201     */
202    public function render($filename, $display = true)
203    {
204        if (empty($filename)) {
205            throw new PrestaShopException('Missing filename.');
206        }
207
208        $this->lastPage();
209
210        if ($display === true) {
211            $output = 'D';
212        } elseif ($display === false) {
213            $output = 'S';
214        } elseif ($display == 'D') {
215            $output = 'D';
216        } elseif ($display == 'S') {
217            $output = 'S';
218        } elseif ($display == 'F') {
219            $output = 'F';
220        } else {
221            $output = 'I';
222        }
223
224        return $this->Output($filename, $output);
225    }
226
227    /**
228     * Write a PDF page.
229     */
230    public function writePage()
231    {
232        $this->SetHeaderMargin(5);
233        $this->SetFooterMargin(21);
234        $this->setMargins(10, 40, 10);
235        $this->AddPage();
236        $this->writeHTML($this->content, true, false, true, false, '');
237    }
238
239    /**
240     * Override of TCPDF::getRandomSeed() - getmypid() is blocked on several hosting.
241     *
242     * @param string $seed
243     *
244     * @return string
245     */
246    protected function getRandomSeed($seed = '')
247    {
248        $seed .= microtime();
249
250        if (function_exists('openssl_random_pseudo_bytes') && (strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN')) {
251            // this is not used on windows systems because it is very slow for a know bug
252            $seed .= openssl_random_pseudo_bytes(512);
253        } else {
254            for ($i = 0; $i < 23; ++$i) {
255                $seed .= uniqid('', true);
256            }
257        }
258
259        $seed .= uniqid('', true);
260        $seed .= mt_rand(0, mt_getrandmax());
261        $seed .= __FILE__;
262        $seed .= $this->bufferlen;
263
264        if (isset($_SERVER['REMOTE_ADDR'])) {
265            $seed .= $_SERVER['REMOTE_ADDR'];
266        }
267        if (isset($_SERVER['HTTP_USER_AGENT'])) {
268            $seed .= $_SERVER['HTTP_USER_AGENT'];
269        }
270        if (isset($_SERVER['HTTP_ACCEPT'])) {
271            $seed .= $_SERVER['HTTP_ACCEPT'];
272        }
273        if (isset($_SERVER['HTTP_ACCEPT_ENCODING'])) {
274            $seed .= $_SERVER['HTTP_ACCEPT_ENCODING'];
275        }
276        if (isset($_SERVER['HTTP_ACCEPT_LANGUAGE'])) {
277            $seed .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
278        }
279        if (isset($_SERVER['HTTP_ACCEPT_CHARSET'])) {
280            $seed .= $_SERVER['HTTP_ACCEPT_CHARSET'];
281        }
282
283        $seed .= mt_rand(0, mt_getrandmax());
284        $seed .= uniqid('', true);
285        $seed .= microtime();
286
287        return $seed;
288    }
289}
290