Total Complexity | 45 |
Total Lines | 262 |
Duplicated Lines | 0 % |
Coverage | 100% |
Changes | 8 | ||
Bugs | 1 | Features | 0 |
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 |
||
15 | class Styles |
||
16 | { |
||
17 | /** |
||
18 | * @var Spreadsheet |
||
19 | */ |
||
20 | private $spreadsheet; |
||
21 | |||
22 | /** |
||
23 | * @var bool |
||
24 | */ |
||
25 | protected $readDataOnly = false; |
||
26 | |||
27 | /** @var array */ |
||
28 | public static $mappings = [ |
||
29 | 'borderStyle' => [ |
||
30 | '0' => Border::BORDER_NONE, |
||
31 | '1' => Border::BORDER_THIN, |
||
32 | '2' => Border::BORDER_MEDIUM, |
||
33 | '3' => Border::BORDER_SLANTDASHDOT, |
||
34 | '4' => Border::BORDER_DASHED, |
||
35 | '5' => Border::BORDER_THICK, |
||
36 | '6' => Border::BORDER_DOUBLE, |
||
37 | '7' => Border::BORDER_DOTTED, |
||
38 | '8' => Border::BORDER_MEDIUMDASHED, |
||
39 | '9' => Border::BORDER_DASHDOT, |
||
40 | '10' => Border::BORDER_MEDIUMDASHDOT, |
||
41 | '11' => Border::BORDER_DASHDOTDOT, |
||
42 | '12' => Border::BORDER_MEDIUMDASHDOTDOT, |
||
43 | '13' => Border::BORDER_MEDIUMDASHDOTDOT, |
||
44 | ], |
||
45 | 'fillType' => [ |
||
46 | '1' => Fill::FILL_SOLID, |
||
47 | '2' => Fill::FILL_PATTERN_DARKGRAY, |
||
48 | '3' => Fill::FILL_PATTERN_MEDIUMGRAY, |
||
49 | '4' => Fill::FILL_PATTERN_LIGHTGRAY, |
||
50 | '5' => Fill::FILL_PATTERN_GRAY125, |
||
51 | '6' => Fill::FILL_PATTERN_GRAY0625, |
||
52 | '7' => Fill::FILL_PATTERN_DARKHORIZONTAL, // horizontal stripe |
||
53 | '8' => Fill::FILL_PATTERN_DARKVERTICAL, // vertical stripe |
||
54 | '9' => Fill::FILL_PATTERN_DARKDOWN, // diagonal stripe |
||
55 | '10' => Fill::FILL_PATTERN_DARKUP, // reverse diagonal stripe |
||
56 | '11' => Fill::FILL_PATTERN_DARKGRID, // diagoanl crosshatch |
||
57 | '12' => Fill::FILL_PATTERN_DARKTRELLIS, // thick diagonal crosshatch |
||
58 | '13' => Fill::FILL_PATTERN_LIGHTHORIZONTAL, |
||
59 | '14' => Fill::FILL_PATTERN_LIGHTVERTICAL, |
||
60 | '15' => Fill::FILL_PATTERN_LIGHTUP, |
||
61 | '16' => Fill::FILL_PATTERN_LIGHTDOWN, |
||
62 | '17' => Fill::FILL_PATTERN_LIGHTGRID, // thin horizontal crosshatch |
||
63 | '18' => Fill::FILL_PATTERN_LIGHTTRELLIS, // thin diagonal crosshatch |
||
64 | ], |
||
65 | 'horizontal' => [ |
||
66 | '1' => Alignment::HORIZONTAL_GENERAL, |
||
67 | '2' => Alignment::HORIZONTAL_LEFT, |
||
68 | '4' => Alignment::HORIZONTAL_RIGHT, |
||
69 | '8' => Alignment::HORIZONTAL_CENTER, |
||
70 | '16' => Alignment::HORIZONTAL_CENTER_CONTINUOUS, |
||
71 | '32' => Alignment::HORIZONTAL_JUSTIFY, |
||
72 | '64' => Alignment::HORIZONTAL_CENTER_CONTINUOUS, |
||
73 | ], |
||
74 | 'underline' => [ |
||
75 | '1' => Font::UNDERLINE_SINGLE, |
||
76 | '2' => Font::UNDERLINE_DOUBLE, |
||
77 | '3' => Font::UNDERLINE_SINGLEACCOUNTING, |
||
78 | '4' => Font::UNDERLINE_DOUBLEACCOUNTING, |
||
79 | ], |
||
80 | 'vertical' => [ |
||
81 | '1' => Alignment::VERTICAL_TOP, |
||
82 | '2' => Alignment::VERTICAL_BOTTOM, |
||
83 | '4' => Alignment::VERTICAL_CENTER, |
||
84 | '8' => Alignment::VERTICAL_JUSTIFY, |
||
85 | ], |
||
86 | ]; |
||
87 | |||
88 | 10 | public function __construct(Spreadsheet $spreadsheet, bool $readDataOnly) |
|
89 | { |
||
90 | 10 | $this->spreadsheet = $spreadsheet; |
|
91 | 10 | $this->readDataOnly = $readDataOnly; |
|
92 | 10 | } |
|
93 | |||
94 | 10 | public function read(SimpleXMLElement $sheet, int $maxRow, int $maxCol): void |
|
98 | } |
||
99 | 10 | } |
|
100 | |||
101 | 10 | private function readStyles(SimpleXMLElement $styleRegion, int $maxRow, int $maxCol): void |
|
102 | { |
||
103 | 10 | foreach ($styleRegion as $style) { |
|
104 | 10 | $styleAttributes = $style->attributes(); |
|
1 ignored issue
–
show
|
|||
105 | 10 | if ($styleAttributes !== null && ($styleAttributes['startRow'] <= $maxRow) && ($styleAttributes['startCol'] <= $maxCol)) { |
|
106 | 10 | $cellRange = $this->readStyleRange($styleAttributes, $maxCol, $maxRow); |
|
107 | |||
108 | 10 | $styleAttributes = $style->Style->attributes(); |
|
109 | |||
110 | 10 | $styleArray = []; |
|
111 | // We still set the number format mask for date/time values, even if readDataOnly is true |
||
112 | // so that we can identify whether a float is a float or a date value |
||
113 | 10 | $formatCode = $styleAttributes ? (string) $styleAttributes['Format'] : null; |
|
114 | 10 | if ($formatCode && Date::isDateTimeFormatCode($formatCode)) { |
|
115 | 5 | $styleArray['numberFormat']['formatCode'] = $formatCode; |
|
116 | } |
||
117 | 10 | if ($this->readDataOnly === false && $styleAttributes !== null) { |
|
118 | // If readDataOnly is false, we set all formatting information |
||
119 | 10 | $styleArray['numberFormat']['formatCode'] = $formatCode; |
|
120 | 10 | $styleArray = $this->readStyle($styleArray, $styleAttributes, $style); |
|
1 ignored issue
–
show
|
|||
121 | } |
||
122 | 10 | $this->spreadsheet->getActiveSheet()->getStyle($cellRange)->applyFromArray($styleArray); |
|
123 | } |
||
124 | } |
||
125 | 10 | } |
|
126 | |||
127 | 6 | private function addBorderDiagonal(SimpleXMLElement $srssb, array &$styleArray): void |
|
128 | { |
||
129 | 6 | if (isset($srssb->Diagonal, $srssb->{'Rev-Diagonal'})) { |
|
130 | 6 | $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes()); |
|
131 | 6 | $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_BOTH; |
|
132 | 4 | } elseif (isset($srssb->Diagonal)) { |
|
133 | 4 | $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->Diagonal->attributes()); |
|
134 | 4 | $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_UP; |
|
135 | 4 | } elseif (isset($srssb->{'Rev-Diagonal'})) { |
|
136 | 4 | $styleArray['borders']['diagonal'] = self::parseBorderAttributes($srssb->{'Rev-Diagonal'}->attributes()); |
|
137 | 4 | $styleArray['borders']['diagonalDirection'] = Borders::DIAGONAL_DOWN; |
|
138 | } |
||
139 | 6 | } |
|
140 | |||
141 | 6 | private function addBorderStyle(SimpleXMLElement $srssb, array &$styleArray, string $direction): void |
|
142 | { |
||
143 | 6 | $ucDirection = ucfirst($direction); |
|
144 | 6 | if (isset($srssb->$ucDirection)) { |
|
145 | 6 | $styleArray['borders'][$direction] = self::parseBorderAttributes($srssb->$ucDirection->attributes()); |
|
146 | } |
||
147 | 6 | } |
|
148 | |||
149 | 10 | private function calcRotation(SimpleXMLElement $styleAttributes): int |
|
150 | { |
||
151 | 10 | $rotation = (int) $styleAttributes->Rotation; |
|
152 | 10 | if ($rotation >= 270 && $rotation <= 360) { |
|
153 | 4 | $rotation -= 360; |
|
154 | } |
||
155 | 10 | $rotation = (abs($rotation) > 90) ? 0 : $rotation; |
|
156 | |||
157 | 10 | return $rotation; |
|
158 | } |
||
159 | |||
160 | 6 | private static function addStyle(array &$styleArray, string $key, string $value): void |
|
161 | { |
||
162 | 6 | if (array_key_exists($value, self::$mappings[$key])) { |
|
163 | 6 | $styleArray[$key] = self::$mappings[$key][$value]; |
|
164 | } |
||
165 | 6 | } |
|
166 | |||
167 | 10 | private static function addStyle2(array &$styleArray, string $key1, string $key, string $value): void |
|
168 | { |
||
169 | 10 | if (array_key_exists($value, self::$mappings[$key])) { |
|
170 | 6 | $styleArray[$key1][$key] = self::$mappings[$key][$value]; |
|
171 | } |
||
172 | 10 | } |
|
173 | |||
174 | 6 | private static function parseBorderAttributes(?SimpleXMLElement $borderAttributes): array |
|
175 | { |
||
176 | 6 | $styleArray = []; |
|
177 | 6 | if ($borderAttributes !== null) { |
|
178 | 6 | if (isset($borderAttributes['Color'])) { |
|
179 | 4 | $styleArray['color']['rgb'] = self::parseGnumericColour($borderAttributes['Color']); |
|
180 | } |
||
181 | |||
182 | 6 | self::addStyle($styleArray, 'borderStyle', (string) $borderAttributes['Style']); |
|
183 | } |
||
184 | |||
185 | 6 | return $styleArray; |
|
186 | } |
||
187 | |||
188 | 10 | private static function parseGnumericColour(string $gnmColour): string |
|
189 | { |
||
190 | 10 | [$gnmR, $gnmG, $gnmB] = explode(':', $gnmColour); |
|
191 | 10 | $gnmR = substr(str_pad($gnmR, 4, '0', STR_PAD_RIGHT), 0, 2); |
|
192 | 10 | $gnmG = substr(str_pad($gnmG, 4, '0', STR_PAD_RIGHT), 0, 2); |
|
193 | 10 | $gnmB = substr(str_pad($gnmB, 4, '0', STR_PAD_RIGHT), 0, 2); |
|
194 | |||
195 | 10 | return $gnmR . $gnmG . $gnmB; |
|
196 | } |
||
197 | |||
198 | 10 | private function addColors(array &$styleArray, SimpleXMLElement $styleAttributes): void |
|
199 | { |
||
200 | 10 | $RGB = self::parseGnumericColour((string) $styleAttributes['Fore']); |
|
201 | 10 | $styleArray['font']['color']['rgb'] = $RGB; |
|
202 | 10 | $RGB = self::parseGnumericColour((string) $styleAttributes['Back']); |
|
203 | 10 | $shade = (string) $styleAttributes['Shade']; |
|
204 | 10 | if (($RGB !== '000000') || ($shade !== '0')) { |
|
205 | 10 | $RGB2 = self::parseGnumericColour((string) $styleAttributes['PatternColor']); |
|
206 | 10 | if ($shade === '1') { |
|
207 | 4 | $styleArray['fill']['startColor']['rgb'] = $RGB; |
|
208 | 4 | $styleArray['fill']['endColor']['rgb'] = $RGB2; |
|
209 | } else { |
||
210 | 10 | $styleArray['fill']['endColor']['rgb'] = $RGB; |
|
211 | 10 | $styleArray['fill']['startColor']['rgb'] = $RGB2; |
|
212 | } |
||
213 | 10 | self::addStyle2($styleArray, 'fill', 'fillType', $shade); |
|
214 | } |
||
215 | 10 | } |
|
216 | |||
217 | 10 | private function readStyleRange(SimpleXMLElement $styleAttributes, int $maxCol, int $maxRow): string |
|
218 | { |
||
219 | 10 | $startColumn = Coordinate::stringFromColumnIndex((int) $styleAttributes['startCol'] + 1); |
|
220 | 10 | $startRow = $styleAttributes['startRow'] + 1; |
|
221 | |||
222 | 10 | $endColumn = ($styleAttributes['endCol'] > $maxCol) ? $maxCol : (int) $styleAttributes['endCol']; |
|
223 | 10 | $endColumn = Coordinate::stringFromColumnIndex($endColumn + 1); |
|
224 | |||
225 | 10 | $endRow = 1 + (($styleAttributes['endRow'] > $maxRow) ? $maxRow : (int) $styleAttributes['endRow']); |
|
226 | 10 | $cellRange = $startColumn . $startRow . ':' . $endColumn . $endRow; |
|
227 | |||
228 | 10 | return $cellRange; |
|
229 | } |
||
230 | |||
231 | 10 | private function readStyle(array $styleArray, SimpleXMLElement $styleAttributes, SimpleXMLElement $style): array |
|
277 | } |
||
278 | } |
||
279 |
This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.
This is most likely a typographical error or the method has been renamed.