Completed
Push — master ( 0a0b1f...9f4c09 )
by Adrien
01:48
created

StyleManager::getCellAlignmentSectionContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
namespace Box\Spout\Writer\ODS\Manager\Style;
4
5
use Box\Spout\Common\Entity\Style\BorderPart;
6
use Box\Spout\Common\Entity\Style\CellAlignment;
7
use Box\Spout\Writer\Common\Entity\Worksheet;
8
use Box\Spout\Writer\ODS\Helper\BorderHelper;
9
10
/**
11
 * Class StyleManager
12
 * Manages styles to be applied to a cell
13
 */
14
class StyleManager extends \Box\Spout\Writer\Common\Manager\Style\StyleManager
15
{
16
    /** @var StyleRegistry */
17
    protected $styleRegistry;
18
19
    /**
20
     * Returns the content of the "styles.xml" file, given a list of styles.
21
     *
22
     * @param int $numWorksheets Number of worksheets created
23
     * @return string
24
     */
25 34
    public function getStylesXMLFileContent($numWorksheets)
26
    {
27
        $content = <<<'EOD'
28 34
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
29
<office:document-styles office:version="1.2" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:msoxl="http://schemas.microsoft.com/office/excel/formula" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:xlink="http://www.w3.org/1999/xlink">
30
EOD;
31
32 34
        $content .= $this->getFontFaceSectionContent();
33 34
        $content .= $this->getStylesSectionContent();
34 34
        $content .= $this->getAutomaticStylesSectionContent($numWorksheets);
35 34
        $content .= $this->getMasterStylesSectionContent($numWorksheets);
36
37
        $content .= <<<'EOD'
38 34
</office:document-styles>
39
EOD;
40
41 34
        return $content;
42
    }
43
44
    /**
45
     * Returns the content of the "<office:font-face-decls>" section, inside "styles.xml" file.
46
     *
47
     * @return string
48
     */
49 34
    protected function getFontFaceSectionContent()
50
    {
51 34
        $content = '<office:font-face-decls>';
52 34
        foreach ($this->styleRegistry->getUsedFonts() as $fontName) {
53 34
            $content .= '<style:font-face style:name="' . $fontName . '" svg:font-family="' . $fontName . '"/>';
54
        }
55 34
        $content .= '</office:font-face-decls>';
56
57 34
        return $content;
58
    }
59
60
    /**
61
     * Returns the content of the "<office:styles>" section, inside "styles.xml" file.
62
     *
63
     * @return string
64
     */
65 34
    protected function getStylesSectionContent()
66
    {
67 34
        $defaultStyle = $this->getDefaultStyle();
68
69
        return <<<EOD
70
<office:styles>
71
    <number:number-style style:name="N0">
72
        <number:number number:min-integer-digits="1"/>
73
    </number:number-style>
74
    <style:style style:data-style-name="N0" style:family="table-cell" style:name="Default">
75
        <style:table-cell-properties fo:background-color="transparent" style:vertical-align="automatic"/>
76 34
        <style:text-properties fo:color="#{$defaultStyle->getFontColor()}"
77 34
                               fo:font-size="{$defaultStyle->getFontSize()}pt" style:font-size-asian="{$defaultStyle->getFontSize()}pt" style:font-size-complex="{$defaultStyle->getFontSize()}pt"
78 34
                               style:font-name="{$defaultStyle->getFontName()}" style:font-name-asian="{$defaultStyle->getFontName()}" style:font-name-complex="{$defaultStyle->getFontName()}"/>
79
    </style:style>
80
</office:styles>
81
EOD;
82
    }
83
84
    /**
85
     * Returns the content of the "<office:automatic-styles>" section, inside "styles.xml" file.
86
     *
87
     * @param int $numWorksheets Number of worksheets created
88
     * @return string
89
     */
90 34
    protected function getAutomaticStylesSectionContent($numWorksheets)
91
    {
92 34
        $content = '<office:automatic-styles>';
93
94 34
        for ($i = 1; $i <= $numWorksheets; $i++) {
95
            $content .= <<<EOD
96 34
<style:page-layout style:name="pm$i">
97
    <style:page-layout-properties style:first-page-number="continue" style:print="objects charts drawings" style:table-centering="none"/>
98
    <style:header-style/>
99
    <style:footer-style/>
100
</style:page-layout>
101
EOD;
102
        }
103
104 34
        $content .= '</office:automatic-styles>';
105
106 34
        return $content;
107
    }
108
109
    /**
110
     * Returns the content of the "<office:master-styles>" section, inside "styles.xml" file.
111
     *
112
     * @param int $numWorksheets Number of worksheets created
113
     * @return string
114
     */
115 34
    protected function getMasterStylesSectionContent($numWorksheets)
116
    {
117 34
        $content = '<office:master-styles>';
118
119 34
        for ($i = 1; $i <= $numWorksheets; $i++) {
120
            $content .= <<<EOD
121 34
<style:master-page style:name="mp$i" style:page-layout-name="pm$i">
122
    <style:header/>
123
    <style:header-left style:display="false"/>
124
    <style:footer/>
125
    <style:footer-left style:display="false"/>
126
</style:master-page>
127
EOD;
128
        }
129
130 34
        $content .= '</office:master-styles>';
131
132 34
        return $content;
133
    }
134
135
    /**
136
     * Returns the contents of the "<office:font-face-decls>" section, inside "content.xml" file.
137
     *
138
     * @return string
139
     */
140 34
    public function getContentXmlFontFaceSectionContent()
141
    {
142 34
        $content = '<office:font-face-decls>';
143 34
        foreach ($this->styleRegistry->getUsedFonts() as $fontName) {
144 34
            $content .= '<style:font-face style:name="' . $fontName . '" svg:font-family="' . $fontName . '"/>';
145
        }
146 34
        $content .= '</office:font-face-decls>';
147
148 34
        return $content;
149
    }
150
151
    /**
152
     * Returns the contents of the "<office:automatic-styles>" section, inside "content.xml" file.
153
     *
154
     * @param Worksheet[] $worksheets
155
     * @return string
156
     */
157 34
    public function getContentXmlAutomaticStylesSectionContent($worksheets)
158
    {
159 34
        $content = '<office:automatic-styles>';
160
161 34
        foreach ($this->styleRegistry->getRegisteredStyles() as $style) {
162 34
            $content .= $this->getStyleSectionContent($style);
163
        }
164
165
        $content .= <<<'EOD'
166 34
<style:style style:family="table-column" style:name="co1">
167
    <style:table-column-properties fo:break-before="auto"/>
168
</style:style>
169
<style:style style:family="table-row" style:name="ro1">
170
    <style:table-row-properties fo:break-before="auto" style:row-height="15pt" style:use-optimal-row-height="true"/>
171
</style:style>
172
EOD;
173
174 34
        foreach ($worksheets as $worksheet) {
175 34
            $worksheetId = $worksheet->getId();
176 34
            $isSheetVisible = $worksheet->getExternalSheet()->isVisible() ? 'true' : 'false';
177
178
            $content .= <<<EOD
179 34
<style:style style:family="table" style:master-page-name="mp$worksheetId" style:name="ta$worksheetId">
180 34
    <style:table-properties style:writing-mode="lr-tb" table:display="$isSheetVisible"/>
181
</style:style>
182
EOD;
183
        }
184
185 34
        $content .= '</office:automatic-styles>';
186
187 34
        return $content;
188
    }
189
190
    /**
191
     * Returns the contents of the "<style:style>" section, inside "<office:automatic-styles>" section
192
     *
193
     * @param \Box\Spout\Common\Entity\Style\Style $style
194
     * @return string
195
     */
196 34
    protected function getStyleSectionContent($style)
197
    {
198 34
        $styleIndex = $style->getId() + 1; // 1-based
199
200 34
        $content = '<style:style style:data-style-name="N0" style:family="table-cell" style:name="ce' . $styleIndex . '" style:parent-style-name="Default">';
201
202 34
        $content .= $this->getTextPropertiesSectionContent($style);
203 34
        $content .= $this->getParagraphPropertiesSectionContent($style);
204 34
        $content .= $this->getTableCellPropertiesSectionContent($style);
205
206 34
        $content .= '</style:style>';
207
208 34
        return $content;
209
    }
210
211
    /**
212
     * Returns the contents of the "<style:text-properties>" section, inside "<style:style>" section
213
     *
214
     * @param \Box\Spout\Common\Entity\Style\Style $style
215
     * @return string
216
     */
217 34
    private function getTextPropertiesSectionContent($style)
218
    {
219 34
        if (!$style->shouldApplyFont()) {
220 33
            return '';
221
        }
222
223
        return '<style:text-properties '
224 5
            . $this->getFontSectionContent($style)
225 5
            . '/>';
226
    }
227
228
    /**
229
     * Returns the contents of the fonts definition section, inside "<style:text-properties>" section
230
     *
231
     * @param \Box\Spout\Common\Entity\Style\Style $style
232
     *
233
     * @return string
234
     */
235 5
    private function getFontSectionContent($style)
236
    {
237 5
        $defaultStyle = $this->getDefaultStyle();
238 5
        $content = '';
239
240 5
        $fontColor = $style->getFontColor();
241 5
        if ($fontColor !== $defaultStyle->getFontColor()) {
242 1
            $content .= ' fo:color="#' . $fontColor . '"';
243
        }
244
245 5
        $fontName = $style->getFontName();
246 5
        if ($fontName !== $defaultStyle->getFontName()) {
247 1
            $content .= ' style:font-name="' . $fontName . '" style:font-name-asian="' . $fontName . '" style:font-name-complex="' . $fontName . '"';
248
        }
249
250 5
        $fontSize = $style->getFontSize();
251 5
        if ($fontSize !== $defaultStyle->getFontSize()) {
252 2
            $content .= ' fo:font-size="' . $fontSize . 'pt" style:font-size-asian="' . $fontSize . 'pt" style:font-size-complex="' . $fontSize . 'pt"';
253
        }
254
255 5
        if ($style->isFontBold()) {
256 4
            $content .= ' fo:font-weight="bold" style:font-weight-asian="bold" style:font-weight-complex="bold"';
257
        }
258 5
        if ($style->isFontItalic()) {
259 1
            $content .= ' fo:font-style="italic" style:font-style-asian="italic" style:font-style-complex="italic"';
260
        }
261 5
        if ($style->isFontUnderline()) {
262 2
            $content .= ' style:text-underline-style="solid" style:text-underline-type="single"';
263
        }
264 5
        if ($style->isFontStrikethrough()) {
265 1
            $content .= ' style:text-line-through-style="solid"';
266
        }
267
268 5
        return $content;
269
    }
270
271
    /**
272
     * Returns the contents of the "<style:paragraph-properties>" section, inside "<style:style>" section
273
     *
274
     * @param \Box\Spout\Common\Entity\Style\Style $style
275
     *
276
     * @return string
277
     */
278 34
    private function getParagraphPropertiesSectionContent($style)
279
    {
280 34
        if (!$style->shouldApplyCellAlignment()) {
281 34
            return '';
282
        }
283
284
        return '<style:paragraph-properties '
285 1
            . $this->getCellAlignmentSectionContent($style)
286 1
            . '/>';
287
    }
288
289
    /**
290
     * Returns the contents of the cell alignment definition for the "<style:paragraph-properties>" section
291
     *
292
     * @param \Box\Spout\Common\Entity\Style\Style $style
293
     *
294
     * @return string
295
     */
296 1
    private function getCellAlignmentSectionContent($style)
297
    {
298 1
        return sprintf(
299 1
            ' fo:text-align="%s" ',
300 1
            $this->transformCellAlignment($style->getCellAlignment())
301
        );
302
    }
303
304
    /**
305
     * Even though "left" and "right" alignments are part of the spec, and interpreted
306
     * respectively as "start" and "end", using the recommended values increase compatibility
307
     * with software that will read the created ODS file.
308
     *
309
     * @param string $cellAlignment
310
     *
311
     * @return string
312
     */
313 1
    private function transformCellAlignment($cellAlignment)
314
    {
315
        switch ($cellAlignment) {
316 1
            case CellAlignment::LEFT: return 'start';
317 1
            case CellAlignment::RIGHT: return 'end';
318
            default: return $cellAlignment;
319
        }
320
    }
321
322
    /**
323
     * Returns the contents of the "<style:table-cell-properties>" section, inside "<style:style>" section
324
     *
325
     * @param \Box\Spout\Common\Entity\Style\Style $style
326
     * @return string
327
     */
328 34
    private function getTableCellPropertiesSectionContent($style)
329
    {
330 34
        $content = '<style:table-cell-properties ';
331
332 34
        if ($style->shouldWrapText()) {
333 3
            $content .= $this->getWrapTextXMLContent();
334
        }
335
336 34
        if ($style->shouldApplyBorder()) {
337 1
            $content .= $this->getBorderXMLContent($style);
338
        }
339
340 34
        if ($style->shouldApplyBackgroundColor()) {
341 2
            $content .= $this->getBackgroundColorXMLContent($style);
342
        }
343
344 34
        $content .= '/>';
345
346 34
        return $content;
347
    }
348
349
    /**
350
     * Returns the contents of the wrap text definition for the "<style:table-cell-properties>" section
351
     *
352
     * @return string
353
     */
354 3
    private function getWrapTextXMLContent()
355
    {
356 3
        return ' fo:wrap-option="wrap" style:vertical-align="automatic" ';
357
    }
358
359
    /**
360
     * Returns the contents of the borders definition for the "<style:table-cell-properties>" section
361
     *
362
     * @param \Box\Spout\Common\Entity\Style\Style $style
363
     * @return string
364
     */
365 1
    private function getBorderXMLContent($style)
366
    {
367
        $borders = array_map(function (BorderPart $borderPart) {
368 1
            return BorderHelper::serializeBorderPart($borderPart);
369 1
        }, $style->getBorder()->getParts());
370
371 1
        return sprintf(' %s ', implode(' ', $borders));
372
    }
373
374
    /**
375
     * Returns the contents of the background color definition for the "<style:table-cell-properties>" section
376
     *
377
     * @param \Box\Spout\Common\Entity\Style\Style $style
378
     * @return string
379
     */
380 2
    private function getBackgroundColorXMLContent($style)
381
    {
382 2
        return sprintf(' fo:background-color="#%s" ', $style->getBackgroundColor());
383
    }
384
}
385