1<?php
2/**
3 * TCPDF wrapper class.
4 */
5
6declare(strict_types=1);
7
8namespace PhpMyAdmin;
9
10use Exception;
11use TCPDF;
12use TCPDF_FONTS;
13use function count;
14use function strlen;
15use function strtr;
16
17/**
18 * PDF export base class providing basic configuration.
19 */
20class Pdf extends TCPDF
21{
22    /** @var array */
23    public $footerset;
24
25    /** @var array */
26    public $alias = [];
27
28    /**
29     * PDF font to use.
30     */
31    public const PMA_PDF_FONT = 'DejaVuSans';
32
33    /**
34     * Constructs PDF and configures standard parameters.
35     *
36     * @param string    $orientation page orientation
37     * @param string    $unit        unit
38     * @param string    $format      the format used for pages
39     * @param bool      $unicode     true means that the input text is unicode
40     * @param string    $encoding    charset encoding; default is UTF-8.
41     * @param bool      $diskcache   DEPRECATED TCPDF FEATURE
42     * @param false|int $pdfa        If not false, set the document to PDF/A mode and the good version (1 or 3)
43     *
44     * @throws Exception
45     *
46     * @access public
47     */
48    public function __construct(
49        $orientation = 'P',
50        $unit = 'mm',
51        $format = 'A4',
52        $unicode = true,
53        $encoding = 'UTF-8',
54        $diskcache = false,
55        $pdfa = false
56    ) {
57        parent::__construct(
58            $orientation,
59            $unit,
60            $format,
61            $unicode,
62            $encoding,
63            $diskcache,
64            $pdfa
65        );
66        $this->SetAuthor('phpMyAdmin ' . PMA_VERSION);
67        $this->AddFont('DejaVuSans', '', 'dejavusans.php');
68        $this->AddFont('DejaVuSans', 'B', 'dejavusansb.php');
69        $this->SetFont(self::PMA_PDF_FONT, '', 14);
70        $this->setFooterFont([self::PMA_PDF_FONT, '', 14]);
71    }
72
73    /**
74     * This function must be named "Footer" to work with the TCPDF library
75     *
76     * @return void
77     */
78    // @codingStandardsIgnoreLine
79    public function Footer()
80    {
81        // Check if footer for this page already exists
82        if (isset($this->footerset[$this->page])) {
83            return;
84        }
85
86        $this->SetY(-15);
87        $this->SetFont(self::PMA_PDF_FONT, '', 14);
88        $this->Cell(
89            0,
90            6,
91            __('Page number:') . ' '
92            . $this->getAliasNumPage() . '/' . $this->getAliasNbPages(),
93            'T',
94            0,
95            'C'
96        );
97        $this->Cell(0, 6, Util::localisedDate(), 0, 1, 'R');
98        $this->SetY(20);
99
100        // set footerset
101        $this->footerset[$this->page] = 1;
102    }
103
104    /**
105     * Function to set alias which will be expanded on page rendering.
106     *
107     * @param string $name  name of the alias
108     * @param string $value value of the alias
109     *
110     * @return void
111     */
112    public function setAlias($name, $value)
113    {
114        $name = TCPDF_FONTS::UTF8ToUTF16BE(
115            $name,
116            false,
117            true,
118            $this->CurrentFont
119        );
120        $this->alias[$name] = TCPDF_FONTS::UTF8ToUTF16BE(
121            $value,
122            false,
123            true,
124            $this->CurrentFont
125        );
126    }
127
128    // phpcs:disable PSR2.Methods.MethodDeclaration.Underscore
129
130    /**
131     * Improved with alias expanding.
132     *
133     * @return void
134     */
135    public function _putpages()
136    {
137        if (count($this->alias) > 0) {
138            $nbPages = count($this->pages);
139            for ($n = 1; $n <= $nbPages; $n++) {
140                $this->pages[$n] = strtr($this->pages[$n], $this->alias);
141            }
142        }
143        parent::_putpages();
144        // phpcs:enable
145    }
146
147    /**
148     * Displays an error message
149     *
150     * @param string $error_message the error message
151     *
152     * @return void
153     */
154    // @codingStandardsIgnoreLine
155    public function Error($error_message = '')
156    {
157        echo Message::error(
158            __('Error while creating PDF:') . ' ' . $error_message
159        )->getDisplay();
160        exit;
161    }
162
163    /**
164     * Sends file as a download to user.
165     *
166     * @param string $filename file name
167     *
168     * @return void
169     */
170    public function download($filename)
171    {
172        $pdfData = $this->getPDFData();
173        Response::getInstance()->disable();
174        Core::downloadHeader(
175            $filename,
176            'application/pdf',
177            strlen($pdfData)
178        );
179        echo $pdfData;
180    }
181}
182