Completed
Push — develop ( 360db8...810f17 )
by Adrien
18:39
created

LookupRef   F

Complexity

Total Complexity 187

Size/Duplication

Total Lines 887
Duplicated Lines 14.54 %

Coupling/Cohesion

Components 0
Dependencies 6

Test Coverage

Coverage 34.43%

Importance

Changes 0
Metric Value
dl 129
loc 887
ccs 126
cts 366
cp 0.3443
rs 1.263
c 0
b 0
f 0
wmc 187
lcom 0
cbo 6

16 Methods

Rating   Name   Duplication   Size   Complexity  
D INDIRECT() 14 40 10
C cellAddress() 0 38 15
C COLUMN() 19 32 8
B COLUMNS() 18 18 5
D ROW() 19 32 9
B ROWS() 18 18 5
C OFFSET() 0 66 16
C CHOOSE() 0 24 7
D MATCH() 7 97 31
A TRANSPOSE() 0 19 4
A vlookupSort() 0 10 3
C VLOOKUP() 11 53 21
C HLOOKUP() 11 49 17
C LOOKUP() 12 59 16
B HYPERLINK() 0 18 7
C INDEX() 0 45 13

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complex Class

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like LookupRef 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. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

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 LookupRef, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
namespace PhpOffice\PhpSpreadsheet\Calculation;
4
5
use PhpOffice\PhpSpreadsheet\Calculation;
6
use PhpOffice\PhpSpreadsheet\Cell;
7
8
/**
9
 * Copyright (c) 2006 - 2016 PhpSpreadsheet.
10
 *
11
 * This library is free software; you can redistribute it and/or
12
 * modify it under the terms of the GNU Lesser General Public
13
 * License as published by the Free Software Foundation; either
14
 * version 2.1 of the License, or (at your option) any later version.
15
 *
16
 * This library is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
19
 * Lesser General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU Lesser General Public
22
 * License along with this library; if not, write to the Free Software
23
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24
 *
25
 * @category    PhpSpreadsheet
26
 *
27
 * @copyright   Copyright (c) 2006 - 2016 PhpSpreadsheet (https://github.com/PHPOffice/PhpSpreadsheet)
28
 * @license     http://www.gnu.org/licenses/old-licenses/lgpl-2.1.txt    LGPL
29
 */
30
class LookupRef
31
{
32
    /**
33
     * CELL_ADDRESS.
34
     *
35
     * Creates a cell address as text, given specified row and column numbers.
36
     *
37
     * Excel Function:
38
     *        =ADDRESS(row, column, [relativity], [referenceStyle], [sheetText])
39
     *
40
     * @param row Row number to use in the cell reference
41
     * @param column Column number to use in the cell reference
42
     * @param relativity Flag indicating the type of reference to return
43
     *                                1 or omitted    Absolute
44
     *                                2                Absolute row; relative column
45
     *                                3                Relative row; absolute column
46
     *                                4                Relative
47
     * @param referenceStyle A logical value that specifies the A1 or R1C1 reference style.
48
     *                                TRUE or omitted        CELL_ADDRESS returns an A1-style reference
49
     *                                FALSE                CELL_ADDRESS returns an R1C1-style reference
50
     * @param sheetText Optional Name of worksheet to use
51
     * @param mixed $row
52
     * @param mixed $column
53
     * @param mixed $relativity
54
     * @param mixed $referenceStyle
55
     * @param mixed $sheetText
56
     *
57
     * @return string
58
     */
59
    public static function cellAddress($row, $column, $relativity = 1, $referenceStyle = true, $sheetText = '')
60
    {
61
        $row = Functions::flattenSingleValue($row);
62
        $column = Functions::flattenSingleValue($column);
63
        $relativity = Functions::flattenSingleValue($relativity);
64
        $sheetText = Functions::flattenSingleValue($sheetText);
65
66
        if (($row < 1) || ($column < 1)) {
67
            return Functions::VALUE();
68
        }
69
70
        if ($sheetText > '') {
71
            if (strpos($sheetText, ' ') !== false) {
72
                $sheetText = "'" . $sheetText . "'";
73
            }
74
            $sheetText .= '!';
75
        }
76
        if ((!is_bool($referenceStyle)) || $referenceStyle) {
77
            $rowRelative = $columnRelative = '$';
78
            $column = Cell::stringFromColumnIndex($column - 1);
79
            if (($relativity == 2) || ($relativity == 4)) {
80
                $columnRelative = '';
81
            }
82
            if (($relativity == 3) || ($relativity == 4)) {
83
                $rowRelative = '';
84
            }
85
86
            return $sheetText . $columnRelative . $column . $rowRelative . $row;
87
        }
88
        if (($relativity == 2) || ($relativity == 4)) {
89
            $column = '[' . $column . ']';
90
        }
91
        if (($relativity == 3) || ($relativity == 4)) {
92
            $row = '[' . $row . ']';
93
        }
94
95
        return $sheetText . 'R' . $row . 'C' . $column;
96
    }
97
98
    /**
99
     * COLUMN.
100
     *
101
     * Returns the column number of the given cell reference
102
     * If the cell reference is a range of cells, COLUMN returns the column numbers of each column in the reference as a horizontal array.
103
     * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the
104
     *        reference of the cell in which the COLUMN function appears; otherwise this function returns 0.
105
     *
106
     * Excel Function:
107
     *        =COLUMN([cellAddress])
108
     *
109
     * @param cellAddress A reference to a range of cells for which you want the column numbers
110
     * @param null|mixed $cellAddress
111
     *
112
     * @return int or array of integer
113
     */
114
    public static function COLUMN($cellAddress = null)
115
    {
116
        if (is_null($cellAddress) || trim($cellAddress) === '') {
117
            return 0;
118
        }
119
120
        if (is_array($cellAddress)) {
121
            foreach ($cellAddress as $columnKey => $value) {
122
                $columnKey = preg_replace('/[^a-z]/i', '', $columnKey);
123
124
                return (int) Cell::columnIndexFromString($columnKey);
125
            }
126 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
127
            if (strpos($cellAddress, '!') !== false) {
128
                list($sheet, $cellAddress) = explode('!', $cellAddress);
0 ignored issues
show
Unused Code introduced by
The assignment to $sheet is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
129
            }
130
            if (strpos($cellAddress, ':') !== false) {
131
                list($startAddress, $endAddress) = explode(':', $cellAddress);
132
                $startAddress = preg_replace('/[^a-z]/i', '', $startAddress);
133
                $endAddress = preg_replace('/[^a-z]/i', '', $endAddress);
134
                $returnValue = [];
135
                do {
136
                    $returnValue[] = (int) Cell::columnIndexFromString($startAddress);
137
                } while ($startAddress++ != $endAddress);
138
139
                return $returnValue;
140
            }
141
            $cellAddress = preg_replace('/[^a-z]/i', '', $cellAddress);
142
143
            return (int) Cell::columnIndexFromString($cellAddress);
144
        }
145
    }
146
147
    /**
148
     * COLUMNS.
149
     *
150
     * Returns the number of columns in an array or reference.
151
     *
152
     * Excel Function:
153
     *        =COLUMNS(cellAddress)
154
     *
155
     * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of columns
156
     * @param null|mixed $cellAddress
157
     *
158
     * @return int The number of columns in cellAddress
159
     */
160 View Code Duplication
    public static function COLUMNS($cellAddress = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
161
    {
162
        if (is_null($cellAddress) || $cellAddress === '') {
163
            return 1;
164
        } elseif (!is_array($cellAddress)) {
165
            return Functions::VALUE();
166
        }
167
168
        reset($cellAddress);
169
        $isMatrix = (is_numeric(key($cellAddress)));
170
        list($columns, $rows) = Calculation::_getMatrixDimensions($cellAddress);
0 ignored issues
show
Bug introduced by
The method _getMatrixDimensions() does not exist on PhpOffice\PhpSpreadsheet\Calculation. Did you maybe mean getMatrixDimensions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
171
172
        if ($isMatrix) {
173
            return $rows;
174
        }
175
176
        return $columns;
177
    }
178
179
    /**
180
     * ROW.
181
     *
182
     * Returns the row number of the given cell reference
183
     * If the cell reference is a range of cells, ROW returns the row numbers of each row in the reference as a vertical array.
184
     * If cell reference is omitted, and the function is being called through the calculation engine, then it is assumed to be the
185
     *        reference of the cell in which the ROW function appears; otherwise this function returns 0.
186
     *
187
     * Excel Function:
188
     *        =ROW([cellAddress])
189
     *
190
     * @param cellAddress A reference to a range of cells for which you want the row numbers
191
     * @param null|mixed $cellAddress
192
     *
193
     * @return int or array of integer
194
     */
195
    public static function ROW($cellAddress = null)
196
    {
197
        if (is_null($cellAddress) || trim($cellAddress) === '') {
198
            return 0;
199
        }
200
201
        if (is_array($cellAddress)) {
202
            foreach ($cellAddress as $columnKey => $rowValue) {
203
                foreach ($rowValue as $rowKey => $cellValue) {
204
                    return (int) preg_replace('/[^0-9]/', '', $rowKey);
205
                }
206
            }
207 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
208
            if (strpos($cellAddress, '!') !== false) {
209
                list($sheet, $cellAddress) = explode('!', $cellAddress);
0 ignored issues
show
Unused Code introduced by
The assignment to $sheet is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
210
            }
211
            if (strpos($cellAddress, ':') !== false) {
212
                list($startAddress, $endAddress) = explode(':', $cellAddress);
213
                $startAddress = preg_replace('/[^0-9]/', '', $startAddress);
214
                $endAddress = preg_replace('/[^0-9]/', '', $endAddress);
215
                $returnValue = [];
216
                do {
217
                    $returnValue[][] = (int) $startAddress;
218
                } while ($startAddress++ != $endAddress);
219
220
                return $returnValue;
221
            }
222
            list($cellAddress) = explode(':', $cellAddress);
223
224
            return (int) preg_replace('/[^0-9]/', '', $cellAddress);
225
        }
226
    }
227
228
    /**
229
     * ROWS.
230
     *
231
     * Returns the number of rows in an array or reference.
232
     *
233
     * Excel Function:
234
     *        =ROWS(cellAddress)
235
     *
236
     * @param cellAddress An array or array formula, or a reference to a range of cells for which you want the number of rows
237
     * @param null|mixed $cellAddress
238
     *
239
     * @return int The number of rows in cellAddress
240
     */
241 View Code Duplication
    public static function ROWS($cellAddress = null)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
242
    {
243
        if (is_null($cellAddress) || $cellAddress === '') {
244
            return 1;
245
        } elseif (!is_array($cellAddress)) {
246
            return Functions::VALUE();
247
        }
248
249
        reset($cellAddress);
250
        $isMatrix = (is_numeric(key($cellAddress)));
251
        list($columns, $rows) = Calculation::_getMatrixDimensions($cellAddress);
0 ignored issues
show
Bug introduced by
The method _getMatrixDimensions() does not exist on PhpOffice\PhpSpreadsheet\Calculation. Did you maybe mean getMatrixDimensions()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
252
253
        if ($isMatrix) {
254
            return $columns;
255
        }
256
257
        return $rows;
258
    }
259
260
    /**
261
     * HYPERLINK.
262
     *
263
     * Excel Function:
264
     *        =HYPERLINK(linkURL,displayName)
265
     *
266
     * @category Logical Functions
267
     *
268
     * @param string $linkURL Value to check, is also the value returned when no error
269
     * @param string $displayName Value to return when testValue is an error condition
270
     * @param Cell $pCell The cell to set the hyperlink in
271
     *
272
     * @return mixed The value of $displayName (or $linkURL if $displayName was blank)
273
     */
274 1
    public static function HYPERLINK($linkURL = '', $displayName = null, Cell $pCell = null)
275
    {
276 1
        $linkURL = (is_null($linkURL)) ? '' : Functions::flattenSingleValue($linkURL);
277 1
        $displayName = (is_null($displayName)) ? '' : Functions::flattenSingleValue($displayName);
278
279 1
        if ((!is_object($pCell)) || (trim($linkURL) == '')) {
280
            return Functions::REF();
281
        }
282
283 1
        if ((is_object($displayName)) || trim($displayName) == '') {
284
            $displayName = $linkURL;
285
        }
286
287 1
        $pCell->getHyperlink()->setUrl($linkURL);
288 1
        $pCell->getHyperlink()->setTooltip($displayName);
289
290 1
        return $displayName;
291
    }
292
293
    /**
294
     * INDIRECT.
295
     *
296
     * Returns the reference specified by a text string.
297
     * References are immediately evaluated to display their contents.
298
     *
299
     * Excel Function:
300
     *        =INDIRECT(cellAddress)
301
     *
302
     * NOTE - INDIRECT() does not yet support the optional a1 parameter introduced in Excel 2010
303
     *
304
     * @param cellAddress $cellAddress The cell address of the current cell (containing this formula)
305
     * @param Cell $pCell The current cell (containing this formula)
306
     *
307
     * @return mixed The cells referenced by cellAddress
308
     *
309
     * @todo    Support for the optional a1 parameter introduced in Excel 2010
310
     */
311
    public static function INDIRECT($cellAddress = null, Cell $pCell = null)
312
    {
313
        $cellAddress = Functions::flattenSingleValue($cellAddress);
314
        if (is_null($cellAddress) || $cellAddress === '') {
315
            return Functions::REF();
316
        }
317
318
        $cellAddress1 = $cellAddress;
319
        $cellAddress2 = null;
320
        if (strpos($cellAddress, ':') !== false) {
321
            list($cellAddress1, $cellAddress2) = explode(':', $cellAddress);
322
        }
323
324
        if ((!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellAddress1, $matches)) ||
325
            ((!is_null($cellAddress2)) && (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellAddress2, $matches)))) {
326
            if (!preg_match('/^' . Calculation::CALCULATION_REGEXP_NAMEDRANGE . '$/i', $cellAddress1, $matches)) {
327
                return Functions::REF();
328
            }
329
330 View Code Duplication
            if (strpos($cellAddress, '!') !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
331
                list($sheetName, $cellAddress) = explode('!', $cellAddress);
332
                $sheetName = trim($sheetName, "'");
333
                $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName);
0 ignored issues
show
Bug introduced by
It seems like $pCell is not always an object, but can also be of type null. Maybe add an additional type check?

If a variable is not always an object, we recommend to add an additional type check to ensure your method call is safe:

function someFunction(A $objectMaybe = null)
{
    if ($objectMaybe instanceof A) {
        $objectMaybe->doSomething();
    }
}
Loading history...
334
            } else {
335
                $pSheet = $pCell->getWorksheet();
336
            }
337
338
            return Calculation::getInstance()->extractNamedRange($cellAddress, $pSheet, false);
339
        }
340
341 View Code Duplication
        if (strpos($cellAddress, '!') !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
342
            list($sheetName, $cellAddress) = explode('!', $cellAddress);
343
            $sheetName = trim($sheetName, "'");
344
            $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName);
345
        } else {
346
            $pSheet = $pCell->getWorksheet();
347
        }
348
349
        return Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, false);
350
    }
351
352
    /**
353
     * OFFSET.
354
     *
355
     * Returns a reference to a range that is a specified number of rows and columns from a cell or range of cells.
356
     * The reference that is returned can be a single cell or a range of cells. You can specify the number of rows and
357
     * the number of columns to be returned.
358
     *
359
     * Excel Function:
360
     *        =OFFSET(cellAddress, rows, cols, [height], [width])
361
     *
362
     * @param cellAddress The reference from which you want to base the offset. Reference must refer to a cell or
363
     *                                range of adjacent cells; otherwise, OFFSET returns the #VALUE! error value.
364
     * @param rows The number of rows, up or down, that you want the upper-left cell to refer to.
365
     *                                Using 5 as the rows argument specifies that the upper-left cell in the reference is
366
     *                                five rows below reference. Rows can be positive (which means below the starting reference)
367
     *                                or negative (which means above the starting reference).
368
     * @param cols The number of columns, to the left or right, that you want the upper-left cell of the result
369
     *                                to refer to. Using 5 as the cols argument specifies that the upper-left cell in the
370
     *                                reference is five columns to the right of reference. Cols can be positive (which means
371
     *                                to the right of the starting reference) or negative (which means to the left of the
372
     *                                starting reference).
373
     * @param height The height, in number of rows, that you want the returned reference to be. Height must be a positive number.
374
     * @param width The width, in number of columns, that you want the returned reference to be. Width must be a positive number.
375
     * @param null|mixed $cellAddress
376
     * @param mixed $rows
377
     * @param mixed $columns
378
     * @param null|mixed $height
379
     * @param null|mixed $width
380
     * @param Cell $pCell
381
     *
382
     * @return string A reference to a cell or range of cells
383
     */
384
    public static function OFFSET($cellAddress = null, $rows = 0, $columns = 0, $height = null, $width = null, Cell $pCell = null)
385
    {
386
        $rows = Functions::flattenSingleValue($rows);
387
        $columns = Functions::flattenSingleValue($columns);
388
        $height = Functions::flattenSingleValue($height);
389
        $width = Functions::flattenSingleValue($width);
390
        if ($cellAddress == null) {
391
            return 0;
392
        }
393
394
        if (!is_object($pCell)) {
395
            return Functions::REF();
396
        }
397
398
        $sheetName = null;
399
        if (strpos($cellAddress, '!')) {
400
            list($sheetName, $cellAddress) = explode('!', $cellAddress);
401
            $sheetName = trim($sheetName, "'");
402
        }
403
        if (strpos($cellAddress, ':')) {
404
            list($startCell, $endCell) = explode(':', $cellAddress);
405
        } else {
406
            $startCell = $endCell = $cellAddress;
407
        }
408
        list($startCellColumn, $startCellRow) = Cell::coordinateFromString($startCell);
409
        list($endCellColumn, $endCellRow) = Cell::coordinateFromString($endCell);
410
411
        $startCellRow += $rows;
412
        $startCellColumn = Cell::columnIndexFromString($startCellColumn) - 1;
413
        $startCellColumn += $columns;
414
415
        if (($startCellRow <= 0) || ($startCellColumn < 0)) {
416
            return Functions::REF();
417
        }
418
        $endCellColumn = Cell::columnIndexFromString($endCellColumn) - 1;
419
        if (($width != null) && (!is_object($width))) {
420
            $endCellColumn = $startCellColumn + $width - 1;
421
        } else {
422
            $endCellColumn += $columns;
423
        }
424
        $startCellColumn = Cell::stringFromColumnIndex($startCellColumn);
425
426
        if (($height != null) && (!is_object($height))) {
427
            $endCellRow = $startCellRow + $height - 1;
428
        } else {
429
            $endCellRow += $rows;
430
        }
431
432
        if (($endCellRow <= 0) || ($endCellColumn < 0)) {
433
            return Functions::REF();
434
        }
435
        $endCellColumn = Cell::stringFromColumnIndex($endCellColumn);
436
437
        $cellAddress = $startCellColumn . $startCellRow;
438
        if (($startCellColumn != $endCellColumn) || ($startCellRow != $endCellRow)) {
439
            $cellAddress .= ':' . $endCellColumn . $endCellRow;
440
        }
441
442
        if ($sheetName !== null) {
443
            $pSheet = $pCell->getWorksheet()->getParent()->getSheetByName($sheetName);
444
        } else {
445
            $pSheet = $pCell->getWorksheet();
446
        }
447
448
        return Calculation::getInstance()->extractCellRange($cellAddress, $pSheet, false);
449
    }
450
451
    /**
452
     * CHOOSE.
453
     *
454
     * Uses lookup_value to return a value from the list of value arguments.
455
     * Use CHOOSE to select one of up to 254 values based on the lookup_value.
456
     *
457
     * Excel Function:
458
     *        =CHOOSE(index_num, value1, [value2], ...)
459
     *
460
     * @param index_num Specifies which value argument is selected.
461
     *                            Index_num must be a number between 1 and 254, or a formula or reference to a cell containing a number
462
     *                                between 1 and 254.
463
     * @param value1... Value1 is required, subsequent values are optional.
464
     *                            Between 1 to 254 value arguments from which CHOOSE selects a value or an action to perform based on
465
     *                                index_num. The arguments can be numbers, cell references, defined names, formulas, functions, or
466
     *                                text.
467
     *
468
     * @return mixed The selected value
469
     */
470
    public static function CHOOSE(...$chooseArgs)
471
    {
472
        $chosenEntry = Functions::flattenArray(array_shift($chooseArgs));
473
        $entryCount = count($chooseArgs) - 1;
474
475
        if (is_array($chosenEntry)) {
476
            $chosenEntry = array_shift($chosenEntry);
477
        }
478
        if ((is_numeric($chosenEntry)) && (!is_bool($chosenEntry))) {
479
            --$chosenEntry;
480
        } else {
481
            return Functions::VALUE();
482
        }
483
        $chosenEntry = floor($chosenEntry);
484
        if (($chosenEntry < 0) || ($chosenEntry > $entryCount)) {
485
            return Functions::VALUE();
486
        }
487
488
        if (is_array($chooseArgs[$chosenEntry])) {
489
            return Functions::flattenArray($chooseArgs[$chosenEntry]);
490
        }
491
492
        return $chooseArgs[$chosenEntry];
493
    }
494
495
    /**
496
     * MATCH.
497
     *
498
     * The MATCH function searches for a specified item in a range of cells
499
     *
500
     * Excel Function:
501
     *        =MATCH(lookup_value, lookup_array, [match_type])
502
     *
503
     * @param mixed $lookupValue The value that you want to match in lookup_array
504
     * @param mixed $lookupArray The range of cells being searched
505
     * @param mixed $matchType The number -1, 0, or 1. -1 means above, 0 means exact match, 1 means below. If match_type is 1 or -1, the list has to be ordered.
506
     *
507
     * @return int The relative position of the found item
508
     */
509 15
    public static function MATCH($lookupValue, $lookupArray, $matchType = 1)
510
    {
511 15
        $lookupArray = Functions::flattenArray($lookupArray);
512 15
        $lookupValue = Functions::flattenSingleValue($lookupValue);
513 15
        $matchType = (is_null($matchType)) ? 1 : (int) Functions::flattenSingleValue($matchType);
514
515
        // MATCH is not case sensitive
516 15
        $lookupValue = strtolower($lookupValue);
517
518
        // Lookup_value type has to be number, text, or logical values
519 15 View Code Duplication
        if ((!is_numeric($lookupValue)) && (!is_string($lookupValue)) && (!is_bool($lookupValue))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
520
            return Functions::NA();
521
        }
522
523
        // Match_type is 0, 1 or -1
0 ignored issues
show
Unused Code Comprehensibility introduced by
36% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
524 15
        if (($matchType !== 0) && ($matchType !== -1) && ($matchType !== 1)) {
525
            return Functions::NA();
526
        }
527
528
        // Lookup_array should not be empty
529 15
        $lookupArraySize = count($lookupArray);
530 15
        if ($lookupArraySize <= 0) {
531
            return Functions::NA();
532
        }
533
534
        // Lookup_array should contain only number, text, or logical values, or empty (null) cells
535 15
        foreach ($lookupArray as $i => $lookupArrayValue) {
536
            //    check the type of the value
537 15 View Code Duplication
            if ((!is_numeric($lookupArrayValue)) && (!is_string($lookupArrayValue)) &&
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
538 15
                (!is_bool($lookupArrayValue)) && (!is_null($lookupArrayValue))
539
            ) {
540
                return Functions::NA();
541
            }
542
            // Convert strings to lowercase for case-insensitive testing
543 15
            if (is_string($lookupArrayValue)) {
544
                $lookupArray[$i] = strtolower($lookupArrayValue);
545
            }
546 15
            if ((is_null($lookupArrayValue)) && (($matchType == 1) || ($matchType == -1))) {
547 15
                $lookupArray = array_slice($lookupArray, 0, $i - 1);
548
            }
549
        }
550
551 15
        if ($matchType == 1) {
552
            // If match_type is 1 the list has to be processed from last to first
553
554 4
            $lookupArray = array_reverse($lookupArray);
555 4
            $keySet = array_reverse(array_keys($lookupArray));
556
        }
557
558
        // **
559
        // find the match
560
        // **
561
562 15
        if ($matchType == 0 || $matchType == 1) {
563 8
            foreach ($lookupArray as $i => $lookupArrayValue) {
564 8
                if (($matchType == 0) && ($lookupArrayValue == $lookupValue)) {
565
                    //    exact match
566 3
                    return ++$i;
567 6
                } elseif (($matchType == 1) && ($lookupArrayValue <= $lookupValue)) {
568 4
                    $i = array_search($i, $keySet);
0 ignored issues
show
Bug introduced by
The variable $keySet does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
569
570
                    // The current value is the (first) match
571 6
                    return $i + 1;
572
                }
573
            }
574
        } else {
575
            // matchType = -1
576
577
            // "Special" case: since the array it's supposed to be ordered in descending order, the
578
            // Excel algorithm gives up immediately if the first element is smaller than the searched value
579 7
            if ($lookupArray[0] < $lookupValue) {
580 1
                return Functions::NA();
581
            }
582
583 6
            $maxValueKey = null;
584
585
            // The basic algorithm is:
586
            // Iterate and keep the highest match until the next element is smaller than the searched value.
587
            // Return immediately if perfect match is found
588 6
            foreach ($lookupArray as $i => $lookupArrayValue) {
589 6
                if ($lookupArrayValue == $lookupValue) {
590
                    // Another "special" case. If a perfect match is found,
591
                    // the algorithm gives up immediately
592 2
                    return $i + 1;
593 5
                } elseif ($lookupArrayValue >= $lookupValue) {
594 5
                    $maxValueKey = $i + 1;
595
                }
596
            }
597
598 4
            if ($maxValueKey !== null) {
599 4
                return $maxValueKey;
600
            }
601
        }
602
603
        // Unsuccessful in finding a match, return #N/A error value
604 1
        return Functions::NA();
605
    }
606
607
    /**
608
     * INDEX.
609
     *
610
     * Uses an index to choose a value from a reference or array
611
     *
612
     * Excel Function:
613
     *        =INDEX(range_array, row_num, [column_num])
614
     *
615
     * @param range_array A range of cells or an array constant
616
     * @param row_num The row in array from which to return a value. If row_num is omitted, column_num is required.
617
     * @param column_num The column in array from which to return a value. If column_num is omitted, row_num is required.
618
     * @param mixed $arrayValues
619
     * @param mixed $rowNum
620
     * @param mixed $columnNum
621
     *
622
     * @return mixed the value of a specified cell or array of cells
623
     */
624 8
    public static function INDEX($arrayValues, $rowNum = 0, $columnNum = 0)
625
    {
626 8
        if (($rowNum < 0) || ($columnNum < 0)) {
627 2
            return Functions::VALUE();
628
        }
629
630 6
        if (!is_array($arrayValues) || ($rowNum > count($arrayValues))) {
631 1
            return Functions::REF();
632
        }
633
634 5
        $rowKeys = array_keys($arrayValues);
635 5
        $columnKeys = @array_keys($arrayValues[$rowKeys[0]]);
636
637 5
        if ($columnNum > count($columnKeys)) {
638 1
            return Functions::VALUE();
639 4
        } elseif ($columnNum == 0) {
640 3
            if ($rowNum == 0) {
641 1
                return $arrayValues;
642
            }
643 2
            $rowNum = $rowKeys[--$rowNum];
644 2
            $returnArray = [];
645 2
            foreach ($arrayValues as $arrayColumn) {
646 2
                if (is_array($arrayColumn)) {
647 2
                    if (isset($arrayColumn[$rowNum])) {
648
                        $returnArray[] = $arrayColumn[$rowNum];
649
                    } else {
650 2
                        return [$rowNum => $arrayValues[$rowNum]];
651
                    }
652
                } else {
653
                    return $arrayValues[$rowNum];
654
                }
655
            }
656
657
            return $returnArray;
658
        }
659 1
        $columnNum = $columnKeys[--$columnNum];
660 1
        if ($rowNum > count($rowKeys)) {
661
            return Functions::VALUE();
662 1
        } elseif ($rowNum == 0) {
663
            return $arrayValues[$columnNum];
664
        }
665 1
        $rowNum = $rowKeys[--$rowNum];
666
667 1
        return $arrayValues[$rowNum][$columnNum];
668
    }
669
670
    /**
671
     * TRANSPOSE.
672
     *
673
     * @param array $matrixData A matrix of values
674
     *
675
     * @return array
676
     *
677
     * Unlike the Excel TRANSPOSE function, which will only work on a single row or column, this function will transpose a full matrix
678
     */
679
    public static function TRANSPOSE($matrixData)
680
    {
681
        $returnMatrix = [];
682
        if (!is_array($matrixData)) {
683
            $matrixData = [[$matrixData]];
684
        }
685
686
        $column = 0;
687
        foreach ($matrixData as $matrixRow) {
688
            $row = 0;
689
            foreach ($matrixRow as $matrixCell) {
690
                $returnMatrix[$row][$column] = $matrixCell;
691
                ++$row;
692
            }
693
            ++$column;
694
        }
695
696
        return $returnMatrix;
697
    }
698
699 2
    private static function vlookupSort($a, $b)
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
700
    {
701 2
        reset($a);
702 2
        $firstColumn = key($a);
703 2
        if (($aLower = strtolower($a[$firstColumn])) == ($bLower = strtolower($b[$firstColumn]))) {
704
            return 0;
705
        }
706
707 2
        return ($aLower < $bLower) ? -1 : 1;
708
    }
709
710
    /**
711
     * VLOOKUP
712
     * The VLOOKUP function searches for value in the left-most column of lookup_array and returns the value in the same row based on the index_number.
713
     *
714
     * @param lookup_value The value that you want to match in lookup_array
715
     * @param lookup_array The range of cells being searched
716
     * @param index_number The column number in table_array from which the matching value must be returned. The first column is 1.
717
     * @param not_exact_match determines if you are looking for an exact match based on lookup_value
718
     * @param mixed $lookup_value
719
     * @param mixed $lookup_array
720
     * @param mixed $index_number
721
     * @param mixed $not_exact_match
722
     *
723
     * @return mixed The value of the found cell
724
     */
725 5
    public static function VLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match = true)
726
    {
727 5
        $lookup_value = Functions::flattenSingleValue($lookup_value);
728 5
        $index_number = Functions::flattenSingleValue($index_number);
729 5
        $not_exact_match = Functions::flattenSingleValue($not_exact_match);
730
731
        // index_number must be greater than or equal to 1
732 5
        if ($index_number < 1) {
733
            return Functions::VALUE();
734
        }
735
736
        // index_number must be less than or equal to the number of columns in lookup_array
737 5
        if ((!is_array($lookup_array)) || (empty($lookup_array))) {
738
            return Functions::REF();
739
        }
740 5
        $f = array_keys($lookup_array);
741 5
        $firstRow = array_pop($f);
742 5 View Code Duplication
        if ((!is_array($lookup_array[$firstRow])) || ($index_number > count($lookup_array[$firstRow]))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
743
            return Functions::REF();
744
        }
745 5
        $columnKeys = array_keys($lookup_array[$firstRow]);
746 5
        $returnColumn = $columnKeys[--$index_number];
747 5
        $firstColumn = array_shift($columnKeys);
748
749 5
        if (!$not_exact_match) {
750 2
            uasort($lookup_array, ['self', 'vlookupSort']);
751
        }
752
753 5
        $rowNumber = $rowValue = false;
754 5
        foreach ($lookup_array as $rowKey => $rowData) {
755 5
            if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn]) && ($rowData[$firstColumn] > $lookup_value)) ||
756 5
                (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]) && (strtolower($rowData[$firstColumn]) > strtolower($lookup_value)))) {
757 4
                break;
758
            }
759
            // remember the last key, but only if datatypes match
760 5
            if ((is_numeric($lookup_value) && is_numeric($rowData[$firstColumn])) ||
761 5
                (!is_numeric($lookup_value) && !is_numeric($rowData[$firstColumn]))) {
762 4
                $rowNumber = $rowKey;
763 5
                $rowValue = $rowData[$firstColumn];
764
            }
765
        }
766
767 5 View Code Duplication
        if ($rowNumber !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
768 4
            if ((!$not_exact_match) && ($rowValue != $lookup_value)) {
769
                //    if an exact match is required, we have what we need to return an appropriate response
770 2
                return Functions::NA();
771
            }
772
                //    otherwise return the appropriate value
773 2
                return $lookup_array[$rowNumber][$returnColumn];
774
        }
775
776 1
        return Functions::NA();
777
    }
778
779
    /**
780
     * HLOOKUP
781
     * The HLOOKUP function searches for value in the top-most row of lookup_array and returns the value in the same column based on the index_number.
782
     *
783
     * @param lookup_value The value that you want to match in lookup_array
784
     * @param lookup_array The range of cells being searched
785
     * @param index_number The row number in table_array from which the matching value must be returned. The first row is 1.
786
     * @param not_exact_match determines if you are looking for an exact match based on lookup_value
787
     * @param mixed $lookup_value
788
     * @param mixed $lookup_array
789
     * @param mixed $index_number
790
     * @param mixed $not_exact_match
791
     *
792
     * @return mixed The value of the found cell
793
     */
794 9
    public static function HLOOKUP($lookup_value, $lookup_array, $index_number, $not_exact_match = true)
795
    {
796 9
        $lookup_value = Functions::flattenSingleValue($lookup_value);
797 9
        $index_number = Functions::flattenSingleValue($index_number);
798 9
        $not_exact_match = Functions::flattenSingleValue($not_exact_match);
799
800
        // index_number must be greater than or equal to 1
801 9
        if ($index_number < 1) {
802
            return Functions::VALUE();
803
        }
804
805
        // index_number must be less than or equal to the number of columns in lookup_array
806 9
        if ((!is_array($lookup_array)) || (empty($lookup_array))) {
807
            return Functions::REF();
808
        }
809 9
        $f = array_keys($lookup_array);
810 9
        $firstRow = array_pop($f);
811 9 View Code Duplication
        if ((!is_array($lookup_array[$firstRow])) || ($index_number - 1 > count($lookup_array[$firstRow]))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
812
            return Functions::REF();
813
        }
814 9
        $columnKeys = array_keys($lookup_array[$firstRow]);
0 ignored issues
show
Unused Code introduced by
$columnKeys is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
815 9
        $firstkey = $f[0] - 1;
816 9
        $returnColumn = $firstkey + $index_number;
817 9
        $firstColumn = array_shift($f);
818
819 9
        if (!$not_exact_match) {
820 4
            $firstRowH = asort($lookup_array[$firstColumn]);
0 ignored issues
show
Unused Code introduced by
$firstRowH is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
821
        }
822 9
        $rowNumber = $rowValue = false;
823 9
        foreach ($lookup_array[$firstColumn] as $rowKey => $rowData) {
824 9
            if ((is_numeric($lookup_value) && is_numeric($rowData) && ($rowData > $lookup_value)) ||
825 9
                (!is_numeric($lookup_value) && !is_numeric($rowData) && (strtolower($rowData) > strtolower($lookup_value)))) {
826 7
                break;
827
            }
828 9
            $rowNumber = $rowKey;
829 9
            $rowValue = $rowData;
830
        }
831
832 9 View Code Duplication
        if ($rowNumber !== false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
833 9
            if ((!$not_exact_match) && ($rowValue != $lookup_value)) {
834
                //  if an exact match is required, we have what we need to return an appropriate response
835 1
                return Functions::NA();
836
            }
837
                //  otherwise return the appropriate value
838 8
                return $lookup_array[$returnColumn][$rowNumber];
839
        }
840
841
        return Functions::NA();
842
    }
843
844
    /**
845
     * LOOKUP
846
     * The LOOKUP function searches for value either from a one-row or one-column range or from an array.
847
     *
848
     * @param lookup_value The value that you want to match in lookup_array
849
     * @param lookup_vector The range of cells being searched
850
     * @param result_vector The column from which the matching value must be returned
851
     * @param mixed $lookup_value
852
     * @param mixed $lookup_vector
853
     * @param null|mixed $result_vector
854
     *
855
     * @return mixed The value of the found cell
856
     */
857
    public static function LOOKUP($lookup_value, $lookup_vector, $result_vector = null)
858
    {
859
        $lookup_value = Functions::flattenSingleValue($lookup_value);
860
861
        if (!is_array($lookup_vector)) {
862
            return Functions::NA();
863
        }
864
        $lookupRows = count($lookup_vector);
865
        $l = array_keys($lookup_vector);
866
        $l = array_shift($l);
867
        $lookupColumns = count($lookup_vector[$l]);
868 View Code Duplication
        if ((($lookupRows == 1) && ($lookupColumns > 1)) || (($lookupRows == 2) && ($lookupColumns != 2))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
869
            $lookup_vector = self::TRANSPOSE($lookup_vector);
870
            $lookupRows = count($lookup_vector);
871
            $l = array_keys($lookup_vector);
872
            $lookupColumns = count($lookup_vector[array_shift($l)]);
873
        }
874
875
        if (is_null($result_vector)) {
876
            $result_vector = $lookup_vector;
877
        }
878
        $resultRows = count($result_vector);
879
        $l = array_keys($result_vector);
880
        $l = array_shift($l);
881
        $resultColumns = count($result_vector[$l]);
882 View Code Duplication
        if ((($resultRows == 1) && ($resultColumns > 1)) || (($resultRows == 2) && ($resultColumns != 2))) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
883
            $result_vector = self::TRANSPOSE($result_vector);
884
            $resultRows = count($result_vector);
0 ignored issues
show
Unused Code introduced by
$resultRows is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
885
            $r = array_keys($result_vector);
886
            $resultColumns = count($result_vector[array_shift($r)]);
0 ignored issues
show
Unused Code introduced by
$resultColumns is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
887
        }
888
889
        if ($lookupRows == 2) {
890
            $result_vector = array_pop($lookup_vector);
891
            $lookup_vector = array_shift($lookup_vector);
892
        }
893
        if ($lookupColumns != 2) {
894
            foreach ($lookup_vector as &$value) {
895
                if (is_array($value)) {
896
                    $k = array_keys($value);
897
                    $key1 = $key2 = array_shift($k);
898
                    ++$key2;
899
                    $dataValue1 = $value[$key1];
900
                } else {
901
                    $key1 = 0;
902
                    $key2 = 1;
903
                    $dataValue1 = $value;
904
                }
905
                $dataValue2 = array_shift($result_vector);
906
                if (is_array($dataValue2)) {
907
                    $dataValue2 = array_shift($dataValue2);
908
                }
909
                $value = [$key1 => $dataValue1, $key2 => $dataValue2];
910
            }
911
            unset($value);
912
        }
913
914
        return self::VLOOKUP($lookup_value, $lookup_vector, 2);
0 ignored issues
show
Documentation introduced by
2 is of type integer, but the function expects a object<PhpOffice\PhpSpreadsheet\Calculation\The>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
915
    }
916
}
917