Passed
Push — master ( 30369c...0dbe15 )
by
unknown
23:07 queued 15:34
created

Styles   F

Complexity

Total Complexity 127

Size/Duplication

Total Lines 538
Duplicated Lines 0 %

Test Coverage

Coverage 97.92%

Importance

Changes 0
Metric Value
wmc 127
eloc 284
dl 0
loc 538
ccs 282
cts 288
cp 0.9792
rs 2
c 0
b 0
f 0

24 Methods

Rating   Name   Duplication   Size   Complexity  
A setStyleBaseData() 0 5 1
A setTheme() 0 3 1
A getFontCharsets() 0 3 1
A setNamespace() 0 3 1
A setWorkbookPalette() 0 3 1
A getStyleAttributes() 0 8 3
A setStyleXml() 0 3 1
B readColor() 0 27 8
A readProtectionLocked() 0 16 5
B dxfs() 0 30 9
A readAlignmentStyle() 0 31 5
A getArrayItem() 0 3 2
A styles() 0 3 1
A readNumberFormat() 0 10 3
F readFillStyle() 0 57 17
B readBorderStyle() 0 32 9
A readColorTheme() 0 9 4
A formatGeneral() 0 7 2
F readFontStyle() 0 69 23
A readProtectionHidden() 0 16 5
A getAttribute() 0 13 3
B tableStyles() 0 37 11
A readBorder() 0 10 3
B readStyle() 0 36 8

How to fix   Complexity   

Complex Class

Complex classes like Styles often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Styles, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
6
use PhpOffice\PhpSpreadsheet\Style\Alignment;
7
use PhpOffice\PhpSpreadsheet\Style\Border;
8
use PhpOffice\PhpSpreadsheet\Style\Borders;
9
use PhpOffice\PhpSpreadsheet\Style\Color;
10
use PhpOffice\PhpSpreadsheet\Style\Fill;
11
use PhpOffice\PhpSpreadsheet\Style\Font;
12
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
13
use PhpOffice\PhpSpreadsheet\Style\Protection;
14
use PhpOffice\PhpSpreadsheet\Style\Style;
15
use PhpOffice\PhpSpreadsheet\Worksheet\Table\TableDxfsStyle;
16
use SimpleXMLElement;
17
use stdClass;
18
19
class Styles extends BaseParserClass
20
{
21
    /**
22
     * Theme instance.
23
     */
24
    private ?Theme $theme = null;
25
26
    /** @var string[] */
27
    private array $workbookPalette = [];
28
29
    /** @var mixed[] */
30
    private array $styles = [];
31
32
    /** @var array<SimpleXMLElement|stdClass> */
33
    private array $cellStyles = [];
34
35
    private SimpleXMLElement $styleXml;
36
37
    private string $namespace = '';
38
39
    /** @var array<string, int> */
40
    private array $fontCharsets = [];
41
42
    /** @return array<string, int> */
43 683
    public function getFontCharsets(): array
44
    {
45 683
        return $this->fontCharsets;
46
    }
47
48 686
    public function setNamespace(string $namespace): void
49
    {
50 686
        $this->namespace = $namespace;
51
    }
52
53
    /** @param string[] $palette */
54 686
    public function setWorkbookPalette(array $palette): void
55
    {
56 686
        $this->workbookPalette = $palette;
57
    }
58
59 688
    private function getStyleAttributes(SimpleXMLElement $value): SimpleXMLElement
60
    {
61 688
        $attr = $value->attributes('');
62 688
        if ($attr === null || count($attr) === 0) {
63 683
            $attr = $value->attributes($this->namespace);
64
        }
65
66 688
        return Xlsx::testSimpleXml($attr);
67
    }
68
69 686
    public function setStyleXml(SimpleXMLElement $styleXml): void
70
    {
71 686
        $this->styleXml = $styleXml;
72
    }
73
74 666
    public function setTheme(Theme $theme): void
75
    {
76 666
        $this->theme = $theme;
77
    }
78
79
    /**
80
     * @param mixed[] $styles
81
     * @param array<SimpleXMLElement|stdClass> $cellStyles
82
     */
83 686
    public function setStyleBaseData(?Theme $theme = null, array $styles = [], array $cellStyles = []): void
84
    {
85 686
        $this->theme = $theme;
86 686
        $this->styles = $styles;
87 686
        $this->cellStyles = $cellStyles;
88
    }
89
90 683
    public function readFontStyle(Font $fontStyle, SimpleXMLElement $fontStyleXml): void
91
    {
92 683
        if (isset($fontStyleXml->name)) {
93 682
            $attr = $this->getStyleAttributes($fontStyleXml->name);
94 682
            if (isset($attr['val'])) {
95 682
                $fontStyle->setName((string) $attr['val']);
96
            }
97 682
            if (isset($fontStyleXml->charset)) {
98 21
                $charsetAttr = $this->getStyleAttributes($fontStyleXml->charset);
99 21
                if (isset($charsetAttr['val'])) {
100 21
                    $charsetVal = (int) $charsetAttr['val'];
101 21
                    $this->fontCharsets[$fontStyle->getName()] = $charsetVal;
102
                }
103
            }
104
        }
105 683
        if (isset($fontStyleXml->sz)) {
106 682
            $attr = $this->getStyleAttributes($fontStyleXml->sz);
107 682
            if (isset($attr['val'])) {
108 682
                $fontStyle->setSize((float) $attr['val']);
109
            }
110
        }
111 683
        if (isset($fontStyleXml->b)) {
112 519
            $attr = $this->getStyleAttributes($fontStyleXml->b);
113 519
            $fontStyle->setBold(!isset($attr['val']) || self::boolean((string) $attr['val']));
114
        }
115 683
        if (isset($fontStyleXml->i)) {
116 481
            $attr = $this->getStyleAttributes($fontStyleXml->i);
117 481
            $fontStyle->setItalic(!isset($attr['val']) || self::boolean((string) $attr['val']));
118
        }
119 683
        if (isset($fontStyleXml->strike)) {
120 462
            $attr = $this->getStyleAttributes($fontStyleXml->strike);
121 462
            $fontStyle->setStrikethrough(!isset($attr['val']) || self::boolean((string) $attr['val']));
122
        }
123 683
        $fontStyle->getColor()
124 683
            ->setARGB(
125 683
                $this->readColor($fontStyleXml->color)
126 683
            );
127 683
        $theme = $this->readColorTheme($fontStyleXml->color);
128 683
        if ($theme >= 0) {
129 404
            $fontStyle->getColor()->setTheme($theme);
130
        }
131
132 683
        if (isset($fontStyleXml->u)) {
133 476
            $attr = $this->getStyleAttributes($fontStyleXml->u);
134 476
            if (!isset($attr['val'])) {
135 205
                $fontStyle->setUnderline(Font::UNDERLINE_SINGLE);
136
            } else {
137 456
                $fontStyle->setUnderline((string) $attr['val']);
138
            }
139
        }
140 683
        if (isset($fontStyleXml->vertAlign)) {
141 24
            $attr = $this->getStyleAttributes($fontStyleXml->vertAlign);
142 24
            if (isset($attr['val'])) {
143 24
                $verticalAlign = strtolower((string) $attr['val']);
144 24
                if ($verticalAlign === 'superscript') {
145 2
                    $fontStyle->setSuperscript(true);
146 24
                } elseif ($verticalAlign === 'subscript') {
147 2
                    $fontStyle->setSubscript(true);
148
                }
149
            }
150
        }
151 683
        if (isset($fontStyleXml->scheme)) {
152 398
            $attr = $this->getStyleAttributes($fontStyleXml->scheme);
153 398
            $fontStyle->setScheme((string) $attr['val']);
154
        }
155 683
        if (isset($fontStyleXml->auto)) {
156 1
            $attr = $this->getStyleAttributes($fontStyleXml->auto);
157 1
            if (isset($attr['val'])) {
158 1
                $fontStyle->setAutoColor(self::boolean((string) $attr['val']));
159
            }
160
        }
161
    }
162
163 239
    private function readNumberFormat(NumberFormat $numfmtStyle, SimpleXMLElement $numfmtStyleXml): void
164
    {
165 239
        if ((string) $numfmtStyleXml['formatCode'] !== '') {
166
            $numfmtStyle->setFormatCode(self::formatGeneral((string) $numfmtStyleXml['formatCode']));
167
168
            return;
169
        }
170 239
        $numfmt = $this->getStyleAttributes($numfmtStyleXml);
171 239
        if (isset($numfmt['formatCode'])) {
172 197
            $numfmtStyle->setFormatCode(self::formatGeneral((string) $numfmt['formatCode']));
173
        }
174
    }
175
176 683
    public function readFillStyle(Fill $fillStyle, SimpleXMLElement $fillStyleXml): void
177
    {
178 683
        if ($fillStyleXml->gradientFill) {
179
            /** @var SimpleXMLElement $gradientFill */
180 4
            $gradientFill = $fillStyleXml->gradientFill[0];
181 4
            $attr = $this->getStyleAttributes($gradientFill);
182 4
            if (!empty($attr['type'])) {
183 2
                $fillStyle->setFillType((string) $attr['type']);
184
            }
185 4
            $fillStyle->setRotation((float) ($attr['degree']));
186 4
            $gradientFill->registerXPathNamespace('sml', Namespaces::MAIN);
187 4
            $fillStyle->getStartColor()->setARGB($this->readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=0]'))->color)); //* @phpstan-ignore-line
188 4
            $fillStyle->getEndColor()->setARGB($this->readColor(self::getArrayItem($gradientFill->xpath('sml:stop[@position=1]'))->color)); //* @phpstan-ignore-line
189 683
        } elseif ($fillStyleXml->patternFill) {
190 682
            $defaultFillStyle = ($fillStyle->getFillType() !== null) ? Fill::FILL_NONE : '';
191 682
            $fgFound = false;
192 682
            $bgFound = false;
193 682
            if ($fillStyleXml->patternFill->fgColor) {
194 268
                $fillStyle->getStartColor()->setARGB($this->readColor($fillStyleXml->patternFill->fgColor, true));
195 268
                if ($fillStyle->getFillType() !== null) {
196 84
                    $defaultFillStyle = Fill::FILL_SOLID;
197
                }
198 268
                $fgFound = true;
199
            }
200 682
            if ($fillStyleXml->patternFill->bgColor) {
201 279
                $fillStyle->getEndColor()->setARGB($this->readColor($fillStyleXml->patternFill->bgColor, true));
202 279
                if ($fillStyle->getFillType() !== null) {
203 80
                    $defaultFillStyle = Fill::FILL_SOLID;
204
                }
205 279
                $bgFound = true;
206
            }
207
208 682
            $type = '';
209 682
            if ((string) $fillStyleXml->patternFill['patternType'] !== '') {
210
                $type = (string) $fillStyleXml->patternFill['patternType'];
211
            } else {
212 682
                $attr = $this->getStyleAttributes($fillStyleXml->patternFill);
213 682
                $type = (string) $attr['patternType'];
214
            }
215 682
            $patternType = ($type === '') ? $defaultFillStyle : $type;
216
217 682
            $fillStyle->setFillType($patternType);
218
            if (
219 682
                !$fgFound // no foreground color specified
220 682
                && !in_array($patternType, [Fill::FILL_NONE, Fill::FILL_SOLID], true) // these patterns aren't relevant
221 682
                && $fillStyle->getStartColor()->getARGB() // not conditional
222
            ) {
223 11
                $fillStyle->getStartColor()
224 11
                    ->setARGB('', true);
225
            }
226
            if (
227 682
                !$bgFound // no background color specified
228 682
                && !in_array($patternType, [Fill::FILL_NONE, Fill::FILL_SOLID], true) // these patterns aren't relevant
229 682
                && $fillStyle->getEndColor()->getARGB() // not conditional
230
            ) {
231 11
                $fillStyle->getEndColor()
232 11
                    ->setARGB('', true);
233
            }
234
        }
235
    }
236
237 683
    public function readBorderStyle(Borders $borderStyle, SimpleXMLElement $borderStyleXml): void
238
    {
239 683
        $diagonalUp = $this->getAttribute($borderStyleXml, 'diagonalUp');
240 683
        $diagonalUp = self::boolean($diagonalUp);
241 683
        $diagonalDown = $this->getAttribute($borderStyleXml, 'diagonalDown');
242 683
        $diagonalDown = self::boolean($diagonalDown);
243 683
        if ($diagonalUp === false) {
244 683
            if ($diagonalDown === false) {
245 683
                $borderStyle->setDiagonalDirection(Borders::DIAGONAL_NONE);
246
            } else {
247 2
                $borderStyle->setDiagonalDirection(Borders::DIAGONAL_DOWN);
248
            }
249 3
        } elseif ($diagonalDown === false) {
250 2
            $borderStyle->setDiagonalDirection(Borders::DIAGONAL_UP);
251
        } else {
252 1
            $borderStyle->setDiagonalDirection(Borders::DIAGONAL_BOTH);
253
        }
254
255 683
        if (isset($borderStyleXml->left)) {
256 664
            $this->readBorder($borderStyle->getLeft(), $borderStyleXml->left);
257
        }
258 683
        if (isset($borderStyleXml->right)) {
259 663
            $this->readBorder($borderStyle->getRight(), $borderStyleXml->right);
260
        }
261 683
        if (isset($borderStyleXml->top)) {
262 665
            $this->readBorder($borderStyle->getTop(), $borderStyleXml->top);
263
        }
264 683
        if (isset($borderStyleXml->bottom)) {
265 664
            $this->readBorder($borderStyle->getBottom(), $borderStyleXml->bottom);
266
        }
267 683
        if (isset($borderStyleXml->diagonal)) {
268 661
            $this->readBorder($borderStyle->getDiagonal(), $borderStyleXml->diagonal);
269
        }
270
    }
271
272 683
    private function getAttribute(SimpleXMLElement $xml, string $attribute): string
273
    {
274 683
        $style = '';
275 683
        if ((string) $xml[$attribute] !== '') {
276
            $style = (string) $xml[$attribute];
277
        } else {
278 683
            $attr = $this->getStyleAttributes($xml);
279 683
            if (isset($attr[$attribute])) {
280 351
                $style = (string) $attr[$attribute];
281
            }
282
        }
283
284 683
        return $style;
285
    }
286
287 665
    private function readBorder(Border $border, SimpleXMLElement $borderXml): void
288
    {
289 665
        $style = $this->getAttribute($borderXml, 'style');
290 665
        if ($style !== '') {
291 83
            $border->setBorderStyle((string) $style);
292
        } else {
293 664
            $border->setBorderStyle(Border::BORDER_NONE);
294
        }
295 665
        if (isset($borderXml->color)) {
296 81
            $border->getColor()->setARGB($this->readColor($borderXml->color));
297
        }
298
    }
299
300 683
    public function readAlignmentStyle(Alignment $alignment, SimpleXMLElement $alignmentXml): void
301
    {
302 683
        $horizontal = (string) $this->getAttribute($alignmentXml, 'horizontal');
303 683
        if ($horizontal !== '') {
304 315
            $alignment->setHorizontal($horizontal);
305
        }
306 683
        $justifyLastLine = (string) $this->getAttribute($alignmentXml, 'justifyLastLine');
307 683
        if ($justifyLastLine !== '') {
308 20
            $alignment->setJustifyLastLine(
309 20
                self::boolean($justifyLastLine)
310 20
            );
311
        }
312 683
        $vertical = (string) $this->getAttribute($alignmentXml, 'vertical');
313 683
        if ($vertical !== '') {
314 300
            $alignment->setVertical($vertical);
315
        }
316
317 683
        $textRotation = (int) $this->getAttribute($alignmentXml, 'textRotation');
318 683
        if ($textRotation > 90) {
319 2
            $textRotation = 90 - $textRotation;
320
        }
321 683
        $alignment->setTextRotation($textRotation);
322
323 683
        $wrapText = $this->getAttribute($alignmentXml, 'wrapText');
324 683
        $alignment->setWrapText(self::boolean((string) $wrapText));
325 683
        $shrinkToFit = $this->getAttribute($alignmentXml, 'shrinkToFit');
326 683
        $alignment->setShrinkToFit(self::boolean((string) $shrinkToFit));
327 683
        $indent = (int) $this->getAttribute($alignmentXml, 'indent');
328 683
        $alignment->setIndent(max($indent, 0));
329 683
        $readingOrder = (int) $this->getAttribute($alignmentXml, 'readingOrder');
330 683
        $alignment->setReadOrder(max($readingOrder, 0));
331
    }
332
333 683
    private static function formatGeneral(string $formatString): string
334
    {
335 683
        if ($formatString === 'GENERAL') {
336 1
            $formatString = NumberFormat::FORMAT_GENERAL;
337
        }
338
339 683
        return $formatString;
340
    }
341
342
    /**
343
     * Read style.
344
     */
345 683
    public function readStyle(Style $docStyle, SimpleXMLElement|stdClass $style): void
346
    {
347 683
        if ($style instanceof SimpleXMLElement) {
348 239
            $this->readNumberFormat($docStyle->getNumberFormat(), $style->numFmt);
349
        } else {
350
            /** @var SimpleXMLElement */
351 683
            $temp = $style->numFmt;
352 683
            $docStyle->getNumberFormat()->setFormatCode(self::formatGeneral((string) $temp));
353
        }
354
355
        /** @var SimpleXMLElement $style */
356 683
        if (isset($style->font)) {
357 683
            $this->readFontStyle($docStyle->getFont(), $style->font);
358
        }
359
360 683
        if (isset($style->fill)) {
361 683
            $this->readFillStyle($docStyle->getFill(), $style->fill);
362
        }
363
364 683
        if (isset($style->border)) {
365 683
            $this->readBorderStyle($docStyle->getBorders(), $style->border);
366
        }
367
368 683
        if (isset($style->alignment)) {
369 683
            $this->readAlignmentStyle($docStyle->getAlignment(), $style->alignment);
370
        }
371
372
        // protection
373 683
        if (isset($style->protection)) {
374 683
            $this->readProtectionLocked($docStyle, $style->protection);
375 683
            $this->readProtectionHidden($docStyle, $style->protection);
376
        }
377
378
        // top-level style settings
379 683
        if (isset($style->quotePrefix)) {
380 683
            $docStyle->setQuotePrefix((bool) $style->quotePrefix);
381
        }
382
    }
383
384
    /**
385
     * Read protection locked attribute.
386
     */
387 683
    public function readProtectionLocked(Style $docStyle, SimpleXMLElement $style): void
388
    {
389 683
        $locked = '';
390 683
        if ((string) $style['locked'] !== '') {
391
            $locked = (string) $style['locked'];
392
        } else {
393 683
            $attr = $this->getStyleAttributes($style);
394 683
            if (isset($attr['locked'])) {
395 40
                $locked = (string) $attr['locked'];
396
            }
397
        }
398 683
        if ($locked !== '') {
399 40
            if (self::boolean($locked)) {
400 17
                $docStyle->getProtection()->setLocked(Protection::PROTECTION_PROTECTED);
401
            } else {
402 23
                $docStyle->getProtection()->setLocked(Protection::PROTECTION_UNPROTECTED);
403
            }
404
        }
405
    }
406
407
    /**
408
     * Read protection hidden attribute.
409
     */
410 683
    public function readProtectionHidden(Style $docStyle, SimpleXMLElement $style): void
411
    {
412 683
        $hidden = '';
413 683
        if ((string) $style['hidden'] !== '') {
414
            $hidden = (string) $style['hidden'];
415
        } else {
416 683
            $attr = $this->getStyleAttributes($style);
417 683
            if (isset($attr['hidden'])) {
418 22
                $hidden = (string) $attr['hidden'];
419
            }
420
        }
421 683
        if ($hidden !== '') {
422 22
            if (self::boolean((string) $hidden)) {
423 1
                $docStyle->getProtection()->setHidden(Protection::PROTECTION_PROTECTED);
424
            } else {
425 21
                $docStyle->getProtection()->setHidden(Protection::PROTECTION_UNPROTECTED);
426
            }
427
        }
428
    }
429
430 683
    public function readColorTheme(SimpleXMLElement $color): int
431
    {
432 683
        $attr = $this->getStyleAttributes($color);
433 683
        $retVal = -1;
434 683
        if (isset($attr['theme']) && is_numeric((string) $attr['theme']) && !isset($attr['tint'])) {
435 404
            $retVal = (int) $attr['theme'];
436
        }
437
438 683
        return $retVal;
439
    }
440
441 688
    public function readColor(SimpleXMLElement $color, bool $background = false): string
442
    {
443 688
        $attr = $this->getStyleAttributes($color);
444 688
        if (isset($attr['rgb'])) {
445 552
            return (string) $attr['rgb'];
446
        }
447 444
        if (isset($attr['indexed'])) {
448 103
            $indexedColor = (int) $attr['indexed'];
449 103
            if ($indexedColor >= count($this->workbookPalette)) {
450 100
                return Color::indexedColor($indexedColor - 7, $background)->getARGB() ?? '';
451
            }
452
453 4
            return Color::indexedColor($indexedColor, $background, $this->workbookPalette)->getARGB() ?? '';
454
        }
455 437
        if (isset($attr['theme'])) {
456 404
            if ($this->theme !== null) {
457 401
                $returnColour = $this->theme->getColourByIndex((int) $attr['theme']);
458 401
                if (isset($attr['tint'])) {
459 213
                    $tintAdjust = (float) $attr['tint'];
460 213
                    $returnColour = Color::changeBrightness($returnColour ?? '', $tintAdjust);
461
                }
462
463 401
                return 'FF' . $returnColour;
464
            }
465
        }
466
467 72
        return ($background) ? 'FFFFFFFF' : 'FF000000';
468
    }
469
470
    /** @return Style[] */
471 686
    public function dxfs(bool $readDataOnly = false): array
472
    {
473 686
        $dxfs = [];
474 686
        if (!$readDataOnly && $this->styleXml) {
475
            //    Conditional Styles
476 683
            if ($this->styleXml->dxfs) {
477 662
                foreach ($this->styleXml->dxfs->dxf as $dxf) {
478 239
                    $style = new Style(false, true);
479 239
                    $this->readStyle($style, $dxf);
480 239
                    $dxfs[] = $style;
481
                }
482
            }
483
            //    Cell Styles
484 683
            if ($this->styleXml->cellStyles) {
485 679
                foreach ($this->styleXml->cellStyles->cellStyle as $cellStylex) {
486 679
                    $cellStyle = Xlsx::getAttributes($cellStylex);
487 679
                    if ((int) ($cellStyle['builtinId']) == 0) {
488 679
                        if (isset($this->cellStyles[(int) ($cellStyle['xfId'])])) {
489
                            // Set default style
490 679
                            $style = new Style();
491 679
                            $this->readStyle($style, $this->cellStyles[(int) ($cellStyle['xfId'])]);
492
493
                            // normal style, currently not using it for anything
494
                        }
495
                    }
496
                }
497
            }
498
        }
499
500 686
        return $dxfs;
501
    }
502
503
    /** @return TableDxfsStyle[] */
504 686
    public function tableStyles(bool $readDataOnly = false): array
505
    {
506 686
        $tableStyles = [];
507 686
        if (!$readDataOnly && $this->styleXml) {
508
            //    Conditional Styles
509 683
            if ($this->styleXml->tableStyles) {
510 656
                foreach ($this->styleXml->tableStyles->tableStyle as $s) {
511 6
                    $attrs = Xlsx::getAttributes($s);
512 6
                    if (isset($attrs['name'][0])) {
513 6
                        $style = new TableDxfsStyle((string) ($attrs['name'][0]));
514 6
                        foreach ($s->tableStyleElement as $e) {
515 6
                            $a = Xlsx::getAttributes($e);
516 6
                            if (isset($a['dxfId'][0], $a['type'][0])) {
517 6
                                switch ($a['type'][0]) {
518 6
                                    case 'headerRow':
519 5
                                        $style->setHeaderRow((int) ($a['dxfId'][0]));
520
521 5
                                        break;
522 6
                                    case 'firstRowStripe':
523 6
                                        $style->setFirstRowStripe((int) ($a['dxfId'][0]));
524
525 6
                                        break;
526 6
                                    case 'secondRowStripe':
527 6
                                        $style->setSecondRowStripe((int) ($a['dxfId'][0]));
528
529 6
                                        break;
530
                                    default:
531
                                }
532
                            }
533
                        }
534 6
                        $tableStyles[] = $style;
535
                    }
536
                }
537
            }
538
        }
539
540 686
        return $tableStyles;
541
    }
542
543
    /** @return mixed[] */
544 686
    public function styles(): array
545
    {
546 686
        return $this->styles;
547
    }
548
549
    /**
550
     * Get array item.
551
     *
552
     * @param false|mixed[] $array (usually array, in theory can be false)
553
     */
554 4
    private static function getArrayItem(mixed $array): ?SimpleXMLElement
555
    {
556 4
        return is_array($array) ? ($array[0] ?? null) : null; // @phpstan-ignore-line
557
    }
558
}
559