Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
96.88% covered (success)
96.88%
31 / 32
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
MPDF
96.88% covered (success)
96.88%
31 / 32
50.00% covered (danger)
50.00%
1 / 2
11
0.00% covered (danger)
0.00%
0 / 1
 __construct
n/a
0 / 0
n/a
0 / 0
2
 createExternalWriterInstance
83.33% covered (warning)
83.33%
5 / 6
0.00% covered (danger)
0.00%
0 / 1
2.02
 save
100.00% covered (success)
100.00%
26 / 26
100.00% covered (success)
100.00%
1 / 1
5
 getMPdfClassName
n/a
0 / 0
n/a
0 / 0
2
1<?php
2
3/**
4 * This file is part of PHPWord - A pure PHP library for reading and writing
5 * word processing documents.
6 *
7 * PHPWord is free software distributed under the terms of the GNU Lesser
8 * General Public License version 3 as published by the Free Software Foundation.
9 *
10 * For the full copyright and license information, please read the LICENSE
11 * file that was distributed with this source code. For the full list of
12 * contributors, visit https://github.com/PHPOffice/PHPWord/contributors.
13 *
14 * @see         https://github.com/PHPOffice/PhpWord
15 *
16 * @license     http://www.gnu.org/licenses/lgpl.txt LGPL version 3
17 */
18
19namespace PhpOffice\PhpWord\Writer\PDF;
20
21use PhpOffice\PhpWord\PhpWord;
22use PhpOffice\PhpWord\Settings;
23use PhpOffice\PhpWord\Writer\WriterInterface;
24
25/**
26 * MPDF writer.
27 *
28 * @see  http://www.mpdf1.com/
29 * @since 0.11.0
30 */
31class MPDF extends AbstractRenderer implements WriterInterface
32{
33    public const SIMULATED_BODY_START = '<!-- simulated body start -->';
34    private const BODY_TAG = '<body>';
35
36    /**
37     * Overridden to set the correct includefile, only needed for MPDF 5.
38     *
39     * @codeCoverageIgnore
40     */
41    public function __construct(PhpWord $phpWord)
42    {
43        if (file_exists(Settings::getPdfRendererPath() . '/mpdf.php')) {
44            // MPDF version 5.* needs this file to be included, later versions not
45            $this->includeFile = 'mpdf.php';
46        }
47        parent::__construct($phpWord);
48    }
49
50    /**
51     * Gets the implementation of external PDF library that should be used.
52     *
53     * @return \Mpdf\Mpdf implementation
54     */
55    protected function createExternalWriterInstance()
56    {
57        $mPdfClass = $this->getMPdfClassName();
58
59        $options = [];
60        if ($this->getFont()) {
61            $options['default_font'] = $this->getFont();
62        }
63
64        $options['tempDir'] = Settings::getPdfRendererOptions()['tempDir'] ?? sys_get_temp_dir() . '/mpdf';
65
66        return new $mPdfClass($options);
67    }
68
69    /**
70     * Save PhpWord to file.
71     */
72    public function save(string $filename): void
73    {
74        $fileHandle = parent::prepareForSave($filename);
75
76        //  PDF settings
77        $paperSize = strtoupper('A4');
78        $orientation = strtoupper('portrait');
79
80        //  Create PDF
81        $pdf = $this->createExternalWriterInstance();
82        $pdf->_setPageSize($paperSize, $orientation);
83        $pdf->addPage($orientation);
84
85        // Write document properties
86        $phpWord = $this->getPhpWord();
87        $docProps = $phpWord->getDocInfo();
88        $pdf->setTitle($docProps->getTitle());
89        $pdf->setAuthor($docProps->getCreator());
90        $pdf->setSubject($docProps->getSubject());
91        $pdf->setKeywords($docProps->getKeywords());
92        $pdf->setCreator($docProps->getCreator());
93
94        $html = $this->getContent();
95        $bodyLocation = strpos($html, self::SIMULATED_BODY_START);
96        if ($bodyLocation === false) {
97            $bodyLocation = strpos($html, self::BODY_TAG);
98            if ($bodyLocation !== false) {
99                $bodyLocation += strlen(self::BODY_TAG);
100            }
101        }
102        // Make sure first data presented to Mpdf includes body tag
103        //   (and any htmlpageheader/htmlpagefooter tags)
104        //   so that Mpdf doesn't parse it as content. Issue 2432.
105        if ($bodyLocation !== false) {
106            $pdf->WriteHTML(substr($html, 0, $bodyLocation));
107            $html = substr($html, $bodyLocation);
108        }
109        foreach (explode("\n", $html) as $line) {
110            $pdf->WriteHTML("$line\n");
111        }
112
113        //  Write to file
114        fwrite($fileHandle, $pdf->output($filename, 'S'));
115
116        parent::restoreStateAfterSave($fileHandle);
117    }
118
119    /**
120     * Return classname of MPDF to instantiate.
121     *
122     * @codeCoverageIgnore
123     *
124     * @return string
125     */
126    private function getMPdfClassName()
127    {
128        if ($this->includeFile != null) {
129            // MPDF version 5.*
130            return '\mpdf';
131        }
132
133        // MPDF version > 6.*
134        return '\Mpdf\Mpdf';
135    }
136}