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/**
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        return new $mPdfClass($options);
65    }
66
67    /**
68     * Save PhpWord to file.
69     */
70    public function save(string $filename): void
71    {
72        $fileHandle = parent::prepareForSave($filename);
73
74        //  PDF settings
75        $paperSize = strtoupper('A4');
76        $orientation = strtoupper('portrait');
77
78        //  Create PDF
79        $pdf = $this->createExternalWriterInstance();
80        $pdf->_setPageSize($paperSize, $orientation);
81        $pdf->addPage($orientation);
82
83        // Write document properties
84        $phpWord = $this->getPhpWord();
85        $docProps = $phpWord->getDocInfo();
86        $pdf->setTitle($docProps->getTitle());
87        $pdf->setAuthor($docProps->getCreator());
88        $pdf->setSubject($docProps->getSubject());
89        $pdf->setKeywords($docProps->getKeywords());
90        $pdf->setCreator($docProps->getCreator());
91
92        $html = $this->getContent();
93        $bodyLocation = strpos($html, self::SIMULATED_BODY_START);
94        if ($bodyLocation === false) {
95            $bodyLocation = strpos($html, self::BODY_TAG);
96            if ($bodyLocation !== false) {
97                $bodyLocation += strlen(self::BODY_TAG);
98            }
99        }
100        // Make sure first data presented to Mpdf includes body tag
101        //   (and any htmlpageheader/htmlpagefooter tags)
102        //   so that Mpdf doesn't parse it as content. Issue 2432.
103        if ($bodyLocation !== false) {
104            $pdf->WriteHTML(substr($html, 0, $bodyLocation));
105            $html = substr($html, $bodyLocation);
106        }
107        foreach (explode("\n", $html) as $line) {
108            $pdf->WriteHTML("$line\n");
109        }
110
111        //  Write to file
112        fwrite($fileHandle, $pdf->output($filename, 'S'));
113
114        parent::restoreStateAfterSave($fileHandle);
115    }
116
117    /**
118     * Return classname of MPDF to instantiate.
119     *
120     * @codeCoverageIgnore
121     *
122     * @return string
123     */
124    private function getMPdfClassName()
125    {
126        if ($this->includeFile != null) {
127            // MPDF version 5.*
128            return '\mpdf';
129        }
130
131        // MPDF version > 6.*
132        return '\Mpdf\Mpdf';
133    }
134}