Completed
Pull Request — develop_3.0 (#433)
by Adrien
06:44
created

StyleManager::getCellStylesSectionContent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 2
cts 2
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 0
crap 1
1
<?php
2
3
namespace Box\Spout\Writer\XLSX\Manager\Style;
4
5
use Box\Spout\Writer\Common\Entity\Style\Color;
6
use Box\Spout\Writer\Common\Entity\Style\Style;
7
use Box\Spout\Writer\XLSX\Helper\BorderHelper;
8
9
/**
10
 * Class StyleManager
11
 * Manages styles to be applied to a cell
12
 *
13
 * @package Box\Spout\Writer\XLSX\Manager\Style
14
 */
15
class StyleManager extends \Box\Spout\Writer\Common\Manager\Style\StyleManager
16
{
17
    /** @var StyleRegistry */
18
    protected $styleRegistry;
19
20
    /**
21
     * For empty cells, we can specify a style or not. If no style are specified,
22
     * then the software default will be applied. But sometimes, it may be useful
23
     * to override this default style, for instance if the cell should have a
24
     * background color different than the default one or some borders
25
     * (fonts property don't really matter here).
26
     *
27
     * @param int $styleId
28
     * @return bool Whether the cell should define a custom style
29
     */
30 11
    public function shouldApplyStyleOnEmptyCell($styleId)
31
    {
32 11
        $associatedFillId = $this->styleRegistry->getFillIdForStyleId($styleId);
33 11
        $hasStyleCustomFill = ($associatedFillId !== null && $associatedFillId !== 0);
34
35 11
        $associatedBorderId = $this->styleRegistry->getBorderIdForStyleId($styleId);
36 11
        $hasStyleCustomBorders = ($associatedBorderId !== null && $associatedBorderId !== 0);
37
38 11
        return ($hasStyleCustomFill || $hasStyleCustomBorders);
39
    }
40
41
42
    /**
43
     * Returns the content of the "styles.xml" file, given a list of styles.
44
     *
45
     * @return string
46
     */
47 36
    public function getStylesXMLFileContent()
48
    {
49
        $content = <<<EOD
50 36
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
51
<styleSheet xmlns="http://schemas.openxmlformats.org/spreadsheetml/2006/main">
52
EOD;
53
54 36
        $content .= $this->getFontsSectionContent();
55 36
        $content .= $this->getFillsSectionContent();
56 36
        $content .= $this->getBordersSectionContent();
57 36
        $content .= $this->getCellStyleXfsSectionContent();
58 36
        $content .= $this->getCellXfsSectionContent();
59 36
        $content .= $this->getCellStylesSectionContent();
60
61
        $content .= <<<EOD
62 36
</styleSheet>
63
EOD;
64
65 36
        return $content;
66
    }
67
68
    /**
69
     * Returns the content of the "<fonts>" section.
70
     *
71
     * @return string
72
     */
73 36
    protected function getFontsSectionContent()
74
    {
75 36
        $registeredStyles = $this->styleRegistry->getRegisteredStyles();
76
77 36
        $content = '<fonts count="' . count($registeredStyles) . '">';
78
79
        /** @var Style $style */
80 36
        foreach ($registeredStyles as $style) {
81 36
            $content .= '<font>';
82
83 36
            $content .= '<sz val="' . $style->getFontSize() . '"/>';
84 36
            $content .= '<color rgb="' . Color::toARGB($style->getFontColor()) . '"/>';
85 36
            $content .= '<name val="' . $style->getFontName() . '"/>';
86
87 36
            if ($style->isFontBold()) {
88 6
                $content .= '<b/>';
89
            }
90 36
            if ($style->isFontItalic()) {
91 1
                $content .= '<i/>';
92
            }
93 36
            if ($style->isFontUnderline()) {
94 1
                $content .= '<u/>';
95
            }
96 36
            if ($style->isFontStrikethrough()) {
97 1
                $content .= '<strike/>';
98
            }
99
100 36
            $content .= '</font>';
101
        }
102
103 36
        $content .= '</fonts>';
104
105 36
        return $content;
106
    }
107
108
    /**
109
     * Returns the content of the "<fills>" section.
110
     *
111
     * @return string
112
     */
113 36
    protected function getFillsSectionContent()
114
    {
115 36
        $registeredFills = $this->styleRegistry->getRegisteredFills();
116
117
        // Excel reserves two default fills
118 36
        $fillsCount = count($registeredFills) + 2;
119 36
        $content = sprintf('<fills count="%d">', $fillsCount);
120
121 36
        $content .= '<fill><patternFill patternType="none"/></fill>';
122 36
        $content .= '<fill><patternFill patternType="gray125"/></fill>';
123
124
        // The other fills are actually registered by setting a background color
125 36
        foreach ($registeredFills as $styleId) {
126
            /** @var Style $style */
127 3
            $style = $this->styleRegistry->getStyleFromStyleId($styleId);
128
129 3
            $backgroundColor = $style->getBackgroundColor();
130 3
            $content .= sprintf(
131 3
                '<fill><patternFill patternType="solid"><fgColor rgb="%s"/></patternFill></fill>',
132 3
                $backgroundColor
133
            );
134
        }
135
136 36
        $content .= '</fills>';
137
138 36
        return $content;
139
    }
140
141
    /**
142
     * Returns the content of the "<borders>" section.
143
     *
144
     * @return string
145
     */
146 36
    protected function getBordersSectionContent()
147
    {
148 36
        $registeredBorders = $this->styleRegistry->getRegisteredBorders();
149
150
        // There is one default border with index 0
151 36
        $borderCount = count($registeredBorders) + 1;
152
153 36
        $content = '<borders count="' . $borderCount . '">';
154
155
        // Default border starting at index 0
156 36
        $content .= '<border><left/><right/><top/><bottom/></border>';
157
158 36
        foreach ($registeredBorders as $styleId) {
159
            /** @var \Box\Spout\Writer\Common\Entity\Style\Style $style */
160 4
            $style = $this->styleRegistry->getStyleFromStyleId($styleId);
161 4
            $border = $style->getBorder();
162 4
            $content .= '<border>';
163
164
            // @link https://github.com/box/spout/issues/271
165 4
            $sortOrder = ['left', 'right', 'top', 'bottom'];
166
167 4
            foreach ($sortOrder as $partName) {
168 4
                if ($border->hasPart($partName)) {
169
                    /** @var $part \Box\Spout\Writer\Common\Entity\Style\BorderPart */
170 4
                    $part = $border->getPart($partName);
171 4
                    $content .= BorderHelper::serializeBorderPart($part);
172
                }
173
            }
174
175 4
            $content .= '</border>';
176
        }
177
178 36
        $content .= '</borders>';
179
180 36
        return $content;
181
    }
182
183
    /**
184
     * Returns the content of the "<cellStyleXfs>" section.
185
     *
186
     * @return string
187
     */
188 36
    protected function getCellStyleXfsSectionContent()
189
    {
190
        return <<<EOD
191 36
<cellStyleXfs count="1">
192
    <xf borderId="0" fillId="0" fontId="0" numFmtId="0"/>
193
</cellStyleXfs>
194
EOD;
195
    }
196
197
    /**
198
     * Returns the content of the "<cellXfs>" section.
199
     *
200
     * @return string
201
     */
202 36
    protected function getCellXfsSectionContent()
203
    {
204 36
        $registeredStyles = $this->styleRegistry->getRegisteredStyles();
205
206 36
        $content = '<cellXfs count="' . count($registeredStyles) . '">';
207
208 36
        foreach ($registeredStyles as $style) {
209 36
            $styleId = $style->getId();
210 36
            $fillId = $this->styleRegistry->getFillIdForStyleId($styleId);
211 36
            $borderId = $this->styleRegistry->getBorderIdForStyleId($styleId);
212
213 36
            $content .= '<xf numFmtId="0" fontId="' . $styleId . '" fillId="' . $fillId . '" borderId="' . $borderId . '" xfId="0"';
214
215 36
            if ($style->shouldApplyFont()) {
216 36
                $content .= ' applyFont="1"';
217
            }
218
219 36
            $content .= sprintf(' applyBorder="%d"', $style->shouldApplyBorder() ? 1 : 0);
220
221 36
            if ($style->shouldWrapText()) {
222 2
                $content .= ' applyAlignment="1">';
223 2
                $content .= '<alignment wrapText="1"/>';
224 2
                $content .= '</xf>';
225
            } else {
226 36
                $content .= '/>';
227
            }
228
        }
229
230 36
        $content .= '</cellXfs>';
231
232 36
        return $content;
233
    }
234
235
    /**
236
     * Returns the content of the "<cellStyles>" section.
237
     *
238
     * @return string
239
     */
240 36
    protected function getCellStylesSectionContent()
241
    {
242
        return <<<EOD
243 36
<cellStyles count="1">
244
    <cellStyle builtinId="0" name="Normal" xfId="0"/>
245
</cellStyles>
246
EOD;
247
    }
248
}
249