Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
88.38% |
175 / 198 |
|
66.67% |
4 / 6 |
CRAP | |
0.00% |
0 / 1 |
Field | |
88.38% |
175 / 198 |
|
66.67% |
4 / 6 |
50.46 | |
0.00% |
0 / 1 |
write | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
3 | |||
writeDefault | |
100.00% |
54 / 54 |
|
100.00% |
1 / 1 |
7 | |||
writeMacrobutton | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
4 | |||
buildPropertiesAndOptions | |
100.00% |
42 / 42 |
|
100.00% |
1 / 1 |
16 | |||
writeRef | |
73.08% |
38 / 52 |
|
0.00% |
0 / 1 |
7.96 | |||
convertRefOption | |
47.06% |
8 / 17 |
|
0.00% |
0 / 1 |
24.84 |
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 | |
18 | namespace PhpOffice\PhpWord\Writer\Word2007\Element; |
19 | |
20 | use PhpOffice\PhpWord\Element\Field as ElementField; |
21 | use PhpOffice\PhpWord\Element\TextRun; |
22 | |
23 | /** |
24 | * Field element writer. |
25 | * |
26 | * @since 0.11.0 |
27 | */ |
28 | class Field extends Text |
29 | { |
30 | /** |
31 | * Write field element. |
32 | */ |
33 | public function write(): void |
34 | { |
35 | $element = $this->getElement(); |
36 | if (!$element instanceof ElementField) { |
37 | return; |
38 | } |
39 | |
40 | $methodName = 'write' . ucfirst(strtolower($element->getType())); |
41 | if (method_exists($this, $methodName)) { |
42 | $this->$methodName($element); |
43 | } else { |
44 | $this->writeDefault($element); |
45 | } |
46 | } |
47 | |
48 | private function writeDefault(ElementField $element): void |
49 | { |
50 | $xmlWriter = $this->getXmlWriter(); |
51 | $this->startElementP(); |
52 | |
53 | $xmlWriter->startElement('w:r'); |
54 | $xmlWriter->startElement('w:fldChar'); |
55 | $xmlWriter->writeAttribute('w:fldCharType', 'begin'); |
56 | $xmlWriter->endElement(); // w:fldChar |
57 | $xmlWriter->endElement(); // w:r |
58 | |
59 | $instruction = ' ' . $element->getType() . ' '; |
60 | if ($element->getText() != null) { |
61 | if (is_string($element->getText())) { |
62 | $instruction .= '"' . $element->getText() . '" '; |
63 | $instruction .= $this->buildPropertiesAndOptions($element); |
64 | } else { |
65 | $instruction .= '"'; |
66 | } |
67 | } else { |
68 | $instruction .= $this->buildPropertiesAndOptions($element); |
69 | } |
70 | $xmlWriter->startElement('w:r'); |
71 | $this->writeFontStyle(); |
72 | $xmlWriter->startElement('w:instrText'); |
73 | $xmlWriter->writeAttribute('xml:space', 'preserve'); |
74 | $xmlWriter->text($instruction); |
75 | $xmlWriter->endElement(); // w:instrText |
76 | $xmlWriter->endElement(); // w:r |
77 | |
78 | if ($element->getText() != null) { |
79 | if ($element->getText() instanceof TextRun) { |
80 | $containerWriter = new Container($xmlWriter, $element->getText(), true); |
81 | $containerWriter->write(); |
82 | |
83 | $xmlWriter->startElement('w:r'); |
84 | $xmlWriter->startElement('w:instrText'); |
85 | $xmlWriter->text('"' . $this->buildPropertiesAndOptions($element)); |
86 | $xmlWriter->endElement(); // w:instrText |
87 | $xmlWriter->endElement(); // w:r |
88 | |
89 | $xmlWriter->startElement('w:r'); |
90 | $xmlWriter->startElement('w:instrText'); |
91 | $xmlWriter->writeAttribute('xml:space', 'preserve'); |
92 | $xmlWriter->text(' '); |
93 | $xmlWriter->endElement(); // w:instrText |
94 | $xmlWriter->endElement(); // w:r |
95 | } |
96 | } |
97 | |
98 | $xmlWriter->startElement('w:r'); |
99 | $xmlWriter->startElement('w:fldChar'); |
100 | $xmlWriter->writeAttribute('w:fldCharType', 'separate'); |
101 | $xmlWriter->endElement(); // w:fldChar |
102 | $xmlWriter->endElement(); // w:r |
103 | |
104 | $xmlWriter->startElement('w:r'); |
105 | $xmlWriter->startElement('w:rPr'); |
106 | $xmlWriter->startElement('w:noProof'); |
107 | $xmlWriter->endElement(); // w:noProof |
108 | $xmlWriter->endElement(); // w:rPr |
109 | $xmlWriter->writeElement('w:t', $element->getText() != null && is_string($element->getText()) ? $element->getText() : '1'); |
110 | $xmlWriter->endElement(); // w:r |
111 | |
112 | $xmlWriter->startElement('w:r'); |
113 | $xmlWriter->startElement('w:fldChar'); |
114 | $xmlWriter->writeAttribute('w:fldCharType', 'end'); |
115 | $xmlWriter->endElement(); // w:fldChar |
116 | $xmlWriter->endElement(); // w:r |
117 | |
118 | $this->endElementP(); // w:p |
119 | } |
120 | |
121 | /** |
122 | * Writes a macrobutton field. |
123 | * |
124 | * //TODO A lot of code duplication with general method, should maybe be refactored |
125 | */ |
126 | protected function writeMacrobutton(ElementField $element): void |
127 | { |
128 | $xmlWriter = $this->getXmlWriter(); |
129 | $this->startElementP(); |
130 | |
131 | $xmlWriter->startElement('w:r'); |
132 | $xmlWriter->startElement('w:fldChar'); |
133 | $xmlWriter->writeAttribute('w:fldCharType', 'begin'); |
134 | $xmlWriter->endElement(); // w:fldChar |
135 | $xmlWriter->endElement(); // w:r |
136 | |
137 | $instruction = ' ' . $element->getType() . ' ' . $this->buildPropertiesAndOptions($element); |
138 | if (is_string($element->getText())) { |
139 | $instruction .= $element->getText() . ' '; |
140 | } |
141 | |
142 | $xmlWriter->startElement('w:r'); |
143 | $xmlWriter->startElement('w:instrText'); |
144 | $xmlWriter->writeAttribute('xml:space', 'preserve'); |
145 | $xmlWriter->text($instruction); |
146 | $xmlWriter->endElement(); // w:instrText |
147 | $xmlWriter->endElement(); // w:r |
148 | |
149 | if ($element->getText() != null) { |
150 | if ($element->getText() instanceof \PhpOffice\PhpWord\Element\TextRun) { |
151 | $containerWriter = new Container($xmlWriter, $element->getText(), true); |
152 | $containerWriter->write(); |
153 | } |
154 | } |
155 | |
156 | $xmlWriter->startElement('w:r'); |
157 | $xmlWriter->startElement('w:fldChar'); |
158 | $xmlWriter->writeAttribute('w:fldCharType', 'end'); |
159 | $xmlWriter->endElement(); // w:fldChar |
160 | $xmlWriter->endElement(); // w:r |
161 | |
162 | $this->endElementP(); // w:p |
163 | } |
164 | |
165 | private function buildPropertiesAndOptions(ElementField $element) |
166 | { |
167 | $propertiesAndOptions = ''; |
168 | $properties = $element->getProperties(); |
169 | foreach ($properties as $propkey => $propval) { |
170 | switch ($propkey) { |
171 | case 'format': |
172 | $propertiesAndOptions .= '\\* ' . $propval . ' '; |
173 | |
174 | break; |
175 | case 'numformat': |
176 | $propertiesAndOptions .= '\\# ' . $propval . ' '; |
177 | |
178 | break; |
179 | case 'dateformat': |
180 | $propertiesAndOptions .= '\\@ "' . $propval . '" '; |
181 | |
182 | break; |
183 | case 'macroname': |
184 | $propertiesAndOptions .= $propval . ' '; |
185 | |
186 | break; |
187 | default: |
188 | $propertiesAndOptions .= '"' . $propval . '" '; |
189 | |
190 | break; |
191 | } |
192 | } |
193 | |
194 | $options = $element->getOptions(); |
195 | foreach ($options as $option) { |
196 | switch ($option) { |
197 | case 'PreserveFormat': |
198 | $propertiesAndOptions .= '\\* MERGEFORMAT '; |
199 | |
200 | break; |
201 | case 'LunarCalendar': |
202 | $propertiesAndOptions .= '\\h '; |
203 | |
204 | break; |
205 | case 'SakaEraCalendar': |
206 | $propertiesAndOptions .= '\\s '; |
207 | |
208 | break; |
209 | case 'LastUsedFormat': |
210 | $propertiesAndOptions .= '\\l '; |
211 | |
212 | break; |
213 | case 'Bold': |
214 | $propertiesAndOptions .= '\\b '; |
215 | |
216 | break; |
217 | case 'Italic': |
218 | $propertiesAndOptions .= '\\i '; |
219 | |
220 | break; |
221 | case 'Path': |
222 | $propertiesAndOptions .= '\\p '; |
223 | |
224 | break; |
225 | default: |
226 | $propertiesAndOptions .= $option . ' '; |
227 | } |
228 | } |
229 | |
230 | return $propertiesAndOptions; |
231 | } |
232 | |
233 | /** |
234 | * Writes a REF field. |
235 | */ |
236 | protected function writeRef(ElementField $element): void |
237 | { |
238 | $xmlWriter = $this->getXmlWriter(); |
239 | $this->startElementP(); |
240 | |
241 | $xmlWriter->startElement('w:r'); |
242 | $xmlWriter->startElement('w:fldChar'); |
243 | $xmlWriter->writeAttribute('w:fldCharType', 'begin'); |
244 | $xmlWriter->endElement(); // w:fldChar |
245 | $xmlWriter->endElement(); // w:r |
246 | |
247 | $instruction = ' ' . $element->getType() . ' '; |
248 | |
249 | foreach ($element->getProperties() as $property) { |
250 | $instruction .= $property . ' '; |
251 | } |
252 | foreach ($element->getOptions() as $optionKey => $optionValue) { |
253 | $instruction .= $this->convertRefOption($optionKey, $optionValue) . ' '; |
254 | } |
255 | |
256 | $xmlWriter->startElement('w:r'); |
257 | $this->writeFontStyle(); |
258 | $xmlWriter->startElement('w:instrText'); |
259 | $xmlWriter->writeAttribute('xml:space', 'preserve'); |
260 | $xmlWriter->text($instruction); |
261 | $xmlWriter->endElement(); // w:instrText |
262 | $xmlWriter->endElement(); // w:r |
263 | |
264 | if ($element->getText() != null) { |
265 | if ($element->getText() instanceof \PhpOffice\PhpWord\Element\TextRun) { |
266 | $containerWriter = new Container($xmlWriter, $element->getText(), true); |
267 | $containerWriter->write(); |
268 | |
269 | $xmlWriter->startElement('w:r'); |
270 | $xmlWriter->startElement('w:instrText'); |
271 | $xmlWriter->text('"' . $this->buildPropertiesAndOptions($element)); |
272 | $xmlWriter->endElement(); // w:instrText |
273 | $xmlWriter->endElement(); // w:r |
274 | |
275 | $xmlWriter->startElement('w:r'); |
276 | $xmlWriter->startElement('w:instrText'); |
277 | $xmlWriter->writeAttribute('xml:space', 'preserve'); |
278 | $xmlWriter->text(' '); |
279 | $xmlWriter->endElement(); // w:instrText |
280 | $xmlWriter->endElement(); // w:r |
281 | } |
282 | } |
283 | |
284 | $xmlWriter->startElement('w:r'); |
285 | $xmlWriter->startElement('w:fldChar'); |
286 | $xmlWriter->writeAttribute('w:fldCharType', 'separate'); |
287 | $xmlWriter->endElement(); // w:fldChar |
288 | $xmlWriter->endElement(); // w:r |
289 | |
290 | $xmlWriter->startElement('w:r'); |
291 | $xmlWriter->startElement('w:rPr'); |
292 | $xmlWriter->startElement('w:noProof'); |
293 | $xmlWriter->endElement(); // w:noProof |
294 | $xmlWriter->endElement(); // w:rPr |
295 | $xmlWriter->writeElement('w:t', $element->getText() != null && is_string($element->getText()) ? $element->getText() : '1'); |
296 | $xmlWriter->endElement(); // w:r |
297 | |
298 | $xmlWriter->startElement('w:r'); |
299 | $xmlWriter->startElement('w:fldChar'); |
300 | $xmlWriter->writeAttribute('w:fldCharType', 'end'); |
301 | $xmlWriter->endElement(); // w:fldChar |
302 | $xmlWriter->endElement(); // w:r |
303 | |
304 | $this->endElementP(); // w:p |
305 | } |
306 | |
307 | private function convertRefOption(string $optionKey, string $optionValue): string |
308 | { |
309 | if ($optionKey === 'NumberSeperatorSequence') { |
310 | return '\\d ' . $optionValue; |
311 | } |
312 | |
313 | switch ($optionValue) { |
314 | case 'IncrementAndInsertText': |
315 | return '\\f'; |
316 | case 'CreateHyperLink': |
317 | return '\\h'; |
318 | case 'NoTrailingPeriod': |
319 | return '\\n'; |
320 | case 'IncludeAboveOrBelow': |
321 | return '\\p'; |
322 | case 'InsertParagraphNumberRelativeContext': |
323 | return '\\r'; |
324 | case 'SuppressNonDelimiterNonNumericalText': |
325 | return '\\t'; |
326 | case 'InsertParagraphNumberFullContext': |
327 | return '\\w'; |
328 | default: |
329 | return ''; |
330 | } |
331 | } |
332 | } |