Completed
Push — master ( d08653...6fb3d8 )
by
unknown
27s queued 21s
created

ConditionalStyles::readConditionalStyles()   A

Complexity

Conditions 6
Paths 5

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 6

Importance

Changes 0
Metric Value
cc 6
eloc 8
nc 5
nop 1
dl 0
loc 14
ccs 11
cts 11
cp 1
crap 6
rs 9.2222
c 0
b 0
f 0
1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
4
5
use PhpOffice\PhpSpreadsheet\Style\Conditional;
6
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar;
7
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension;
8
use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormatValueObject;
9
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
10
use SimpleXMLElement;
11
12
class ConditionalStyles
13
{
14
    private $worksheet;
15
16
    private $worksheetXml;
17
18
    private $dxfs;
19
20
    public function __construct(Worksheet $workSheet, SimpleXMLElement $worksheetXml, array $dxfs = [])
21 13
    {
22
        $this->worksheet = $workSheet;
23 13
        $this->worksheetXml = $worksheetXml;
24 13
        $this->dxfs = $dxfs;
25 13
    }
26 13
27
    public function load(): void
28 13
    {
29
        $this->setConditionalStyles(
30 13
            $this->worksheet,
31 13
            $this->readConditionalStyles($this->worksheetXml),
32 13
            $this->worksheetXml->extLst
33 13
        );
34
    }
35 13
36
    private function readConditionalStyles($xmlSheet)
37 13
    {
38
        $conditionals = [];
39 13
        foreach ($xmlSheet->conditionalFormatting as $conditional) {
40 13
            foreach ($conditional->cfRule as $cfRule) {
41 13
                if (Conditional::isValidConditionType((string) $cfRule['type']) && isset($this->dxfs[(int) ($cfRule['dxfId'])])) {
42
                    $conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
43 13
                } elseif ((string) $cfRule['type'] == Conditional::CONDITION_DATABAR) {
44 13
                    $conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
45 13
                }
46 13
            }
47 13
        }
48 13
49 13
        return $conditionals;
50
    }
51 10
52 3
    private function setConditionalStyles(Worksheet $worksheet, array $conditionals, $xmlExtLst): void
53 3
    {
54
        foreach ($conditionals as $ref => $cfRules) {
55
            ksort($cfRules);
56
            $conditionalStyles = $this->readStyleRules($cfRules, $xmlExtLst);
57
58 13
            // Extract all cell references in $ref
59
            $cellBlocks = explode(' ', str_replace('$', '', strtoupper($ref)));
60
            foreach ($cellBlocks as $cellBlock) {
61 13
                $worksheet->getStyle($cellBlock)->setConditionalStyles($conditionalStyles);
62
            }
63 13
        }
64 13
    }
65 13
66
    private function readStyleRules($cfRules, $extLst)
67
    {
68 13
        $conditionalFormattingRuleExtensions = ConditionalFormattingRuleExtension::parseExtLstXml($extLst);
69 13
        $conditionalStyles = [];
70 13
        foreach ($cfRules as $cfRule) {
71
            $objConditional = new Conditional();
72
            $objConditional->setConditionType((string) $cfRule['type']);
73 13
            $objConditional->setOperatorType((string) $cfRule['operator']);
74
75 13
            if ((string) $cfRule['text'] != '') {
76
                $objConditional->setText((string) $cfRule['text']);
77 13
            }
78 13
79 13
            if (isset($cfRule['stopIfTrue']) && (int) $cfRule['stopIfTrue'] === 1) {
80 13
                $objConditional->setStopIfTrue(true);
81 13
            }
82 13
83
            if (count($cfRule->formula) > 1) {
84 13
                foreach ($cfRule->formula as $formula) {
85 1
                    $objConditional->addCondition((string) $formula);
86
                }
87
            } else {
88 13
                $objConditional->addCondition((string) $cfRule->formula);
89 1
            }
90
91
            if (isset($cfRule->dataBar)) {
92 13
                $objConditional->setDataBar(
93 1
                    $this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions)
94 1
                );
95
            } else {
96
                $objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]);
97 13
            }
98
99
            $conditionalStyles[] = $objConditional;
100 13
        }
101 3
102 3
        return $conditionalStyles;
103
    }
104
105 10
    private function readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions): ConditionalDataBar
106
    {
107
        $dataBar = new ConditionalDataBar();
108 13
        //dataBar attribute
109
        if (isset($cfRule->dataBar['showValue'])) {
110
            $dataBar->setShowValue((bool) $cfRule->dataBar['showValue']);
111 13
        }
112
113
        //dataBar children
114 3
        //conditionalFormatValueObjects
115
        $cfvoXml = $cfRule->dataBar->cfvo;
116 3
        $cfvoIndex = 0;
117
        foreach ((count($cfvoXml) > 1 ? $cfvoXml : [$cfvoXml]) as $cfvo) {
118 3
            if ($cfvoIndex === 0) {
119 2
                $dataBar->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val']));
120
            }
121
            if ($cfvoIndex === 1) {
122
                $dataBar->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val']));
123
            }
124 3
            ++$cfvoIndex;
125 3
        }
126 3
127 3
        //color
128 3
        if (isset($cfRule->dataBar->color)) {
129
            $dataBar->setColor((string) $cfRule->dataBar->color['rgb']);
130 3
        }
131 3
        //extLst
132
        $this->readDataBarExtLstOfConditionalRule($dataBar, $cfRule, $conditionalFormattingRuleExtensions);
133 3
134
        return $dataBar;
135
    }
136
137 3
    private function readDataBarExtLstOfConditionalRule(ConditionalDataBar $dataBar, $cfRule, $conditionalFormattingRuleExtensions): void
138 3
    {
139
        if (isset($cfRule->extLst)) {
140
            $ns = $cfRule->extLst->getNamespaces(true);
141 3
            foreach ((count($cfRule->extLst) > 0 ? $cfRule->extLst->ext : [$cfRule->extLst->ext]) as $ext) {
142
                $extId = (string) $ext->children($ns['x14'])->id;
143 3
                if (isset($conditionalFormattingRuleExtensions[$extId]) && (string) $ext['uri'] === '{B025F937-C7B1-47D3-B67F-A62EFF666E3E}') {
144
                    $dataBar->setConditionalFormattingRuleExt($conditionalFormattingRuleExtensions[$extId]);
145
                }
146 3
            }
147
        }
148 3
    }
149
}
150