Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
98 / 98 |
|
100.00% |
9 / 9 |
CRAP | |
100.00% |
1 / 1 |
Text | |
100.00% |
98 / 98 |
|
100.00% |
9 / 9 |
37 | |
100.00% |
1 / 1 |
write | |
100.00% |
14 / 14 |
|
100.00% |
1 / 1 |
3 | |||
setOpeningText | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setClosingText | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
writeOpening | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
writeClosing | |
100.00% |
6 / 6 |
|
100.00% |
1 / 1 |
2 | |||
writeTrackChangeOpening | |
100.00% |
19 / 19 |
|
100.00% |
1 / 1 |
6 | |||
writeTrackChangeClosing | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
4 | |||
getParagraphStyle | |
100.00% |
16 / 16 |
|
100.00% |
1 / 1 |
6 | |||
processFontStyle | |
100.00% |
26 / 26 |
|
100.00% |
1 / 1 |
12 |
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\HTML\Element; |
19 | |
20 | use PhpOffice\PhpWord\Element\TrackChange; |
21 | use PhpOffice\PhpWord\Style; |
22 | use PhpOffice\PhpWord\Style\Font; |
23 | use PhpOffice\PhpWord\Style\Paragraph; |
24 | use PhpOffice\PhpWord\Writer\HTML; |
25 | use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter; |
26 | use PhpOffice\PhpWord\Writer\HTML\Style\Paragraph as ParagraphStyleWriter; |
27 | |
28 | /** |
29 | * Text element HTML writer. |
30 | * |
31 | * @since 0.10.0 |
32 | */ |
33 | class Text extends AbstractElement |
34 | { |
35 | /** |
36 | * Text written after opening. |
37 | * |
38 | * @var string |
39 | */ |
40 | private $openingText = ''; |
41 | |
42 | /** |
43 | * Text written before closing. |
44 | * |
45 | * @var string |
46 | */ |
47 | private $closingText = ''; |
48 | |
49 | /** |
50 | * Opening tags. |
51 | * |
52 | * @var string |
53 | */ |
54 | private $openingTags = ''; |
55 | |
56 | /** |
57 | * Closing tag. |
58 | * |
59 | * @var string |
60 | */ |
61 | private $closingTags = ''; |
62 | |
63 | /** |
64 | * Write text. |
65 | * |
66 | * @return string |
67 | */ |
68 | public function write() |
69 | { |
70 | $this->processFontStyle(); |
71 | |
72 | /** @var \PhpOffice\PhpWord\Element\Text $element Type hint */ |
73 | $element = $this->element; |
74 | |
75 | $text = $this->parentWriter->escapeHTML($element->getText()); |
76 | if (!$this->withoutP && !trim($text)) { |
77 | $text = ' '; |
78 | } |
79 | |
80 | $content = ''; |
81 | $content .= $this->writeOpening(); |
82 | $content .= $this->openingText; |
83 | $content .= $this->openingTags; |
84 | $content .= $text; |
85 | $content .= $this->closingTags; |
86 | $content .= $this->closingText; |
87 | $content .= $this->writeClosing(); |
88 | |
89 | return $content; |
90 | } |
91 | |
92 | /** |
93 | * Set opening text. |
94 | * |
95 | * @param string $value |
96 | */ |
97 | public function setOpeningText($value): void |
98 | { |
99 | $this->openingText = $value; |
100 | } |
101 | |
102 | /** |
103 | * Set closing text. |
104 | * |
105 | * @param string $value |
106 | */ |
107 | public function setClosingText($value): void |
108 | { |
109 | $this->closingText = $value; |
110 | } |
111 | |
112 | /** |
113 | * Write opening. |
114 | * |
115 | * @return string |
116 | */ |
117 | protected function writeOpening() |
118 | { |
119 | $content = ''; |
120 | if (!$this->withoutP) { |
121 | $style = $this->getParagraphStyle(); |
122 | $content .= "<p{$style}>"; |
123 | } |
124 | |
125 | //open track change tag |
126 | $content .= $this->writeTrackChangeOpening(); |
127 | |
128 | return $content; |
129 | } |
130 | |
131 | /** |
132 | * Write ending. |
133 | * |
134 | * @return string |
135 | */ |
136 | protected function writeClosing() |
137 | { |
138 | $content = ''; |
139 | |
140 | //close track change tag |
141 | $content .= $this->writeTrackChangeClosing(); |
142 | |
143 | if (!$this->withoutP) { |
144 | $content .= $this->parentWriter->escapeHTML($this->closingText); |
145 | $content .= '</p>' . PHP_EOL; |
146 | } |
147 | |
148 | return $content; |
149 | } |
150 | |
151 | /** |
152 | * writes the track change opening tag. |
153 | * |
154 | * @return string the HTML, an empty string if no track change information |
155 | */ |
156 | private function writeTrackChangeOpening() |
157 | { |
158 | $changed = $this->element->getTrackChange(); |
159 | if ($changed == null) { |
160 | return ''; |
161 | } |
162 | |
163 | $content = ''; |
164 | if (($changed->getChangeType() == TrackChange::INSERTED)) { |
165 | $content .= '<ins data-phpword-prop=\''; |
166 | } elseif ($changed->getChangeType() == TrackChange::DELETED) { |
167 | $content .= '<del data-phpword-prop=\''; |
168 | } |
169 | |
170 | $changedProp = ['changed' => ['author' => $changed->getAuthor(), 'id' => $this->element->getElementId()]]; |
171 | if ($changed->getDate() != null) { |
172 | $changedProp['changed']['date'] = $changed->getDate()->format('Y-m-d\TH:i:s\Z'); |
173 | } |
174 | $content .= json_encode($changedProp); |
175 | $content .= '\' '; |
176 | $content .= 'title="' . $changed->getAuthor(); |
177 | if ($changed->getDate() != null) { |
178 | $dateUser = $changed->getDate()->format('Y-m-d H:i:s'); |
179 | $content .= ' - ' . $dateUser; |
180 | } |
181 | $content .= '">'; |
182 | |
183 | return $content; |
184 | } |
185 | |
186 | /** |
187 | * writes the track change closing tag. |
188 | * |
189 | * @return string the HTML, an empty string if no track change information |
190 | */ |
191 | private function writeTrackChangeClosing() |
192 | { |
193 | $changed = $this->element->getTrackChange(); |
194 | if ($changed == null) { |
195 | return ''; |
196 | } |
197 | |
198 | $content = ''; |
199 | if (($changed->getChangeType() == TrackChange::INSERTED)) { |
200 | $content .= '</ins>'; |
201 | } elseif ($changed->getChangeType() == TrackChange::DELETED) { |
202 | $content .= '</del>'; |
203 | } |
204 | |
205 | return $content; |
206 | } |
207 | |
208 | /** |
209 | * Write paragraph style. |
210 | * |
211 | * @return string |
212 | */ |
213 | private function getParagraphStyle() |
214 | { |
215 | /** @var \PhpOffice\PhpWord\Element\Text $element Type hint */ |
216 | $element = $this->element; |
217 | $style = ''; |
218 | if (!method_exists($element, 'getParagraphStyle')) { |
219 | return $style; |
220 | } |
221 | |
222 | $paragraphStyle = $element->getParagraphStyle(); |
223 | $pStyleIsObject = ($paragraphStyle instanceof Paragraph); |
224 | if ($pStyleIsObject) { |
225 | $styleWriter = new ParagraphStyleWriter($paragraphStyle); |
226 | $styleWriter->setParentWriter($this->parentWriter); |
227 | $style = $styleWriter->write(); |
228 | } elseif (is_string($paragraphStyle)) { |
229 | $style = $paragraphStyle; |
230 | } |
231 | if ($style) { |
232 | $attribute = $pStyleIsObject ? 'style' : 'class'; |
233 | $style = " {$attribute}=\"{$style}\""; |
234 | } |
235 | |
236 | return $style; |
237 | } |
238 | |
239 | /** |
240 | * Get font style. |
241 | */ |
242 | private function processFontStyle(): void |
243 | { |
244 | /** @var \PhpOffice\PhpWord\Element\Text $element Type hint */ |
245 | $element = $this->element; |
246 | |
247 | $attributeStyle = $attributeLang = ''; |
248 | $lang = null; |
249 | |
250 | $fontStyle = $element->getFontStyle(); |
251 | if ($fontStyle instanceof Font) { |
252 | // Attribute style |
253 | $styleWriter = new FontStyleWriter($fontStyle); |
254 | $fontCSS = $styleWriter->write(); |
255 | if ($fontCSS) { |
256 | $attributeStyle = ' style="' . $fontCSS . '"'; |
257 | } |
258 | // Attribute Lang |
259 | $lang = $fontStyle->getLang(); |
260 | } elseif (!empty($fontStyle)) { |
261 | // Attribute class |
262 | $attributeStyle = ' class="' . $fontStyle . '"'; |
263 | // Attribute Lang |
264 | /** @var Font $cssClassStyle */ |
265 | $cssClassStyle = Style::getStyle($fontStyle); |
266 | if ($cssClassStyle !== null && method_exists($cssClassStyle, 'getLang')) { |
267 | $lang = $cssClassStyle->getLang(); |
268 | } |
269 | } |
270 | |
271 | if ($lang) { |
272 | $attributeLang = $lang->getLatin(); |
273 | if (!$attributeLang) { |
274 | $attributeLang = $lang->getEastAsia(); |
275 | } |
276 | if (!$attributeLang) { |
277 | $attributeLang = $lang->getBidirectional(); |
278 | } |
279 | if ($attributeLang) { |
280 | $attributeLang = " lang='$attributeLang'"; |
281 | } |
282 | } |
283 | |
284 | if ($attributeStyle || $attributeLang) { |
285 | $this->openingTags = "<span$attributeLang$attributeStyle>"; |
286 | $this->closingTags = '</span>'; |
287 | } |
288 | } |
289 | } |