Passed
Push — master ( 653645...08f2f1 )
by
unknown
16:09 queued 04:49
created

Value   C

Complexity

Total Complexity 55

Size/Duplication

Total Lines 310
Duplicated Lines 0 %

Test Coverage

Coverage 94.5%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 55
eloc 101
dl 0
loc 310
ccs 103
cts 109
cp 0.945
rs 6
c 1
b 0
f 0

11 Methods

Rating   Name   Duplication   Size   Complexity  
A isLogical() 0 7 2
A isNumber() 0 11 3
A isText() 0 7 3
B asNumber() 0 16 7
A isBlank() 0 7 2
A isNonText() 0 7 2
B isFormula() 0 36 8
A isEven() 0 14 4
B isRef() 0 24 7
C type() 0 35 13
A isOdd() 0 14 4

How to fix   Complexity   

Complex Class

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

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation\Information;
4
5
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
6
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
7
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
8
use PhpOffice\PhpSpreadsheet\Cell\Cell;
9
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
10
use PhpOffice\PhpSpreadsheet\Exception as SpreadsheetException;
11
use PhpOffice\PhpSpreadsheet\NamedRange;
12
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
13
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
14
15
class Value
16
{
17
    use ArrayEnabled;
18
19
    /**
20
     * IS_BLANK.
21
     *
22
     * @param mixed $value Value to check
23
     *                      Or can be an array of values
24
     *
25
     * @return array<mixed>|bool If an array of numbers is passed as an argument, then the returned result will also be an array
26
     *            with the same dimensions
27
     */
28 19
    public static function isBlank(mixed $value = null): array|bool
29
    {
30 19
        if (is_array($value)) {
31 2
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
32
        }
33
34 19
        return $value === null;
35
    }
36
37
    /**
38
     * IS_REF.
39
     *
40
     * @param mixed $value Value to check
41
     */
42 15
    public static function isRef(mixed $value, ?Cell $cell = null): bool
43
    {
44 15
        if ($cell === null) {
45
            return false;
46
        }
47
48 15
        $value = StringHelper::convertToString($value);
49 15
        $cellValue = Functions::trimTrailingRange($value);
50 15
        if (preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/ui', $cellValue) === 1) {
51 10
            [$worksheet, $cellValue] = Worksheet::extractSheetTitle($cellValue, true, true);
52 10
            if (!empty($worksheet) && $cell->getWorksheet()->getParentOrThrow()->getSheetByName($worksheet) === null) {
53
                return false;
54
            }
55 10
            [$column, $row] = Coordinate::indexesFromString($cellValue ?? '');
56 10
            if ($column > 16384 || $row > 1048576) {
57 1
                return false;
58
            }
59
60 9
            return true;
61
        }
62
63 5
        $namedRange = $cell->getWorksheet()->getParentOrThrow()->getNamedRange($value);
64
65 5
        return $namedRange instanceof NamedRange;
66
    }
67
68
    /**
69
     * IS_EVEN.
70
     *
71
     * @param mixed $value Value to check
72
     *                      Or can be an array of values
73
     *
74
     * @return array<mixed>|bool|string If an array of numbers is passed as an argument, then the returned result will also be an array
75
     *            with the same dimensions
76
     */
77 29
    public static function isEven(mixed $value = null): array|string|bool
78
    {
79 29
        if (is_array($value)) {
80 1
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
81
        }
82
83 29
        if ($value === null) {
84 2
            return ExcelError::NAME();
85
        }
86 27
        if (!is_numeric($value)) {
87 7
            return ExcelError::VALUE();
88
        }
89
90 20
        return ((int) fmod($value + 0, 2)) === 0;
91
    }
92
93
    /**
94
     * IS_ODD.
95
     *
96
     * @param mixed $value Value to check
97
     *                      Or can be an array of values
98
     *
99
     * @return array<mixed>|bool|string If an array of numbers is passed as an argument, then the returned result will also be an array
100
     *            with the same dimensions
101
     */
102 29
    public static function isOdd(mixed $value = null): array|string|bool
103
    {
104 29
        if (is_array($value)) {
105 1
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
106
        }
107
108 29
        if ($value === null) {
109 2
            return ExcelError::NAME();
110
        }
111 27
        if (!is_numeric($value)) {
112 7
            return ExcelError::VALUE();
113
        }
114
115 20
        return ((int) fmod($value + 0, 2)) !== 0;
116
    }
117
118
    /**
119
     * IS_NUMBER.
120
     *
121
     * @param mixed $value Value to check
122
     *                      Or can be an array of values
123
     *
124
     * @return array<mixed>|bool If an array of numbers is passed as an argument, then the returned result will also be an array
125
     *            with the same dimensions
126
     */
127 19
    public static function isNumber(mixed $value = null): array|bool
128
    {
129 19
        if (is_array($value)) {
130 2
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
131
        }
132
133 19
        if (is_string($value)) {
134 10
            return false;
135
        }
136
137 11
        return is_numeric($value);
138
    }
139
140
    /**
141
     * IS_LOGICAL.
142
     *
143
     * @param mixed $value Value to check
144
     *                      Or can be an array of values
145
     *
146
     * @return array<mixed>|bool If an array of numbers is passed as an argument, then the returned result will also be an array
147
     *            with the same dimensions
148
     */
149 18
    public static function isLogical(mixed $value = null): array|bool
150
    {
151 18
        if (is_array($value)) {
152 1
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
153
        }
154
155 18
        return is_bool($value);
156
    }
157
158
    /**
159
     * IS_TEXT.
160
     *
161
     * @param mixed $value Value to check
162
     *                      Or can be an array of values
163
     *
164
     * @return array<mixed>|bool If an array of numbers is passed as an argument, then the returned result will also be an array
165
     *            with the same dimensions
166
     */
167 35
    public static function isText(mixed $value = null): array|bool
168
    {
169 35
        if (is_array($value)) {
170 1
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
171
        }
172
173 35
        return is_string($value) && !ErrorValue::isError($value);
174
    }
175
176
    /**
177
     * IS_NONTEXT.
178
     *
179
     * @param mixed $value Value to check
180
     *                      Or can be an array of values
181
     *
182
     * @return array<mixed>|bool If an array of numbers is passed as an argument, then the returned result will also be an array
183
     *            with the same dimensions
184
     */
185 18
    public static function isNonText(mixed $value = null): array|bool
186
    {
187 18
        if (is_array($value)) {
188 1
            return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value);
189
        }
190
191 18
        return !self::isText($value);
192
    }
193
194
    /**
195
     * ISFORMULA.
196
     *
197
     * @param mixed $cellReference The cell to check
198
     * @param ?Cell $cell The current cell (containing this formula)
199
     *
200
     * @return array<mixed>|bool|string
201
     */
202 5
    public static function isFormula(mixed $cellReference = '', ?Cell $cell = null): array|bool|string
203
    {
204 5
        if ($cell === null) {
205 1
            return ExcelError::REF();
206
        }
207 4
        $cellReference = StringHelper::convertToString($cellReference);
208
209 4
        $fullCellReference = Functions::expandDefinedName($cellReference, $cell);
210
211 4
        if (str_contains($cellReference, '!')) {
212 4
            $cellReference = Functions::trimSheetFromCellReference($cellReference);
213 4
            $cellReferences = Coordinate::extractAllCellReferencesInRange($cellReference);
214 4
            if (count($cellReferences) > 1) {
215 2
                return self::evaluateArrayArgumentsSubset([self::class, __FUNCTION__], 1, $cellReferences, $cell);
216
            }
217
        }
218
219 4
        $fullCellReference = Functions::trimTrailingRange($fullCellReference);
220
221 4
        $worksheetName = '';
222 4
        if (1 == preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $fullCellReference, $matches)) {
223 4
            $fullCellReference = $matches[6] . $matches[7];
224 4
            $worksheetName = str_replace("''", "'", trim($matches[2], "'"));
225
        }
226
227 4
        $worksheet = (!empty($worksheetName))
228 3
            ? $cell->getWorksheet()->getParentOrThrow()->getSheetByName($worksheetName)
229 2
            : $cell->getWorksheet();
230 4
        if ($worksheet === null) {
231
            return ExcelError::REF();
232
        }
233
234
        try {
235 4
            return $worksheet->getCell($fullCellReference)->isFormula();
236 1
        } catch (SpreadsheetException) {
237 1
            return true;
238
        }
239
    }
240
241
    /**
242
     * N.
243
     *
244
     * Returns a value converted to a number
245
     *
246
     * @param null|mixed $value The value you want converted
247
     *
248
     * @return number|string N converts values listed in the following table
249
     *        If value is or refers to N returns
250
     *        A number            That number value
251
     *        A date              The Excel serialized number of that date
252
     *        TRUE                1
253
     *        FALSE               0
254
     *        An error value      The error value
255
     *        Anything else       0
256
     */
257 21
    public static function asNumber($value = null)
258
    {
259 21
        while (is_array($value)) {
260 9
            $value = array_shift($value);
261
        }
262 21
        if (is_float($value) || is_int($value)) {
263 9
            return $value;
264
        }
265 12
        if (is_bool($value)) {
266 1
            return (int) $value;
267
        }
268 11
        if (is_string($value) && substr($value, 0, 1) === '#') {
269 2
            return $value;
270
        }
271
272 9
        return 0;
273
    }
274
275
    /**
276
     * TYPE.
277
     *
278
     * Returns a number that identifies the type of a value
279
     *
280
     * @param null|mixed $value The value you want tested
281
     *
282
     * @return int N converts values listed in the following table
283
     *        If value is or refers to N returns
284
     *        A number            1
285
     *        Text                2
286
     *        Logical Value       4
287
     *        An error value      16
288
     *        Array or Matrix     64
289
     */
290 17
    public static function type($value = null): int
291
    {
292 17
        $value = Functions::flattenArrayIndexed($value);
293 17
        if (count($value) > 1) {
294 3
            end($value);
295 3
            $a = key($value);
296
            //    Range of cells is an error
297 3
            if (Functions::isCellValue($a)) {
298
                return 16;
299
            //    Test for Matrix
300 3
            } elseif (Functions::isMatrixValue($a)) {
301 3
                return 64;
302
            }
303 14
        } elseif (empty($value)) {
304
            //    Empty Cell
305 2
            return 1;
306
        }
307
308 12
        $value = Functions::flattenSingleValue($value);
309 12
        if (($value === null) || (is_float($value)) || (is_int($value))) {
310 4
            return 1;
311 8
        } elseif (is_bool($value)) {
312 1
            return 4;
313 7
        } elseif (is_array($value)) {
314
            return 64;
315 7
        } elseif (is_string($value)) {
316
            //    Errors
317 7
            if (($value !== '') && ($value[0] == '#')) {
318 2
                return 16;
319
            }
320
321 5
            return 2;
322
        }
323
324
        return 0;
325
    }
326
}
327