Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
97.22% covered (success)
97.22%
35 / 36
85.71% covered (warning)
85.71%
6 / 7
CRAP
0.00% covered (danger)
0.00%
0 / 1
XMLWriter
97.22% covered (success)
97.22%
35 / 36
85.71% covered (warning)
85.71%
6 / 7
21
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
11 / 11
100.00% covered (success)
100.00%
1 / 1
5
 __destruct
75.00% covered (warning)
75.00%
3 / 4
0.00% covered (danger)
0.00%
0 / 1
4.25
 getData
100.00% covered (success)
100.00%
4 / 4
100.00% covered (success)
100.00%
1 / 1
2
 writeElementBlock
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 writeElementIf
100.00% covered (success)
100.00%
6 / 6
100.00% covered (success)
100.00%
1 / 1
3
 writeAttributeIf
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
2
 writeAttribute
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
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\Shared;
19
20use Exception;
21use ReturnTypeWillChange;
22
23/**
24 * XMLWriter.
25 *
26 * @method bool endElement()
27 * @method mixed flush(bool $empty = null)
28 * @method bool openMemory()
29 * @method string outputMemory(bool $flush = null)
30 * @method bool setIndent(bool $indent)
31 * @method bool startDocument(string $version = 1.0, string $encoding = null, string $standalone = null)
32 * @method bool startElement(string $name)
33 * @method bool text(string $content)
34 * @method bool writeCData(string $content)
35 * @method bool writeComment(string $content)
36 * @method bool writeElement(string $name, string $content = null)
37 * @method bool writeRaw(string $content)
38 */
39class XMLWriter extends \XMLWriter
40{
41    /** Temporary storage method */
42    const STORAGE_MEMORY = 1;
43    const STORAGE_DISK = 2;
44
45    /**
46     * Temporary filename.
47     *
48     * @var string
49     */
50    private $tempFileName = '';
51
52    /**
53     * Create a new \PhpOffice\PhpWord\Shared\XMLWriter instance.
54     *
55     * @param int $pTemporaryStorage Temporary storage location
56     * @param string $pTemporaryStorageDir Temporary storage folder
57     * @param bool $compatibility
58     */
59    public function __construct($pTemporaryStorage = self::STORAGE_MEMORY, $pTemporaryStorageDir = null, $compatibility = false)
60    {
61        // Open temporary storage
62        if ($pTemporaryStorage == self::STORAGE_MEMORY) {
63            $this->openMemory();
64        } else {
65            if (!$pTemporaryStorageDir || !is_dir($pTemporaryStorageDir)) {
66                $pTemporaryStorageDir = sys_get_temp_dir();
67            }
68            // Create temporary filename
69            $this->tempFileName = @tempnam($pTemporaryStorageDir, 'xml');
70
71            // Open storage
72            $this->openUri($this->tempFileName);
73        }
74
75        if ($compatibility) {
76            $this->setIndent(false);
77            $this->setIndentString('');
78        } else {
79            $this->setIndent(true);
80            $this->setIndentString('  ');
81        }
82    }
83
84    /**
85     * Destructor.
86     */
87    public function __destruct()
88    {
89        // Unlink temporary files
90        if (empty($this->tempFileName)) {
91            return;
92        }
93        if (PHP_OS != 'WINNT' && @unlink($this->tempFileName) === false) {
94            throw new Exception('The file ' . $this->tempFileName . ' could not be deleted.');
95        }
96    }
97
98    /**
99     * Get written data.
100     *
101     * @return string
102     */
103    public function getData()
104    {
105        if ($this->tempFileName == '') {
106            return $this->outputMemory(true);
107        }
108
109        $this->flush();
110
111        return file_get_contents($this->tempFileName);
112    }
113
114    /**
115     * Write simple element and attribute(s) block.
116     *
117     * There are two options:
118     * 1. If the `$attributes` is an array, then it's an associative array of attributes
119     * 2. If not, then it's a simple attribute-value pair
120     *
121     * @param string $element
122     * @param array|string $attributes
123     * @param string $value
124     */
125    public function writeElementBlock($element, $attributes, $value = null): void
126    {
127        $this->startElement($element);
128        if (!is_array($attributes)) {
129            $attributes = [$attributes => $value];
130        }
131        foreach ($attributes as $attribute => $value) {
132            $this->writeAttribute($attribute, $value);
133        }
134        $this->endElement();
135    }
136
137    /**
138     * Write element if ...
139     *
140     * @param bool $condition
141     * @param string $element
142     * @param string $attribute
143     * @param mixed $value
144     */
145    public function writeElementIf($condition, $element, $attribute = null, $value = null): void
146    {
147        if ($condition == true) {
148            if (null === $attribute) {
149                $this->writeElement($element, $value);
150            } else {
151                $this->startElement($element);
152                $this->writeAttribute($attribute, $value);
153                $this->endElement();
154            }
155        }
156    }
157
158    /**
159     * Write attribute if ...
160     *
161     * @param bool $condition
162     * @param string $attribute
163     * @param mixed $value
164     */
165    public function writeAttributeIf($condition, $attribute, $value): void
166    {
167        if ($condition == true) {
168            $this->writeAttribute($attribute, $value);
169        }
170    }
171
172    /**
173     * @param string $name
174     * @param mixed $value
175     *
176     * @return bool
177     */
178    #[ReturnTypeWillChange]
179    public function writeAttribute($name, $value)
180    {
181        if (is_float($value)) {
182            $value = json_encode($value);
183        }
184
185        return parent::writeAttribute($name, $value ?? '');
186    }
187}