Skip to content

Commit d5dc58d

Browse files
author
Mark Baker
authored
Extract information functions (#2605)
* Split Information functions into a dedicated class and namespace and categorise as Value or Error * Refactor all error functions into the new ExcelError class
1 parent 9c47368 commit d5dc58d

File tree

167 files changed

+1365
-831
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

167 files changed

+1365
-831
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org).
1717
-
1818
### Deprecated
1919

20-
- Nothing
20+
- All Excel Function implementations in `Calculation\Functions` (including the Error functions) have been moved to dedicated classes for groups of related functions. See the docblocks against all the deprecated methods for details of the new methods to call instead. At some point, these old classes will be deleted.
2121

2222
### Removed
2323

phpstan-baseline.neon

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -595,11 +595,6 @@ parameters:
595595
count: 1
596596
path: src/PhpSpreadsheet/Calculation/FormulaParser.php
597597

598-
-
599-
message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
600-
count: 1
601-
path: src/PhpSpreadsheet/Calculation/Functions.php
602-
603598
-
604599
message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:ifCondition\\(\\) has no return type specified\\.$#"
605600
count: 1

src/PhpSpreadsheet/Calculation/Calculation.php

Lines changed: 29 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use PhpOffice\PhpSpreadsheet\Calculation\Engine\CyclicReferenceStack;
66
use PhpOffice\PhpSpreadsheet\Calculation\Engine\Logger;
7+
use PhpOffice\PhpSpreadsheet\Calculation\Information\Value;
78
use PhpOffice\PhpSpreadsheet\Calculation\Token\Stack;
89
use PhpOffice\PhpSpreadsheet\Cell\Cell;
910
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
@@ -973,7 +974,7 @@ class Calculation
973974
],
974975
'ERROR.TYPE' => [
975976
'category' => Category::CATEGORY_INFORMATION,
976-
'functionCall' => [Functions::class, 'errorType'],
977+
'functionCall' => [Information\ExcelError::class, 'type'],
977978
'argumentCount' => '1',
978979
],
979980
'EVEN' => [
@@ -1457,49 +1458,49 @@ class Calculation
14571458
],
14581459
'ISBLANK' => [
14591460
'category' => Category::CATEGORY_INFORMATION,
1460-
'functionCall' => [Functions::class, 'isBlank'],
1461+
'functionCall' => [Information\Value::class, 'isBlank'],
14611462
'argumentCount' => '1',
14621463
],
14631464
'ISERR' => [
14641465
'category' => Category::CATEGORY_INFORMATION,
1465-
'functionCall' => [Functions::class, 'isErr'],
1466+
'functionCall' => [Information\Value::class, 'isErr'],
14661467
'argumentCount' => '1',
14671468
],
14681469
'ISERROR' => [
14691470
'category' => Category::CATEGORY_INFORMATION,
1470-
'functionCall' => [Functions::class, 'isError'],
1471+
'functionCall' => [Information\Value::class, 'isError'],
14711472
'argumentCount' => '1',
14721473
],
14731474
'ISEVEN' => [
14741475
'category' => Category::CATEGORY_INFORMATION,
1475-
'functionCall' => [Functions::class, 'isEven'],
1476+
'functionCall' => [Information\Value::class, 'isEven'],
14761477
'argumentCount' => '1',
14771478
],
14781479
'ISFORMULA' => [
14791480
'category' => Category::CATEGORY_INFORMATION,
1480-
'functionCall' => [Functions::class, 'isFormula'],
1481+
'functionCall' => [Information\Value::class, 'isFormula'],
14811482
'argumentCount' => '1',
14821483
'passCellReference' => true,
14831484
'passByReference' => [true],
14841485
],
14851486
'ISLOGICAL' => [
14861487
'category' => Category::CATEGORY_INFORMATION,
1487-
'functionCall' => [Functions::class, 'isLogical'],
1488+
'functionCall' => [Information\Value::class, 'isLogical'],
14881489
'argumentCount' => '1',
14891490
],
14901491
'ISNA' => [
14911492
'category' => Category::CATEGORY_INFORMATION,
1492-
'functionCall' => [Functions::class, 'isNa'],
1493+
'functionCall' => [Information\Value::class, 'isNa'],
14931494
'argumentCount' => '1',
14941495
],
14951496
'ISNONTEXT' => [
14961497
'category' => Category::CATEGORY_INFORMATION,
1497-
'functionCall' => [Functions::class, 'isNonText'],
1498+
'functionCall' => [Information\Value::class, 'isNonText'],
14981499
'argumentCount' => '1',
14991500
],
15001501
'ISNUMBER' => [
15011502
'category' => Category::CATEGORY_INFORMATION,
1502-
'functionCall' => [Functions::class, 'isNumber'],
1503+
'functionCall' => [Information\Value::class, 'isNumber'],
15031504
'argumentCount' => '1',
15041505
],
15051506
'ISO.CEILING' => [
@@ -1509,7 +1510,7 @@ class Calculation
15091510
],
15101511
'ISODD' => [
15111512
'category' => Category::CATEGORY_INFORMATION,
1512-
'functionCall' => [Functions::class, 'isOdd'],
1513+
'functionCall' => [Information\Value::class, 'isOdd'],
15131514
'argumentCount' => '1',
15141515
],
15151516
'ISOWEEKNUM' => [
@@ -1529,7 +1530,7 @@ class Calculation
15291530
],
15301531
'ISTEXT' => [
15311532
'category' => Category::CATEGORY_INFORMATION,
1532-
'functionCall' => [Functions::class, 'isText'],
1533+
'functionCall' => [Information\Value::class, 'isText'],
15331534
'argumentCount' => '1',
15341535
],
15351536
'ISTHAIDIGIT' => [
@@ -1759,7 +1760,7 @@ class Calculation
17591760
],
17601761
'N' => [
17611762
'category' => Category::CATEGORY_INFORMATION,
1762-
'functionCall' => [Functions::class, 'n'],
1763+
'functionCall' => [Information\Value::class, 'asNumber'],
17631764
'argumentCount' => '1',
17641765
],
17651766
'NA' => [
@@ -2559,7 +2560,7 @@ class Calculation
25592560
],
25602561
'TYPE' => [
25612562
'category' => Category::CATEGORY_INFORMATION,
2562-
'functionCall' => [Functions::class, 'TYPE'],
2563+
'functionCall' => [Information\Value::class, 'type'],
25632564
'argumentCount' => '1',
25642565
],
25652566
'UNICHAR' => [
@@ -3252,7 +3253,7 @@ public static function wrapResult($value)
32523253
return self::FORMULA_STRING_QUOTE . $value . self::FORMULA_STRING_QUOTE;
32533254
} elseif ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
32543255
// Convert numeric errors to NaN error
3255-
return Functions::NAN();
3256+
return Information\ExcelError::NAN();
32563257
}
32573258

32583259
return $value;
@@ -3273,7 +3274,7 @@ public static function unwrapResult($value)
32733274
}
32743275
// Convert numeric errors to NAN error
32753276
} elseif ((is_float($value)) && ((is_nan($value)) || (is_infinite($value)))) {
3276-
return Functions::NAN();
3277+
return Information\ExcelError::NAN();
32773278
}
32783279

32793280
return $value;
@@ -3342,21 +3343,21 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true)
33423343
self::$returnArrayAsType = $returnArrayAsType;
33433344
$testResult = Functions::flattenArray($result);
33443345
if (self::$returnArrayAsType == self::RETURN_ARRAY_AS_ERROR) {
3345-
return Functions::VALUE();
3346+
return Information\ExcelError::VALUE();
33463347
}
33473348
// If there's only a single cell in the array, then we allow it
33483349
if (count($testResult) != 1) {
33493350
// If keys are numeric, then it's a matrix result rather than a cell range result, so we permit it
33503351
$r = array_keys($result);
33513352
$r = array_shift($r);
33523353
if (!is_numeric($r)) {
3353-
return Functions::VALUE();
3354+
return Information\ExcelError::VALUE();
33543355
}
33553356
if (is_array($result[$r])) {
33563357
$c = array_keys($result[$r]);
33573358
$c = array_shift($c);
33583359
if (!is_numeric($c)) {
3359-
return Functions::VALUE();
3360+
return Information\ExcelError::VALUE();
33603361
}
33613362
}
33623363
}
@@ -3367,7 +3368,7 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true)
33673368
if ($result === null && $cell->getWorksheet()->getSheetView()->getShowZeros()) {
33683369
return 0;
33693370
} elseif ((is_float($result)) && ((is_nan($result)) || (is_infinite($result)))) {
3370-
return Functions::NAN();
3371+
return Information\ExcelError::NAN();
33713372
}
33723373

33733374
return $result;
@@ -4428,7 +4429,7 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null)
44284429
isset($storeValue)
44294430
&& (
44304431
!$storeValueAsBool
4431-
|| Functions::isError($storeValue)
4432+
|| Value::isError($storeValue)
44324433
|| ($storeValue === 'Pruned branch')
44334434
)
44344435
) {
@@ -4463,7 +4464,7 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null)
44634464
isset($storeValue)
44644465
&& (
44654466
$storeValueAsBool
4466-
|| Functions::isError($storeValue)
4467+
|| Value::isError($storeValue)
44674468
|| ($storeValue === 'Pruned branch')
44684469
)
44694470
) {
@@ -4569,7 +4570,7 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null)
45694570

45704571
$stack->push('Cell Reference', $cellValue, $cellRef);
45714572
} else {
4572-
$stack->push('Error', Functions::REF(), null);
4573+
$stack->push('Error', Information\ExcelError::REF(), null);
45734574
}
45744575

45754576
break;
@@ -4704,7 +4705,7 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null)
47044705
if (isset($matches[8])) {
47054706
if ($cell === null) {
47064707
// We can't access the range, so return a REF error
4707-
$cellValue = Functions::REF();
4708+
$cellValue = Information\ExcelError::REF();
47084709
} else {
47094710
$cellRef = $matches[6] . $matches[7] . ':' . $matches[9] . $matches[10];
47104711
if ($matches[2] > '') {
@@ -4734,7 +4735,7 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null)
47344735
} else {
47354736
if ($cell === null) {
47364737
// We can't access the cell, so return a REF error
4737-
$cellValue = Functions::REF();
4738+
$cellValue = Information\ExcelError::REF();
47384739
} else {
47394740
$cellRef = $matches[6] . $matches[7];
47404741
if ($matches[2] > '') {
@@ -5069,7 +5070,7 @@ private function executeNumericBinaryOperation($operand1, $operand2, $operation,
50695070
((is_string($operand1) && !is_numeric($operand1) && strlen($operand1) > 0) ||
50705071
(is_string($operand2) && !is_numeric($operand2) && strlen($operand2) > 0))
50715072
) {
5072-
$result = Functions::VALUE();
5073+
$result = Information\ExcelError::VALUE();
50735074
} else {
50745075
// If we're dealing with non-matrix operations, execute the necessary operation
50755076
switch ($operation) {
@@ -5217,7 +5218,7 @@ public function extractNamedRange(string &$range = 'A1', ?Worksheet $worksheet =
52175218
// Named range?
52185219
$namedRange = DefinedName::resolveName($range, $worksheet);
52195220
if ($namedRange === null) {
5220-
return Functions::REF();
5221+
return Information\ExcelError::REF();
52215222
}
52225223

52235224
$worksheet = $namedRange->getWorksheet();
@@ -5406,7 +5407,7 @@ private function evaluateDefinedName(Cell $cell, DefinedName $namedRange, Worksh
54065407
$definedNameScope = $namedRange->getScope();
54075408
if ($definedNameScope !== null && $definedNameScope !== $cellWorksheet) {
54085409
// The defined name isn't in our current scope, so #REF
5409-
$result = Functions::REF();
5410+
$result = Information\ExcelError::REF();
54105411
$stack->push('Error', $result, $namedRange->getName());
54115412

54125413
return $result;

src/PhpSpreadsheet/Calculation/Database/DGet.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace PhpOffice\PhpSpreadsheet\Calculation\Database;
44

5-
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
5+
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
66

77
class DGet extends DatabaseAbstract
88
{
@@ -41,7 +41,7 @@ public static function evaluate($database, $field, $criteria)
4141

4242
$columnData = self::getFilteredColumn($database, $field, $criteria);
4343
if (count($columnData) > 1) {
44-
return Functions::NAN();
44+
return ExcelError::NAN();
4545
}
4646

4747
$row = array_pop($columnData);

src/PhpSpreadsheet/Calculation/DateTimeExcel/Current.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
namespace PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
44

55
use DateTimeImmutable;
6-
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
6+
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
77

88
class Current
99
{
@@ -29,7 +29,7 @@ public static function today()
2929
$dti = new DateTimeImmutable();
3030
$dateArray = Helpers::dateParse($dti->format('c'));
3131

32-
return Helpers::dateParseSucceeded($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : Functions::VALUE();
32+
return Helpers::dateParseSucceeded($dateArray) ? Helpers::returnIn3FormatsArray($dateArray, true) : ExcelError::VALUE();
3333
}
3434

3535
/**
@@ -54,6 +54,6 @@ public static function now()
5454
$dti = new DateTimeImmutable();
5555
$dateArray = Helpers::dateParse($dti->format('c'));
5656

57-
return Helpers::dateParseSucceeded($dateArray) ? Helpers::returnIn3FormatsArray($dateArray) : Functions::VALUE();
57+
return Helpers::dateParseSucceeded($dateArray) ? Helpers::returnIn3FormatsArray($dateArray) : ExcelError::VALUE();
5858
}
5959
}

src/PhpSpreadsheet/Calculation/DateTimeExcel/Date.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled;
66
use PhpOffice\PhpSpreadsheet\Calculation\Exception;
7-
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
7+
use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError;
88
use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDateHelper;
99
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
1010

@@ -95,15 +95,15 @@ private static function getYear($year, int $baseYear): int
9595
{
9696
$year = ($year !== null) ? StringHelper::testStringAsNumeric((string) $year) : 0;
9797
if (!is_numeric($year)) {
98-
throw new Exception(Functions::VALUE());
98+
throw new Exception(ExcelError::VALUE());
9999
}
100100
$year = (int) $year;
101101

102102
if ($year < ($baseYear - 1900)) {
103-
throw new Exception(Functions::NAN());
103+
throw new Exception(ExcelError::NAN());
104104
}
105105
if ((($baseYear - 1900) !== 0) && ($year < $baseYear) && ($year >= 1900)) {
106-
throw new Exception(Functions::NAN());
106+
throw new Exception(ExcelError::NAN());
107107
}
108108

109109
if (($year < $baseYear) && ($year >= ($baseYear - 1900))) {
@@ -126,7 +126,7 @@ private static function getMonth($month): int
126126

127127
$month = ($month !== null) ? StringHelper::testStringAsNumeric((string) $month) : 0;
128128
if (!is_numeric($month)) {
129-
throw new Exception(Functions::VALUE());
129+
throw new Exception(ExcelError::VALUE());
130130
}
131131

132132
return (int) $month;
@@ -145,7 +145,7 @@ private static function getDay($day): int
145145

146146
$day = ($day !== null) ? StringHelper::testStringAsNumeric((string) $day) : 0;
147147
if (!is_numeric($day)) {
148-
throw new Exception(Functions::VALUE());
148+
throw new Exception(ExcelError::VALUE());
149149
}
150150

151151
return (int) $day;
@@ -166,7 +166,7 @@ private static function adjustYearMonth(int &$year, int &$month, int $baseYear):
166166

167167
// Re-validate the year parameter after adjustments
168168
if (($year < $baseYear) || ($year >= 10000)) {
169-
throw new Exception(Functions::NAN());
169+
throw new Exception(ExcelError::NAN());
170170
}
171171
}
172172
}

0 commit comments

Comments
 (0)