Completed
Pull Request — master (#668)
by
unknown
01:54
created

StyleRegistry   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 272
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 95.52%

Importance

Changes 0
Metric Value
wmc 20
lcom 1
cbo 2
dl 0
loc 272
ccs 64
cts 67
cp 0.9552
rs 10
c 0
b 0
f 0

10 Methods

Rating   Name   Duplication   Size   Complexity  
A registerStyle() 0 9 1
A registerFormat() 0 29 4
A getFormatIdForStyleId() 0 6 2
A registerFill() 0 26 3
A getFillIdForStyleId() 0 6 2
A registerBorder() 0 23 3
A getBorderIdForStyleId() 0 6 2
A getRegisteredFills() 0 4 1
A getRegisteredBorders() 0 4 1
A getRegisteredFormats() 0 4 1
1
<?php
2
3
namespace Box\Spout\Writer\XLSX\Manager\Style;
4
5
use Box\Spout\Common\Entity\Style\Style;
6
7
/**
8
 * Class StyleRegistry
9
 * Registry for all used styles
10
 */
11
class StyleRegistry extends \Box\Spout\Writer\Common\Manager\Style\StyleRegistry
12
{
13
    /**
14
     * @see https://msdn.microsoft.com/en-us/library/ff529597(v=office.12).aspx
15
     * @var array Mapping between built-in format and the associated numFmtId
16
     */
17
    protected static $builtinNumFormatToIdMapping = [
18
        'General' => 0,
19
        '0' => 1,
20
        '0.00' => 2,
21
        '#,##0' => 3,
22
        '#,##0.00' => 4,
23
        '$#,##0,\-$#,##0' => 5,
24
        '$#,##0,[Red]\-$#,##0' => 6,
25
        '$#,##0.00,\-$#,##0.00' => 7,
26
        '$#,##0.00,[Red]\-$#,##0.00' => 8,
27
        '0%' => 9,
28
        '0.00%' => 10,
29
        '0.00E+00' => 11,
30
        '# ?/?' => 12,
31
        '# ??/??' => 13,
32
        'mm-dd-yy' => 14,
33
        'd-mmm-yy' => 15,
34
        'd-mmm' => 16,
35
        'mmm-yy' => 17,
36
        'h:mm AM/PM' => 18,
37
        'h:mm:ss AM/PM' => 19,
38
        'h:mm' => 20,
39
        'h:mm:ss' => 21,
40
        'm/d/yy h:mm' => 22,
41
42
        '#,##0 ,(#,##0)' => 37,
43
        '#,##0 ,[Red](#,##0)' => 38,
44
        '#,##0.00,(#,##0.00)' => 39,
45
        '#,##0.00,[Red](#,##0.00)' => 40,
46
47
        '_("$"* #,##0.00_),_("$"* \(#,##0.00\),_("$"* "-"??_),_(@_)' => 44,
48
        'mm:ss' => 45,
49
        '[h]:mm:ss' => 46,
50
        'mm:ss.0' => 47,
51
52
        '##0.0E+0' => 48,
53
        '@' => 49,
54
55
        '[$-404]e/m/d' => 27,
56
        'm/d/yy' => 30,
57
        't0' => 59,
58
        't0.00' => 60,
59
        't#,##0' => 61,
60
        't#,##0.00' => 62,
61
        't0%' => 67,
62
        't0.00%' => 68,
63
        't# ?/?' => 69,
64
        't# ??/??' => 70,
65
    ];
66
67
    /**
68
     * @var array
69
     */
70
    protected $registeredFormats = [];
71
72
    /**
73
     * @var array [STYLE_ID] => [FORMAT_ID] maps a style to a format declaration
74
     */
75
    protected $styleIdToFormatsMappingTable = [];
76
77
    /**
78
     * If the numFmtId is lower than 0xA4 (164 in decimal)
79
     * then it's a built-in number format.
80
     * Since Excel is the dominant vendor - we play along here
81
     *
82
     * @var int The fill index counter for custom fills.
83
     */
84
    protected $formatIndex = 164;
85
86
    /**
87
     * @var array
88
     */
89
    protected $registeredFills = [];
90
91
    /**
92
     * @var array [STYLE_ID] => [FILL_ID] maps a style to a fill declaration
93
     */
94
    protected $styleIdToFillMappingTable = [];
95
96
    /**
97
     * Excel preserves two default fills with index 0 and 1
98
     * Since Excel is the dominant vendor - we play along here
99
     *
100
     * @var int The fill index counter for custom fills.
101
     */
102
    protected $fillIndex = 2;
103
104
    /**
105
     * @var array
106
     */
107
    protected $registeredBorders = [];
108
109
    /**
110
     * @var array [STYLE_ID] => [BORDER_ID] maps a style to a border declaration
111
     */
112
    protected $styleIdToBorderMappingTable = [];
113
114
    /**
115
     * XLSX specific operations on the registered styles
116
     *
117
     * @param Style $style
118
     * @return Style
119
     */
120 42
    public function registerStyle(Style $style)
121
    {
122 42
        $registeredStyle = parent::registerStyle($style);
123 42
        $this->registerFill($registeredStyle);
124 42
        $this->registerFormat($registeredStyle);
125 42
        $this->registerBorder($registeredStyle);
126
127 42
        return $registeredStyle;
128
    }
129
130
    /**
131
     * Register a format definition
132
     *
133
     * @param Style $style
134
     */
135 42
    protected function registerFormat(Style $style)
136
    {
137 42
        $styleId = $style->getId();
138
139 42
        $format = $style->getFormat();
140 42
        if ($format) {
141 1
            $isFormatRegistered = isset($this->registeredFormats[$format]);
142
143
            // We need to track the already registered format definitions
144 1
            if ($isFormatRegistered) {
145
                $registeredStyleId = $this->registeredFormats[$format];
146
                $registeredFormatId = $this->styleIdToFormatsMappingTable[$registeredStyleId];
147
                $this->styleIdToFormatsMappingTable[$styleId] = $registeredFormatId;
148
            } else {
149 1
                $this->registeredFormats[$format] = $styleId;
150
151 1
                if (isset(self::$builtinNumFormatToIdMapping[$format])) {
152 1
                    $id = self::$builtinNumFormatToIdMapping[$format];
153
                } else {
154 1
                    $id = $this->formatIndex++;
155
                }
156 1
                $this->styleIdToFormatsMappingTable[$styleId] = $id;
157
            }
158
        } else {
159
            // The formatId maps a style to a format declaration
160
            // When there is no format definition - we default to 0 ( General )
161 42
            $this->styleIdToFormatsMappingTable[$styleId] = 0;
162
        }
163 42
    }
164
165
    /**
166
     * @param int $styleId
167
     * @return int|null Format ID associated to the given style ID
168
     */
169 23
    public function getFormatIdForStyleId($styleId)
170
    {
171 23
        return (isset($this->styleIdToFormatsMappingTable[$styleId])) ?
172 14
            $this->styleIdToFormatsMappingTable[$styleId] :
173 23
            null;
174
    }
175
176
    /**
177
     * Register a fill definition
178
     *
179
     * @param Style $style
180
     */
181 42
    private function registerFill(Style $style)
182
    {
183 42
        $styleId = $style->getId();
184
185
        // Currently - only solid backgrounds are supported
186
        // so $backgroundColor is a scalar value (RGB Color)
187 42
        $backgroundColor = $style->getBackgroundColor();
188
189 42
        if ($backgroundColor) {
190 4
            $isBackgroundColorRegistered = isset($this->registeredFills[$backgroundColor]);
191
192
            // We need to track the already registered background definitions
193 4
            if ($isBackgroundColorRegistered) {
194 3
                $registeredStyleId = $this->registeredFills[$backgroundColor];
195 3
                $registeredFillId = $this->styleIdToFillMappingTable[$registeredStyleId];
196 3
                $this->styleIdToFillMappingTable[$styleId] = $registeredFillId;
197
            } else {
198 4
                $this->registeredFills[$backgroundColor] = $styleId;
199 4
                $this->styleIdToFillMappingTable[$styleId] = $this->fillIndex++;
200
            }
201
        } else {
202
            // The fillId maps a style to a fill declaration
203
            // When there is no background color definition - we default to 0
204 42
            $this->styleIdToFillMappingTable[$styleId] = 0;
205
        }
206 42
    }
207
208
    /**
209
     * @param int $styleId
210
     * @return int|null Fill ID associated to the given style ID
211
     */
212 15
    public function getFillIdForStyleId($styleId)
213
    {
214 15
        return (isset($this->styleIdToFillMappingTable[$styleId])) ?
215 15
            $this->styleIdToFillMappingTable[$styleId] :
216 15
            null;
217
    }
218
219
    /**
220
     * Register a border definition
221
     *
222
     * @param Style $style
223
     */
224 42
    private function registerBorder(Style $style)
225
    {
226 42
        $styleId = $style->getId();
227
228 42
        if ($style->shouldApplyBorder()) {
229 5
            $border = $style->getBorder();
230 5
            $serializedBorder = serialize($border);
231
232 5
            $isBorderAlreadyRegistered = isset($this->registeredBorders[$serializedBorder]);
233
234 5
            if ($isBorderAlreadyRegistered) {
235 3
                $registeredStyleId = $this->registeredBorders[$serializedBorder];
236 3
                $registeredBorderId = $this->styleIdToBorderMappingTable[$registeredStyleId];
237 3
                $this->styleIdToBorderMappingTable[$styleId] = $registeredBorderId;
238
            } else {
239 5
                $this->registeredBorders[$serializedBorder] = $styleId;
240 5
                $this->styleIdToBorderMappingTable[$styleId] = count($this->registeredBorders);
241
            }
242
        } else {
243
            // If no border should be applied - the mapping is the default border: 0
244 42
            $this->styleIdToBorderMappingTable[$styleId] = 0;
245
        }
246 42
    }
247
248
    /**
249
     * @param int $styleId
250
     * @return int|null Fill ID associated to the given style ID
251
     */
252 15
    public function getBorderIdForStyleId($styleId)
253
    {
254 15
        return (isset($this->styleIdToBorderMappingTable[$styleId])) ?
255 15
            $this->styleIdToBorderMappingTable[$styleId] :
256 15
            null;
257
    }
258
259
    /**
260
     * @return array
261
     */
262 37
    public function getRegisteredFills()
263
    {
264 37
        return $this->registeredFills;
265
    }
266
267
    /**
268
     * @return array
269
     */
270 37
    public function getRegisteredBorders()
271
    {
272 37
        return $this->registeredBorders;
273
    }
274
275
    /**
276
     * @return array
277
     */
278 36
    public function getRegisteredFormats()
279
    {
280 36
        return $this->registeredFormats;
281
    }
282
}
283