Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
99.10% |
110 / 111 |
|
66.67% |
2 / 3 |
CRAP | |
0.00% |
0 / 1 |
Head | |
99.10% |
110 / 111 |
|
66.67% |
2 / 3 |
22 | |
0.00% |
0 / 1 |
write | |
100.00% |
29 / 29 |
|
100.00% |
1 / 1 |
5 | |||
writeStyles | |
100.00% |
76 / 76 |
|
100.00% |
1 / 1 |
14 | |||
getFontFamily | |
83.33% |
5 / 6 |
|
0.00% |
0 / 1 |
3.04 |
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\Part; |
19 | |
20 | use PhpOffice\PhpWord\Settings; |
21 | use PhpOffice\PhpWord\Shared\Converter; |
22 | use PhpOffice\PhpWord\Style; |
23 | use PhpOffice\PhpWord\Style\Font; |
24 | use PhpOffice\PhpWord\Style\Paragraph; |
25 | use PhpOffice\PhpWord\Style\Table; |
26 | use PhpOffice\PhpWord\Writer\HTML\Style\Font as FontStyleWriter; |
27 | use PhpOffice\PhpWord\Writer\HTML\Style\Generic as GenericStyleWriter; |
28 | use PhpOffice\PhpWord\Writer\HTML\Style\Paragraph as ParagraphStyleWriter; |
29 | use PhpOffice\PhpWord\Writer\HTML\Style\Table as TableStyleWriter; |
30 | |
31 | /** |
32 | * RTF head part writer. |
33 | * |
34 | * @since 0.11.0 |
35 | */ |
36 | class Head extends AbstractPart |
37 | { |
38 | /** |
39 | * Write part. |
40 | * |
41 | * @return string |
42 | */ |
43 | public function write() |
44 | { |
45 | $docProps = $this->getParentWriter()->getPhpWord()->getDocInfo(); |
46 | $propertiesMapping = [ |
47 | 'creator' => 'author', |
48 | 'title' => '', |
49 | 'description' => '', |
50 | 'subject' => '', |
51 | 'keywords' => '', |
52 | 'category' => '', |
53 | 'company' => '', |
54 | 'manager' => '', |
55 | ]; |
56 | $title = $docProps->getTitle(); |
57 | $title = ($title != '') ? $title : 'PHPWord'; |
58 | |
59 | $content = ''; |
60 | |
61 | $content .= '<head>' . PHP_EOL; |
62 | $content .= '<meta charset="UTF-8" />' . PHP_EOL; |
63 | $content .= '<title>' . $title . '</title>' . PHP_EOL; |
64 | foreach ($propertiesMapping as $key => $value) { |
65 | $value = ($value == '') ? $key : $value; |
66 | $method = 'get' . $key; |
67 | if ($docProps->$method() != '') { |
68 | $content .= '<meta name="' . $value . '"' |
69 | . ' content="' |
70 | . $this->getParentWriter()->escapeHTML($docProps->$method()) |
71 | . '"' |
72 | . ' />' . PHP_EOL; |
73 | } |
74 | } |
75 | $content .= $this->writeStyles(); |
76 | $content .= '</head>' . PHP_EOL; |
77 | |
78 | return $content; |
79 | } |
80 | |
81 | /** |
82 | * Get styles. |
83 | */ |
84 | private function writeStyles(): string |
85 | { |
86 | $css = '<style>' . PHP_EOL; |
87 | |
88 | // Default styles |
89 | $astarray = [ |
90 | 'font-family' => $this->getFontFamily(Settings::getDefaultFontName(), $this->getParentWriter()->getDefaultGenericFont()), |
91 | 'font-size' => Settings::getDefaultFontSize() . 'pt', |
92 | ]; |
93 | // Mpdf sometimes needs separate tag for body; doesn't harm others. |
94 | $bodyarray = $astarray; |
95 | |
96 | $defaultWhiteSpace = $this->getParentWriter()->getDefaultWhiteSpace(); |
97 | if ($defaultWhiteSpace) { |
98 | $astarray['white-space'] = $defaultWhiteSpace; |
99 | } |
100 | |
101 | foreach ([ |
102 | 'body' => $bodyarray, |
103 | '*' => $astarray, |
104 | 'a.NoteRef' => [ |
105 | 'text-decoration' => 'none', |
106 | ], |
107 | 'hr' => [ |
108 | 'height' => '1px', |
109 | 'padding' => '0', |
110 | 'margin' => '1em 0', |
111 | 'border' => '0', |
112 | 'border-top' => '1px solid #CCC', |
113 | ], |
114 | 'table' => [ |
115 | 'border' => '1px solid black', |
116 | 'border-spacing' => '0px', |
117 | 'width ' => '100%', |
118 | ], |
119 | 'td' => [ |
120 | 'border' => '1px solid black', |
121 | ], |
122 | ] as $selector => $style) { |
123 | $styleWriter = new GenericStyleWriter($style); |
124 | $css .= $selector . ' {' . $styleWriter->write() . '}' . PHP_EOL; |
125 | } |
126 | |
127 | // Custom styles |
128 | $customStyles = Style::getStyles(); |
129 | if (is_array($customStyles)) { |
130 | foreach ($customStyles as $name => $style) { |
131 | $styleParagraph = null; |
132 | if ($style instanceof Font) { |
133 | $styleWriter = new FontStyleWriter($style); |
134 | if ($style->getStyleType() == 'title') { |
135 | $name = str_replace('Heading_', 'h', $name); |
136 | $styleParagraph = $style->getParagraph(); |
137 | $style = $styleParagraph; |
138 | } else { |
139 | $name = '.' . $name; |
140 | } |
141 | $css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL; |
142 | } |
143 | if ($style instanceof Paragraph) { |
144 | $styleWriter = new ParagraphStyleWriter($style); |
145 | $styleWriter->setParentWriter($this->getParentWriter()); |
146 | if (!$styleParagraph) { |
147 | $name = '.' . $name; |
148 | } |
149 | if ($name === '.Normal') { |
150 | $name = "p, $name"; |
151 | } |
152 | $css .= "{$name} {" . $styleWriter->write() . '}' . PHP_EOL; |
153 | } |
154 | if ($style instanceof Table) { |
155 | $styleWriter = new TableStyleWriter($style); |
156 | $css .= ".{$name} {" . $styleWriter->write() . '}' . PHP_EOL; |
157 | } |
158 | } |
159 | } |
160 | |
161 | $css .= 'body > div + div {page-break-before: always;}' . PHP_EOL; |
162 | $css .= 'div > *:first-child {page-break-before: auto;}' . PHP_EOL; |
163 | |
164 | $sectionNum = 0; |
165 | foreach ($this->getParentWriter()->getPhpWord()->getSections() as $section) { |
166 | ++$sectionNum; |
167 | |
168 | $css .= "@page page$sectionNum {"; |
169 | |
170 | $paperSize = $section->getStyle()->getPaperSize(); |
171 | $orientation = $section->getStyle()->getOrientation(); |
172 | if ($this->getParentWriter()->isPdf()) { |
173 | if ($orientation === 'landscape') { |
174 | $paperSize .= '-L'; |
175 | } |
176 | $css .= "sheet-size: $paperSize; "; |
177 | } else { |
178 | $css .= "size: $paperSize $orientation; "; |
179 | } |
180 | |
181 | $css .= 'margin-right: ' . (string) ($section->getStyle()->getMarginRight() / Converter::INCH_TO_TWIP) . 'in; '; |
182 | $css .= 'margin-left: ' . (string) ($section->getStyle()->getMarginLeft() / Converter::INCH_TO_TWIP) . 'in; '; |
183 | $css .= 'margin-top: ' . (string) ($section->getStyle()->getMarginTop() / Converter::INCH_TO_TWIP) . 'in; '; |
184 | $css .= 'margin-bottom: ' . (string) ($section->getStyle()->getMarginBottom() / Converter::INCH_TO_TWIP) . 'in; '; |
185 | $css .= '}' . PHP_EOL; |
186 | } |
187 | |
188 | $css .= '</style>' . PHP_EOL; |
189 | |
190 | return $css; |
191 | } |
192 | |
193 | /** |
194 | * Set font and alternates for css font-family. |
195 | */ |
196 | private function getFontFamily(string $font, string $genericFont): string |
197 | { |
198 | if (empty($font)) { |
199 | return ''; |
200 | } |
201 | $fontfamily = "'" . htmlspecialchars($font, ENT_QUOTES, 'UTF-8') . "'"; |
202 | if (!empty($genericFont)) { |
203 | $fontfamily .= ", $genericFont"; |
204 | } |
205 | |
206 | return $fontfamily; |
207 | } |
208 | } |