Failed Conditions
Pull Request — master (#4412)
by
unknown
14:08
created

ConditionalColorScale   B

Complexity

Total Complexity 46

Size/Duplication

Total Lines 235
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 46
eloc 119
dl 0
loc 235
rs 8.72
c 0
b 0
f 0
ccs 30
cts 30
cp 1

18 Methods

Rating   Name   Duplication   Size   Complexity  
A setMinimumConditionalFormatValueObject() 0 5 1
A getMaximumConditionalFormatValueObject() 0 3 1
B getColorForValue() 0 46 11
B prepareColorScale() 0 33 9
A getMinimumConditionalFormatValueObject() 0 3 1
B getLimitValue() 0 21 7
A setMaximumColor() 0 5 1
A setMidpointConditionalFormatValueObject() 0 5 1
A setScaleArray() 0 14 5
A setMinimumColor() 0 5 1
A getSqRef() 0 3 1
A setMidpointColor() 0 5 1
A getMaximumColor() 0 3 1
A getMidpointConditionalFormatValueObject() 0 3 1
A getMidpointColor() 0 3 1
A setSqRef() 0 6 1
A setMaximumConditionalFormatValueObject() 0 5 1
A getMinimumColor() 0 3 1

How to fix   Complexity   

Complex Class

Complex classes like ConditionalColorScale 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 ConditionalColorScale, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Percentiles;
6
use PhpOffice\PhpSpreadsheet\Style\Color;
7
8
class ConditionalColorScale
9
{
10
    private ?ConditionalFormatValueObject $minimumConditionalFormatValueObject = null;
11
12
    private ?ConditionalFormatValueObject $midpointConditionalFormatValueObject = null;
13
14
    private ?ConditionalFormatValueObject $maximumConditionalFormatValueObject = null;
15
16
    private ?Color $minimumColor = null;
17
18
    private ?Color $midpointColor = null;
19
20
    private ?Color $maximumColor = null;
21 3
22
    private ?string $sqref = null;
23 3
24
    private array $valueArray = [];
25
26 4
    private float $minValue = 0;
27
28 4
    private float $maxValue = 0;
29
30 4
    private float $midValue = 0;
31
32
    private ?\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet = null;
33 3
34
    public function getMinimumConditionalFormatValueObject(): ?ConditionalFormatValueObject
35 3
    {
36
        return $this->minimumConditionalFormatValueObject;
37
    }
38 3
39
    public function setMinimumConditionalFormatValueObject(ConditionalFormatValueObject $minimumConditionalFormatValueObject): self
40 3
    {
41
        $this->minimumConditionalFormatValueObject = $minimumConditionalFormatValueObject;
42 3
43
        return $this;
44
    }
45 3
46
    public function getMidpointConditionalFormatValueObject(): ?ConditionalFormatValueObject
47 3
    {
48
        return $this->midpointConditionalFormatValueObject;
49
    }
50 4
51
    public function setMidpointConditionalFormatValueObject(ConditionalFormatValueObject $midpointConditionalFormatValueObject): self
52 4
    {
53
        $this->midpointConditionalFormatValueObject = $midpointConditionalFormatValueObject;
54 4
55
        return $this;
56
    }
57 3
58
    public function getMaximumConditionalFormatValueObject(): ?ConditionalFormatValueObject
59 3
    {
60
        return $this->maximumConditionalFormatValueObject;
61
    }
62 4
63
    public function setMaximumConditionalFormatValueObject(ConditionalFormatValueObject $maximumConditionalFormatValueObject): self
64 4
    {
65
        $this->maximumConditionalFormatValueObject = $maximumConditionalFormatValueObject;
66 4
67
        return $this;
68
    }
69 3
70
    public function getMinimumColor(): ?Color
71 3
    {
72
        return $this->minimumColor;
73
    }
74 3
75
    public function setMinimumColor(Color $minimumColor): self
76 3
    {
77
        $this->minimumColor = $minimumColor;
78 3
79
        return $this;
80
    }
81 3
82
    public function getMidpointColor(): ?Color
83 3
    {
84
        return $this->midpointColor;
85
    }
86 4
87
    public function setMidpointColor(Color $midpointColor): self
88 4
    {
89
        $this->midpointColor = $midpointColor;
90 4
91
        return $this;
92
    }
93
94
    public function getMaximumColor(): ?Color
95
    {
96
        return $this->maximumColor;
97
    }
98
99
    public function setMaximumColor(Color $maximumColor): self
100
    {
101
        $this->maximumColor = $maximumColor;
102
103
        return $this;
104
    }
105
106
    public function getSqRef(): ?string
107
    {
108
        return $this->sqref;
109
    }
110
111
    public function setSqRef(string $sqref, \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $worksheet): self
112
    {
113
        $this->sqref = $sqref;
114
        $this->worksheet = $worksheet;
115
116
        return $this;
117
    }
118
119
    public function setScaleArray(): self
120
    {
121
        if ($this->sqref !== null && $this->worksheet !== null) {
122
            $values = $this->worksheet->rangesToArray($this->sqref, null, true, true, true);
123
            $this->valueArray = [];
124
            foreach ($values as $key => $value) {
125
                foreach ($value as $k => $v) {
126
                    $this->valueArray[] = (float) $v;
127
                }
128
            }
129
            $this->prepareColorScale();
130
        }
131
132
        return $this;
133
    }
134
135
    public function getColorForValue(float $value): string
136
    {
137
        if ($this->minimumColor === null || $this->midpointColor === null || $this->maximumColor === null) {
138
            return 'FF000000';
139
        }
140
        $minColor = $this->minimumColor->getARGB();
141
        $midColor = $this->midpointColor->getARGB();
142
        $maxColor = $this->maximumColor->getARGB();
143
144
        if ($minColor === null || $midColor === null || $maxColor === null) {
145
            return 'FF000000';
146
        }
147
148
        if ($value <= $this->minValue) {
149
            return $minColor;
150
        }
151
        if ($value >= $this->maxValue) {
152
            return $maxColor;
153
        }
154
        if ($value == $this->midValue) {
155
            return $midColor;
156
        }
157
        if ($value < $this->midValue) {
158
            $blend = ($value - $this->minValue) / ($this->midValue - $this->minValue);
159
            $alpha1 = hexdec(substr($minColor, 0, 2));
160
            $alpha2 = hexdec(substr($midColor, 0, 2));
161
            $red1 = hexdec(substr($minColor, 2, 2));
162
            $red2 = hexdec(substr($midColor, 2, 2));
163
            $green1 = hexdec(substr($minColor, 4, 2));
164
            $green2 = hexdec(substr($midColor, 4, 2));
165
            $blue1 = hexdec(substr($minColor, 6, 2));
166
            $blue2 = hexdec(substr($midColor, 6, 2));
167
168
            return strtoupper(dechex((int) ($alpha2 * $blend + $alpha1 * (1 - $blend))) . '' . dechex((int) ($red2 * $blend + $red1 * (1 - $blend))) . '' . dechex((int) ($green2 * $blend + $green1 * (1 - $blend))) . '' . dechex((int) ($blue2 * $blend + $blue1 * (1 - $blend))));
169
        }
170
        $blend = ($value - $this->midValue) / ($this->maxValue - $this->midValue);
171
        $alpha1 = hexdec(substr($midColor, 0, 2));
172
        $alpha2 = hexdec(substr($maxColor, 0, 2));
173
        $red1 = hexdec(substr($midColor, 2, 2));
174
        $red2 = hexdec(substr($maxColor, 2, 2));
175
        $green1 = hexdec(substr($midColor, 4, 2));
176
        $green2 = hexdec(substr($maxColor, 4, 2));
177
        $blue1 = hexdec(substr($midColor, 6, 2));
178
        $blue2 = hexdec(substr($maxColor, 6, 2));
179
180
        return strtoupper(dechex((int) ($alpha2 * $blend + $alpha1 * (1 - $blend))) . '' . dechex((int) ($red2 * $blend + $red1 * (1 - $blend))) . '' . dechex((int) ($green2 * $blend + $green1 * (1 - $blend))) . '' . dechex((int) ($blue2 * $blend + $blue1 * (1 - $blend))));
181
    }
182
183
    private function getLimitValue(string $type, float $value = 0, float $formula = 0): float
184
    {
185
        if (count($this->valueArray) === 0) {
186
            return 0;
187
        }
188
        switch ($type) {
189
            case 'min':
190
                return (float) min($this->valueArray);
191
            case 'max':
192
                return (float) max($this->valueArray);
193
            case 'percentile':
194
                return (float) Percentiles::PERCENTILE($this->valueArray, (float) ($value / 100));
195
            case 'formula':
196
                return $formula;
197
            case 'percent':
198
                $min = (float) min($this->valueArray);
199
                $max = (float) max($this->valueArray);
200
201
                return $min + (float) ($value / 100) * ($max - $min);
202
            default:
203
                return 0;
204
        }
205
    }
206
207
    /**
208
     * Prepares color scale for execution, see the first if for variables that must be set beforehand.
209
     */
210
    public function prepareColorScale(): self
211
    {
212
        if ($this->minimumConditionalFormatValueObject !== null && $this->maximumConditionalFormatValueObject !== null && $this->minimumColor !== null && $this->maximumColor !== null) {
213
            if ($this->midpointConditionalFormatValueObject !== null && $this->midpointConditionalFormatValueObject->getType() !== 'None') {
214
                $this->minValue = $this->getLimitValue($this->minimumConditionalFormatValueObject->getType(), (float) $this->minimumConditionalFormatValueObject->getValue(), (float) $this->minimumConditionalFormatValueObject->getCellFormula());
215
                $this->midValue = $this->getLimitValue($this->midpointConditionalFormatValueObject->getType(), (float) $this->midpointConditionalFormatValueObject->getValue(), (float) $this->midpointConditionalFormatValueObject->getCellFormula());
216
                $this->maxValue = $this->getLimitValue($this->maximumConditionalFormatValueObject->getType(), (float) $this->maximumConditionalFormatValueObject->getValue(), (float) $this->maximumConditionalFormatValueObject->getCellFormula());
217
            } else {
218
                $this->minValue = $this->getLimitValue($this->minimumConditionalFormatValueObject->getType(), (float) $this->minimumConditionalFormatValueObject->getValue(), (float) $this->minimumConditionalFormatValueObject->getCellFormula());
219
                $this->maxValue = $this->getLimitValue($this->maximumConditionalFormatValueObject->getType(), (float) $this->maximumConditionalFormatValueObject->getValue(), (float) $this->maximumConditionalFormatValueObject->getCellFormula());
220
                $this->midValue = (float) ($this->minValue + $this->maxValue) / 2;
221
                $blend = 0.5;
222
223
                $minColor = $this->minimumColor->getARGB();
224
                $maxColor = $this->maximumColor->getARGB();
225
226
                if ($minColor !== null && $maxColor !== null) {
227
                    $alpha1 = hexdec(substr($minColor, 0, 2));
228
                    $alpha2 = hexdec(substr($maxColor, 0, 2));
229
                    $red1 = hexdec(substr($minColor, 2, 2));
230
                    $red2 = hexdec(substr($maxColor, 2, 2));
231
                    $green1 = hexdec(substr($minColor, 4, 2));
232
                    $green2 = hexdec(substr($maxColor, 4, 2));
233
                    $blue1 = hexdec(substr($minColor, 6, 2));
234
                    $blue2 = hexdec(substr($maxColor, 6, 2));
235
                    $this->midpointColor = new Color(strtoupper(dechex((int) ($alpha2 * $blend + $alpha1 * (1 - $blend))) . '' . dechex((int) ($red2 * $blend + $red1 * (1 - $blend))) . '' . dechex((int) ($green2 * $blend + $green1 * (1 - $blend))) . '' . dechex((int) ($blue2 * $blend + $blue1 * (1 - $blend)))));
236
                } else {
237
                    $this->midpointColor = null;
238
                }
239
            }
240
        }
241
242
        return $this;
243
    }
244
}
245