Failed Conditions
Pull Request — master (#3876)
by Abdul Malik
22:45 queued 13:31
created

Value   F

Complexity

Total Complexity 61

Size/Duplication

Total Lines 303
Duplicated Lines 0 %

Test Coverage

Coverage 96.26%

Importance

Changes 0
Metric Value
wmc 61
eloc 98
dl 0
loc 303
ccs 103
cts 107
cp 0.9626
rs 3.52
c 0
b 0
f 0

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