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