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