From 8156ed9fa4b6c873fcc6f8e0d541955aa2aaf86d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 30 Jan 2022 18:19:10 +0100 Subject: [PATCH 01/94] First steps to handling array formulae with the Xlsx Reader and Writer Only supports the basic happy path (no handling for Error results when reading) No functionality yet for setting array formulae in code --- src/PhpSpreadsheet/Reader/Xlsx.php | 8 ++++--- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 22 ++++++++++++-------- 2 files changed, 18 insertions(+), 12 deletions(-) diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 280e3fe1a1..7144ac0fb4 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -810,9 +810,11 @@ public function load(string $filename, int $flags = 0): Spreadsheet } else { // Formula $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToString'); - if (isset($c->f['t'])) { - $attributes = $c->f['t']; - $docSheet->getCell($r)->setFormulaAttributes(['t' => (string) $attributes]); + $formulaAttributes = $c->f->attributes(); + if (isset($formulaAttributes['t'])) { + $formulaType = $formulaAttributes['t']; + $formulaRange = $formulaAttributes['ref'] ? (string) $formulaAttributes['ref'] : null; + $docSheet->getCell($r)->setFormulaAttributes(['t' => (string) $formulaType, 'ref' => $formulaRange]); } } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index a4d28f8a56..5009fd01fb 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\RichText\RichText; @@ -1246,9 +1247,11 @@ private function writeCellError(XMLWriter $objWriter, string $mappedType, string private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $cell): void { - $calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() ? $cell->getCalculatedValue() : $cellValue; + $calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() + ? $cell->getCalculatedValue() : $cellValue; + if (is_string($calculatedValue)) { - if (\PhpOffice\PhpSpreadsheet\Calculation\Functions::isError($calculatedValue)) { + if (Functions::isError($calculatedValue)) { $this->writeCellError($objWriter, 'e', $cellValue, $calculatedValue); return; @@ -1271,14 +1274,15 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $objWriter->endElement(); } else { $objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue)); - self::writeElementIf( - $objWriter, - $this->getParentWriter()->getOffice2003Compatibility() === false, - 'v', - ($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#') - ? StringHelper::formatNumber($calculatedValue) : '0' - ); } + + self::writeElementIf( + $objWriter, + $this->getParentWriter()->getOffice2003Compatibility() === false, + 'v', + ($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#') + ? StringHelper::formatNumber($calculatedValue) : '0' + ); } /** From 39a6c29fb57587cec075181a38245d8db48c4e35 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 30 Jan 2022 20:08:13 +0100 Subject: [PATCH 02/94] Set formula attributes datatype in Cell --- phpstan-baseline.neon | 10 ------ src/PhpSpreadsheet/Cell/Cell.php | 8 +++-- src/PhpSpreadsheet/Reader/Xlsx.php | 52 ++++++++++++++---------------- 3 files changed, 29 insertions(+), 41 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ddaee5a169..98e8c3373a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2065,11 +2065,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Cell.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:getFormulaAttributes\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Cell.php - - message: "#^Parameter \\#1 \\$textValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataType\\:\\:checkString\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\RichText\\|string\\|null, mixed given\\.$#" count: 1 @@ -2080,11 +2075,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Cell.php - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:\\$formulaAttributes has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Cell.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:\\$parent \\(PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\) in isset\\(\\) is not nullable\\.$#" count: 6 diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index fe4a1f41a1..4f8c01b0df 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -65,6 +65,8 @@ class Cell /** * Attributes of the formula. + * + * @var null|array */ private $formulaAttributes; @@ -701,11 +703,11 @@ public function setXfIndex($indexValue) /** * Set the formula attributes. * - * @param mixed $attributes + * @param mixed[] $attributes * * @return $this */ - public function setFormulaAttributes($attributes) + public function setFormulaAttributes(array $attributes) { $this->formulaAttributes = $attributes; @@ -715,7 +717,7 @@ public function setFormulaAttributes($attributes) /** * Get the formula attributes. */ - public function getFormulaAttributes() + public function getFormulaAttributes(): ?array { return $this->formulaAttributes; } diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 7144ac0fb4..aa91b4cd34 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -307,28 +307,34 @@ private static function castToString($c) return isset($c->v) ? (string) $c->v : null; } - private function castToFormula($c, $r, &$cellDataType, &$value, &$calculatedValue, &$sharedFormulas, $castBaseType): void + private function castToFormula(Worksheet $docSheet, $c, $r, &$cellDataType, &$value, &$calculatedValue, &$sharedFormulas, $castBaseType): void { - $attr = $c->f->attributes(); + $formulaAttributes = $c->f->attributes(); $cellDataType = 'f'; $value = "={$c->f}"; $calculatedValue = self::$castBaseType($c); // Shared formula? - if (isset($attr['t']) && strtolower((string) $attr['t']) == 'shared') { - $instance = (string) $attr['si']; + if (isset($formulaAttributes['t'])) { + if (strtolower((string) $formulaAttributes['t']) === 'shared') { + $instance = (string) $formulaAttributes['si']; - if (!isset($sharedFormulas[(string) $attr['si']])) { - $sharedFormulas[$instance] = ['master' => $r, 'formula' => $value]; - } else { - $master = Coordinate::indexesFromString($sharedFormulas[$instance]['master']); - $current = Coordinate::indexesFromString($r); + if (!isset($sharedFormulas[(string) $formulaAttributes['si']])) { + $sharedFormulas[$instance] = ['master' => $r, 'formula' => $value]; + } else { + $master = Coordinate::indexesFromString($sharedFormulas[$instance]['master']); + $current = Coordinate::indexesFromString($r); - $difference = [0, 0]; - $difference[0] = $current[0] - $master[0]; - $difference[1] = $current[1] - $master[1]; + $difference = [0, 0]; + $difference[0] = $current[0] - $master[0]; + $difference[1] = $current[1] - $master[1]; - $value = $this->referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]); + $value = $this->referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]); + } + } elseif (strtolower((string) $formulaAttributes['t']) === 'array') { + $formulaType = (string) $formulaAttributes['t']; + $formulaRange = $formulaAttributes['ref'] ? (string) $formulaAttributes['ref'] : null; + $docSheet->getCell($r)->setFormulaAttributes(['t' => $formulaType, 'ref' => $formulaRange]); } } } @@ -747,7 +753,7 @@ public function load(string $filename, int $flags = 0): Spreadsheet if (!$this->getReadFilter()->readCell($coordinates[0], (int) $coordinates[1], $docSheet->getTitle())) { if (isset($cAttr->f)) { - $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError'); + $this->castToFormula($docSheet, $c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError'); } ++$rowIndex; @@ -779,17 +785,13 @@ public function load(string $filename, int $flags = 0): Spreadsheet } } else { // Formula - $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToBoolean'); - if (isset($c->f['t'])) { - $att = $c->f; - $docSheet->getCell($r)->setFormulaAttributes($att); - } + $this->castToFormula($docSheet, $c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToBoolean'); } break; case 'inlineStr': if (isset($c->f)) { - $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError'); + $this->castToFormula($docSheet, $c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError'); } else { $value = $this->parseRichText($c->is); } @@ -800,7 +802,7 @@ public function load(string $filename, int $flags = 0): Spreadsheet $value = self::castToError($c); } else { // Formula - $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError'); + $this->castToFormula($docSheet, $c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToError'); } break; @@ -809,13 +811,7 @@ public function load(string $filename, int $flags = 0): Spreadsheet $value = self::castToString($c); } else { // Formula - $this->castToFormula($c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToString'); - $formulaAttributes = $c->f->attributes(); - if (isset($formulaAttributes['t'])) { - $formulaType = $formulaAttributes['t']; - $formulaRange = $formulaAttributes['ref'] ? (string) $formulaAttributes['ref'] : null; - $docSheet->getCell($r)->setFormulaAttributes(['t' => (string) $formulaType, 'ref' => $formulaRange]); - } + $this->castToFormula($docSheet, $c, $r, $cellDataType, $value, $calculatedValue, $sharedFormulas, 'castToString'); } break; From 73e7ee00e580588379e71023a0de6e5ded96d97c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 30 Jan 2022 22:19:38 +0100 Subject: [PATCH 03/94] Write correct cell area ref when saving array formulae in cells for Xlsx Writer --- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 5009fd01fb..74999f58a3 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1267,7 +1267,7 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell if (($attributes['t'] ?? null) === 'array') { $objWriter->startElement('f'); $objWriter->writeAttribute('t', 'array'); - $objWriter->writeAttribute('ref', $cell->getCoordinate()); + $objWriter->writeAttribute('ref', $attributes['ref'] ?? $cell->getCoordinate()); $objWriter->writeAttribute('aca', '1'); $objWriter->writeAttribute('ca', '1'); $objWriter->text(substr($cellValue, 1)); From 6a51ad4f3651eb724e7449a1439d7c839fa6eabe Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 30 Jan 2022 23:03:50 +0100 Subject: [PATCH 04/94] Basic Read/Write test for an array function; verify that formula attributes are being set correctly --- src/PhpSpreadsheet/Reader/Xlsx.php | 3 +- .../Writer/Xlsx/ArrayFormulaTest.php | 34 ++++++++++++++++++ tests/data/Writer/XLSX/ArrayFormula.xlsx | Bin 0 -> 9415 bytes 3 files changed, 36 insertions(+), 1 deletion(-) create mode 100644 tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFormulaTest.php create mode 100644 tests/data/Writer/XLSX/ArrayFormula.xlsx diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index aa91b4cd34..e0e34c93af 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -314,9 +314,9 @@ private function castToFormula(Worksheet $docSheet, $c, $r, &$cellDataType, &$va $value = "={$c->f}"; $calculatedValue = self::$castBaseType($c); - // Shared formula? if (isset($formulaAttributes['t'])) { if (strtolower((string) $formulaAttributes['t']) === 'shared') { + // Shared formula $instance = (string) $formulaAttributes['si']; if (!isset($sharedFormulas[(string) $formulaAttributes['si']])) { @@ -332,6 +332,7 @@ private function castToFormula(Worksheet $docSheet, $c, $r, &$cellDataType, &$va $value = $this->referenceHelper->updateFormulaReferences($sharedFormulas[$instance]['formula'], 'A1', $difference[0], $difference[1]); } } elseif (strtolower((string) $formulaAttributes['t']) === 'array') { + // Array formula $formulaType = (string) $formulaAttributes['t']; $formulaRange = $formulaAttributes['ref'] ? (string) $formulaAttributes['ref'] : null; $docSheet->getCell($r)->setFormulaAttributes(['t' => $formulaType, 'ref' => $formulaRange]); diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFormulaTest.php new file mode 100644 index 0000000000..6ecac2d261 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFormulaTest.php @@ -0,0 +1,34 @@ +load('tests/data/Writer/XLSX/ArrayFormula.xlsx'); + + $cellFormulaAttributes = $spreadsheet->getActiveSheet()->getCell('A1')->getFormulaAttributes(); + + self::assertArrayHasKey('t', $cellFormulaAttributes); + self::assertArrayHasKey('ref', $cellFormulaAttributes); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); + $spreadsheet->disconnectWorksheets(); + + $reloadedCellFormulaAttributes = $reloadedSpreadsheet->getActiveSheet()->getCell('A1')->getFormulaAttributes(); + + self::assertArrayHasKey('t', $reloadedCellFormulaAttributes); + self::assertArrayHasKey('ref', $reloadedCellFormulaAttributes); + + self::assertSame($cellFormulaAttributes['t'], $reloadedCellFormulaAttributes['t']); + self::assertSame($cellFormulaAttributes['ref'], $reloadedCellFormulaAttributes['ref']); + + $reloadedSpreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/data/Writer/XLSX/ArrayFormula.xlsx b/tests/data/Writer/XLSX/ArrayFormula.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..a3472b22d17129fa22c79f2dda2f54936ee29736 GIT binary patch literal 9415 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 literal 0 HcmV?d00001 From 1d941b4ffb5e9ebf4d20e7bcabfabc3c110c38dd Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 31 Jan 2022 18:25:49 +0100 Subject: [PATCH 05/94] Initial work on setting an array formula through code, and populating spillage cells when calculating the value No provision yet for the single operator, or for handlng #SPILL! or #CALC! errors --- .../Cell/AdvancedValueBinder.php | 6 +- src/PhpSpreadsheet/Cell/Cell.php | 77 +++++++++++-- .../Cell/DefaultValueBinder.php | 6 +- src/PhpSpreadsheet/Cell/IValueBinder.php | 2 +- src/PhpSpreadsheet/Cell/StringValueBinder.php | 4 +- src/PhpSpreadsheet/Reader/Xlsx.php | 7 +- src/PhpSpreadsheet/Worksheet/Worksheet.php | 38 +++++-- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 2 +- .../Cell/CellFormulaTest.php | 105 ++++++++++++++++++ .../Writer/Xlsx/ArrayFormulaTest.php | 1 + 10 files changed, 213 insertions(+), 35 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php diff --git a/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php b/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php index 025a687bce..91fecae8c2 100644 --- a/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php +++ b/src/PhpSpreadsheet/Cell/AdvancedValueBinder.php @@ -15,10 +15,8 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder * * @param Cell $cell Cell to bind value to * @param mixed $value Value to bind in cell - * - * @return bool */ - public function bindValue(Cell $cell, $value = null) + public function bindValue(Cell $cell, $value, bool $isArrayFormula = false, ?string $arrayFormulaRange = null): bool { if ($value === null) { return parent::bindValue($cell, $value); @@ -119,7 +117,7 @@ public function bindValue(Cell $cell, $value = null) } // Not bound yet? Use parent... - return parent::bindValue($cell, $value); + return parent::bindValue($cell, $value, $isArrayFormula, $arrayFormulaRange); } protected function setImproperFraction(array $matches, Cell $cell): bool diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 4f8c01b0df..c2c51823e3 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -190,15 +190,27 @@ public function getFormattedValue() * * @return $this */ - public function setValue($value) + public function setValue($value, bool $isArrayFormula = false, ?string $arrayFormulaRange = null) { - if (!self::getValueBinder()->bindValue($this, $value)) { + if (!self::getValueBinder()->bindValue($this, $value, $isArrayFormula, $arrayFormulaRange)) { throw new Exception('Value could not be bound to cell.'); } return $this; } + protected function formulaAttributes(bool $isArrayFormula, ?string $arrayFormulaRange): array + { + if ($isArrayFormula === true) { + return [ + 't' => 'array', + 'ref' => $arrayFormulaRange === null ? $this->getCoordinate() : $arrayFormulaRange, + ]; + } + + return []; + } + /** * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder). * @@ -207,7 +219,7 @@ public function setValue($value) * * @return Cell */ - public function setValueExplicit($value, $dataType) + public function setValueExplicit($value, $dataType, bool $isArrayFormula = false, ?string $arrayFormulaRange = null) { // set the value according to data type switch ($dataType) { @@ -233,7 +245,17 @@ public function setValueExplicit($value, $dataType) break; case DataType::TYPE_FORMULA: - $this->value = (string) $value; + if (is_string($value) !== true || strpos($value, '=') !== 0) { + $dataType = DataType::TYPE_STRING; + if (in_array($value, Calculation::$excelConstants, true)) { + $value = array_search($value, Calculation::$excelConstants, true); + } + $value = (string) $value; + $this->formulaAttributes = []; + } else { + $this->formulaAttributes = $this->formulaAttributes($isArrayFormula, $arrayFormulaRange); + } + $this->value = $value; break; case DataType::TYPE_BOOL: @@ -283,19 +305,42 @@ public function getCalculatedValue($resetLog = true) { if ($this->dataType == DataType::TYPE_FORMULA) { try { + $coordinate = $this->getCoordinate(); + $worksheet = $this->getWorksheet(); + $value = $this->value; + $datatype = $this->dataType; + $formulaAttributes = $this->formulaAttributes; $index = $this->getWorksheet()->getParent()->getActiveSheetIndex(); $selected = $this->getWorksheet()->getSelectedCells(); $result = Calculation::getInstance( $this->getWorksheet()->getParent() )->calculateCellValue($this, $resetLog); - $this->getWorksheet()->setSelectedCells($selected); - $this->getWorksheet()->getParent()->setActiveSheetIndex($index); - // We don't yet handle array returns + if (is_array($result)) { + // We'll need to do a check here for the Singular Operator (@) at some point + // and not populate the spillage cells if it's there + if ($this->isArrayFormula()) { + // Here is where we should set all cellRange values from the result (but within the range limit) + // How are we going to handle a #SPILL! error? + $worksheet->fromArray($result, null, $coordinate, true); + // fromArray() will reset the value for this cell with the calculation result + // as well as updating the spillage cells, + // so we need to restore this cell to its formula value, attributes, and datatype + $worksheet->getCell($coordinate); + $this->updateInCollection(); + $this->value = $value; + $this->dataType = $datatype; + $this->formulaAttributes = $formulaAttributes; + } + + // Now we just extract the top-left value from the array to get the result for this specific cell while (is_array($result)) { $result = array_shift($result); } } + + $this->getWorksheet()->setSelectedCells($selected); + $this->getWorksheet()->getParent()->setActiveSheetIndex($index); } catch (Exception $ex) { if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) { return $this->calculatedValue; // Fallback for calculations referencing external files. @@ -380,14 +425,26 @@ public function setDataType($dataType) /** * Identify if the cell contains a formula. - * - * @return bool */ - public function isFormula() + public function isFormula(): bool { return $this->dataType == DataType::TYPE_FORMULA; } + /** + * Identify if the cell contains an array formula. + */ + public function isArrayFormula(): bool + { + if ($this->dataType === DataType::TYPE_FORMULA) { + $formulaAttributes = $this->getFormulaAttributes(); + + return isset($formulaAttributes['t']) && $formulaAttributes['t'] === 'array'; + } + + return false; + } + /** * Does this cell contain Data validation rules? * diff --git a/src/PhpSpreadsheet/Cell/DefaultValueBinder.php b/src/PhpSpreadsheet/Cell/DefaultValueBinder.php index 4f2cdf7879..19f64bd983 100644 --- a/src/PhpSpreadsheet/Cell/DefaultValueBinder.php +++ b/src/PhpSpreadsheet/Cell/DefaultValueBinder.php @@ -13,10 +13,8 @@ class DefaultValueBinder implements IValueBinder * * @param Cell $cell Cell to bind value to * @param mixed $value Value to bind in cell - * - * @return bool */ - public function bindValue(Cell $cell, $value) + public function bindValue(Cell $cell, $value, bool $isArrayFormula = false, ?string $arrayFormulaRange = null): bool { // sanitize UTF-8 strings if (is_string($value)) { @@ -32,7 +30,7 @@ public function bindValue(Cell $cell, $value) } // Set value explicit - $cell->setValueExplicit($value, static::dataTypeForValue($value)); + $cell->setValueExplicit($value, static::dataTypeForValue($value), $isArrayFormula, $arrayFormulaRange); // Done! return true; diff --git a/src/PhpSpreadsheet/Cell/IValueBinder.php b/src/PhpSpreadsheet/Cell/IValueBinder.php index 5af9f5f60e..d1607a806a 100644 --- a/src/PhpSpreadsheet/Cell/IValueBinder.php +++ b/src/PhpSpreadsheet/Cell/IValueBinder.php @@ -12,5 +12,5 @@ interface IValueBinder * * @return bool */ - public function bindValue(Cell $cell, $value); + public function bindValue(Cell $cell, $value, bool $isArrayFormula = false, ?string $arrayFormulaRange = null); } diff --git a/src/PhpSpreadsheet/Cell/StringValueBinder.php b/src/PhpSpreadsheet/Cell/StringValueBinder.php index d525faffff..204dae1907 100644 --- a/src/PhpSpreadsheet/Cell/StringValueBinder.php +++ b/src/PhpSpreadsheet/Cell/StringValueBinder.php @@ -77,7 +77,7 @@ public function setConversionForAllValueTypes(bool $suppressConversion = false): * @param Cell $cell Cell to bind value to * @param mixed $value Value to bind in cell */ - public function bindValue(Cell $cell, $value) + public function bindValue(Cell $cell, $value, bool $isArrayFormula = false, ?string $arrayFormulaRange = null): bool { if (is_object($value)) { return $this->bindObjectValue($cell, $value); @@ -95,7 +95,7 @@ public function bindValue(Cell $cell, $value) } elseif ((is_int($value) || is_float($value)) && $this->convertNumeric === false) { $cell->setValueExplicit($value, DataType::TYPE_NUMERIC); } elseif (is_string($value) && strlen($value) > 1 && $value[0] === '=' && $this->convertFormula === false) { - $cell->setValueExplicit($value, DataType::TYPE_FORMULA); + $cell->setValueExplicit($value, DataType::TYPE_FORMULA, $isArrayFormula, $arrayFormulaRange); } else { if (is_string($value) && strlen($value) > 1 && $value[0] === '=') { $cell->getStyle()->setQuotePrefix(true); diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index e0e34c93af..e0e9efd92b 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -826,6 +826,9 @@ public function load(string $filename, int $flags = 0): Spreadsheet } $cell = $docSheet->getCell($r); + $formulaAttributes = $cell->getFormulaAttributes(); + $isArrayFormula = isset($formulaAttributes['t']) && $formulaAttributes['t'] === 'array'; + $arrayFormulaRange = isset($formulaAttributes['ref']) ? $formulaAttributes['ref'] : null; // Assign value if ($cellDataType != '') { // it is possible, that datatype is numeric but with an empty string, which result in an error @@ -833,10 +836,10 @@ public function load(string $filename, int $flags = 0): Spreadsheet $cellDataType = DataType::TYPE_NULL; } if ($cellDataType !== DataType::TYPE_NULL) { - $cell->setValueExplicit($value, $cellDataType); + $cell->setValueExplicit($value, $cellDataType, $isArrayFormula, $arrayFormulaRange); } } else { - $cell->setValue($value); + $cell->setValue($value, $isArrayFormula, $arrayFormulaRange); } if ($calculatedValue !== null) { $cell->setCalculatedValue($calculatedValue); diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 51cf3c5212..27a5661b13 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -1110,9 +1110,9 @@ public function getHighestRowAndColumn() * * @return $this */ - public function setCellValue($coordinate, $value) + public function setCellValue($coordinate, $value, bool $isArrayFormula = false, ?string $arrayFormulaRange = null) { - $this->getCell($coordinate)->setValue($value); + $this->getCell($coordinate)->setValue($value, $isArrayFormula, $arrayFormulaRange); return $this; } @@ -1126,9 +1126,14 @@ public function setCellValue($coordinate, $value) * * @return $this */ - public function setCellValueByColumnAndRow($columnIndex, $row, $value) - { - $this->getCellByColumnAndRow($columnIndex, $row)->setValue($value); + public function setCellValueByColumnAndRow( + $columnIndex, + $row, + $value, + bool $isArrayFormula = false, + ?string $arrayFormulaRange = null + ) { + $this->getCellByColumnAndRow($columnIndex, $row)->setValue($value, $isArrayFormula, $arrayFormulaRange); return $this; } @@ -1142,10 +1147,15 @@ public function setCellValueByColumnAndRow($columnIndex, $row, $value) * * @return $this */ - public function setCellValueExplicit($coordinate, $value, $dataType) - { + public function setCellValueExplicit( + $coordinate, + $value, + $dataType, + bool $isArrayFormula = false, + ?string $arrayFormulaRange = null + ) { // Set value - $this->getCell($coordinate)->setValueExplicit($value, $dataType); + $this->getCell($coordinate)->setValueExplicit($value, $dataType, $isArrayFormula, $arrayFormulaRange); return $this; } @@ -1160,9 +1170,15 @@ public function setCellValueExplicit($coordinate, $value, $dataType) * * @return $this */ - public function setCellValueExplicitByColumnAndRow($columnIndex, $row, $value, $dataType) - { - $this->getCellByColumnAndRow($columnIndex, $row)->setValueExplicit($value, $dataType); + public function setCellValueExplicitByColumnAndRow( + $columnIndex, + $row, + $value, + $dataType, + bool $isArrayFormula = false, + ?string $arrayFormulaRange = null + ) { + $this->getCellByColumnAndRow($columnIndex, $row)->setValueExplicit($value, $dataType, $isArrayFormula, $arrayFormulaRange); return $this; } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 74999f58a3..3f2b597fba 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1270,7 +1270,7 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $objWriter->writeAttribute('ref', $attributes['ref'] ?? $cell->getCoordinate()); $objWriter->writeAttribute('aca', '1'); $objWriter->writeAttribute('ca', '1'); - $objWriter->text(substr($cellValue, 1)); + $objWriter->text(Xlfn::addXlfnStripEquals($cellValue)); $objWriter->endElement(); } else { $objWriter->writeElement('f', Xlfn::addXlfnStripEquals($cellValue)); diff --git a/tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php b/tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php new file mode 100644 index 0000000000..ed63f0e564 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php @@ -0,0 +1,105 @@ +getActiveSheet()->getCell('A1'); + $cell->setValueExplicit($formula, DataType::TYPE_FORMULA); + + self::assertSame($formula, $cell->getValue()); + self::assertTrue($cell->isFormula()); + self::assertFalse($cell->isArrayFormula()); + + $spreadsheet->disconnectWorksheets(); + } + + public function testSetFormulaDeterminedByBinder(): void + { + $formula = '=A2+B2'; + + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + $cell->setValue($formula); + + self::assertSame($formula, $cell->getValue()); + self::assertTrue($cell->isFormula()); + self::assertFalse($cell->isArrayFormula()); + + $spreadsheet->disconnectWorksheets(); + } + + public function testSetFormulaInvalidValue(): void + { + $formula = true; + + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + + $cell->setValueExplicit($formula, DataType::TYPE_FORMULA); + + self::assertSame('TRUE', $cell->getValue()); + self::assertFalse($cell->isFormula()); + + $spreadsheet->disconnectWorksheets(); + } + + public function testSetFormulaInvalidFormulaValue(): void + { + $formula = 'invalid formula'; + + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + + $cell->setValueExplicit($formula, DataType::TYPE_FORMULA); + + self::assertSame($formula, $cell->getValue()); + self::assertFalse($cell->isFormula()); + + $spreadsheet->disconnectWorksheets(); + } + + public function testSetArrayFormulaExplicitNoRange(): void + { + $formula = '=SUM(B2:B6*C2:C6)'; + + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + $cell->setValueExplicit($formula, DataType::TYPE_FORMULA, true); + + self::assertSame($formula, $cell->getValue()); + self::assertTrue($cell->isFormula()); + self::assertTrue($cell->isArrayFormula()); + self::assertArrayHasKey('ref', $cell->getFormulaAttributes()); + self::assertSame('A1', $cell->getFormulaAttributes()['ref']); + + $spreadsheet->disconnectWorksheets(); + } + + public function testSetArrayFormulaExplicitWithRange(): void + { + $formula = '=SEQUENCE(3,3,-10,2.5)'; + + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + $cell->setValueExplicit($formula, DataType::TYPE_FORMULA, true, 'A1:C3'); + + self::assertSame($formula, $cell->getValue()); + self::assertTrue($cell->isFormula()); + self::assertTrue($cell->isArrayFormula()); + self::assertArrayHasKey('ref', $cell->getFormulaAttributes()); + self::assertSame('A1:C3', $cell->getFormulaAttributes()['ref']); + + $spreadsheet->disconnectWorksheets(); + } +} diff --git a/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFormulaTest.php index 6ecac2d261..ca5512d622 100644 --- a/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Writer/Xlsx/ArrayFormulaTest.php @@ -16,6 +16,7 @@ public function testArrayFormulaReadWrite(): void $cellFormulaAttributes = $spreadsheet->getActiveSheet()->getCell('A1')->getFormulaAttributes(); self::assertArrayHasKey('t', $cellFormulaAttributes); + self::assertSame('array', $cellFormulaAttributes['t']); self::assertArrayHasKey('ref', $cellFormulaAttributes); $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); From 69436d3d778391ad1cea4c8b68d676bd761d5d8d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 31 Jan 2022 20:22:22 +0100 Subject: [PATCH 06/94] phpcs fixes --- src/PhpSpreadsheet/Reader/Xlsx.php | 2 +- tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index e0e9efd92b..df75ce249d 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -828,7 +828,7 @@ public function load(string $filename, int $flags = 0): Spreadsheet $cell = $docSheet->getCell($r); $formulaAttributes = $cell->getFormulaAttributes(); $isArrayFormula = isset($formulaAttributes['t']) && $formulaAttributes['t'] === 'array'; - $arrayFormulaRange = isset($formulaAttributes['ref']) ? $formulaAttributes['ref'] : null; + $arrayFormulaRange = $formulaAttributes['ref'] ?? null; // Assign value if ($cellDataType != '') { // it is possible, that datatype is numeric but with an empty string, which result in an error diff --git a/tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php b/tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php index ed63f0e564..821ce4ca10 100644 --- a/tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Cell/CellFormulaTest.php @@ -3,7 +3,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Cell; use PhpOffice\PhpSpreadsheet\Cell\DataType; -use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PHPUnit\Framework\TestCase; From d2435cde079caa1b860a0914f95fd65d37e2488e Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 1 Feb 2022 21:08:26 +0100 Subject: [PATCH 07/94] Ensure that a basic metadata file containing a cell metadata definition is written and linked; and then tag array formula cells with the `cm` tag to link them to that cell metadata definition --- src/PhpSpreadsheet/Cell/Cell.php | 2 +- src/PhpSpreadsheet/Writer/Xlsx.php | 15 ++ .../Writer/Xlsx/ContentTypes.php | 3 + src/PhpSpreadsheet/Writer/Xlsx/Metadata.php | 181 ++++++++++++++++++ src/PhpSpreadsheet/Writer/Xlsx/Rels.php | 11 ++ src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 6 +- 6 files changed, 215 insertions(+), 3 deletions(-) create mode 100644 src/PhpSpreadsheet/Writer/Xlsx/Metadata.php diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index c2c51823e3..a72c6262d9 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -327,10 +327,10 @@ public function getCalculatedValue($resetLog = true) // as well as updating the spillage cells, // so we need to restore this cell to its formula value, attributes, and datatype $worksheet->getCell($coordinate); - $this->updateInCollection(); $this->value = $value; $this->dataType = $datatype; $this->formulaAttributes = $formulaAttributes; + $this->updateInCollection(); } // Now we just extract the top-left value from the array to get the result for this specific cell diff --git a/src/PhpSpreadsheet/Writer/Xlsx.php b/src/PhpSpreadsheet/Writer/Xlsx.php index 4f50607052..b4c741d256 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx.php +++ b/src/PhpSpreadsheet/Writer/Xlsx.php @@ -20,6 +20,7 @@ use PhpOffice\PhpSpreadsheet\Writer\Xlsx\ContentTypes; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\DocProps; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Drawing; +use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Metadata; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\Rels; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\RelsRibbon; use PhpOffice\PhpSpreadsheet\Writer\Xlsx\RelsVBA; @@ -157,6 +158,11 @@ class Xlsx extends BaseWriter */ private $writerPartStringTable; + /** + * @var Metadata + */ + private $writerPartMetadata; + /** * @var Style */ @@ -193,6 +199,7 @@ public function __construct(Spreadsheet $spreadsheet) $this->writerPartRels = new Rels($this); $this->writerPartRelsRibbon = new RelsRibbon($this); $this->writerPartRelsVBA = new RelsVBA($this); + $this->writerPartMetadata = new Metadata($this); $this->writerPartStringTable = new StringTable($this); $this->writerPartStyle = new Style($this); $this->writerPartTheme = new Theme($this); @@ -256,6 +263,11 @@ public function getWriterPartRelsVBA(): RelsVBA return $this->writerPartRelsVBA; } + public function getWriterPartMetadata(): Metadata + { + return $this->writerPartMetadata; + } + public function getWriterPartStringTable(): StringTable { return $this->writerPartStringTable; @@ -364,6 +376,9 @@ public function save($filename, int $flags = 0): void // Add theme to ZIP file $zipContent['xl/theme/theme1.xml'] = $this->getWriterPartTheme()->writeTheme($this->spreadSheet); + // Add metadata to ZIP file + $zipContent['xl/metadata.xml'] = $this->getWriterPartMetadata()->writeMetadata(); + // Add string table to ZIP file $zipContent['xl/sharedStrings.xml'] = $this->getWriterPartStringTable()->writeStringTable($this->stringTable); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php b/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php index f62c14af70..5dccb0a468 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php @@ -82,6 +82,9 @@ public function writeContentTypes(Spreadsheet $spreadsheet, $includeCharts = fal $this->writeOverrideContentType($objWriter, '/xl/worksheets/sheet' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.worksheet+xml'); } + // Shared strings + $this->writeOverrideContentType($objWriter, '/xl/metadata.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheetMetadata+xml'); + // Shared strings $this->writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php b/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php new file mode 100644 index 0000000000..72959100dc --- /dev/null +++ b/src/PhpSpreadsheet/Writer/Xlsx/Metadata.php @@ -0,0 +1,181 @@ + '1', + 'coerce' => '1', + 'assign' => '1', + 'clearComments' => '1', + 'clearFormats' => '1', + 'rowColShift' => '1', + 'splitFirst' => '1', + 'merge' => '1', + 'pasteValues' => '1', + 'pasteAll' => '1', + 'copy' => '1', + 'minSupportedVersion' => '120000', + 'name' => 'XLDAPR', + ], + [ + 'coerce' => '1', + 'assign' => '1', + 'clearComments' => '1', + 'clearFormats' => '1', + 'rowColShift' => '1', + 'splitFirst' => '1', + 'merge' => '1', + 'pasteValues' => '1', + 'pasteAll' => '1', + 'copy' => '1', + 'minSupportedVersion' => '120000', + 'name' => 'XLRICHVALUE', + ], + ]; + + protected const FUTURE_METADATA = [ + 'XLDAPR' => [ + [ + 'uri' => '{bdbb8cdc-fa1e-496e-a857-3c3f30c029c3}', + 'xda:dynamicArrayProperties' => [ + 'fCollapsed' => '0', + 'fDynamic' => '1', + ], + ], + ], + 'XLRICHVALUE' => [ + [ + 'uri' => '{3e2802c4-a4d2-4d8b-9148-e3be6c30e623}', + 'xlrd:rvb' => [ + 'i' => '0', + ], + ], + ], + ]; + + protected const EXTRA_METADATA = [ + 'cellMetadata' => [ + [ + 'v' => '0', + 't' => '1', + ], + ], + 'valueMetadata' => [ + [ + 'v' => '0', + 't' => '2', + ], + ], + ]; + + /** + * Write metadata to XML format. + * + * @return string XML Output + */ + public function writeMetadata() + { + // Create XML writer + $objWriter = null; + if ($this->getParentWriter()->getUseDiskCaching()) { + $objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory()); + } else { + $objWriter = new XMLWriter(XMLWriter::STORAGE_MEMORY); + } + + // XML header + $objWriter->startDocument('1.0', 'UTF-8', 'yes'); + + $objWriter->startElement('metadata'); + $objWriter->writeAttribute('xmlns:xda', 'http://schemas.microsoft.com/office/spreadsheetml/2017/dynamicarray'); + $objWriter->writeAttribute('xmlns:xlrd', 'http://schemas.microsoft.com/office/spreadsheetml/2017/richdata'); + $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); + + $this->writeMetadataTypes($objWriter); + $this->writeFutureMetadata($objWriter); + $this->writeExtraMetadata($objWriter); + + $objWriter->endElement(); // metadata + + return $objWriter->getData(); + } + + private function writeMetadataTypes(XMLWriter $objWriter): void + { + $objWriter->startElement('metadataTypes'); + $objWriter->writeAttribute('count', (string) count(self::METADATA_TYPES)); + + foreach (self::METADATA_TYPES as $metadataType) { + $objWriter->startElement('metadataType'); + + foreach ($metadataType as $metadataTypeKey => $metadataTypeValue) { + $objWriter->writeAttribute($metadataTypeKey, $metadataTypeValue); + } + + $objWriter->endElement(); //metadataType + } + + $objWriter->endElement(); //metadataTypes + } + + private function writeFutureMetadata(XMLWriter $objWriter): void + { + foreach (self::FUTURE_METADATA as $name => $futureMetadata) { + $objWriter->startElement('futureMetadata'); + $objWriter->writeAttribute('count', (string) count($futureMetadata)); + $objWriter->writeAttribute('name', $name); + + foreach ($futureMetadata as $futureMetadatum) { + $objWriter->startElement('bk'); + $objWriter->startElement('extLst'); + + $ext = array_shift($futureMetadatum); + $objWriter->startElement('ext'); + $objWriter->writeAttribute('uri', $ext); + + foreach ($futureMetadatum as $extElementName => $extElementProperties) { + $objWriter->startElement($extElementName); + + foreach ($extElementProperties as $extElementPropertyName => $extElementPropertyValue) { + $objWriter->writeAttribute($extElementPropertyName, $extElementPropertyValue); + } + + $objWriter->endElement(); // ext + } + + $objWriter->endElement(); // ext + $objWriter->endElement(); // extLst + $objWriter->endElement(); // bk + } + + $objWriter->endElement(); // futureMetadata + } + } + + private function writeExtraMetadata(XMLWriter $objWriter): void + { + foreach (self::EXTRA_METADATA as $name => $metadata) { + $objWriter->startElement($name); + $objWriter->writeAttribute('count', (string) count($metadata)); + + foreach ($metadata as $metadatum) { + $objWriter->startElement('bk'); + $objWriter->startElement('rc'); + + foreach ($metadatum as $attributeName => $attrbuteValue) { + $objWriter->writeAttribute($attributeName, $attrbuteValue); + } + + $objWriter->endElement(); // rc + $objWriter->endElement(); // bk + } + + $objWriter->endElement(); + } + } +} diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php index 5aa878760a..e81df3589c 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php @@ -137,6 +137,17 @@ public function writeWorkbookRelationships(Spreadsheet $spreadsheet) 'worksheets/sheet' . ($i + 1) . '.xml' ); } + + // Relationship sharedStrings.xml + // id : just after the last sheet + $this->writeRelationship( + $objWriter, + ($i + 1 + 3), + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/sheetMetadata', + 'metadata.xml' + ); + ++$i; //increment i if needed for an another relation + // Relationships for vbaProject if needed // id : just after the last sheet if ($spreadsheet->hasMacros()) { diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 3f2b597fba..499af11fcb 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1265,11 +1265,13 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $attributes = $cell->getFormulaAttributes(); if (($attributes['t'] ?? null) === 'array') { + $objWriter->writeAttribute('cm', '1'); + $objWriter->startElement('f'); $objWriter->writeAttribute('t', 'array'); $objWriter->writeAttribute('ref', $attributes['ref'] ?? $cell->getCoordinate()); - $objWriter->writeAttribute('aca', '1'); - $objWriter->writeAttribute('ca', '1'); + $objWriter->writeAttribute('aca', '1'); // Always calculate array, true + $objWriter->writeAttribute('ca', '1'); // Calculate cell, true $objWriter->text(Xlfn::addXlfnStripEquals($cellValue)); $objWriter->endElement(); } else { From 9f3db9968f2206d5116b061276e2d1f61dc21cc3 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 2 Feb 2022 12:51:22 +0100 Subject: [PATCH 08/94] Ensure that our array result dimensions match the specified array formula range dimensions, expanding or shrinking it as necessary. --- src/PhpSpreadsheet/Calculation/Functions.php | 45 +++++++++++++ src/PhpSpreadsheet/Cell/Cell.php | 17 ++++- .../Calculation/FunctionsMatrixResizeTest.php | 24 +++++++ tests/data/Calculation/MatrixResize.php | 67 +++++++++++++++++++ 4 files changed, 151 insertions(+), 2 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Calculation/FunctionsMatrixResizeTest.php create mode 100644 tests/data/Calculation/MatrixResize.php diff --git a/src/PhpSpreadsheet/Calculation/Functions.php b/src/PhpSpreadsheet/Calculation/Functions.php index 75d4582b2c..91189a209e 100644 --- a/src/PhpSpreadsheet/Calculation/Functions.php +++ b/src/PhpSpreadsheet/Calculation/Functions.php @@ -657,6 +657,51 @@ public static function flattenSingleValue($value = '') return $value; } + protected static function resizeMatrixColumns(array $matrix, int $columns): array + { + $matrix = array_map( + function ($row) use ($columns) { + if (count($row) > $columns) { + // remove extra columns + $row = array_slice($row, 0, $columns); + } elseif (count($row) < $columns) { + // add new empty columns + $row = array_merge($row, array_fill(0, $columns - count($row), null)); + } + + return $row; + }, + $matrix + ); + + return $matrix; + } + + protected static function resizeMatrixRows(array $matrix, int $columns, int $rows): array + { + if (count($matrix) > $rows) { + // remove extra rows + return array_slice($matrix, 0, $rows); + } + + if (count($matrix) < $rows) { + // add new empty rows + for ($row = count($matrix); $row < $rows; ++$row) { + $matrix[] = array_fill(0, $columns-1, null); + } + } + + return $matrix; + } + + public static function resizeMatrix(array $matrix, int $columns, int $rows): array + { + $matrix = self::resizeMatrixRows($matrix, $columns, $rows); + $matrix = self::resizeMatrixColumns($matrix, $columns); + + return $matrix; + } + /** * ISFORMULA. * diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index a72c6262d9..3c127833ab 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -4,6 +4,7 @@ use DateTime; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Collection\Cells; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\RichText\RichText; @@ -316,13 +317,25 @@ public function getCalculatedValue($resetLog = true) $this->getWorksheet()->getParent() )->calculateCellValue($this, $resetLog); + $worksheet->getCell($coordinate); + if (is_array($result)) { // We'll need to do a check here for the Singular Operator (@) at some point // and not populate the spillage cells if it's there if ($this->isArrayFormula()) { // Here is where we should set all cellRange values from the result (but within the range limit) - // How are we going to handle a #SPILL! error? - $worksheet->fromArray($result, null, $coordinate, true); + // Ensure that our array result dimensions match the specified array formula range dimensions, + // expanding or shrinking it as necessary. + // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? + $worksheet->fromArray( + Functions::resizeMatrix( + $result, + ...Coordinate::rangeDimension($this->formulaAttributes['ref']) + ), + null, + $coordinate, + true + ); // fromArray() will reset the value for this cell with the calculation result // as well as updating the spillage cells, // so we need to restore this cell to its formula value, attributes, and datatype diff --git a/tests/PhpSpreadsheetTests/Calculation/FunctionsMatrixResizeTest.php b/tests/PhpSpreadsheetTests/Calculation/FunctionsMatrixResizeTest.php new file mode 100644 index 0000000000..40ea7a0476 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/FunctionsMatrixResizeTest.php @@ -0,0 +1,24 @@ + Date: Wed, 2 Feb 2022 14:59:06 +0100 Subject: [PATCH 09/94] Provide a method to easily access the array formula range for a cell containing an array formula --- src/PhpSpreadsheet/Cell/Cell.php | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 3c127833ab..344faaa77b 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -458,6 +458,17 @@ public function isArrayFormula(): bool return false; } + public function arrayFormulaRange(): ?string + { + if ($this->isFormula() && $this->isArrayFormula()) { + $formulaAttributes = $this->getFormulaAttributes(); + + return $formulaAttributes['ref'] ?? null; + } + + return null; + } + /** * Does this cell contain Data validation rules? * From beb1e8f6fae4be6326e0bae33d86dc4bb38fbd68 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 2 Feb 2022 15:00:16 +0100 Subject: [PATCH 10/94] Update array formula ranges when inserting/deleting rows/columns --- src/PhpSpreadsheet/ReferenceHelper.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/PhpSpreadsheet/ReferenceHelper.php b/src/PhpSpreadsheet/ReferenceHelper.php index 0d72b3055d..561944fb26 100644 --- a/src/PhpSpreadsheet/ReferenceHelper.php +++ b/src/PhpSpreadsheet/ReferenceHelper.php @@ -424,6 +424,12 @@ public function insertNewBefore($beforeCellAddress, $numberOfColumns, $numberOfR // Formula should be adjusted $worksheet->getCell($newCoordinate) ->setValue($this->updateFormulaReferences($cell->getValue(), $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle())); + if ($cell->arrayFormulaRange() !== null) { + $newArrayFormulaRange = $this->updateFormulaReferences( + $cell->arrayFormulaRange(), $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle() + ); + $worksheet->getCell($newCoordinate)->setFormulaAttributes(['t' => 'array', 'ref' => $newArrayFormulaRange]); + } } else { // Formula should not be adjusted $worksheet->getCell($newCoordinate)->setValueExplicit($cell->getValue(), $cell->getDataType()); From 9bfc4be2346e267aa41224b719ee5ff4d587df7b Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 2 Feb 2022 17:27:26 +0100 Subject: [PATCH 11/94] Stubs for MS pseudo-functions used to handle the Spillage (`ANCHORARRAY()`) and Single (`SINGLE()`) Operators --- infra/DocumentGenerator.php | 6 +++++ .../Calculation/Calculation.php | 24 ++++++++++++++++--- src/PhpSpreadsheet/Calculation/Category.php | 2 ++ src/PhpSpreadsheet/Calculation/Functions.php | 2 +- .../Internal/ExcelArrayPseudoFunctions.php | 18 ++++++++++++++ src/PhpSpreadsheet/Cell/Cell.php | 2 +- src/PhpSpreadsheet/ReferenceHelper.php | 6 ++++- src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php | 2 ++ 8 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php diff --git a/infra/DocumentGenerator.php b/infra/DocumentGenerator.php index e2c3c86cb9..cd49d156b1 100644 --- a/infra/DocumentGenerator.php +++ b/infra/DocumentGenerator.php @@ -16,6 +16,9 @@ public static function generateFunctionListByCategory(array $phpSpreadsheetFunct { $result = "# Function list by category\n"; foreach (self::getCategories() as $categoryConstant => $category) { + if ($category === Category::CATEGORY_MICROSOFT_INTERNAL_PSEUDOFUNCTION) { + continue; + } $result .= "\n"; $result .= "## {$categoryConstant}\n"; $result .= "\n"; @@ -78,6 +81,9 @@ public static function generateFunctionListByName(array $phpSpreadsheetFunctions $result = "# Function list by name\n"; $lastAlphabet = null; foreach ($phpSpreadsheetFunctions as $excelFunction => $functionInfo) { + if ($functionInfo['category'] === Category::CATEGORY_MICROSOFT_INTERNAL_PSEUDOFUNCTION) { + continue; + } /** @var string $excelFunction */ $lengths = [25, 31, 37]; if ($lastAlphabet !== $excelFunction[0]) { diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index c5ce0afa7a..d03c714f87 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -2739,6 +2739,19 @@ class Calculation 'functionCall' => [Statistical\Distributions\StandardNormal::class, 'zTest'], 'argumentCount' => '2-3', ], + // Internal MS Excel Functions + 'ANCHORARRAY' => [ + 'category' => Category::CATEGORY_MICROSOFT_INTERNAL_PSEUDOFUNCTION, + 'functionCall' => [Internal\ExcelArrayPseudoFunctions::class, 'anchorArray'], + 'argumentCount' => '1', + 'passCellReference' => true, + ], + 'SINGLE' => [ + 'category' => Category::CATEGORY_MICROSOFT_INTERNAL_PSEUDOFUNCTION, + 'functionCall' => [Internal\ExcelArrayPseudoFunctions::class, 'single'], + 'argumentCount' => '1', + 'passCellReference' => true, + ], ]; // Internal functions used for special control purposes @@ -5382,11 +5395,16 @@ public function isImplemented($function) } /** - * Get a list of all implemented functions as an array of function objects. + * Get a list of all functions as an array of function objects. */ public function getFunctions(): array { - return self::$phpSpreadsheetFunctions; + return array_filter( + self::$phpSpreadsheetFunctions, + function ($function) { + return $function['category'] !== Category::CATEGORY_MICROSOFT_INTERNAL_PSEUDOFUNCTION; + } + ); } /** @@ -5397,7 +5415,7 @@ public function getFunctions(): array public function getImplementedFunctionNames() { $returnValue = []; - foreach (self::$phpSpreadsheetFunctions as $functionName => $function) { + foreach ($this->getFunctions() as $functionName => $function) { if ($this->isImplemented($functionName)) { $returnValue[] = $functionName; } diff --git a/src/PhpSpreadsheet/Calculation/Category.php b/src/PhpSpreadsheet/Calculation/Category.php index 96bb72ad4c..ff94fc25e2 100644 --- a/src/PhpSpreadsheet/Calculation/Category.php +++ b/src/PhpSpreadsheet/Calculation/Category.php @@ -17,4 +17,6 @@ abstract class Category const CATEGORY_STATISTICAL = 'Statistical'; const CATEGORY_TEXT_AND_DATA = 'Text and Data'; const CATEGORY_WEB = 'Web'; + + const CATEGORY_MICROSOFT_INTERNAL_PSEUDOFUNCTION = 'MS Pseudo'; } diff --git a/src/PhpSpreadsheet/Calculation/Functions.php b/src/PhpSpreadsheet/Calculation/Functions.php index 91189a209e..2edae1921a 100644 --- a/src/PhpSpreadsheet/Calculation/Functions.php +++ b/src/PhpSpreadsheet/Calculation/Functions.php @@ -687,7 +687,7 @@ protected static function resizeMatrixRows(array $matrix, int $columns, int $row if (count($matrix) < $rows) { // add new empty rows for ($row = count($matrix); $row < $rows; ++$row) { - $matrix[] = array_fill(0, $columns-1, null); + $matrix[] = array_fill(0, $columns - 1, null); } } diff --git a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php new file mode 100644 index 0000000000..e07d3a7d93 --- /dev/null +++ b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -0,0 +1,18 @@ +fromArray( Functions::resizeMatrix( $result, - ...Coordinate::rangeDimension($this->formulaAttributes['ref']) + ...Coordinate::rangeDimension($this->formulaAttributes['ref'] ?? $coordinate) ), null, $coordinate, diff --git a/src/PhpSpreadsheet/ReferenceHelper.php b/src/PhpSpreadsheet/ReferenceHelper.php index 561944fb26..6ffdf17e8c 100644 --- a/src/PhpSpreadsheet/ReferenceHelper.php +++ b/src/PhpSpreadsheet/ReferenceHelper.php @@ -426,7 +426,11 @@ public function insertNewBefore($beforeCellAddress, $numberOfColumns, $numberOfR ->setValue($this->updateFormulaReferences($cell->getValue(), $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle())); if ($cell->arrayFormulaRange() !== null) { $newArrayFormulaRange = $this->updateFormulaReferences( - $cell->arrayFormulaRange(), $beforeCellAddress, $numberOfColumns, $numberOfRows, $worksheet->getTitle() + $cell->arrayFormulaRange(), + $beforeCellAddress, + $numberOfColumns, + $numberOfRows, + $worksheet->getTitle() ); $worksheet->getCell($newCoordinate)->setFormulaAttributes(['t' => 'array', 'ref' => $newArrayFormulaRange]); } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php b/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php index c88ef245b6..910eabbeb4 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php @@ -132,8 +132,10 @@ class Xlfn . '|sumifs' . '|textjoin' // functions added with Excel 365 + . '|anchorarray' // Pseudo-function used by the Spill Operator: =A1# => =ANCHORARRAY(A1) . '|filter' . '|randarray' + . '|single' // Pseudo-function used by the Single Operator: =@A1 => =SINGLE(A1) . '|sequence' . '|sort' . '|sortby' From ceb1c04ca9489a6c2dc9032998833e6dccd28103 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 2 Feb 2022 23:23:05 +0100 Subject: [PATCH 12/94] Initial work implementing the SINGLE() and ANCHORARRAY() pseudo-functions --- .../Calculation/Calculation.php | 2 + .../Internal/ExcelArrayPseudoFunctions.php | 59 +++++++++++++++++-- 2 files changed, 57 insertions(+), 4 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index d03c714f87..61e98390c6 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -2745,12 +2745,14 @@ class Calculation 'functionCall' => [Internal\ExcelArrayPseudoFunctions::class, 'anchorArray'], 'argumentCount' => '1', 'passCellReference' => true, + 'passByReference' => [true], ], 'SINGLE' => [ 'category' => Category::CATEGORY_MICROSOFT_INTERNAL_PSEUDOFUNCTION, 'functionCall' => [Internal\ExcelArrayPseudoFunctions::class, 'single'], 'argumentCount' => '1', 'passCellReference' => true, + 'passByReference' => [true], ], ]; diff --git a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php index e07d3a7d93..b416c91039 100644 --- a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php +++ b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -2,17 +2,68 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Internal; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Cell\Cell; +use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Cell\DataType; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class ExcelArrayPseudoFunctions { - public static function single(string $cellReference, ?Cell $cell): array + public static function single(string $cellReference, Cell $cell): array { - return [[$cellReference]]; + $worksheet = $cell->getWorksheet(); + + [$referenceWorksheetName, $referenceCellCoordinate] = Worksheet::extractSheetTitle($cellReference, true); + + $result = ($referenceWorksheetName === '') + ? $worksheet->getCell($referenceCellCoordinate)->getCalculatedValue() + : $worksheet->getParent() + ->getSheetByName($referenceWorksheetName) + ->getCell($referenceCellCoordinate)->getCalculatedValue(); + + return [[$result]]; } - public static function anchorArray(string $cellReference, ?Cell $cell): array + public static function anchorArray($cellReference, Cell $cell): array { - return [[$cellReference]]; + $coordinate = $cell->getCoordinate(); + $worksheet = $cell->getWorksheet(); + $value = $cell->getValue(); + + [$referenceWorksheetName, $referenceCellCoordinate] = Worksheet::extractSheetTitle($cellReference, true); + + $calcEngine = Calculation::getInstance($worksheet->getParent()); + $result = $calcEngine->calculateCellValue( + ($referenceWorksheetName === '') + ? $worksheet->getCell($referenceCellCoordinate) + : $worksheet->getParent() + ->getSheetByName($referenceWorksheetName) + ->getCell($referenceCellCoordinate) + ); + + // Set the result + $worksheet->fromArray( + $result, + null, + $coordinate, + true + ); + + [$col, $row] = Coordinate::indexesFromString($coordinate); + $row += count($result) - 1; + $col = Coordinate::stringFromColumnIndex($col + count($result[0]) - 1); + $formulaAttributes = ['t' => 'array', 'ref' => "{$coordinate}:{$col}{$row}"]; + + // fromArray() will reset the value for this cell with the calculation result + // as well as updating the spillage cells, + // so we need to restore this cell to its formula value, attributes, and datatype + $cell = $worksheet->getCell($coordinate); + $cell->setValueExplicit($value, DataType::TYPE_FORMULA); + $cell->setFormulaAttributes($formulaAttributes); + + $cell->updateInCollection(); + + return $result; } } From 54d49eddf61480485ad0708f5dc4d09d3af3d135 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Feb 2022 15:38:55 +0100 Subject: [PATCH 13/94] Unit tests for pseudo-functions --- .../Internal/ExcelArrayPseudoFunctions.php | 62 +++++++++----- src/PhpSpreadsheet/Worksheet/Worksheet.php | 5 +- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 14 +++- .../Calculation/InternalFunctionsTest.php | 81 +++++++++++++++++++ 4 files changed, 139 insertions(+), 23 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Calculation/InternalFunctionsTest.php diff --git a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php index b416c91039..77cfe8705e 100644 --- a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php +++ b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation\Internal; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\DataType; @@ -15,12 +16,13 @@ public static function single(string $cellReference, Cell $cell): array $worksheet = $cell->getWorksheet(); [$referenceWorksheetName, $referenceCellCoordinate] = Worksheet::extractSheetTitle($cellReference, true); - - $result = ($referenceWorksheetName === '') - ? $worksheet->getCell($referenceCellCoordinate)->getCalculatedValue() + $referenceCell = ($referenceWorksheetName === '') + ? $worksheet->getCell($referenceCellCoordinate) : $worksheet->getParent() ->getSheetByName($referenceWorksheetName) - ->getCell($referenceCellCoordinate)->getCalculatedValue(); + ->getCell($referenceCellCoordinate); + + $result = $referenceCell->getCalculatedValue(); return [[$result]]; } @@ -32,30 +34,50 @@ public static function anchorArray($cellReference, Cell $cell): array $value = $cell->getValue(); [$referenceWorksheetName, $referenceCellCoordinate] = Worksheet::extractSheetTitle($cellReference, true); + $referenceCell = ($referenceWorksheetName === '') + ? $worksheet->getCell($referenceCellCoordinate) + : $worksheet->getParent() + ->getSheetByName($referenceWorksheetName) + ->getCell($referenceCellCoordinate); + + // We should always use the sizing for the array formula range from the referenced cell formula + $referenceRange = null; + if ($referenceCell->isFormula() && $referenceCell->isArrayFormula()) { + $referenceRange = $referenceCell->arrayFormulaRange(); + } $calcEngine = Calculation::getInstance($worksheet->getParent()); - $result = $calcEngine->calculateCellValue( - ($referenceWorksheetName === '') - ? $worksheet->getCell($referenceCellCoordinate) - : $worksheet->getParent() - ->getSheetByName($referenceWorksheetName) - ->getCell($referenceCellCoordinate) - ); - - // Set the result - $worksheet->fromArray( - $result, - null, - $coordinate, - true - ); + $result = $calcEngine->calculateCellValue($referenceCell); + if (!is_array($result)) { + $result = [[$result]]; + } + + // Ensure that our array result dimensions match the specified array formula range dimensions, + // from the referenced cell, expanding or shrinking it as necessary. + if ($referenceRange !== null) { + $result = Functions::resizeMatrix( + $result, + ...Coordinate::rangeDimension($referenceRange ?? $coordinate) + ); + } + + // Set the result for our target cell (with spillage) + // But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved + // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? +// $worksheet->fromArray( +// $result, +// null, +// $coordinate, +// true +// ); + // Calculate the array formula range that we should set for our target, based on our target cell coordinate [$col, $row] = Coordinate::indexesFromString($coordinate); $row += count($result) - 1; $col = Coordinate::stringFromColumnIndex($col + count($result[0]) - 1); $formulaAttributes = ['t' => 'array', 'ref' => "{$coordinate}:{$col}{$row}"]; - // fromArray() will reset the value for this cell with the calculation result + // Using fromArray() would reset the value for this cell with the calculation result // as well as updating the spillage cells, // so we need to restore this cell to its formula value, attributes, and datatype $cell = $worksheet->getCell($coordinate); diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 27a5661b13..341d9bf16f 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -2900,12 +2900,13 @@ public function getHashCode() * @param string $range Range to extract title from * @param bool $returnRange Return range? (see example) * - * @return mixed + * @return string|string[] */ public static function extractSheetTitle($range, $returnRange = false) { // Sheet title included? - if (($sep = strrpos($range, '!')) === false) { + $sep = strrpos($range, '!'); + if ($sep === false) { return $returnRange ? ['', $range] : ''; } diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 499af11fcb..faa006d4d9 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1245,6 +1245,16 @@ private function writeCellError(XMLWriter $objWriter, string $mappedType, string $objWriter->writeElement('v', $cellIsFormula ? $formulaerr : $cellValue); } + private const CM_SPILLAGE_ARRAY_FUNCTIONS = '/\b(' . + 'anchorarray|' . + 'filter|' . + 'randarray|' . + 'sequence|' . + 'sort|' . + 'sortby|' . + 'unique' . + ')\(/ui'; + private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $cell): void { $calculatedValue = $this->getParentWriter()->getPreCalculateFormulas() @@ -1265,7 +1275,9 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $attributes = $cell->getFormulaAttributes(); if (($attributes['t'] ?? null) === 'array') { - $objWriter->writeAttribute('cm', '1'); + if (preg_match(self::CM_SPILLAGE_ARRAY_FUNCTIONS, $cellValue) === 1) { + $objWriter->writeAttribute('cm', '1'); + } $objWriter->startElement('f'); $objWriter->writeAttribute('t', 'array'); diff --git a/tests/PhpSpreadsheetTests/Calculation/InternalFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/InternalFunctionsTest.php new file mode 100644 index 0000000000..1d59a7a554 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Calculation/InternalFunctionsTest.php @@ -0,0 +1,81 @@ +getActiveSheet(); + $sheet1->setTitle('SheetOne'); // no space in sheet title + $sheet2 = $spreadsheet->createSheet(); + $sheet2->setTitle('Sheet Two'); // space in sheet title + + $sheet1->setCellValue('C3', '=SEQUENCE(3,3,-4)', true, 'C3:E5'); + $sheet2->setCellValue('C3', '=SEQUENCE(3,3, 9, -1)', true, 'C3:E5'); + + $sheet1->setCellValue('A8', "=ANCHORARRAY({$reference})", true, $range); + + $result1 = $sheet1->getCell('A8')->getCalculatedValue(true, true); + self::assertSame($expectedResult, $result1); + $attributes1 = $sheet1->getCell('A8')->getFormulaAttributes(); + self::assertSame(['t' => 'array', 'ref' => $range], $attributes1); + } + + public function anchorArrayDataProvider(): array + { + return [ + [ + 'C3', + 'A8:C10', + [[-4, -3, -2], [-1, 0, 1], [2, 3, 4]], + ], + [ + "'Sheet Two'!C3", + 'A8:C10', + [[9, 8, 7], [6, 5, 4], [3, 2, 1]], + ], + ]; + } + + /** + * @dataProvider singleDataProvider + */ + public function testSingleArrayFormula(string $reference, array $expectedResult): void + { + $spreadsheet = new Spreadsheet(); + $sheet1 = $spreadsheet->getActiveSheet(); + $sheet1->setTitle('SheetOne'); // no space in sheet title + $sheet2 = $spreadsheet->createSheet(); + $sheet2->setTitle('Sheet Two'); // space in sheet title + + $sheet1->setCellValue('C3', '=SEQUENCE(3,3,-4)', true, 'C3:E5'); + $sheet2->setCellValue('C3', '=SEQUENCE(3,3, 9, -1)', true, 'C3:E5'); + + $sheet1->setCellValue('A8', "=SINGLE({$reference})"); + + $result1 = $sheet1->getCell('A8')->getCalculatedValue(true, true); + self::assertSame($expectedResult, $result1); + } + + public function singleDataProvider(): array + { + return [ + [ + 'C3', + [[-4]], + ], + [ + "'Sheet Two'!C3", + [[9]], + ], + ]; + } +} From 12ddc9ecfbff5eee056f1dba214145bb1ed5bf95 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Feb 2022 15:40:06 +0100 Subject: [PATCH 14/94] General fixes for array functions with partial-range --- .../Calculation/Calculation.php | 1 - src/PhpSpreadsheet/Cell/Cell.php | 32 +++++++++++-------- 2 files changed, 19 insertions(+), 14 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 61e98390c6..363ee24aaf 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -3352,7 +3352,6 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true) } catch (\Exception $e) { $cellAddress = array_pop($this->cellStack); $this->spreadsheet->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); - throw new Exception($e->getMessage()); } diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 13b42b8935..601dc91971 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -302,7 +302,7 @@ public function setValueExplicit($value, $dataType, bool $isArrayFormula = false * * @return mixed */ - public function getCalculatedValue($resetLog = true) + public function getCalculatedValue($resetLog = true, bool $asArray = false) { if ($this->dataType == DataType::TYPE_FORMULA) { try { @@ -313,6 +313,7 @@ public function getCalculatedValue($resetLog = true) $formulaAttributes = $this->formulaAttributes; $index = $this->getWorksheet()->getParent()->getActiveSheetIndex(); $selected = $this->getWorksheet()->getSelectedCells(); + $result = Calculation::getInstance( $this->getWorksheet()->getParent() )->calculateCellValue($this, $resetLog); @@ -326,17 +327,19 @@ public function getCalculatedValue($resetLog = true) // Here is where we should set all cellRange values from the result (but within the range limit) // Ensure that our array result dimensions match the specified array formula range dimensions, // expanding or shrinking it as necessary. - // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? - $worksheet->fromArray( - Functions::resizeMatrix( - $result, - ...Coordinate::rangeDimension($this->formulaAttributes['ref'] ?? $coordinate) - ), - null, - $coordinate, - true + $result = Functions::resizeMatrix( + $result, + ...Coordinate::rangeDimension($this->formulaAttributes['ref'] ?? $coordinate) ); - // fromArray() will reset the value for this cell with the calculation result + // But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved + // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? +// $worksheet->fromArray( +// $result, +// null, +// $coordinate, +// true +// ); + // Using fromArray() would reset the value for this cell with the calculation result // as well as updating the spillage cells, // so we need to restore this cell to its formula value, attributes, and datatype $worksheet->getCell($coordinate); @@ -347,8 +350,10 @@ public function getCalculatedValue($resetLog = true) } // Now we just extract the top-left value from the array to get the result for this specific cell - while (is_array($result)) { - $result = array_shift($result); + if ($asArray === false) { + while (is_array($result)) { + $result = array_shift($result); + } } } @@ -361,6 +366,7 @@ public function getCalculatedValue($resetLog = true) return \PhpOffice\PhpSpreadsheet\Calculation\Functions::NAME(); } +// var_dump($ex); throw new \PhpOffice\PhpSpreadsheet\Calculation\Exception( $this->getWorksheet()->getTitle() . '!' . $this->getCoordinate() . ' -> ' . $ex->getMessage() ); From 7d84fafbb0039fbfe31ae99a29c3eff001612962 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Feb 2022 15:40:26 +0100 Subject: [PATCH 15/94] Updates to function lists --- docs/references/function-list-by-category.md | 18 ++++++++++++++++-- docs/references/function-list-by-name.md | 18 ++++++++++++++++-- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/docs/references/function-list-by-category.md b/docs/references/function-list-by-category.md index 0ce7340e61..97994d971b 100644 --- a/docs/references/function-list-by-category.md +++ b/docs/references/function-list-by-category.md @@ -35,6 +35,7 @@ Excel Function | PhpSpreadsheet Function -------------------------|-------------------------------------- DATE | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Date::fromYMD DATEDIF | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Difference::interval +DATESTRING | **Not yet Implemented** DATEVALUE | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue::fromString DAY | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateParts::day DAYS | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Days::between @@ -49,6 +50,9 @@ NETWORKDAYS | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\N NETWORKDAYS.INTL | **Not yet Implemented** NOW | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Current::now SECOND | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeParts::second +THAIDAYOFWEEK | **Not yet Implemented** +THAIMONTHOFYEAR | **Not yet Implemented** +THAIYEAR | **Not yet Implemented** TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Time::fromHMS TIMEVALUE | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeValue::fromString TODAY | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Current::today @@ -309,15 +313,17 @@ PRODUCT | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Operat QUOTIENT | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Operations::quotient RADIANS | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Angle::toRadians RAND | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Random::rand -RANDARRAY | **Not yet Implemented** +RANDARRAY | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Random::randArray RANDBETWEEN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Random::randBetween ROMAN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Roman::evaluate ROUND | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Round::round +ROUNDBAHTDOWN | **Not yet Implemented** +ROUNDBAHTUP | **Not yet Implemented** ROUNDDOWN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Round::down ROUNDUP | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Round::up SEC | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Secant::sec SECH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Secant::sech -SEQUENCE | **Not yet Implemented** +SEQUENCE | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\MatrixFunctions::sequence SERIESSUM | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\SeriesSum::evaluate SIGN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Sign::evaluate SIN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Sine::sin @@ -496,6 +502,7 @@ ZTEST | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Dis Excel Function | PhpSpreadsheet Function -------------------------|-------------------------------------- +ARRAYTOTEXT | **Not yet Implemented** ASC | **Not yet Implemented** BAHTTEXT | **Not yet Implemented** CHAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData\CharacterConvert::character @@ -509,6 +516,7 @@ EXACT | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Text:: FIND | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Search::sensitive FINDB | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Search::sensitive FIXED | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Format::FIXEDFORMAT +ISTHAIDIGIT | **Not yet Implemented** JIS | **Not yet Implemented** LEFT | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Extract::left LEFTB | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Extract::left @@ -517,6 +525,7 @@ LENB | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Text:: LOWER | \PhpOffice\PhpSpreadsheet\Calculation\TextData\CaseConvert::lower MID | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Extract::mid MIDB | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Extract::mid +NUMBERSTRING | **Not yet Implemented** NUMBERVALUE | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Format::NUMBERVALUE PHONETIC | **Not yet Implemented** PROPER | \PhpOffice\PhpSpreadsheet\Calculation\TextData\CaseConvert::proper @@ -531,11 +540,16 @@ SUBSTITUTE | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Replac T | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Text::test TEXT | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Format::TEXTFORMAT TEXTJOIN | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Concatenate::TEXTJOIN +THAIDIGIT | **Not yet Implemented** +THAINUMSOUND | **Not yet Implemented** +THAINUMSTRING | **Not yet Implemented** +THAISTRINGLENGTH | **Not yet Implemented** TRIM | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Trim::spaces UNICHAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData\CharacterConvert::character UNICODE | \PhpOffice\PhpSpreadsheet\Calculation\TextData\CharacterConvert::code UPPER | \PhpOffice\PhpSpreadsheet\Calculation\TextData\CaseConvert::upper VALUE | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Format::VALUE +VALUETOTEXT | **Not yet Implemented** ## CATEGORY_WEB diff --git a/docs/references/function-list-by-name.md b/docs/references/function-list-by-name.md index c5f733ea84..2a01075613 100644 --- a/docs/references/function-list-by-name.md +++ b/docs/references/function-list-by-name.md @@ -18,6 +18,7 @@ AMORLINC | CATEGORY_FINANCIAL | \PhpOffice\PhpSpread AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical\Operations::logicalAnd ARABIC | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Arabic::evaluate AREAS | CATEGORY_LOOKUP_AND_REFERENCE | **Not yet Implemented** +ARRAYTOTEXT | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** ASC | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** ASIN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Sine::asin ASINH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Sine::asinh @@ -126,6 +127,7 @@ Excel Function | Category | PhpSpreadsheet Funct -------------------------|--------------------------------|-------------------------------------- DATE | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Date::fromYMD DATEDIF | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Difference::interval +DATESTRING | CATEGORY_DATE_AND_TIME | **Not yet Implemented** DATEVALUE | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue::fromString DAVERAGE | CATEGORY_DATABASE | \PhpOffice\PhpSpreadsheet\Calculation\Database\DAverage::evaluate DAY | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateParts::day @@ -302,6 +304,7 @@ ISOWEEKNUM | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpread ISPMT | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial\CashFlow\Constant\Periodic\Interest::schedulePayment ISREF | CATEGORY_INFORMATION | **Not yet Implemented** ISTEXT | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::isText +ISTHAIDIGIT | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** ## J @@ -390,6 +393,7 @@ NOT | CATEGORY_LOGICAL | \PhpOffice\PhpSpread NOW | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Current::now NPER | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial\CashFlow\Constant\Periodic::periods NPV | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial\CashFlow\Variable\Periodic::presentValue +NUMBERSTRING | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** NUMBERVALUE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Format::NUMBERVALUE ## O @@ -452,7 +456,7 @@ Excel Function | Category | PhpSpreadsheet Funct -------------------------|--------------------------------|-------------------------------------- RADIANS | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Angle::toRadians RAND | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Random::rand -RANDARRAY | CATEGORY_MATH_AND_TRIG | **Not yet Implemented** +RANDARRAY | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Random::randArray RANDBETWEEN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Random::randBetween RANK | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Percentiles::RANK RANK.AVG | CATEGORY_STATISTICAL | **Not yet Implemented** @@ -466,6 +470,8 @@ RIGHT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpread RIGHTB | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Extract::right ROMAN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Roman::evaluate ROUND | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Round::round +ROUNDBAHTDOWN | CATEGORY_MATH_AND_TRIG | **Not yet Implemented** +ROUNDBAHTUP | CATEGORY_MATH_AND_TRIG | **Not yet Implemented** ROUNDDOWN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Round::down ROUNDUP | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Round::up ROW | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef\RowColumnInformation::ROW @@ -483,7 +489,7 @@ SEARCHB | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpread SEC | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Secant::sec SECH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\Trig\Secant::sech SECOND | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeParts::second -SEQUENCE | CATEGORY_MATH_AND_TRIG | **Not yet Implemented** +SEQUENCE | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\MatrixFunctions::sequence SERIESSUM | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig\SeriesSum::evaluate SHEET | CATEGORY_INFORMATION | **Not yet Implemented** SHEETS | CATEGORY_INFORMATION | **Not yet Implemented** @@ -539,6 +545,13 @@ TBILLYIELD | CATEGORY_FINANCIAL | \PhpOffice\PhpSpread TDIST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StudentT::distribution TEXT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Format::TEXTFORMAT TEXTJOIN | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Concatenate::TEXTJOIN +THAIDAYOFWEEK | CATEGORY_DATE_AND_TIME | **Not yet Implemented** +THAIDIGIT | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** +THAIMONTHOFYEAR | CATEGORY_DATE_AND_TIME | **Not yet Implemented** +THAINUMSOUND | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** +THAINUMSTRING | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** +THAISTRINGLENGTH | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** +THAIYEAR | CATEGORY_DATE_AND_TIME | **Not yet Implemented** TIME | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Time::fromHMS TIMEVALUE | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeValue::fromString TINV | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StudentT::inverse @@ -567,6 +580,7 @@ USDOLLAR | CATEGORY_FINANCIAL | \PhpOffice\PhpSpread Excel Function | Category | PhpSpreadsheet Function -------------------------|--------------------------------|-------------------------------------- VALUE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData\Format::VALUE +VALUETOTEXT | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** VAR | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances::VAR VAR.P | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances::VARP VAR.S | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances::VAR From abf4f9c598eb2c889000f7d4fabd1325ac5ce463 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Feb 2022 17:00:56 +0100 Subject: [PATCH 16/94] regenerate phpstan baseline (it is smaller, honest) --- phpstan-baseline.neon | 247 ++---------------- .../Calculation/Calculation.php | 1 + .../Internal/ExcelArrayPseudoFunctions.php | 12 +- 3 files changed, 32 insertions(+), 228 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 98e8c3373a..e2ec12b0f8 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -101,7 +101,7 @@ parameters: path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 6 path: src/PhpSpreadsheet/Calculation/Calculation.php @@ -175,21 +175,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Parameter \\#1 \\$cellRange of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:extractAllCellReferencesInRange\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Parameter \\#1 \\$column of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getHighestDataRow\\(\\) expects string\\|null, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Parameter \\#1 \\$definedName of static method PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\:\\:resolveName\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Parameter \\#1 \\$formula of method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_calculateFormulaValue\\(\\) expects string, mixed given\\.$#" count: 1 @@ -225,11 +210,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Parameter \\#1 \\$str of function trim expects string, mixed given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Parameter \\#1 \\$str of function trim expects string, null given\\.$#" count: 2 @@ -245,21 +225,11 @@ parameters: count: 2 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Parameter \\#1 \\$string of function strlen expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Parameter \\#1 \\$textValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:strCaseReverse\\(\\) expects string, string\\|null given\\.$#" count: 2 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Parameter \\#1 \\$worksheetName of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getSheetByName\\(\\) expects string, mixed given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Parameter \\#2 \\$str2 of method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:strcmpAllowNull\\(\\) expects string\\|null, mixed given\\.$#" count: 4 @@ -315,11 +285,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Part \\$val \\(mixed\\) of encapsed string cannot be cast to string\\.$#" - count: 2 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$branchPruningEnabled has no type specified\\.$#" count: 1 @@ -1080,6 +1045,16 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Functions.php + - + message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#" + count: 2 + path: src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php + + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 2 + path: src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php + - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Internal\\\\MakeMatrix\\:\\:make\\(\\) has parameter \\$args with no type specified\\.$#" count: 1 @@ -1256,12 +1231,7 @@ parameters: path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php - - message: "#^Cannot use array destructuring on mixed\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php - - - - message: "#^Parameter \\#1 \\$str of function trim expects string, mixed given\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php @@ -1331,7 +1301,7 @@ parameters: path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php @@ -1376,23 +1346,13 @@ parameters: path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php - - message: "#^Parameter \\#1 \\$str of function trim expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php - - - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 2 path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - message: "#^Parameter \\#1 \\$columnAddress of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:columnIndexFromString\\(\\) expects string, string\\|null given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - - - - message: "#^Parameter \\#1 \\$haystack of function strpos expects string, mixed given\\.$#" - count: 2 + count: 4 path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - @@ -1405,16 +1365,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - - - message: "#^Parameter \\#2 \\$str of function explode expects string, mixed given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - - - - message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - - message: "#^Cannot access offset \\(int\\|string\\) on mixed\\.$#" count: 1 @@ -2091,22 +2041,12 @@ parameters: path: src/PhpSpreadsheet/Cell/Coordinate.php - - message: "#^Cannot use array destructuring on array\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Coordinate.php - - - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 2 path: src/PhpSpreadsheet/Cell/Coordinate.php - - message: "#^Parameter \\#1 \\$cellAddress of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:absoluteCoordinate\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Coordinate.php - - - - message: "#^Parameter \\#1 \\$cellAddress of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:coordinateFromString\\(\\) expects string, mixed given\\.$#" + message: "#^Cannot use array destructuring on array\\|null\\.$#" count: 1 path: src/PhpSpreadsheet/Cell/Coordinate.php @@ -2115,11 +2055,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Coordinate.php - - - message: "#^Parameter \\#1 \\$str of function strtoupper expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Coordinate.php - - message: "#^Parameter \\#2 \\$str of function explode expects string, array\\\\|string given\\.$#" count: 1 @@ -2431,7 +2366,7 @@ parameters: path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Chart/DataSeriesValues.php @@ -2455,11 +2390,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:\\$dataSource \\(string\\) does not accept string\\|null\\.$#" count: 1 @@ -3176,7 +3106,7 @@ parameters: path: src/PhpSpreadsheet/Reader/BaseReader.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Gnumeric.php @@ -3185,11 +3115,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Reader/Gnumeric.php - - - message: "#^Parameter \\#1 \\$str of function trim expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Gnumeric.php - - message: "#^Offset 'percentage' does not exist on SimpleXMLElement\\|null\\.$#" count: 1 @@ -3286,12 +3211,7 @@ parameters: path: src/PhpSpreadsheet/Reader/Ods.php - - message: "#^Cannot use array destructuring on mixed\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods/DefinedNames.php - - - - message: "#^Parameter \\#1 \\$worksheetName of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getSheetByName\\(\\) expects string, mixed given\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Ods/DefinedNames.php @@ -3460,21 +3380,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xls.php - - - message: "#^Cannot access offset 0 on mixed\\.$#" - count: 4 - path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^Cannot access offset 1 on array\\|false\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Xls.php - - - message: "#^Cannot access offset 1 on mixed\\.$#" - count: 7 - path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^If condition is always true\\.$#" count: 1 @@ -3515,11 +3425,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xls.php - - - message: "#^Parameter \\#1 \\$haystack of function strpos expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^Parameter \\#1 \\$operator of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataValidation\\:\\:setOperator\\(\\) expects string, int\\|string given\\.$#" count: 1 @@ -3535,26 +3440,16 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xls.php - - - message: "#^Parameter \\#1 \\$str of function trim expects string, mixed given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^Parameter \\#1 \\$type of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataValidation\\:\\:setType\\(\\) expects string, int\\|string given\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, mixed given\\.$#" + message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\\\|string given\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Xls.php - - - message: "#^Parameter \\#1 \\$worksheetName of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getSheetByName\\(\\) expects string, mixed given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^Parameter \\#2 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter\\:\\:readCell\\(\\) expects int, string given\\.$#" count: 1 @@ -3575,11 +3470,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xls.php - - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, mixed given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^Parameter \\#4 \\$endRow of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Xls\\:\\:getDistanceY\\(\\) expects int, string given\\.$#" count: 1 @@ -3705,11 +3595,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Cannot access offset 0 on mixed\\.$#" - count: 5 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Cannot access property \\$r on SimpleXMLElement\\|null\\.$#" count: 2 @@ -3766,7 +3651,7 @@ parameters: path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 2 path: src/PhpSpreadsheet/Reader/Xlsx.php @@ -3950,11 +3835,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Parameter \\#1 \\$haystack of function strpos expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Parameter \\#1 \\$sizeInCm of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:centimeterSizeToPixels\\(\\) expects int, string given\\.$#" count: 1 @@ -3965,26 +3845,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Parameter \\#1 \\$str of function trim expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$worksheetName of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getSheetByName\\(\\) expects string, array\\|string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, int\\|string given\\.$#" count: 2 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, mixed given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:readAutoFilter\\(\\) has parameter \\$autoFilterRange with no type specified\\.$#" count: 1 @@ -5836,7 +5701,7 @@ parameters: path: src/PhpSpreadsheet/Worksheet/AutoFilter.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Worksheet/AutoFilter.php @@ -5850,16 +5715,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Worksheet/AutoFilter.php - - - message: "#^Parameter \\#1 \\$haystack of function strpos expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/AutoFilter.php - - - - message: "#^Parameter \\#1 \\$range of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:rangeBoundaries\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/AutoFilter.php - - message: "#^Parameter \\#1 \\$string of function strlen expects string, mixed given\\.$#" count: 1 @@ -5880,11 +5735,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Worksheet/AutoFilter.php - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:\\$range \\(string\\) does not accept mixed\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/AutoFilter.php - - message: "#^Argument of an invalid type mixed supplied for foreach, only iterables are supported\\.$#" count: 1 @@ -5995,16 +5845,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Worksheet/SheetView.php - - - message: "#^Cannot access offset 0 on mixed\\.$#" - count: 2 - path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - - - message: "#^Cannot access offset 1 on mixed\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - message: "#^Cannot call method getCalculatedValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#" count: 1 @@ -6080,16 +5920,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - - message: "#^Parameter \\#1 \\$str of function strtoupper expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - - - message: "#^Parameter \\#1 \\$worksheetName of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getSheetByName\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - message: "#^Parameter \\#2 \\$format of static method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\:\\:toFormattedString\\(\\) expects string, string\\|null given\\.$#" count: 2 @@ -6656,7 +6486,7 @@ parameters: path: src/PhpSpreadsheet/Writer/Xls/Font.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 2 path: src/PhpSpreadsheet/Writer/Xls/Parser.php @@ -6680,11 +6510,6 @@ parameters: count: 7 path: src/PhpSpreadsheet/Writer/Xls/Parser.php - - - message: "#^Parameter \\#1 \\$cell of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Parser\\:\\:cellToPackedRowcol\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xls/Parser.php - - message: "#^Parameter \\#1 \\$cell of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Parser\\:\\:convertRef2d\\(\\) expects string, mixed given\\.$#" count: 1 @@ -6700,11 +6525,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Writer/Xls/Parser.php - - - message: "#^Parameter \\#1 \\$ext_ref of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Parser\\:\\:getRefIndex\\(\\) expects string, mixed given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xls/Parser.php - - message: "#^Parameter \\#1 \\$haystack of function substr_count expects string, mixed given\\.$#" count: 1 @@ -6740,11 +6560,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Writer/Xls/Parser.php - - - message: "#^Parameter \\#2 \\$str of function explode expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xls/Parser.php - - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, mixed given\\.$#" count: 20 @@ -7161,7 +6976,7 @@ parameters: path: src/PhpSpreadsheet/Writer/Xlsx/Comments.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php @@ -7396,7 +7211,7 @@ parameters: path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - message: "#^Cannot use array destructuring on mixed\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -8665,16 +8480,6 @@ parameters: count: 1 path: tests/PhpSpreadsheetTests/Worksheet/RowCellIterator2Test.php - - - message: "#^Cannot access offset 0 on mixed\\.$#" - count: 1 - path: tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php - - - - message: "#^Cannot access offset 1 on mixed\\.$#" - count: 1 - path: tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheetTests\\\\Writer\\\\Html\\\\CallbackTest\\:\\:yellowBody\\(\\) should return string but returns string\\|null\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 363ee24aaf..61e98390c6 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -3352,6 +3352,7 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true) } catch (\Exception $e) { $cellAddress = array_pop($this->cellStack); $this->spreadsheet->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); + throw new Exception($e->getMessage()); } diff --git a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php index 77cfe8705e..bc3db6bba5 100644 --- a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php +++ b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -27,7 +27,7 @@ public static function single(string $cellReference, Cell $cell): array return [[$result]]; } - public static function anchorArray($cellReference, Cell $cell): array + public static function anchorArray(string $cellReference, Cell $cell): array { $coordinate = $cell->getCoordinate(); $worksheet = $cell->getWorksheet(); @@ -54,12 +54,10 @@ public static function anchorArray($cellReference, Cell $cell): array // Ensure that our array result dimensions match the specified array formula range dimensions, // from the referenced cell, expanding or shrinking it as necessary. - if ($referenceRange !== null) { - $result = Functions::resizeMatrix( - $result, - ...Coordinate::rangeDimension($referenceRange ?? $coordinate) - ); - } + $result = Functions::resizeMatrix( + $result, + ...Coordinate::rangeDimension($referenceRange ?? $coordinate) + ); // Set the result for our target cell (with spillage) // But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved From c84e3344d96dc5eafb8baf3f93f07aa3edaf0695 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Feb 2022 22:37:18 +0100 Subject: [PATCH 17/94] Update documentation with details of array formula handling, and the Spill Operator --- docs/topics/calculation-engine.md | 27 +++- .../12-CalculationEngine-Array-Formula-2.png | Bin 0 -> 35123 bytes .../12-CalculationEngine-Array-Formula-3.png | Bin 0 -> 19300 bytes .../12-CalculationEngine-Array-Formula.png | Bin 0 -> 20934 bytes .../12-CalculationEngine-Basic-Formula-2.png | Bin 0 -> 20314 bytes .../12-CalculationEngine-Basic-Formula.png | Bin 0 -> 17581 bytes ...2-CalculationEngine-Spillage-Formula-2.png | Bin 0 -> 11750 bytes .../12-CalculationEngine-Spillage-Formula.png | Bin 0 -> 11564 bytes ...12-CalculationEngine-Spillage-Operator.png | Bin 0 -> 9381 bytes docs/topics/recipes.md | 126 +++++++++++++++++- 10 files changed, 150 insertions(+), 3 deletions(-) create mode 100644 docs/topics/images/12-CalculationEngine-Array-Formula-2.png create mode 100644 docs/topics/images/12-CalculationEngine-Array-Formula-3.png create mode 100644 docs/topics/images/12-CalculationEngine-Array-Formula.png create mode 100644 docs/topics/images/12-CalculationEngine-Basic-Formula-2.png create mode 100644 docs/topics/images/12-CalculationEngine-Basic-Formula.png create mode 100644 docs/topics/images/12-CalculationEngine-Spillage-Formula-2.png create mode 100644 docs/topics/images/12-CalculationEngine-Spillage-Formula.png create mode 100644 docs/topics/images/12-CalculationEngine-Spillage-Operator.png diff --git a/docs/topics/calculation-engine.md b/docs/topics/calculation-engine.md index 4fd300e82e..a228b3115a 100644 --- a/docs/topics/calculation-engine.md +++ b/docs/topics/calculation-engine.md @@ -10,6 +10,8 @@ formula calculation capabilities. A cell can be of a value type which can be evaluated). For example, the formula `=SUM(A1:A10)` evaluates to the sum of values in A1, A2, ..., A10. +Calling `getValue()` on a cell that contains a formula will return the formula itself. + To calculate a formula, you can call the cell containing the formula’s method `getCalculatedValue()`, for example: @@ -22,6 +24,28 @@ with PhpSpreadsheet, it evaluates to the value "64": ![09-command-line-calculation.png](./images/09-command-line-calculation.png) +Calling `getCalculatedValue()` on a cell that doesn't contain a formula will simply return the value of that cell; but if the cell does contain a formula, then PhpSpreadsheet will evaluate that formula to calculate the result. + +There are a few useful mehods to help identify whether a cell contains a formula or a simple value; and if a formula, to provide further information about it: + +```php +$spreadsheet->getActiveSheet()->getCell('E11')->isFormula(); +``` +will return a boolean true/false, telling you whether that cell contains a formula or not, so you can determine if a call to `getCalculatedVaue()` will need to perform an evaluation. + +A formula can be either a simple formula, or an array formula; and another method will identify which it is: +```php +$spreadsheet->getActiveSheet()->getCell('E11')->isArrayFormula(); +``` +Finally, an array formula might result in a single cell result, or a result that can spill over into a range of cells; so for array formulae the following method also exists: +```php +$spreadsheet->getActiveSheet()->getCell('E11')->arrayFormulaRange(); +``` +which returns a string containing a cell reference (e.g. `E11`) or a cell range reference (e.g. `E11:G13`). + + +### Adjustments to formulae when Inserting/Deleting Columns/Rows + Another nice feature of PhpSpreadsheet's formula parser, is that it can automatically adjust a formula when inserting/removing rows/columns. Here's an example: @@ -149,8 +173,7 @@ number of seconds from the PHP/Unix base date. The PHP/Unix base date (0) is 00:00 UST on 1st January 1970. This value can be positive or negative: so a value of -3600 would be 23:00 hrs on 31st December 1969; while a value of +3600 would be 01:00 hrs on 1st January 1970. This -gives PHP a date range of between 14th December 1901 and 19th January -2038. +gives 32-bit PHP a date range of between 14th December 1901 and 19th January 2038. #### PHP `DateTime` Objects diff --git a/docs/topics/images/12-CalculationEngine-Array-Formula-2.png b/docs/topics/images/12-CalculationEngine-Array-Formula-2.png new file mode 100644 index 0000000000000000000000000000000000000000..45fc3ce5e8f1254e20971fbe1641fa2f0b72f363 GIT binary patch literal 35123 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

NUGAh>fPf~ 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 literal 0 HcmV?d00001 diff --git a/docs/topics/images/12-CalculationEngine-Array-Formula.png b/docs/topics/images/12-CalculationEngine-Array-Formula.png new file mode 100644 index 0000000000000000000000000000000000000000..77987b27070b0e709f77cb455277d7885cd1f57c GIT binary patch literal 20934 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 (c$FEFcJv**$!G(mTi3V2!pN|&_RMoBu&@1 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 literal 0 HcmV?d00001 diff --git a/docs/topics/images/12-CalculationEngine-Spillage-Formula-2.png b/docs/topics/images/12-CalculationEngine-Spillage-Formula-2.png new file mode 100644 index 0000000000000000000000000000000000000000..8fc397d1d6dbc56b29fad3ff7d9afd4e71330307 GIT binary patch literal 11750 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 PA%L8WvUH84Y0&=xym|29 literal 0 HcmV?d00001 diff --git a/docs/topics/images/12-CalculationEngine-Spillage-Formula.png b/docs/topics/images/12-CalculationEngine-Spillage-Formula.png new file mode 100644 index 0000000000000000000000000000000000000000..4189cb47fae559be478be25fd06a62bbdf257e54 GIT binary patch literal 11564 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 %8Sc)Yr9rV(qn@^R&IA~y&HOl- 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 literal 0 HcmV?d00001 diff --git a/docs/topics/images/12-CalculationEngine-Spillage-Operator.png b/docs/topics/images/12-CalculationEngine-Spillage-Operator.png new file mode 100644 index 0000000000000000000000000000000000000000..c096875e949b2cc4f95b35be3cdc30f0f0fef039 GIT binary patch literal 9381 zcma)?1yozl+U|oEheDx9v9=UVDehj}EkFVUD=r0!yB8~zqQ$L1vEs$uEkJN9?iyTg zdd`1+_q*$^d+xW^B-wk`WY4>2Wa|Qq?rvAQA$j1f_0D#wm z^6w?I+zk&F9c`aYr$0G9XHcM%W)O!cPzPn#KGKoxB>V}~;SqQnJ5$K)s$U!p$=-g! zuFanOx<>{3xwd`>#_F?jXYGo?@b@~hU+I%&I;g}qC|QKY40m|oj#@{Ucq3Ds*yzMh zh~IbIn=hrF?;j2w?jPKTH|cy5phkHY#4z7zGDi@f^3%E9zJg3&&y4}nCG?9FQJ<%^;YJDX#32}Of=t;9PQcp-t;xv z8yLO+#QR_}7ZQt+wCe$#7EZTA{Uvk(b8qjvAVSe(F~62S3ppc>pFVMmi9Jq195$3= z<vDSo39QMi z$(1CG4`<&p;jL#Hml32Jgu-fKqM{FH6RP-xgov=UoXXT;lLFUISbxNS|0WkViPweH z-g%pttcEkz+Al4fKHP5U-uBY^b&&xo@g#BAKkmYd29wwkq=VZGXOb`yWODw27Vhp>UEw718)PCWhLY@Q zrwchbr>}k=M#gLQEC45l50KC@APg0xgrzcZ*wdF(|>aw~SIV z6;meTo>Aq30nSU~R_CQ!M*_psJmv?k5|#lX$bfIMdoJW(AQ#`@c)nukR-$Odc8Df_ zHeH(T^20@)L*oJORI(_gsOZJat9|!1w-yBT6qc)y>y`hY_FRK8Dbx+{q&YvN_^`;a z9@B0A3yxZqYojhUkStC8XK^v)@`Yl2e!*omh;`HzUWU`x=V|}J&7^*jb$dF9u#Auv zVe7Cg4ICbhsnFh0d(x;}w%()mj@JG;F`;uzC>2=}?o9urP4gCFr=Ss+hPS z(MkpccY)1^lH0+rsU6hW8+)9MVm+~!s($%)OJ-7yT9pne{OaGqe_gVuW@CR%I)@J4`+%!8sY;HpvLae(tQ=S z%1=A#tqis%=4|EpWsH-hL$5>xX(6$h?z_i0ld z+W11AG1V-O`|Z>*yL^!oUNrf5?4{YNS#Cj`gwKPsh&=ZzWRZ(^WzTU;^fnYf`b-F# z6sBkY!N+6=pXGKvV&0)O9oY97A5Q_|H=DJG^}K9uY`(EGLzDNi>qyW8tJ?l|7~l45 zEUW|m#ZYSbFU;GSy(WrDEXcTeAqqLp=4i!n(sRo_lD1CiD?86VKQs=_*~M$zULYC z-$*Lq0<`lJ3K=?2z@1?UAG&h~GLI;IGsw;zfB({z_n!$!*Ymm=#{=eL*(6+UQi}3i zA7x3*u%IV?WME(z6{)is%aJ~Dj$|MM+AcrPvg(wXMehu5$6xBI*C&K`eNRrlnqPkC z(J6WQO*dZ2Hb8W*+~>f?w!Z$Fqt2^45g0R3(CWNJV4b~vv!luU0(Jb`6NjN&}q)?3p#W+m$jq3_F>kPzu8k2qzZ?~L-L1*AAg z#Gzku%lihNjTVf*`6NM_6skjc=6Bp7y}Lnn15it;DPTWI0)0$o zy(WUAR6O|dMuGDrkxl1Q5Gg4sht_*usOozqldtXVt(74RiibwH>#|}uV;2XbzY_VD z$c>y=RntA)dZH-clHKZ=445v1K_}=}h-x$*xIwu(<783k#kdCRjS+=dvN@+)+LOrs z!Z*A81{y^!-&OBngvV@?^v({lrvJKF?wUH8eCj9_D*aPEJBY!)Bfw?B9N1vz-|$ z9+v)L4@%j#Lu3tRp~ZL!M*f~=aOgEqK`C;@`nqigb`DNK5}35%BTStcZqWbimRaS53Z zZ6$ulAMfg$@eZd>S^j#;K`UTjE7)W9q-^*TpJ;jlK&!OYpCrEEehCMXhXwX)Yw#blHv6rW1e=NYh= z-8d+f5m>e6W1SQjGey?=ax=>bRnK4&rJw%6T3N{1U{hh6dMjGj#Yl!tYYMIz$Ql(X zSd>n>J1-Yr3WoeHeBWFilw$HAEae^i&I48KfxG$&LBcIu1IK#DpGemEi5P_ttK-XM z$O*{ix$TLc#)3S~m`mR=1cxglwEZRAh*IW?}Tx@Axf`x+ z%E~cpdX>Q-|-L@)Xi6Xhkw+#V?C@Q8}G7)!lshCCVVQ)BFBE~tl(NTd*rNEUKA z@wrbD9E3XVR=vtp3c^!#^H~+)ulOi9xNW4Lqe*{b8tZwJp?M%^x?GzeID<%x+fH-w zAfYx9^nOoHVrhP`Q}qly2bXru)5>0m`2C}%1|gT_7S?_~iSoeR0qH28EMpC3`!>dW zG({5G|H*zhO+eGzR-8%2}#3uCyQqv^_rYE49-NY0$7e0oEz~NDFgx1 zUj@4%2Ov_osz#k;vx03wPMQ^mhtrv874uS1s@sX+UHy$7o-o~N)UL_Pm$h5mp7Y48 zHu^W0FgkyV-O$^IO_qrGcVa^ttr$yF7e5&u)-asd;j(@Y;IxoFHJhMs=;M>cSZg(WvS-V)>!hsQiY} zMF00k$pL;C3TS-X? zX0Bj)yQv&I$yCh5h)zq&{XX?YHhQzu295*jtx~3FdS#fXO-Cwm_CiifkSE#=HA$55 z07V!X5`WQFR!snaSWHP=03a^_hJ<@7x@rJGoDvK8Kdb(;6a@HVX)&6S{ud_$qUt~G zjNe@&t|Nl5sjV39{D|7f3aiNfT`J)e*$E+P799UBL}1KcC*c8tk^dCfDiU1=l8|+Q z|EfFbehxim=zFcVn>GtWg4Oyr)hnEq^_;8`lYf^!jV-)Tkd_GwAPjY6Ls#7QxWb#RUwku-I31` zq+2+%0^tjjU;*^5r|@HHQZ;yW!?|!)FGqi<@@~1EsLaINdnx^9!bwjTXN( zC!QM5yqU`+L*H2$GDsZ0J@xQ%HcbeymbcyY}>HS(OO?Q7Bxu<*wzq%8w`C|zDc1$ZrZu}^C_+g6W!>M+-SwXDXE~Zq9Rcr9aFes|$aI&U>HHHZ2 zoP7FYj%=skQ$L;mu!5U3^o{BKELg(!ixAfwjG0pdr!WP(&5+m9#zMCZL*p8XiL)q` zKK-)X-uG7{2GpEGUSG3E?ktPpm5kMCz*H&Lny!~l&q53`NWbdEQ+K>y9#79(k+&&aItDI<`!B5WQ*=3>eK_SM zzl%)>tsD5*p12Qn5)~w;aB<@$L61~qupcBL{qKdgbx73+nC%=BF=HWZuZk5b@pnN)_cyHz~(JAAd$-K6M z+;7B{p6w_Fr{@a$=qIsy2(`IgVacbfQdzU2s{F>Lf)w4A#-`TChg<0VuFh;FiMrb? zTqI}du;+>;J6QE2X2EpI+GJij`Z=in=dq)1!L%;Dd^+hf)kb(D;ZJy=O}?vd{_X9p zqN3t;gj95MNys>DFA=15eMsGA?wNgM1iSh7p=SUG;ZwN}DE zU9*`~|AE}5zp^(^*;W%7q(T^2eR*~9=&I`_aWvp`khj*O8F)^52f9%x$}g&Z=8`d5 zWgTA`aql$D%*0$Y`^$Bnc9%hpEso(85JJoU-I^yunI9=8*ScjT{$1$3q-#ng2#HU0I5iB>cY%Azr-{tCT65t@l4t zYSvE8kw>SP4jiVb9$bEWxODJdqw>b!#Qc|*uFX`KDki<%V2$NqR7umVu_lE&zAK)# znnm^c@y`X2ii{M}>{q3i$o;e0dHXeF+kdG(;PL9n#Tz^Ls?~3AMNuVT>++V_sIxGf zU0R{l2SH^3|LuG&btVMxCj~k@gt7+^jU445M$!a2pL6Y(5#*B<%n?*+_r17Ldd{ZX zrbB0{W`RP+vnv7%1~PD{cFcpSv)aC^3&7? z+r)LWIa=1o$XGWx+GuM-TV*U9IsC9}yCRE&1Q|nglo@~e&(1g`hb3~hc{&Xq7ut-R z#tAgx?-$_xiYR6(AD|lc0%aDsf2*9Wxx^@g9x+arKe?eykZt%$1o2EzR`4*f(=OIt zYN^-o0qaNm+(`>6OW#TS!rx8%5sWc3;@inq-D7w$1}OfsL^}VV24!e}#C=noY(dQx5Mj26Yx>qr)%>rFSJq69hEZ9KTWp=O(e-onhP)tC&7 zSQxaaeZ1=LO&VUqk9{g_Q#Wp?=4Y`$t<-YRefB$HFBY75m7#sXXAljkpe3w-1-Zqa z=nTSGE@8_YPNH{?U~%!1=n3o$8i*N>OWq=72N5z65SU8J2+t7|BuE7T^j_NBMqiO| zv|*!44ZLgLe&(Vs&kRM??5CyN|LGLw(PTI@Hbev$P(Hy;uDQpQWW~k9!?+^ulG}m( z5!apmp{(8QVL#;Bk7Z~UC|D4z6O*SVu6K(coCpvlT&BW7tTv|56f;bQ>X8xRlkuEC zL7isAK=p~<|N%Lj#d!lhoz z4^gs>i&YgCR#s&y*HUf^1TS$@V2i#&Mz!-?ZORudJHew`r|UATL-1QBu@QITRsq;K zraNwq%O+N}wnJiO{dMzf?uZp9n-SRs6&7%dD|4??rG|2t5cS6TjhiJAU9p*6YXHot zC8x$^cV#!(SS)qmz*;{{Wfnkdp6@5YF@Svb(|#19n*VJU=U;nn2QC-tr9AWa8E;33 zhHW~>H?a?+YuzY(sID1ZyLdlLMR3z(Uo*6=cn~C5&~JiLRkPeDoh>Y={qT6r{;nR;{5nFK&a?UT6_QY1Hg(ADGe|B--J45(|v>V7s03|suHVVJW|{qFI84yb@kr|^HhOyXnVqvBB% zmBZLgd$WfzG~nC$Der?&RCRDWmN?P_0+2^v{qm4H@#o!Ni>ub7s}W`S6e$)0*2r)w zTCYr1kc9Jp+F+TC<)baPDlK&qXhgj4?IvIR;L5|6v9J0IfVkx2S(E2;-9CR!yDWr71>@o5%z4|WPYPU${&4Nh zpeNwt=m^_lE;Fe+V_|1^!^gub9DJ)|3eBpj{9K-##qM$P#xvk_K+c8zf={}Y{JH55 zm16Gjt7OXCGB;3V_ph`vuG+1VSIX(k)p$+Kb=k)AORpRd+SdG)bu0FhwXd3(J#H@! z*4##iB?2x^PkSy}0MPu<7T1U9d;$&>&x-slj_R29Bsu|~{mqh%hEe9WdAy&Q6D~a$ zX)egT-oMg*w_95qJ=s97jWja`Aq}7Ilv{5|;xys#<>lGDc?{rB+qr?8&axo>H>+4J zK?AVtrhDndEiJ9teiPhG4RqVlchYgmpT9!Y`jXn-bVugKd}({Onxb9DyL+XzA()rQ zFq0wSzivTDMwaKPfU6YG{&rLGUC2Mewe8FTwh-oz!lnQjd4(!f(tweEm6IwLmVPRX z_nBB2o}1SEWwC~DOnZX>;SN-RqZXq|?G_lr*2og#PZ>U=&2xP=;;EKwZfr;x`dL^k zV?O(8+n`)U(`JE^%U}ThzlDs5%+iRdEs2h-)`F-LY-#mXTi4Hz!Un|@sbM|%HIx<1L0-;q`?RFEeC<)k((nTb|PTjaG)Io|=p?W76 zVNb3zOlOGvm;y&T-(p(tM>ex`zyJE+AuXMdes8NWFFs1|J=on=PsxQGhP2>p(p@`H zIVY%`#a!7a;)3qF#Z-5Qp=cl>VOKk4S39|cnZa9wiU2%2P?+W&fl1zRfhXBb2vlHm ziPhH4?D2Ug&hE|bf6;Y`56B+c!m4DZltJJ)(;)8&sA9Q8j2nh=kbN5p5sfnWVgOpV z)=wHa1O}6qmTHa`cfH7z%vMH@GP4mGSdML8?=Ey=BAzO2cU1OPn8WQQ{>>E!g?H~k zZvNDd^M=(YJ~TD3DRc65BIFG7L^&iEOOu6wvfJ(6Ex6cC7Nso@Y*1}lLmhA8dKX^D z!|e_nOrW4l#+XcctW1K5@1Jj01CEE~qlNGmjJQ91qa`V>0aJM~zk|`SGQhdF!>3UTVXr2T5wl!1LB?;eA zBX1zj=7JmKWjZhLC`?bG-^^rG9;aWU8jouI!=<(qRww`f|9|B0ugD)u1zb&az}S!W zwUmZ(2UbT-h>^+Vhg%x+Df$Sf+{+Rw3?}z`R4f?;_(P}WLZ+U)fLBH6_ z{&4#|?8=l51lt?o+WadY16wO098X&f3#)tr4P(Gc69Y)E6xHw9xJUzy6+<@~d0j2} z@MZ2t`eLuFjDE;_D@qE1rRJ)l&T>%#&0OK0Rg(vzcaa{(IVWMIE9GMn>EDRX)D1}; zb}9etVOm~h{f@|xP*opL1froCXm`&D_;a1;+UD_-T1|Nd#ggPK`bq>p- zu8;b18d(O{V7`l!Npu+*nJZ#TqA{~;{T z>51c_rmwC9H+<74J>)Gxy9HwpCYm3v5KKS!%_=5ch=PEh8N}Tn8H;%@ zimVsrf`k$pszDG<^*n$6hw+>17O)*w)rw4-_y`a4_RgX0{hA zAf3=K_O0U2an@;W_3KTK?#M~Bh@j5oSd>k+P~@ak6hrz;A`+uNlwb$%{o{jbDqmkq z1r<8WV1&jSmyf{{bK*2w(2ZDBEU&#%Q|9K7Q_(An!@3J;`dq@yLo`)mrK#~v^YXoeKv{bCVuq}1m=m3t_|N6g3OQBSDH)_O7g=PbL zcLHN$X+_Au#8M262p9qx)M?{H>WE9)Spw*Ai#Kb*JifH{$&IPd2A9PM+rLfGhHnWs zjI%68fz{e{`CMg5F=u2aH`ecG7`x56DPNaM{ci0A--!ldR5o9@M5LyI9Y*2o$hpfF z%I3mLW0hdHaAa3hu7=7gyw|MOtipQU6&SDWig`0fRpT4KOx~zoKU=65leSm#g3``k!MvMpzCIWLmASLJ7AHh<#;5~4cczQRo zw7DR?6@XXj{|{yVO^tq$fwPx3!9O}_SM8ABmaNx*Bz&6d^GcQ8f)#lVke60@UnXf3 G_`d)V?pERe literal 0 HcmV?d00001 diff --git a/docs/topics/recipes.md b/docs/topics/recipes.md index 404f8823f7..f9b56a02c5 100644 --- a/docs/topics/recipes.md +++ b/docs/topics/recipes.md @@ -165,6 +165,128 @@ is further explained in [the calculation engine](./calculation-engine.md). $value = $spreadsheet->getActiveSheet()->getCell('B8')->getCalculatedValue(); ``` +### Array Formulae + +With version 2.0.0 of PhpSpreadsheet, we've introduced support for Excel "array formulae". + +As a basic example, let's look at a receipt for buying some fruit: + +![12-CalculationEngine-Basic-Formula.png](./images/12-CalculationEngine-Basic-Formula.png) + +We can provide a "Cost" formula for each row of the receipt by multiplying the "Quantity" (column `B`) by the "Price" (column `C`); so for the "Apples" in row `2` we enter the formula `=$B2*$C2`. In PhpSpreadsheet, we would set this formula in cell `D2` using: +```php +$spreadsheet->getActiveSheet()->setCellValue('D2','=$B2*$C2'); +``` +and then do the equivalent for rows `3` to `6`. + +To calculate the "Total", we would use a different formula, telling it to calculate the sum value of rows 2 to 6 in the "Cost" column: + +![12-CalculationEngine-Basic-Formula-2.png](./images/12-CalculationEngine-Basic-Formula-2.png) + +I'd imagine that most developers are familiar with this: we're setting a formula that uses an Excel function (the `SUM()` function) and specifying a range of cells to include in the sum (`$D$2:$D6`) +```php +$spreadsheet->getActiveSheet()->setCellValue('D7','=SUM($D$2:$D6'); +``` +However, we could have specified an alternative formula to calculate that result, using the arrays of the "Quantity" and "Cost" columns multiplied directly, and then summed together: + +![12-CalculationEngine-Array-Formula.png](./images/12-CalculationEngine-Array-Formula.png) + +Entering the formula `=SUM(B2:B6*C2:C6)` will calculate the same result; but because it's using arrays, we need to enter it as an "array formula". In MS Excel itself, we'd do this by using `Shift-Ctrl-Enter` rather than simply `Enter` when we define the formula in the formula edit box. MS Excel then shows that this is an array formula in the formula edit box by wrapping it in the `{}` braces (you don't enter these in the formula yourself; MS Excel does it). + +If we want to create an array formula in PhpSpreadsheet, we also have to indicate that it is an array formula. +```php +$spreadsheet->getActiveSheet()->setCellValue('D7','=SUM(B2:B6*C2:C6)', true); +``` +We do this by providing a third argument in the call to `setCellValue()` that is only appropriate when setting a cell value to a formula, and that is the boolean value `true` passed as the `$isArrayFormula` argument. If the value we're setting in the cell isn't a formula value, then this additional argument will be ignored. + +Or to identify the biggest increase in like-for-like sales from one month to the next: + +![12-CalculationEngine-Array-Formula-3.png](./images/12-CalculationEngine-Array-Formula-3.png) +```php +$spreadsheet->getActiveSheet()->setCellValue('F1','=MAX(B2:B6-C2:C6)', true); +``` +Which tells us that the biggest increase in sales between December and January was 30 more (in this case, 30 more Lemons). + +--- + +These are examples of array formula where the results are displayed in a single cell; but other array formulae might be displayed across several cells. +As an example, consider transposing a grid of data: MS Excel provides the `TRANSPOSE()` function for that purpose. Let's transpose our shopping list for the fruit: + +![12-CalculationEngine-Array-Formula-2.png](./images/12-CalculationEngine-Array-Formula-2.png) + +When we do this in MS Excel, we need to indicate ___all___ the cells that will contain the transposed data from cells `A1` to `D7`. We do this by selecting the cells where we want to display our transposed data either by holding the left mouse button down while we move with the mouse, or pressing `Shift` and using the arrow keys. +Once we've selected all the cells to hold our data, then we enter the formula `TRANSPOSE(A1:D7)` in the formula edit box, remembering to use `Shift-Ctrl-Enter` to tell MS Excel that this is an array formula. + +We also need to specify that selected range if we create the same array formula in PhpSpreadsheet. +In addition to passing true for the `$isArrayFormula` argument, we also pass a fourth argument telling PhpSpreadsheet the range of cells that we want the transposed array to cover. +```php +$spreadsheet->getActiveSheet()->setCellValue('A10','=TRANSPOSE(A1:D7)', true, 'A10:G13'); +``` +Specifying this range tells PhpSpreadsheet (and MS Excel) that the result of the formula in cell `A10` is allowed to "spill" out into cells in that specified range; but also that it is limited to that range. +If you don't specify a range, then PhpSpreadsheet will only apply this formula to a single cell. + +Note also that we still set this as the formula for the top-left cell of that range, cell `A10`. + +If you want to use other methods like `setCellValueExplicit()`, `setCellValueByColumnAndRow()` or `setCellValueExplicitByColumnAndRow()`, then the same additional arguments are also available with these methods. +```php +$spreadsheet->getActiveSheet() + ->setCellValueExplicit( + 'A10', + '=TRANSPOSE(A1:D7)', + \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_FORMULA, + true, + 'A10:G13' + ); +``` + +--- + +Excel365 introduced a number of new functions that return arrays of results. +These include the `UNIQUE()`, `SORT()`, `SORTBY()`, `FILTER()`, `SEQUENCE()` and `RANDARRAY()` functions. +While not all of these have been implemented by the Calculation Engine in PhpSpreadsheet, so they cannot all be calculated within your PHP applications, they can still be read from and written to Xlsx files. + +The way these functions are presented in MS Excel itself is slightly different to that of other array functions. + +The `SEQUENCE()` function generates a series of values (in this case, starting with `-10` and increasing in steps of `2.5`); and here we're telling the formula to populate a 3x3 grid with these values. + +![12-CalculationEngine-Spillage-Formula.png](./images/12-CalculationEngine-Spillage-Formula.png) + +Note that this is visually different to the multi-cell array formulae like `TRANSPOSE()`. When we are positioned in the "spill" range for the grid, MS Excel highlights the area with a blue border; and the formula displayed in the formula editing field isn't wrapped in braces (`{}`). + +And if we select any other cell inside the "spill" area other than the top-left cell, the formula in the formula edit field is greyed rather than displayed in black. + +![12-CalculationEngine-Spillage-Formula-2.png](./images/12-CalculationEngine-Spillage-Formula-2.png) + +When we enter this formula in MS Excel, we don't need to select the range of cells that it should occupy; nor do we need to enter it using `Ctrl-Shift-Enter`. MS Excel identifies that it is a multi-cell array formula because of the function that it uses, the `SEQUENCE()` function (and if there are nested function calls in the formula, then it must be the outermost functionin the tree). + +However, PhpSpreadsheet isn't quite as intelligent (yet) and doesn't parse the formula to identify if it should be treated as an array formula or not; a formula is just a string of characters until it is actually evaluated. If we want to use this function through code, we still need to specify that it is an "array" function with the `$isArrayFormula` argument, and the range of cells that it should cover. + +```php +$spreadsheet->getActiveSheet()->setCellValue('A1','=SEQUENCE(3,3,-10,2.5)', true, 'A1:C3'); +``` + +### The Spill Operator + +If you want to reference the entire spillage range of an array formula within another formula, you could do so using the standard Excel range operator (`:`, e.g. `A1:C3`); but you may not always know the range, especially for array functions that spill across as many cells as they need, like `UNIQUE()` and `FILTER()`. +To simplify this, MS Excel has introduced the "Spill" Operator (`#`). + +![12-CalculationEngine-Spillage-Operator.png](./images/12-CalculationEngine-Spillage-Operator.png) + +Using our `SEQUENCE()"`example, where the formula cell is `A1` and the result spills across the range `A1:C3`, we can use the Spill operator `A1#` to reference all the cells in that spillage range. +In this case, we're taking the absolute value of each cell in that range, and adding them together using the `SUM()` function to give us a result of 50. + +PhpSpreadsheet doesn't currently support entry of a formula like this directly; but interally MS Excel implements the Spill Operator as a function (`ANCHORARRAY()`). MS Excel itself doesn't allow you to use this function in a formula, you have to use the "Spill" operator; but PhpSpreadsheet does allow you to use this internal Excel function. + +To create this same function in PhpSpreadsheet, use: +```php +$spreadsheet->getActiveSheet()->setCellValue('D1','=SUM(ABS(ANCHORARRAY(A1)))', true); +``` +Note that this does need to be flagged as an array function with the `$isArrayFormula` argument. + +When the file is saved, and opened in MS Excel, it will be rendered correctly. + + + ## Locale Settings for Formulae Some localisation elements have been included in PhpSpreadsheet. You can @@ -201,7 +323,7 @@ $spreadsheet->getActiveSheet()->setCellValue('B8',$internalFormula); ``` Currently, formula translation only translates the function names, the -constants TRUE and FALSE, and the function argument separators. Cell addressing using R1C1 formatting is not supported. +constants TRUE and FALSE (and NULL), Excel error messages, and the function argument separators. Cell addressing using R1C1 formatting is not supported. At present, the following locale settings are supported: @@ -224,6 +346,8 @@ Russian | русский язык | ru Swedish | Svenska | sv Turkish | Türkçe | tr +If anybody can provide translations for additional languages, particularly Basque (Euskara), Catalan (Català), Croatian (Hrvatski jezik), Galician (Galego), Greek (Ελληνικά), Slovak (Slovenčina) or Slovenian (Slovenščina); please feel free to volunteer your services, and we'll happily show you what is needed to contribute a new language. + ## Write a newline character "\n" in a cell (ALT+"Enter") In Microsoft Office Excel you get a line break in a cell by hitting From 66e63eb3b7ee2739c0abd551f6f8f78e4a693783 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Feb 2022 23:52:49 +0100 Subject: [PATCH 18/94] Modify ABS() function to handle arrays, with appropriate unit tests --- .../Calculation/MathTrig/Absolute.php | 20 +++++++++++++-- .../Functions/MathTrig/AbsTest.php | 25 ++++++++++++++++++- 2 files changed, 42 insertions(+), 3 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php b/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php index 9f1bd80497..13fc13cc8c 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Absolute.php @@ -6,17 +6,33 @@ class Absolute { + private static function evaluateArray(array $numbers): array + { + $result = []; + foreach ($numbers as $number) { + $result[] = self::evaluate($number); + } + + return $result; + } + /** * ABS. * * Returns the result of builtin function abs after validating args. * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|int|string Rounded number + * @return array|float|int|string rounded number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function evaluate($number) { + if (is_array($number)) { + return self::evaluateArray($number); + } + try { $number = Helpers::validateNumericNullBool($number); } catch (Exception $e) { diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php index b68719050b..aa170c9cb8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php @@ -2,6 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; + class AbsTest extends AllSetupTeardown { /** @@ -10,7 +12,7 @@ class AbsTest extends AllSetupTeardown * @param mixed $expectedResult * @param mixed $number */ - public function testRound($expectedResult, $number = 'omitted'): void + public function testAbsolute($expectedResult, $number = 'omitted'): void { $sheet = $this->getSheet(); $this->mightHaveException($expectedResult); @@ -28,4 +30,25 @@ public function providerAbs(): array { return require 'tests/data/Calculation/MathTrig/ABS.php'; } + + /** + * @dataProvider providerAbsArray + */ + public function testAbsoluteArray(array $expectedResult, string $array): void + { + $calculation = Calculation::getInstance(); + + $formula = "=ABS({$array})"; + $result = $calculation->_calculateFormulaValue($formula); + self::assertSame($expectedResult, $result); + } + + public function providerAbsArray(): array + { + return [ + 'row vector' => [[[1, 0, 1]], '{-1, 0, 1}'], + 'column vector' => [[[1], [0], [1]], '{-1; 0; 1}'], + 'matrix' => [[[1, 0], [1, 1]], '{-1, 0; 1, -1}'], + ]; + } } From 3cec90d9f3239e6070b819eea839c7d503041253 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 4 Feb 2022 11:23:40 +0100 Subject: [PATCH 19/94] Minor refactoring, and additional unit tests (including exceptions) for Cell's setValueExplicit() method --- src/PhpSpreadsheet/Cell/Cell.php | 19 +++-------- src/PhpSpreadsheet/Cell/DataType.php | 32 +++++++++++++++++++ tests/data/Cell/SetValueExplicit.php | 10 ++++++ tests/data/Cell/SetValueExplicitException.php | 16 ++++++++++ 4 files changed, 62 insertions(+), 15 deletions(-) diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 601dc91971..90edca5c99 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -2,13 +2,11 @@ namespace PhpOffice\PhpSpreadsheet\Cell; -use DateTime; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Collection\Cells; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\RichText\RichText; -use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\CellStyleAssessor; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Style; @@ -213,7 +211,8 @@ protected function formulaAttributes(bool $isArrayFormula, ?string $arrayFormula } /** - * Set the value for a cell, with the explicit data type passed to the method (bypassing any use of the value binder). + * Set the value for a cell, + * with the explicit data type passed to the method (bypassing any use of the value binders). * * @param mixed $value Value * @param string $dataType Explicit data type, see DataType::TYPE_* @@ -250,6 +249,7 @@ public function setValueExplicit($value, $dataType, bool $isArrayFormula = false $dataType = DataType::TYPE_STRING; if (in_array($value, Calculation::$excelConstants, true)) { $value = array_search($value, Calculation::$excelConstants, true); + $dataType = $value === null ? DataType::TYPE_NULL : DataType::TYPE_BOOL; } $value = (string) $value; $this->formulaAttributes = []; @@ -264,18 +264,7 @@ public function setValueExplicit($value, $dataType, bool $isArrayFormula = false break; case DataType::TYPE_ISO_DATE: - if (!is_string($value)) { - throw new Exception('Non-string supplied for datatype Date'); - } - $date = new DateTime($value); - $newValue = SharedDate::PHPToExcel($date); - if ($newValue === false) { - throw new Exception("Invalid string $value supplied for datatype Date"); - } - if (preg_match('/^\\d\\d:\\d\\d:\\d\\d/', $value) == 1) { - $newValue = fmod($newValue, 1.0); - } - $this->value = $newValue; + $this->value = DataType::checkIsoDate($value); $dataType = DataType::TYPE_NUMERIC; break; diff --git a/src/PhpSpreadsheet/Cell/DataType.php b/src/PhpSpreadsheet/Cell/DataType.php index 0f7efe2a47..7e62f94219 100644 --- a/src/PhpSpreadsheet/Cell/DataType.php +++ b/src/PhpSpreadsheet/Cell/DataType.php @@ -2,7 +2,10 @@ namespace PhpOffice\PhpSpreadsheet\Cell; +use DateTime; +use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\RichText\RichText; +use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class DataType @@ -83,4 +86,33 @@ public static function checkErrorCode($value) return $value; } + + /** + * @param mixed $value + * + * @return float|int + */ + public static function checkIsoDate($value) + { + if (!is_string($value)) { + throw new Exception('Non-string supplied for datatype Date'); + } + + try { + $date = new DateTime($value); + $newValue = SharedDate::PHPToExcel($date); + } catch (\Exception $e) { + throw new Exception("Invalid string $value supplied for datatype Date"); + } + + if ($newValue === false) { + throw new Exception("Invalid string $value supplied for datatype Date"); + } + + if (preg_match('/^\\d\\d:\\d\\d:\\d\\d/', $value) == 1) { + $newValue = fmod($newValue, 1.0); + } + + return $newValue; + } } diff --git a/tests/data/Cell/SetValueExplicit.php b/tests/data/Cell/SetValueExplicit.php index 50b81019d5..2ba4a1531b 100644 --- a/tests/data/Cell/SetValueExplicit.php +++ b/tests/data/Cell/SetValueExplicit.php @@ -38,6 +38,16 @@ true, DataType::TYPE_NUMERIC, ], + [ + '=SUM(A1:A10)', + '=SUM(A1:A10)', + DataType::TYPE_FORMULA, + ], + [ + 44596.5627893519, + '2022-02-04 13:30:25', + DataType::TYPE_ISO_DATE, + ], [ '#DIV/0!', '#DIV/0!', diff --git a/tests/data/Cell/SetValueExplicitException.php b/tests/data/Cell/SetValueExplicitException.php index a05704f025..584cfd936f 100644 --- a/tests/data/Cell/SetValueExplicitException.php +++ b/tests/data/Cell/SetValueExplicitException.php @@ -7,4 +7,20 @@ 'XYZ', DataType::TYPE_NUMERIC, ], + [ + 44596, + DataType::TYPE_ISO_DATE, + ], + [ + false, + DataType::TYPE_ISO_DATE, + ], + [ + 'ABCD-EF-GH II:JJ:KK', + DataType::TYPE_ISO_DATE, + ], + [ + 1234, + 'INVALID DATATYPE', + ], ]; From c1125ba3df5393c7ec8836fbbdd8959ebad9f63d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 4 Feb 2022 12:07:43 +0100 Subject: [PATCH 20/94] Clean up some phpstan issues Note that the deprecated Excel function implementation classes should be removed completely for PhpSpreadsheet 2.0.0; and the bc break that array formula handling entails will require this to be a 2.0.0 implementation... but just for the moment, this is a cleanup... those files will be deleted once we switch to development on a 2.0-dev branch, and I want to do a few more PR merges before then, and update this branch as part of the 2.0-dev changes --- src/PhpSpreadsheet/Calculation/MathTrig.php | 6 ++++-- src/PhpSpreadsheet/Cell/Cell.php | 1 - 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/MathTrig.php b/src/PhpSpreadsheet/Calculation/MathTrig.php index ec251f6d25..f59bc341f9 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig.php @@ -1147,9 +1147,11 @@ public static function builtinROUND($number, $precision) * @See MathTrig\Absolute::evaluate() * Use the evaluate method in the MathTrig\Absolute class instead * - * @param mixed $number Should be numeric + * @param mixed $number Should be numeric, or can be an array of numbers * - * @return float|int|string Rounded number + * @return array|float|int|string rounded number + * If an array of numbers is passed as the argument, then the returned result will also be an array + * with the same dimensions */ public static function builtinABS($number) { diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 90edca5c99..e48f0f749e 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -249,7 +249,6 @@ public function setValueExplicit($value, $dataType, bool $isArrayFormula = false $dataType = DataType::TYPE_STRING; if (in_array($value, Calculation::$excelConstants, true)) { $value = array_search($value, Calculation::$excelConstants, true); - $dataType = $value === null ? DataType::TYPE_NULL : DataType::TYPE_BOOL; } $value = (string) $value; $this->formulaAttributes = []; From 3ed98ab9ce75e7a42d10812f043ec416cf30c36d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 4 Feb 2022 16:34:31 +0100 Subject: [PATCH 21/94] Resolve phpstan issues --- phpstan-baseline.neon | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index a497f7063b..ec9427ffb6 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -240,26 +240,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Parameter \\#1 \\$str1 of method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:strcmpAllowNull\\(\\) expects string\\|null, mixed given\\.$#" - count: 4 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Parameter \\#1 \\$str1 of method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:strcmpLowercaseFirst\\(\\) expects string\\|null, mixed given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Parameter \\#1 \\$textValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:strCaseReverse\\(\\) expects string, string\\|null given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Parameter \\#2 \\$str2 of method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:strcmpAllowNull\\(\\) expects string\\|null, mixed given\\.$#" - count: 4 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, mixed given\\.$#" count: 4 From 6bd181bae0d0986c36cf6f2dc848e8c237434d82 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 4 Feb 2022 17:30:36 +0100 Subject: [PATCH 22/94] Eliminate spurious var_dump --- src/PhpSpreadsheet/Cell/Cell.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index e48f0f749e..b75f3fa99d 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -354,7 +354,6 @@ public function getCalculatedValue($resetLog = true, bool $asArray = false) return \PhpOffice\PhpSpreadsheet\Calculation\Functions::NAME(); } -// var_dump($ex); throw new \PhpOffice\PhpSpreadsheet\Calculation\Exception( $this->getWorksheet()->getTitle() . '!' . $this->getCoordinate() . ' -> ' . $ex->getMessage() ); From 3357af3b7f33d763b41556dc8cc59b34bf902077 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 9 Feb 2022 15:40:58 +0100 Subject: [PATCH 23/94] Minor refactoring of Cell calculation logic for array response --- phpstan-baseline.neon | 12 +++- src/PhpSpreadsheet/Cell/Cell.php | 67 ++++++++++++-------- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 4 +- 3 files changed, 52 insertions(+), 31 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index d15ddfad0f..792edbba2a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -242,7 +242,7 @@ parameters: - message: "#^Parameter \\#1 \\$str of function trim expects string, null given\\.$#" - count: 2 + count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php - @@ -375,6 +375,11 @@ parameters: count: 2 path: src/PhpSpreadsheet/Calculation/Calculation.php + - + message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#" + count: 1 + path: src/PhpSpreadsheet/Calculation/Calculation.php + - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DMAX\\(\\) should return float but returns float\\|string\\|null\\.$#" count: 1 @@ -2005,6 +2010,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Cell.php + - + message: "#^Parameter \\#4 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:processArrayResult\\(\\) expects string, mixed given\\.$#" + count: 1 + path: src/PhpSpreadsheet/Cell/Cell.php + - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:\\$parent \\(PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\) in isset\\(\\) is not nullable\\.$#" count: 6 diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index b75f3fa99d..18085caa4f 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -283,6 +283,44 @@ public function setValueExplicit($value, $dataType, bool $isArrayFormula = false return $this->updateInCollection(); } + private function processArrayResult( + Worksheet $worksheet, + string $coordinate, + array $result, + string $value, + ?array $formulaAttributes + ): array { + // We'll need to do a check here for the Singular Operator (@) at some point + // and not populate the spillage cells if it's there + if ($this->isArrayFormula()) { + // Here is where we should set all cellRange values from the result (but within the range limit) + // Ensure that our array result dimensions match the specified array formula range dimensions, + // expanding or shrinking it as necessary. + $result = Functions::resizeMatrix( + $result, + ...Coordinate::rangeDimension($this->formulaAttributes['ref'] ?? $coordinate) + ); + // But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved + // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? +// $worksheet->fromArray( +// $result, +// null, +// $coordinate, +// true +// ); + // Using fromArray() would reset the value for this cell with the calculation result + // as well as updating the spillage cells, + // so we need to restore this cell to its formula value, attributes, and datatype + $worksheet->getCell($coordinate); + $this->value = $value; + $this->dataType = DataType::TYPE_FORMULA; + $this->formulaAttributes = $formulaAttributes; + $this->updateInCollection(); + } + + return $result; + } + /** * Get calculated cell value. * @@ -297,7 +335,6 @@ public function getCalculatedValue($resetLog = true, bool $asArray = false) $coordinate = $this->getCoordinate(); $worksheet = $this->getWorksheet(); $value = $this->value; - $datatype = $this->dataType; $formulaAttributes = $this->formulaAttributes; $index = $this->getWorksheet()->getParent()->getActiveSheetIndex(); $selected = $this->getWorksheet()->getSelectedCells(); @@ -309,33 +346,7 @@ public function getCalculatedValue($resetLog = true, bool $asArray = false) $worksheet->getCell($coordinate); if (is_array($result)) { - // We'll need to do a check here for the Singular Operator (@) at some point - // and not populate the spillage cells if it's there - if ($this->isArrayFormula()) { - // Here is where we should set all cellRange values from the result (but within the range limit) - // Ensure that our array result dimensions match the specified array formula range dimensions, - // expanding or shrinking it as necessary. - $result = Functions::resizeMatrix( - $result, - ...Coordinate::rangeDimension($this->formulaAttributes['ref'] ?? $coordinate) - ); - // But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved - // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? -// $worksheet->fromArray( -// $result, -// null, -// $coordinate, -// true -// ); - // Using fromArray() would reset the value for this cell with the calculation result - // as well as updating the spillage cells, - // so we need to restore this cell to its formula value, attributes, and datatype - $worksheet->getCell($coordinate); - $this->value = $value; - $this->dataType = $datatype; - $this->formulaAttributes = $formulaAttributes; - $this->updateInCollection(); - } + $result = $this->processArrayResult($worksheet, $coordinate, $result, $value, $formulaAttributes); // Now we just extract the top-left value from the array to get the result for this specific cell if ($asArray === false) { diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 1252c938c7..19064ae895 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1282,8 +1282,8 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $objWriter->startElement('f'); $objWriter->writeAttribute('t', 'array'); $objWriter->writeAttribute('ref', $attributes['ref'] ?? $cell->getCoordinate()); - $objWriter->writeAttribute('aca', '1'); // Always calculate array, true - $objWriter->writeAttribute('ca', '1'); // Calculate cell, true + $objWriter->writeAttribute('aca', '1'); // Always calculate array, true + $objWriter->writeAttribute('ca', '1'); // Calculate cell, true $objWriter->text(Xlfn::addXlfnStripEquals($cellValue)); $objWriter->endElement(); } else { From c7cbdf658c5e6ab5b3d8ebff216c8cc3dcaf718d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 13 Feb 2022 22:26:35 +0100 Subject: [PATCH 24/94] Reset phpstan baseline --- phpstan-baseline.neon | 124 +++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 57 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index e4a6bf373d..c8fcf2d57d 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -55,6 +55,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 6 + path: src/PhpSpreadsheet/Calculation/Calculation.php + - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has no return type specified\\.$#" count: 1 @@ -152,7 +157,7 @@ parameters: - message: "#^Parameter \\#1 \\$str of function trim expects string, null given\\.$#" - count: 2 + count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php - @@ -790,51 +795,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Formula\\:\\:text\\(\\) should return string but returns mixed\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/Formula.php - - - - message: "#^Parameter \\#2 \\$subject of function preg_match expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/Formula.php - - - - message: "#^Parameter \\#1 \\$lookupArray of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\HLookup\\:\\:convertLiteralArray\\(\\) expects array, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php - - - - message: "#^Parameter \\#1 \\$textValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:strToLower\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php - - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/Helpers.php - - - message: "#^Parameter \\#1 \\$str of function trim expects string, mixed given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Calculation/LookupRef/Hyperlink.php - - - - message: "#^Parameter \\#1 \\$tooltip of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Hyperlink\\:\\:setTooltip\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/Hyperlink.php - - - - message: "#^Parameter \\#1 \\$url of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Hyperlink\\:\\:setUrl\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/Hyperlink.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Indirect\\:\\:INDIRECT\\(\\) should return array\\|string but returns mixed\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Lookup\\:\\:verifyResultVector\\(\\) has no return type specified\\.$#" count: 1 @@ -870,6 +835,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php + - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:adjustEndCellColumnForWidth\\(\\) has no return type specified\\.$#" count: 1 @@ -910,9 +880,14 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 2 + path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php + - message: "#^Parameter \\#1 \\$columnAddress of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:columnIndexFromString\\(\\) expects string, string\\|null given\\.$#" - count: 3 + count: 4 path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - @@ -1345,21 +1320,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Cell.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:getFormulaAttributes\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Cell.php - - message: "#^Parameter \\#2 \\$format of static method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\:\\:toFormattedString\\(\\) expects string, string\\|null given\\.$#" count: 1 path: src/PhpSpreadsheet/Cell/Cell.php - - - message: "#^Parameter \\#4 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:processArrayResult\\(\\) expects string, mixed given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Cell.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:\\$parent \\(PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\) in isset\\(\\) is not nullable\\.$#" count: 6 @@ -1375,6 +1340,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Coordinate.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 2 + path: src/PhpSpreadsheet/Cell/Coordinate.php + - message: "#^Cannot use array destructuring on array\\|null\\.$#" count: 1 @@ -1555,6 +1525,11 @@ parameters: count: 2 path: src/PhpSpreadsheet/Chart/DataSeries.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Chart/DataSeriesValues.php + - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:refresh\\(\\) has parameter \\$flatten with no type specified\\.$#" count: 1 @@ -2215,6 +2190,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/BaseReader.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Reader/Gnumeric.php + - message: "#^Comparison operation \"\\<\" between int and SimpleXMLElement\\|null results in an error\\.$#" count: 2 @@ -2310,6 +2290,11 @@ parameters: count: 2 path: src/PhpSpreadsheet/Reader/Ods.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Reader/Ods/DefinedNames.php + - message: "#^Cannot call method getElementsByTagNameNS\\(\\) on DOMElement\\|null\\.$#" count: 3 @@ -2535,6 +2520,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xls.php + - + message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\\\|string given\\.$#" + count: 1 + path: src/PhpSpreadsheet/Reader/Xls.php + - message: "#^Parameter \\#2 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter\\:\\:readCell\\(\\) expects int, string given\\.$#" count: 1 @@ -2730,6 +2720,11 @@ parameters: count: 2 path: src/PhpSpreadsheet/Reader/Xlsx.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 2 + path: src/PhpSpreadsheet/Reader/Xlsx.php + - message: "#^Comparison operation \"\\>\" between SimpleXMLElement\\|null and 0 results in an error\\.$#" count: 1 @@ -2920,11 +2915,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Parameter \\#1 \\$worksheetName of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getSheetByName\\(\\) expects string, array\\|string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, int\\|string given\\.$#" count: 2 @@ -4565,6 +4555,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Worksheet/AutoFilter.php + - message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#" count: 1 @@ -5265,6 +5260,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Writer/Xls/Font.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 2 + path: src/PhpSpreadsheet/Writer/Xls/Parser.php + - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Parser\\:\\:advance\\(\\) has no return type specified\\.$#" count: 1 @@ -5645,6 +5645,11 @@ parameters: count: 2 path: src/PhpSpreadsheet/Writer/Xlsx/Comments.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php + - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" count: 1 @@ -5855,6 +5860,11 @@ parameters: count: 7 path: src/PhpSpreadsheet/Writer/Xlsx/Workbook.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php + - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" count: 1 From 31cf8fb74901cb89824d126423101db4dbfdb067 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 19 Feb 2022 14:05:44 +0100 Subject: [PATCH 25/94] Fix merge conflicts --- src/PhpSpreadsheet/Cell/Cell.php | 2 +- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index c817c93e3d..539558d18a 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -3,8 +3,8 @@ namespace PhpOffice\PhpSpreadsheet\Cell; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\Functions; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Collection\Cells; use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\RichText\RichText; diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index c74908c062..42ea4a897d 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -3,7 +3,6 @@ namespace PhpOffice\PhpSpreadsheet\Writer\Xlsx; use PhpOffice\PhpSpreadsheet\Calculation\Information\Value; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\RichText\RichText; From 8e8e8f42b02919c67411c7127c99b937e39eb983 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 19 Feb 2022 14:11:18 +0100 Subject: [PATCH 26/94] Apply float precision for unit tests --- tests/PhpSpreadsheetTests/Cell/CellTest.php | 2 +- tests/data/Cell/SetValueExplicit.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PhpSpreadsheetTests/Cell/CellTest.php b/tests/PhpSpreadsheetTests/Cell/CellTest.php index 5fcf4eb446..0547616ee3 100644 --- a/tests/PhpSpreadsheetTests/Cell/CellTest.php +++ b/tests/PhpSpreadsheetTests/Cell/CellTest.php @@ -24,7 +24,7 @@ public function testSetValueExplicit($expected, $value, string $dataType): void $cell = $spreadsheet->getActiveSheet()->getCell('A1'); $cell->setValueExplicit($value, $dataType); - self::assertSame($expected, $cell->getValue()); + self::assertEqualsWithDelta($expected, $cell->getValue(), 1.0e-12); $spreadsheet->disconnectWorksheets(); } diff --git a/tests/data/Cell/SetValueExplicit.php b/tests/data/Cell/SetValueExplicit.php index 2ba4a1531b..b38bf1b9b0 100644 --- a/tests/data/Cell/SetValueExplicit.php +++ b/tests/data/Cell/SetValueExplicit.php @@ -44,7 +44,7 @@ DataType::TYPE_FORMULA, ], [ - 44596.5627893519, + 44596.562789351854, '2022-02-04 13:30:25', DataType::TYPE_ISO_DATE, ], From 568921ca7162435d10e768b4d09fb2eff89b4dd1 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 23 Feb 2022 17:28:40 +0100 Subject: [PATCH 27/94] Start work linking cells in spillage areas to the cell containing the spilled formula --- docs/topics/accessing-cells.md | 6 +- docs/topics/calculation-engine.md | 7 +- src/PhpSpreadsheet/Cell/Cell.php | 133 +++++++++++++++++++---------- src/PhpSpreadsheet/IOFactory.php | 15 ++++ src/PhpSpreadsheet/Reader/Xlsx.php | 5 ++ 5 files changed, 117 insertions(+), 49 deletions(-) diff --git a/docs/topics/accessing-cells.md b/docs/topics/accessing-cells.md index 346e5858ee..c7c5ac9143 100644 --- a/docs/topics/accessing-cells.md +++ b/docs/topics/accessing-cells.md @@ -133,10 +133,10 @@ Formats handled by the advanced value binder include: - TRUE or FALSE (dependent on locale settings) are converted to booleans. - Numeric strings identified as scientific (exponential) format are converted to numbers. -- Fractions and vulgar fractions are converted to numbers, and +- Fractions and "vulgar" fractions are converted to numbers, and an appropriate number format mask applied. -- Percentages are converted - to numbers, divided by 100, and an appropriate number format mask +- Percentages are converted to numbers, divided by 100, and an + appropriate number format mask applied. - Dates and times are converted to Excel timestamp values (numbers), and an appropriate number format mask applied. diff --git a/docs/topics/calculation-engine.md b/docs/topics/calculation-engine.md index a228b3115a..4ce407ee4b 100644 --- a/docs/topics/calculation-engine.md +++ b/docs/topics/calculation-engine.md @@ -103,6 +103,11 @@ formula calculation is subject to PHP's language characteristics. Not all functions are supported, for a comprehensive list, read the [function list by name](../references/function-list-by-name.md). +#### Array arguments for Function Calls in Formulae + +While most of the Excel function implementations now support array arguments, there are a few that should accept arrays as arguments but don't do so. +In these cases, the result may be a single value rather than an array; or it may be a `#VALUE!` error. + #### Operator precedence In Excel `+` wins over `&`, just like `*` wins over `+` in ordinary @@ -124,7 +129,7 @@ content. - [Reference for this behaviour in PHP](https://php.net/manual/en/language.types.string.php#language.types.string.conversion) -#### Formulas don’t seem to be calculated in Excel2003 using compatibility pack? +#### Formulae don’t seem to be calculated in Excel2003 using compatibility pack? This is normal behaviour of the compatibility pack, Xlsx displays this correctly. Use `\PhpOffice\PhpSpreadsheet\Writer\Xls` if you really need diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index f072b1fde4..14bb0e9052 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -7,6 +7,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Collection\Cells; use PhpOffice\PhpSpreadsheet\Exception; +use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\RichText\RichText; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\CellStyleAssessor; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; @@ -63,6 +64,11 @@ class Cell */ private $xfIndex = 0; + /** + * @var string + */ + private $arrayFormulaRange; + /** * Attributes of the formula. * @@ -187,10 +193,8 @@ public function getFormattedValue() * Sets the value for a cell, automatically determining the datatype using the value binder * * @param mixed $value Value - * - * @return $this */ - public function setValue($value, bool $isArrayFormula = false, ?string $arrayFormulaRange = null) + public function setValue($value, bool $isArrayFormula = false, ?string $arrayFormulaRange = null): self { if (!self::getValueBinder()->bindValue($this, $value, $isArrayFormula, $arrayFormulaRange)) { throw new Exception('Value could not be bound to cell.'); @@ -211,6 +215,53 @@ protected function formulaAttributes(bool $isArrayFormula, ?string $arrayFormula return []; } + private function arrayFormulaRangeCheck(?string $arrayFormulaRange = null): bool + { + var_dump('CHECKING RANGE', $arrayFormulaRange); + if ($arrayFormulaRange !== null) { + if ($this->isInRange($arrayFormulaRange) && $this->isTopLeftRangeCell($arrayFormulaRange) === false) { + if (IOFactory::isLoading() === false) { + throw new Exception(sprintf( + 'Cell %s is within the spill range of a formula, and cannot be changed', + $this->getCoordinate() + )); + } + } + + return $this->isTopLeftRangeCell($arrayFormulaRange); + } + + return false; + } + + private function clearSpillageRange(string $arrayFormulaRange): void + { + var_dump('CLEAR OLD SPILLAGE RANGE'); + $cellList = Coordinate::extractAllCellReferencesInRange($arrayFormulaRange); + var_dump($cellList); + foreach ($cellList as $cellAddress) { + if ($this->getWorksheet()->cellExists($cellAddress)) { + var_dump("CLEARING SPILLAGE FOR CELL {$cellAddress}"); + } + } + } + + private function setSpillageRange(string $arrayFormulaRange): void + { + var_dump('SET NEW SPILLAGE RANGE'); + $cellList = Coordinate::extractAllCellReferencesInRange($arrayFormulaRange); + var_dump($cellList); + $thisCell = $this->getCoordinate(); + $worksheet = $this->getWorksheet(); + foreach ($cellList as $cellAddress) { + var_dump("SETTING SPILLAGE FOR CELL {$cellAddress}"); + $cell = $worksheet->getCell($cellAddress); + $cell->arrayFormulaRange = $arrayFormulaRange; + } + var_dump("RESETTING CURRENT CELL TO {$thisCell}"); + $worksheet->getCell($thisCell); + } + /** * Set the value for a cell, * with the explicit data type passed to the method (bypassing any use of the value binders). @@ -222,6 +273,17 @@ protected function formulaAttributes(bool $isArrayFormula, ?string $arrayFormula */ public function setValueExplicit($value, $dataType, bool $isArrayFormula = false, ?string $arrayFormulaRange = null) { + var_dump($this->getCoordinate()); + var_dump('CHECKING CURRENT RANGE'); + if ($this->arrayFormulaRangeCheck($this->arrayFormulaRange)) { + $this->clearSpillageRange($arrayFormulaRange); + } + + var_dump('CHECKING NEW RANGE'); + if ($this->arrayFormulaRangeCheck($arrayFormulaRange)) { + $this->setSpillageRange($arrayFormulaRange); + } + // set the value according to data type switch ($dataType) { case DataType::TYPE_NULL: @@ -387,10 +449,8 @@ public function getCalculatedValue($resetLog = true, bool $asArray = false) * Set old calculated value (cached). * * @param mixed $originalValue Value - * - * @return Cell */ - public function setCalculatedValue($originalValue) + public function setCalculatedValue($originalValue): self { if ($originalValue !== null) { $this->calculatedValue = (is_numeric($originalValue)) ? (float) $originalValue : $originalValue; @@ -416,10 +476,8 @@ public function getOldCalculatedValue() /** * Get cell data type. - * - * @return string */ - public function getDataType() + public function getDataType(): string { return $this->dataType; } @@ -428,10 +486,8 @@ public function getDataType() * Set cell data type. * * @param string $dataType see DataType::TYPE_* - * - * @return Cell */ - public function setDataType($dataType) + public function setDataType($dataType): self { if ($dataType == DataType::TYPE_STRING2) { $dataType = DataType::TYPE_STRING; @@ -488,10 +544,8 @@ public function hasDataValidation(): bool /** * Get Data validation rules. - * - * @return DataValidation */ - public function getDataValidation() + public function getDataValidation(): DataValidation { if (!isset($this->parent)) { throw new Exception('Cannot get data validation for cell that is not bound to a worksheet'); @@ -516,10 +570,8 @@ public function setDataValidation(?DataValidation $dataValidation = null): self /** * Does this cell contain valid value? - * - * @return bool */ - public function hasValidValue() + public function hasValidValue(): bool { $validator = new DataValidator(); @@ -528,10 +580,8 @@ public function hasValidValue() /** * Does this cell contain a Hyperlink? - * - * @return bool */ - public function hasHyperlink() + public function hasHyperlink(): bool { if (!isset($this->parent)) { throw new Exception('Cannot check for hyperlink when cell is not bound to a worksheet'); @@ -542,10 +592,8 @@ public function hasHyperlink() /** * Get Hyperlink. - * - * @return Hyperlink */ - public function getHyperlink() + public function getHyperlink(): Hyperlink { if (!isset($this->parent)) { throw new Exception('Cannot get hyperlink for cell that is not bound to a worksheet'); @@ -556,10 +604,8 @@ public function getHyperlink() /** * Set Hyperlink. - * - * @return Cell */ - public function setHyperlink(?Hyperlink $hyperlink = null) + public function setHyperlink(?Hyperlink $hyperlink = null): self { if (!isset($this->parent)) { throw new Exception('Cannot set hyperlink for cell that is not bound to a worksheet'); @@ -572,25 +618,21 @@ public function setHyperlink(?Hyperlink $hyperlink = null) /** * Get cell collection. - * - * @return Cells */ - public function getParent() + public function getParent(): Cells { return $this->parent; } /** * Get parent worksheet. - * - * @return Worksheet */ - public function getWorksheet() + public function getWorksheet(): ?Worksheet { try { $worksheet = $this->parent->getParent(); } catch (Throwable $e) { - $worksheet = null; + return null; } if ($worksheet === null) { @@ -602,27 +644,28 @@ public function getWorksheet() /** * Is this cell in a merge range. - * - * @return bool */ - public function isInMergeRange() + public function isInMergeRange(): bool { return (bool) $this->getMergeRange(); } + + private function isTopLeftRangeCell($cellRange): bool + { + $mergeRange = Coordinate::splitRange($cellRange); + [$startCell] = $mergeRange[0]; + + return ($this->getCoordinate() === $startCell); + } + /** * Is this cell the master (top left cell) in a merge range (that holds the actual data value). - * - * @return bool */ - public function isMergeRangeValueCell() + public function isMergeRangeValueCell(): bool { if ($mergeRange = $this->getMergeRange()) { - $mergeRange = Coordinate::splitRange($mergeRange); - [$startCell] = $mergeRange[0]; - if ($this->getCoordinate() === $startCell) { - return true; - } + return $this->isTopLeftRangeCell($mergeRange); } return false; diff --git a/src/PhpSpreadsheet/IOFactory.php b/src/PhpSpreadsheet/IOFactory.php index 91613cb440..d7b64af525 100644 --- a/src/PhpSpreadsheet/IOFactory.php +++ b/src/PhpSpreadsheet/IOFactory.php @@ -36,6 +36,21 @@ abstract class IOFactory 'Mpdf' => Writer\Pdf\Mpdf::class, ]; + /** + * @var bool + */ + protected static $loading = false; + + public static function setLoading(bool $loading): void + { + self::$loading = $loading; + } + + public static function isLoading(): bool + { + return self::$loading; + } + /** * Create Writer\IWriter. */ diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 9317f926c5..6bc975df93 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; use PhpOffice\PhpSpreadsheet\DefinedName; +use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner; use PhpOffice\PhpSpreadsheet\Reader\Xlsx\AutoFilter; use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Chart; @@ -396,6 +397,8 @@ public function load(string $filename, int $flags = 0): Spreadsheet File::assertFile($filename, self::INITIAL_FILE); $this->processFlags($flags); + IOFactory::setLoading(true); + // Initialisations $excel = new Spreadsheet(); $excel->removeSheetByIndex(0); @@ -1671,6 +1674,8 @@ public function load(string $filename, int $flags = 0): Spreadsheet $zip->close(); + IOFactory::setLoading(false); + return $excel; } From 7d5dc726b7d1f87b7115be4104d7844031276eeb Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 23 Feb 2022 23:09:30 +0100 Subject: [PATCH 28/94] Maintain reference for cells inside a spillage range to prevent their being updated; but allow update of the actual formula cell (adjusting spillage range sa required), and allow setting/update during file load. Additional unit tests for setting/clearing spillage range for array formulae Plus a bugfix when worksheet context lost on clearing a spillage range --- .../Internal/ExcelArrayPseudoFunctions.php | 19 ++--- src/PhpSpreadsheet/Cell/Cell.php | 67 ++++++++------- src/PhpSpreadsheet/Reader/BaseReader.php | 7 +- src/PhpSpreadsheet/Reader/Xlsx.php | 5 -- .../Calculation/InternalFunctionsTest.php | 1 - .../Cell/CellArrayFormulaTest.php | 81 +++++++++++++++++++ 6 files changed, 134 insertions(+), 46 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php diff --git a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php index bc3db6bba5..6bae57871f 100644 --- a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php +++ b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -31,7 +31,7 @@ public static function anchorArray(string $cellReference, Cell $cell): array { $coordinate = $cell->getCoordinate(); $worksheet = $cell->getWorksheet(); - $value = $cell->getValue(); +// $value = $cell->getValue(); [$referenceWorksheetName, $referenceCellCoordinate] = Worksheet::extractSheetTitle($cellReference, true); $referenceCell = ($referenceWorksheetName === '') @@ -70,19 +70,20 @@ public static function anchorArray(string $cellReference, Cell $cell): array // ); // Calculate the array formula range that we should set for our target, based on our target cell coordinate - [$col, $row] = Coordinate::indexesFromString($coordinate); - $row += count($result) - 1; - $col = Coordinate::stringFromColumnIndex($col + count($result[0]) - 1); - $formulaAttributes = ['t' => 'array', 'ref' => "{$coordinate}:{$col}{$row}"]; +// [$col, $row] = Coordinate::indexesFromString($coordinate); +// $row += count($result) - 1; +// $col = Coordinate::stringFromColumnIndex($col + count($result[0]) - 1); +// $arrayFormulaRange = "{$coordinate}:{$col}{$row}"; +// $formulaAttributes = ['t' => 'array', 'ref' => $arrayFormulaRange]; // Using fromArray() would reset the value for this cell with the calculation result // as well as updating the spillage cells, // so we need to restore this cell to its formula value, attributes, and datatype - $cell = $worksheet->getCell($coordinate); - $cell->setValueExplicit($value, DataType::TYPE_FORMULA); - $cell->setFormulaAttributes($formulaAttributes); +// $cell = $worksheet->getCell($coordinate); +// $cell->setValueExplicit($value, DataType::TYPE_FORMULA, true, $arrayFormulaRange); +// $cell->setFormulaAttributes($formulaAttributes); - $cell->updateInCollection(); +// $cell->updateInCollection(); return $result; } diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 14bb0e9052..7c64c96eab 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -65,7 +65,7 @@ class Cell private $xfIndex = 0; /** - * @var string + * @var ?string */ private $arrayFormulaRange; @@ -217,12 +217,11 @@ protected function formulaAttributes(bool $isArrayFormula, ?string $arrayFormula private function arrayFormulaRangeCheck(?string $arrayFormulaRange = null): bool { - var_dump('CHECKING RANGE', $arrayFormulaRange); if ($arrayFormulaRange !== null) { if ($this->isInRange($arrayFormulaRange) && $this->isTopLeftRangeCell($arrayFormulaRange) === false) { if (IOFactory::isLoading() === false) { throw new Exception(sprintf( - 'Cell %s is within the spill range of a formula, and cannot be changed', + 'Cell %s is within the spillage range of a formula, and cannot be changed', $this->getCoordinate() )); } @@ -236,29 +235,29 @@ private function arrayFormulaRangeCheck(?string $arrayFormulaRange = null): bool private function clearSpillageRange(string $arrayFormulaRange): void { - var_dump('CLEAR OLD SPILLAGE RANGE'); - $cellList = Coordinate::extractAllCellReferencesInRange($arrayFormulaRange); - var_dump($cellList); - foreach ($cellList as $cellAddress) { - if ($this->getWorksheet()->cellExists($cellAddress)) { - var_dump("CLEARING SPILLAGE FOR CELL {$cellAddress}"); + $thisCell = $this->getCoordinate(); + $worksheet = $this->getWorksheet(); + + foreach (Coordinate::extractAllCellReferencesInRange($arrayFormulaRange) as $cellAddress) { + if ($worksheet->cellExists($cellAddress)) { + $cell = $worksheet->getCell($cellAddress); + $cell->arrayFormulaRange = null; } } + + $worksheet->getCell($thisCell); } private function setSpillageRange(string $arrayFormulaRange): void { - var_dump('SET NEW SPILLAGE RANGE'); - $cellList = Coordinate::extractAllCellReferencesInRange($arrayFormulaRange); - var_dump($cellList); $thisCell = $this->getCoordinate(); $worksheet = $this->getWorksheet(); - foreach ($cellList as $cellAddress) { - var_dump("SETTING SPILLAGE FOR CELL {$cellAddress}"); + + foreach (Coordinate::extractAllCellReferencesInRange($arrayFormulaRange) as $cellAddress) { $cell = $worksheet->getCell($cellAddress); $cell->arrayFormulaRange = $arrayFormulaRange; } - var_dump("RESETTING CURRENT CELL TO {$thisCell}"); + $worksheet->getCell($thisCell); } @@ -273,15 +272,12 @@ private function setSpillageRange(string $arrayFormulaRange): void */ public function setValueExplicit($value, $dataType, bool $isArrayFormula = false, ?string $arrayFormulaRange = null) { - var_dump($this->getCoordinate()); - var_dump('CHECKING CURRENT RANGE'); if ($this->arrayFormulaRangeCheck($this->arrayFormulaRange)) { - $this->clearSpillageRange($arrayFormulaRange); + $this->clearSpillageRange((string) $this->arrayFormulaRange); } - var_dump('CHECKING NEW RANGE'); if ($this->arrayFormulaRangeCheck($arrayFormulaRange)) { - $this->setSpillageRange($arrayFormulaRange); + $this->setSpillageRange((string) $arrayFormulaRange); } // set the value according to data type @@ -486,8 +482,10 @@ public function getDataType(): string * Set cell data type. * * @param string $dataType see DataType::TYPE_* + * + * @return Cell */ - public function setDataType($dataType): self + public function setDataType($dataType) { if ($dataType == DataType::TYPE_STRING2) { $dataType = DataType::TYPE_STRING; @@ -544,8 +542,10 @@ public function hasDataValidation(): bool /** * Get Data validation rules. + * + * @return DataValidation */ - public function getDataValidation(): DataValidation + public function getDataValidation() { if (!isset($this->parent)) { throw new Exception('Cannot get data validation for cell that is not bound to a worksheet'); @@ -627,14 +627,13 @@ public function getParent(): Cells /** * Get parent worksheet. */ - public function getWorksheet(): ?Worksheet + public function getWorksheet(): Worksheet { try { $worksheet = $this->parent->getParent(); } catch (Throwable $e) { - return null; + $worksheet = null; } - if ($worksheet === null) { throw new Exception('Worksheet no longer exists'); } @@ -650,13 +649,20 @@ public function isInMergeRange(): bool return (bool) $this->getMergeRange(); } + /** + * Is this cell in an array formula spillage range. + */ + public function isInSpillageRange(): bool + { + return $this->arrayFormulaRange !== null; + } - private function isTopLeftRangeCell($cellRange): bool + private function isTopLeftRangeCell(string $cellRange): bool { $mergeRange = Coordinate::splitRange($cellRange); [$startCell] = $mergeRange[0]; - return ($this->getCoordinate() === $startCell); + return $this->getCoordinate() === $startCell; } /** @@ -664,11 +670,12 @@ private function isTopLeftRangeCell($cellRange): bool */ public function isMergeRangeValueCell(): bool { - if ($mergeRange = $this->getMergeRange()) { - return $this->isTopLeftRangeCell($mergeRange); + $mergeRange = $this->getMergeRange(); + if ($mergeRange === false) { + return false; } - return false; + return $this->isTopLeftRangeCell($mergeRange); } /** diff --git a/src/PhpSpreadsheet/Reader/BaseReader.php b/src/PhpSpreadsheet/Reader/BaseReader.php index c215e65b64..9376a75d6a 100644 --- a/src/PhpSpreadsheet/Reader/BaseReader.php +++ b/src/PhpSpreadsheet/Reader/BaseReader.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; +use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException; use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner; use PhpOffice\PhpSpreadsheet\Shared\File; @@ -158,10 +159,14 @@ public function load(string $filename, int $flags = 0): Spreadsheet { $this->processFlags($flags); + IOFactory::setLoading(true); + try { return $this->loadSpreadsheetFromFile($filename); } catch (ReaderException $e) { throw $e; + } finally { + IOFactory::setLoading(false); } } @@ -178,7 +183,7 @@ protected function openFile(string $filename): void $fileHandle = fopen($filename, 'rb'); } if ($fileHandle === false) { - throw new ReaderException('Could not open file ' . $filename . ' for reading.'); + throw new ReaderException("Could not open file {$filename} for reading."); } $this->fileHandle = $fileHandle; diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index b1fb7da7c0..8cbaab03af 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -6,7 +6,6 @@ use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; use PhpOffice\PhpSpreadsheet\DefinedName; -use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner; use PhpOffice\PhpSpreadsheet\Reader\Xlsx\AutoFilter; use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Chart; @@ -396,8 +395,6 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet { File::assertFile($filename, self::INITIAL_FILE); - IOFactory::setLoading(true); - // Initialisations $excel = new Spreadsheet(); $excel->removeSheetByIndex(0); @@ -1673,8 +1670,6 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet $zip->close(); - IOFactory::setLoading(false); - return $excel; } diff --git a/tests/PhpSpreadsheetTests/Calculation/InternalFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/InternalFunctionsTest.php index 1d59a7a554..24399d39f3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/InternalFunctionsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/InternalFunctionsTest.php @@ -20,7 +20,6 @@ public function testAnchorArrayFormula(string $reference, string $range, array $ $sheet1->setCellValue('C3', '=SEQUENCE(3,3,-4)', true, 'C3:E5'); $sheet2->setCellValue('C3', '=SEQUENCE(3,3, 9, -1)', true, 'C3:E5'); - $sheet1->setCellValue('A8', "=ANCHORARRAY({$reference})", true, $range); $result1 = $sheet1->getCell('A8')->getCalculatedValue(true, true); diff --git a/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php new file mode 100644 index 0000000000..650e4e617e --- /dev/null +++ b/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php @@ -0,0 +1,81 @@ +getActiveSheet()->getCell('A1'); + $cell->setValueExplicit('=MAX(ABS({5, -3; 1, -12}))', DataType::TYPE_FORMULA, true); + + self::assertSame(12, $cell->getCalculatedValue()); + self::assertTrue($cell->isArrayFormula()); + self::assertSame('A1', $cell->arrayFormulaRange()); + + $spreadsheet->disconnectWorksheets(); + } + + public function testSetValueArrayFormulaWithSpillage(): void + { + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + $cell->setValueExplicit('=SEQUENCE(3, 3, 1, 1)', DataType::TYPE_FORMULA, true, 'A1:C3'); + + self::assertSame(1, $cell->getCalculatedValue()); + self::assertTrue($cell->isArrayFormula()); + self::assertSame('A1:C3', $cell->arrayFormulaRange()); + + $spreadsheet->disconnectWorksheets(); + } + + public function testSetValueInSpillageRangeCell(): void + { + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + $cell->setValueExplicit('=SEQUENCE(3, 3, 1, 1)', DataType::TYPE_FORMULA, true, 'A1:C3'); + + $cellAddress = 'C3'; + $spillageCell = $spreadsheet->getActiveSheet()->getCell($cellAddress); + self::assertTrue($spillageCell->isInSpillageRange()); + + $spreadsheet->disconnectWorksheets(); + } + + public function testUpdateArrayFormulaForSpillageRange(): void + { + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + $cell->setValueExplicit('=SEQUENCE(3, 3, 1, 1)', DataType::TYPE_FORMULA, true, 'A1:C3'); + + $cell->setValueExplicit('=SEQUENCE(2, 2, 4, -1)', DataType::TYPE_FORMULA, true, 'A1:B2'); + + self::assertSame(4, $cell->getCalculatedValue()); + self::assertTrue($cell->isArrayFormula()); + self::assertSame('A1:B2', $cell->arrayFormulaRange()); + + $spreadsheet->disconnectWorksheets(); + } + + public function testSetValueToFormerSpillageCell(): void + { + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + $cell->setValueExplicit('=SEQUENCE(3, 3, 1, 1)', DataType::TYPE_FORMULA, true, 'A1:C3'); + + $cell->setValueExplicit('=SEQUENCE(2, 2, 4, -1)', DataType::TYPE_FORMULA, true, 'A1:B2'); + + $cellAddress = 'C3'; + $formerSpillageCell = $spreadsheet->getActiveSheet()->getCell($cellAddress); + $formerSpillageCell->setValue('PHP'); + + self::assertSame('PHP', $formerSpillageCell->getValue()); + + $spreadsheet->disconnectWorksheets(); + } +} From b929dd17b54fe0b720442cf2a04cf9a4ac86be39 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 24 Feb 2022 22:00:13 +0100 Subject: [PATCH 29/94] Ensure that the `fromArray()` and `toArray()` functions retain the current cell --- .../Calculation/Calculation.php | 2 +- .../Internal/ExcelArrayPseudoFunctions.php | 2 +- src/PhpSpreadsheet/Cell/Cell.php | 20 +++++++++------- src/PhpSpreadsheet/Worksheet/Worksheet.php | 23 +++++++++++++++++-- .../Cell/CellArrayFormulaTest.php | 18 +++++++++++++++ .../Worksheet/WorksheetTest.php | 21 +++++++++++++++++ 6 files changed, 74 insertions(+), 12 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 3990e42fac..6ddd7422af 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -3323,7 +3323,7 @@ public function calculate(?Cell $cell = null) * * @return mixed */ - public function calculateCellValue(?Cell $cell = null, $resetLog = true) + public function calculateCellValue(?Cell $cell = null, bool $resetLog = true, bool $asArray = false) { if ($cell === null) { return null; diff --git a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php index 6bae57871f..3e279e373e 100644 --- a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php +++ b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -47,7 +47,7 @@ public static function anchorArray(string $cellReference, Cell $cell): array } $calcEngine = Calculation::getInstance($worksheet->getParent()); - $result = $calcEngine->calculateCellValue($referenceCell); + $result = $calcEngine->calculateCellValue($referenceCell, false, true); if (!is_array($result)) { $result = [[$result]]; } diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 7c64c96eab..fb97ae56ef 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -241,7 +241,10 @@ private function clearSpillageRange(string $arrayFormulaRange): void foreach (Coordinate::extractAllCellReferencesInRange($arrayFormulaRange) as $cellAddress) { if ($worksheet->cellExists($cellAddress)) { $cell = $worksheet->getCell($cellAddress); + $cell->value = null; + $cell->dataType = DataType::TYPE_NULL; $cell->arrayFormulaRange = null; + $cell->updateInCollection(); } } @@ -256,6 +259,7 @@ private function setSpillageRange(string $arrayFormulaRange): void foreach (Coordinate::extractAllCellReferencesInRange($arrayFormulaRange) as $cellAddress) { $cell = $worksheet->getCell($cellAddress); $cell->arrayFormulaRange = $arrayFormulaRange; + $cell->updateInCollection(); } $worksheet->getCell($thisCell); @@ -361,12 +365,12 @@ private function processArrayResult( ); // But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? -// $worksheet->fromArray( -// $result, -// null, -// $coordinate, -// true -// ); +// $worksheet->fromArray( +// $result, +// null, +// $coordinate, +// true +// ); // Using fromArray() would reset the value for this cell with the calculation result // as well as updating the spillage cells, // so we need to restore this cell to its formula value, attributes, and datatype @@ -387,7 +391,7 @@ private function processArrayResult( * * @return mixed */ - public function getCalculatedValue($resetLog = true, bool $asArray = false) + public function getCalculatedValue(bool $resetLog = true, bool $asArray = false) { if ($this->dataType === DataType::TYPE_FORMULA) { try { @@ -400,7 +404,7 @@ public function getCalculatedValue($resetLog = true, bool $asArray = false) $result = Calculation::getInstance( $this->getWorksheet()->getParent() - )->calculateCellValue($this, $resetLog); + )->calculateCellValue($this, $resetLog, $asArray); $worksheet->getCell($coordinate); diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 052f6bf0d3..6e6845f0a6 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -2639,6 +2639,8 @@ public function fromArray(array $source, $nullValue = null, $startCell = 'A1', $ $source = [$source]; } + $currentCellAddress = $this->cellCollection->getCurrentCoordinate(); + // start coordinate [$startColumn, $startRow] = Coordinate::coordinateFromString($startCell); @@ -2646,15 +2648,16 @@ public function fromArray(array $source, $nullValue = null, $startCell = 'A1', $ foreach ($source as $rowData) { $currentColumn = $startColumn; foreach ($rowData as $cellValue) { + $cell = $this->getCell($currentColumn . $startRow); if ($strictNullComparison) { if ($cellValue !== $nullValue) { // Set cell value - $this->getCell($currentColumn . $startRow)->setValue($cellValue); + $cell->setValue($cellValue, $cell->isArrayFormula(), $cell->arrayFormulaRange()); } } else { if ($cellValue != $nullValue) { // Set cell value - $this->getCell($currentColumn . $startRow)->setValue($cellValue); + $cell->setValue($cellValue, $cell->isArrayFormula(), $cell->arrayFormulaRange()); } } ++$currentColumn; @@ -2662,6 +2665,10 @@ public function fromArray(array $source, $nullValue = null, $startCell = 'A1', $ ++$startRow; } + if ($currentCellAddress !== null) { + $this->getCell($currentCellAddress); + } + return $this; } @@ -2679,6 +2686,8 @@ public function fromArray(array $source, $nullValue = null, $startCell = 'A1', $ */ public function rangeToArray($range, $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + $currentCellAddress = $this->cellCollection->getCurrentCoordinate(); + // Returnvalue $returnValue = []; // Identify the range that we need to extract from the worksheet @@ -2731,6 +2740,10 @@ public function rangeToArray($range, $nullValue = null, $calculateFormulas = tru } } + if ($currentCellAddress !== null) { + $this->getCell($currentCellAddress); + } + // Return return $returnValue; } @@ -2802,6 +2815,8 @@ public function namedRangeToArray(string $definedName, $nullValue = null, $calcu */ public function toArray($nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false) { + $currentCellAddress = $this->cellCollection->getCurrentCoordinate(); + // Garbage collect... $this->garbageCollect(); @@ -2809,6 +2824,10 @@ public function toArray($nullValue = null, $calculateFormulas = true, $formatDat $maxCol = $this->getHighestColumn(); $maxRow = $this->getHighestRow(); + if ($currentCellAddress !== null) { + $this->getCell($currentCellAddress); + } + // Return return $this->rangeToArray('A1:' . $maxCol . $maxRow, $nullValue, $calculateFormulas, $formatData, $returnCellRef); } diff --git a/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php index 650e4e617e..ceb7f82c8f 100644 --- a/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Cell; use PhpOffice\PhpSpreadsheet\Cell\DataType; +use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PHPUnit\Framework\TestCase; @@ -47,6 +48,23 @@ public function testSetValueInSpillageRangeCell(): void $spreadsheet->disconnectWorksheets(); } + public function testUpdateValueInSpillageRangeCell(): void + { + $spreadsheet = new Spreadsheet(); + $cell = $spreadsheet->getActiveSheet()->getCell('A1'); + $cell->setValueExplicit('=SEQUENCE(3, 3, 1, 1)', DataType::TYPE_FORMULA, true, 'A1:C3'); + + $cellAddress = 'C3'; + $spillageCell = $spreadsheet->getActiveSheet()->getCell($cellAddress); + self::assertTrue($spillageCell->isInSpillageRange()); + + self::expectException(Exception::class); + self::expectExceptionMessage("Cell {$cellAddress} is within the spillage range of a formula, and cannot be changed"); + $spillageCell->setValue('PHP'); + + $spreadsheet->disconnectWorksheets(); + } + public function testUpdateArrayFormulaForSpillageRange(): void { $spreadsheet = new Spreadsheet(); diff --git a/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php b/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php index 5377444d9c..41e07f9ad3 100644 --- a/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php +++ b/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Worksheet; use Exception; +use PhpOffice\PhpSpreadsheet\NamedRange; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use PHPUnit\Framework\TestCase; @@ -125,6 +126,26 @@ public function testSetCodeNameDuplicate(): void self::assertSame('Test Code Name', $sheet->getCodeName()); } + public function testFromAndToArray(): void + { + $testData = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]; + + $workbook = new Spreadsheet(); + $worksheet = $workbook->getActiveSheet(); + $currentCell = 'B2'; + $cell = $worksheet->getCell($currentCell); + + $worksheet->fromArray($testData); + self::assertSame($currentCell, $cell->getCoordinate(), 'Cell retained after fromArray()'); + + self::assertSame($testData, $worksheet->toArray()); + self::assertSame($currentCell, $cell->getCoordinate(), 'Cell retained after toArray()'); + + $workbook->addNamedRange(new NamedRange('NAMED_RANGE', $worksheet, 'A1:C3')); + self::assertSame($testData, $worksheet->namedRangeToArray('NAMED_RANGE')); + self::assertSame($currentCell, $cell->getCoordinate(), 'Cell retained after namedRangeToArray()'); + } + public function testFreezePaneSelectedCell(): void { $worksheet = new Worksheet(); From 38069812cae5bba166712de53798280f3cc168cc Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 24 Feb 2022 22:36:37 +0100 Subject: [PATCH 30/94] Allow recalc of all values for a spillage range --- .../Internal/ExcelArrayPseudoFunctions.php | 3 ++- src/PhpSpreadsheet/Cell/Cell.php | 14 ++++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php index 3e279e373e..c7af11dc28 100644 --- a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php +++ b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -6,7 +6,6 @@ use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Cell\Cell; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; -use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class ExcelArrayPseudoFunctions @@ -62,12 +61,14 @@ public static function anchorArray(string $cellReference, Cell $cell): array // Set the result for our target cell (with spillage) // But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? +// IOFactory::setLoading(true); // $worksheet->fromArray( // $result, // null, // $coordinate, // true // ); +// IOFactory::setLoading(true); // Calculate the array formula range that we should set for our target, based on our target cell coordinate // [$col, $row] = Coordinate::indexesFromString($coordinate); diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index fb97ae56ef..556e965bcf 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -365,12 +365,14 @@ private function processArrayResult( ); // But if we do write it, we get problems with #SPILL! Errors if the spreadsheet is saved // TODO How are we going to identify and handle a #SPILL! or a #CALC! error? -// $worksheet->fromArray( -// $result, -// null, -// $coordinate, -// true -// ); + IOFactory::setLoading(true); + $worksheet->fromArray( + $result, + null, + $coordinate, + true + ); + IOFactory::setLoading(false); // Using fromArray() would reset the value for this cell with the calculation result // as well as updating the spillage cells, // so we need to restore this cell to its formula value, attributes, and datatype From a67cffc7d2759ff181d22384bc86fc8f5911a61f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 24 Feb 2022 23:51:00 +0100 Subject: [PATCH 31/94] minor tweaks --- tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php index ceb7f82c8f..7cccdd4ee2 100644 --- a/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Cell/CellArrayFormulaTest.php @@ -58,8 +58,8 @@ public function testUpdateValueInSpillageRangeCell(): void $spillageCell = $spreadsheet->getActiveSheet()->getCell($cellAddress); self::assertTrue($spillageCell->isInSpillageRange()); - self::expectException(Exception::class); - self::expectExceptionMessage("Cell {$cellAddress} is within the spillage range of a formula, and cannot be changed"); + $this->expectException(Exception::class); + $this->expectExceptionMessage("Cell {$cellAddress} is within the spillage range of a formula, and cannot be changed"); $spillageCell->setValue('PHP'); $spreadsheet->disconnectWorksheets(); From 200713a9b79799b2d8c84872985aacb0fdaf8d02 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 25 Feb 2022 21:17:18 +0100 Subject: [PATCH 32/94] Initial work on ODS reader to support array formulae --- src/PhpSpreadsheet/Reader/Ods.php | 27 ++++++++++++++++++-- src/PhpSpreadsheet/Reader/Ods/BaseReader.php | 1 + 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index 08b8157b65..e3d0b6f50e 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -218,7 +218,7 @@ public function listWorksheetInfo($filename) /** * Loads PhpSpreadsheet from file. */ - protected function loadSpreadsheetFromFile(string $filename): Spreadsheet + public function loadSpreadsheetFromFile(string $filename): Spreadsheet { // Create new Spreadsheet $spreadsheet = new Spreadsheet(); @@ -374,9 +374,12 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) $hasCalculatedValue = false; $cellDataFormula = ''; + $arrayAttributeRows = $arrayAttributeColumns = null; if ($cellData->hasAttributeNS($tableNs, 'formula')) { $cellDataFormula = $cellData->getAttributeNS($tableNs, 'formula'); $hasCalculatedValue = true; + $arrayAttributeRows = $cellData->getAttributeNS($tableNs, 'number-matrix-rows-spanned'); + $arrayAttributeColumns = $cellData->getAttributeNS($tableNs, 'number-matrix-columns-spanned'); } // Annotations @@ -524,10 +527,14 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) $dataValue = null; } + $isArrayFormula = false; + $arrayFormulaRange = null; if ($hasCalculatedValue) { $type = DataType::TYPE_FORMULA; $cellDataFormula = substr($cellDataFormula, strpos($cellDataFormula, ':=') + 1); $cellDataFormula = $this->convertToExcelFormulaValue($cellDataFormula); + $isArrayFormula = (!empty($arrayAttributeRows) && !empty($arrayAttributeColumns)); + $arrayFormulaRange = null; } if ($cellData->hasAttributeNS($tableNs, 'number-columns-repeated')) { @@ -551,7 +558,22 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) // Set value if ($hasCalculatedValue) { - $cell->setValueExplicit($cellDataFormula, $type); + $arrayFormulaRange = null; + if ($isArrayFormula === true) { + $arrayFormulaRange = $columnID . $rID; + $arrayAttributeRows = (int) $arrayAttributeRows; + $arrayAttributeColumns = (int) $arrayAttributeColumns; + if ($arrayAttributeRows > 1 || $arrayAttributeColumns > 1) { + $arrayFormulaRange .= ':' . + Coordinate::stringFromColumnIndex( + Coordinate::columnIndexFromString($columnID) + + $arrayAttributeColumns - 1 + ) . + (string) ($rID + $arrayAttributeRows - 1); + } + } + + $cell->setValueExplicit($cellDataFormula, $type, $isArrayFormula, $arrayFormulaRange); } else { $cell->setValueExplicit($dataValue, $type); } @@ -769,6 +791,7 @@ private function convertToExcelFormulaValue(string $openOfficeFormula): string $value = str_replace('$$', '', $value ?? ''); $value = Calculation::translateSeparator(';', ',', $value, $inBraces); + $value = preg_replace('/COM\.MICROSOFT\./ui', '_xlfn.', $value); } } diff --git a/src/PhpSpreadsheet/Reader/Ods/BaseReader.php b/src/PhpSpreadsheet/Reader/Ods/BaseReader.php index 17e2d4d573..9059bb7310 100644 --- a/src/PhpSpreadsheet/Reader/Ods/BaseReader.php +++ b/src/PhpSpreadsheet/Reader/Ods/BaseReader.php @@ -66,6 +66,7 @@ protected function convertToExcelFormulaValue(string $openOfficeFormula): string $value = str_replace('$$', '', $value ?? ''); $value = Calculation::translateSeparator(';', ',', $value, $inBraces); + $value = preg_replace('/COM\.MICROSOFT\./ui', '', $value); } } From a83e3c6b2ba847d25d07e9cd60f770007c0e7264 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 26 Feb 2022 12:10:11 +0100 Subject: [PATCH 33/94] Initial work on Gnumeric reader to support array formulae --- src/PhpSpreadsheet/Reader/Gnumeric.php | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Reader/Gnumeric.php b/src/PhpSpreadsheet/Reader/Gnumeric.php index ead5ae51c8..46cee36c9d 100644 --- a/src/PhpSpreadsheet/Reader/Gnumeric.php +++ b/src/PhpSpreadsheet/Reader/Gnumeric.php @@ -300,6 +300,8 @@ public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Sp } } + $isArrayFormula = false; + $arrayFormulaRange = null; $ValueType = $cellAttributes->ValueType; $ExprID = (string) $cellAttributes->ExprID; $type = DataType::TYPE_FORMULA; @@ -323,15 +325,29 @@ public function loadIntoExisting(string $filename, Spreadsheet $spreadsheet): Sp } $type = DataType::TYPE_FORMULA; } else { + $cell = (string) $cell; $vtype = (string) $ValueType; if (array_key_exists($vtype, self::$mappings['dataType'])) { $type = self::$mappings['dataType'][$vtype]; } if ($vtype === '20') { // Boolean $cell = $cell == 'TRUE'; + } elseif ($vtype === '' && strlen($cell) > 0 && substr($cell, 0, 1) === '=') { + // Array formula with possible spillage + $type = DataType::TYPE_FORMULA; + $isArrayFormula = true; + $arrayFormulaRange = $column . $row; + $cols = (int) $cellAttributes->Cols; + $rows = (int) $cellAttributes->Rows; + if ($cols > 1 || $rows > 1) { + $arrayFormulaRange .= ':' . + Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($column) + $cols - 1) . + (string) ($row + $rows - 1); + } } } - $this->spreadsheet->getActiveSheet()->getCell($column . $row)->setValueExplicit((string) $cell, $type); + $this->spreadsheet->getActiveSheet()->getCell($column . $row) + ->setValueExplicit($cell, $type, $isArrayFormula, $arrayFormulaRange); } if ($sheet->Styles !== null) { From dc718ddfd6b695d3923bfa1986305c2ee482efb4 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 26 Feb 2022 12:10:46 +0100 Subject: [PATCH 34/94] Rename xlfn functions for Ods --- src/PhpSpreadsheet/Writer/Ods/Content.php | 5 +++++ src/PhpSpreadsheet/Writer/Ods/Formula.php | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/src/PhpSpreadsheet/Writer/Ods/Content.php b/src/PhpSpreadsheet/Writer/Ods/Content.php index a589e54923..d85ac52f42 100644 --- a/src/PhpSpreadsheet/Writer/Ods/Content.php +++ b/src/PhpSpreadsheet/Writer/Ods/Content.php @@ -210,6 +210,11 @@ private function writeCells(XMLWriter $objWriter, Row $row): void // don't do anything } } + if ($cell->isArrayFormula()) { + [$columnSpan, $rowSpan] = Coordinate::rangeDimension((string) $cell->arrayFormulaRange()); + $objWriter->writeAttribute('table:number-matrix-rows-spanned', $rowSpan); + $objWriter->writeAttribute('table:number-matrix-columns-spanned', $columnSpan); + } $objWriter->writeAttribute('table:formula', $this->formulaConvertor->convertFormula($cell->getValue())); if (is_numeric($formulaValue)) { $objWriter->writeAttribute('office:value-type', 'float'); diff --git a/src/PhpSpreadsheet/Writer/Ods/Formula.php b/src/PhpSpreadsheet/Writer/Ods/Formula.php index db766fb42e..6743f08987 100644 --- a/src/PhpSpreadsheet/Writer/Ods/Formula.php +++ b/src/PhpSpreadsheet/Writer/Ods/Formula.php @@ -23,6 +23,7 @@ public function convertFormula(string $formula, string $worksheetName = ''): str { $formula = $this->convertCellReferences($formula, $worksheetName); $formula = $this->convertDefinedNames($formula); + $formula = $this->convertFunctionNames($formula); if (substr($formula, 0, 1) !== '=') { $formula = '=' . $formula; @@ -31,6 +32,11 @@ public function convertFormula(string $formula, string $worksheetName = ''): str return 'of:' . $formula; } + private function convertFunctionNames(string $formula): string + { + return (string) preg_replace('/_xlfn\./ui', 'COM.MICROSOFT.', $formula); + } + private function convertDefinedNames(string $formula): string { $splitCount = preg_match_all( From 5672bd8df16a88fa2d81124afc9a035ecb4abee4 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 26 Feb 2022 17:52:01 +0100 Subject: [PATCH 35/94] Resolve issues introduced during resolution of merge conflicts from master minor refactoring --- phpstan-baseline.neon | 15 ++--- src/PhpSpreadsheet/Cell/Cell.php | 1 + src/PhpSpreadsheet/Cell/DataType.php | 32 ---------- src/PhpSpreadsheet/Reader/Ods.php | 91 ++++++++++++++-------------- src/PhpSpreadsheet/Shared/Date.php | 38 ++++++------ 5 files changed, 74 insertions(+), 103 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index be9a5cb641..f32cfbab87 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -655,6 +655,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Functions.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Calculation/Information/Value.php + - message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#" count: 2 @@ -2210,16 +2215,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Ods.php - - - message: "#^Parameter \\#1 \\$settings of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:lookForActiveSheet\\(\\) expects DOMElement, DOMElement\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods.php - - - - message: "#^Parameter \\#1 \\$settings of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:lookForSelectedCells\\(\\) expects DOMElement, DOMElement\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods.php - - message: "#^While loop condition is always true\\.$#" count: 2 diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 470fe25378..085e895fe2 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -9,6 +9,7 @@ use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\IOFactory; use PhpOffice\PhpSpreadsheet\RichText\RichText; +use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate; use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\CellStyleAssessor; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use PhpOffice\PhpSpreadsheet\Style\Style; diff --git a/src/PhpSpreadsheet/Cell/DataType.php b/src/PhpSpreadsheet/Cell/DataType.php index 7e62f94219..0f7efe2a47 100644 --- a/src/PhpSpreadsheet/Cell/DataType.php +++ b/src/PhpSpreadsheet/Cell/DataType.php @@ -2,10 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Cell; -use DateTime; -use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\RichText\RichText; -use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; class DataType @@ -86,33 +83,4 @@ public static function checkErrorCode($value) return $value; } - - /** - * @param mixed $value - * - * @return float|int - */ - public static function checkIsoDate($value) - { - if (!is_string($value)) { - throw new Exception('Non-string supplied for datatype Date'); - } - - try { - $date = new DateTime($value); - $newValue = SharedDate::PHPToExcel($date); - } catch (\Exception $e) { - throw new Exception("Invalid string $value supplied for datatype Date"); - } - - if ($newValue === false) { - throw new Exception("Invalid string $value supplied for datatype Date"); - } - - if (preg_match('/^\\d\\d:\\d\\d:\\d\\d/', $value) == 1) { - $newValue = fmod($newValue, 1.0); - } - - return $newValue; - } } diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index 2c912ae01a..8d6bfd53cd 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -512,14 +512,10 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) $dataValue = null; } - $isArrayFormula = false; - $arrayFormulaRange = null; if ($hasCalculatedValue) { $type = DataType::TYPE_FORMULA; $cellDataFormula = substr($cellDataFormula, strpos($cellDataFormula, ':=') + 1); $cellDataFormula = $this->convertToExcelFormulaValue($cellDataFormula); - $isArrayFormula = (!empty($arrayAttributeRows) && !empty($arrayAttributeColumns)); - $arrayFormulaRange = null; } if ($cellData->hasAttributeNS($tableNs, 'number-columns-repeated')) { @@ -544,6 +540,7 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) // Set value if ($hasCalculatedValue) { $arrayFormulaRange = null; + $isArrayFormula = (!empty($arrayAttributeRows) && !empty($arrayAttributeColumns)); if ($isArrayFormula === true) { $arrayFormulaRange = $columnID . $rID; $arrayAttributeRows = (int) $arrayAttributeRows; @@ -568,17 +565,10 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) } // Set other properties - if ($formatting !== null) { - $spreadsheet->getActiveSheet() - ->getStyle($columnID . $rID) - ->getNumberFormat() - ->setFormatCode($formatting); - } else { - $spreadsheet->getActiveSheet() - ->getStyle($columnID . $rID) - ->getNumberFormat() - ->setFormatCode(NumberFormat::FORMAT_GENERAL); - } + $spreadsheet->getActiveSheet() + ->getStyle($columnID . $rID) + ->getNumberFormat() + ->setFormatCode($formatting ?? NumberFormat::FORMAT_GENERAL); if ($hyperlink !== null) { $cell->getHyperlink() @@ -590,31 +580,7 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) } // Merged cells - if ( - $cellData->hasAttributeNS($tableNs, 'number-columns-spanned') - || $cellData->hasAttributeNS($tableNs, 'number-rows-spanned') - ) { - if (($type !== DataType::TYPE_NULL) || (!$this->readDataOnly)) { - $columnTo = $columnID; - - if ($cellData->hasAttributeNS($tableNs, 'number-columns-spanned')) { - $columnIndex = Coordinate::columnIndexFromString($columnID); - $columnIndex += (int) $cellData->getAttributeNS($tableNs, 'number-columns-spanned'); - $columnIndex -= 2; - - $columnTo = Coordinate::stringFromColumnIndex($columnIndex + 1); - } - - $rowTo = $rowID; - - if ($cellData->hasAttributeNS($tableNs, 'number-rows-spanned')) { - $rowTo = $rowTo + (int) $cellData->getAttributeNS($tableNs, 'number-rows-spanned') - 1; - } - - $cellRange = $columnID . $rowID . ':' . $columnTo . $rowTo; - $spreadsheet->getActiveSheet()->mergeCells($cellRange); - } - } + $this->processMergedCells($cellData, $tableNs, $type, $columnID, $rowID, $spreadsheet); ++$columnID; } @@ -653,11 +619,13 @@ private function processSettings(ZipArchive $zip, Spreadsheet $spreadsheet): voi $officeNs = $dom->lookupNamespaceUri('office'); $settings = $dom->getElementsByTagNameNS($officeNs, 'settings') ->item(0); - $this->lookForActiveSheet($settings, $spreadsheet, $configNs); - $this->lookForSelectedCells($settings, $spreadsheet, $configNs); + if ($settings !== null) { + $this->activeSheet($settings, $spreadsheet, $configNs); + $this->selectedCells($settings, $spreadsheet, $configNs); + } } - private function lookForActiveSheet(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void + private function activeSheet(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void { /** @var DOMElement $t */ foreach ($settings->getElementsByTagNameNS($configNs, 'config-item') as $t) { @@ -673,7 +641,7 @@ private function lookForActiveSheet(DOMElement $settings, Spreadsheet $spreadshe } } - private function lookForSelectedCells(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void + private function selectedCells(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void { /** @var DOMElement $t */ foreach ($settings->getElementsByTagNameNS($configNs, 'config-item-map-named') as $t) { @@ -785,4 +753,39 @@ private function convertToExcelFormulaValue(string $openOfficeFormula): string return $excelFormula; } + + private function processMergedCells( + DOMElement $cellData, + string $tableNs, + string $type, + string $columnID, + int $rowID, + Spreadsheet $spreadsheet + ): void { + if ( + $cellData->hasAttributeNS($tableNs, 'number-columns-spanned') + || $cellData->hasAttributeNS($tableNs, 'number-rows-spanned') + ) { + if (($type !== DataType::TYPE_NULL) || ($this->readDataOnly === false)) { + $columnTo = $columnID; + + if ($cellData->hasAttributeNS($tableNs, 'number-columns-spanned')) { + $columnIndex = Coordinate::columnIndexFromString($columnID); + $columnIndex += (int) $cellData->getAttributeNS($tableNs, 'number-columns-spanned'); + $columnIndex -= 2; + + $columnTo = Coordinate::stringFromColumnIndex($columnIndex + 1); + } + + $rowTo = $rowID; + + if ($cellData->hasAttributeNS($tableNs, 'number-rows-spanned')) { + $rowTo = $rowTo + (int) $cellData->getAttributeNS($tableNs, 'number-rows-spanned') - 1; + } + + $cellRange = $columnID . $rowID . ':' . $columnTo . $rowTo; + $spreadsheet->getActiveSheet()->mergeCells($cellRange); + } + } + } } diff --git a/src/PhpSpreadsheet/Shared/Date.php b/src/PhpSpreadsheet/Shared/Date.php index 872780737f..8cac2c63e8 100644 --- a/src/PhpSpreadsheet/Shared/Date.php +++ b/src/PhpSpreadsheet/Shared/Date.php @@ -5,11 +5,11 @@ use DateTime; use DateTimeInterface; use DateTimeZone; +use Exception; use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\Cell; -use PhpOffice\PhpSpreadsheet\Exception; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; use PhpOffice\PhpSpreadsheet\Shared\Date as SharedDate; use PhpOffice\PhpSpreadsheet\Style\NumberFormat; @@ -75,10 +75,7 @@ class Date */ public static function setExcelCalendar($baseYear) { - if ( - ($baseYear == self::CALENDAR_WINDOWS_1900) || - ($baseYear == self::CALENDAR_MAC_1904) - ) { + if (($baseYear == self::CALENDAR_WINDOWS_1900) || ($baseYear == self::CALENDAR_MAC_1904)) { self::$excelCalendar = $baseYear; return true; @@ -168,19 +165,23 @@ private static function validateTimeZone($timeZone) public static function convertIsoDate($value) { if (!is_string($value)) { - throw new Exception('Non-string value supplied for Iso Date conversion'); + throw new PhpSpreadsheetException('Non-string value supplied for Iso Date conversion'); } - $date = new DateTime($value); + try { + $date = new DateTime($value); + } catch (Exception $e) { + throw new PhpSpreadsheetException("Invalid string $value supplied for datatype Date"); + } $dateErrors = DateTime::getLastErrors(); if (is_array($dateErrors) && ($dateErrors['warning_count'] > 0 || $dateErrors['error_count'] > 0)) { - throw new Exception("Invalid string $value supplied for datatype Date"); + throw new PhpSpreadsheetException("Invalid string $value supplied for datatype Date"); } $newValue = SharedDate::PHPToExcel($date); if ($newValue === false) { - throw new Exception("Invalid string $value supplied for datatype Date"); + throw new PhpSpreadsheetException("Invalid string $value supplied for datatype Date"); } if (preg_match('/^\\d\\d:\\d\\d:\\d\\d/', $value) == 1) { @@ -194,9 +195,9 @@ public static function convertIsoDate($value) * Convert a MS serialized datetime value from Excel to a PHP Date/Time object. * * @param float|int $excelTimestamp MS Excel serialized date/time value - * @param null|DateTimeZone|string $timeZone The timezone to assume for the Excel timestamp, - * if you don't want to treat it as a UTC value - * Use the default (UTC) unless you absolutely need a conversion + * @param null|DateTimeZone|string $timeZone The timezone to assume for the Excel timestamp + * if you don't want to treat it as a UTC value + * Use the default (UTC) unless you absolutely need a conversion * * @return DateTime PHP date/time object */ @@ -211,7 +212,9 @@ public static function excelToDateTimeObject($excelTimestamp, $timeZone = null) // MS Excel calendar base dates if (self::$excelCalendar == self::CALENDAR_WINDOWS_1900) { // Allow adjustment for 1900 Leap Year in MS Excel - $baseDate = ($excelTimestamp < 60) ? new DateTime('1899-12-31', $timeZone) : new DateTime('1899-12-30', $timeZone); + $baseDate = ($excelTimestamp < 60) + ? new DateTime('1899-12-31', $timeZone) + : new DateTime('1899-12-30', $timeZone); } else { $baseDate = new DateTime('1904-01-01', $timeZone); } @@ -243,9 +246,9 @@ public static function excelToDateTimeObject($excelTimestamp, $timeZone = null) * They are not Y2038-safe on a 32-bit system, and have no timezone info. * * @param float|int $excelTimestamp MS Excel serialized date/time value - * @param null|DateTimeZone|string $timeZone The timezone to assume for the Excel timestamp, - * if you don't want to treat it as a UTC value - * Use the default (UTC) unless you absolutely need a conversion + * @param null|DateTimeZone|string $timeZone The timezone to assume for the Excel timestamp + * if you don't want to treat it as a UTC value + * Use the default (UTC) unless you absolutely need a conversion * * @return int Unix timetamp for this date/time */ @@ -527,7 +530,8 @@ public static function monthStringToNumber($monthName) * * @param string $day Day number with an ordinal * - * @return int|string The integer value with any ordinal stripped, or the original string argument if it isn't a valid numeric + * @return int|string The integer value with any ordinal stripped, + * or the original string argument if it isn't a valid numeric */ public static function dayStringToNumber($day) { From e30e7cbfd41a61e1bdb2d05ca1d126c74dfb7166 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 26 Feb 2022 21:41:37 +0100 Subject: [PATCH 36/94] More unit tests --- .../Reader/Ods/ArrayFormulaTest.php | 31 ++++++++++++++++++ .../Reader/Ods/MergeRangeTest.php | 30 +++++++++++++++++ .../Writer/Ods/ArrayFormulaTest.php | 23 +++++++++++++ .../Writer/Ods/MergeRangeTest.php | 24 ++++++++++++++ tests/data/Reader/Ods/ArrayFormulaTest.ods | Bin 0 -> 8443 bytes tests/data/Reader/Ods/MergeRangeTest.ods | Bin 0 -> 9075 bytes 6 files changed, 108 insertions(+) create mode 100644 tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php create mode 100644 tests/PhpSpreadsheetTests/Reader/Ods/MergeRangeTest.php create mode 100644 tests/PhpSpreadsheetTests/Writer/Ods/ArrayFormulaTest.php create mode 100644 tests/PhpSpreadsheetTests/Writer/Ods/MergeRangeTest.php create mode 100644 tests/data/Reader/Ods/ArrayFormulaTest.ods create mode 100644 tests/data/Reader/Ods/MergeRangeTest.ods diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php new file mode 100644 index 0000000000..b3b6b00bf0 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php @@ -0,0 +1,31 @@ +spreadsheet = $reader->load($filename); + } + + public function testAutoFilterRange(): void + { + $worksheet = $this->spreadsheet->getActiveSheet(); + + $cell = $worksheet->getCell('B2'); + self::assertTrue($cell->isArrayFormula()); + self::assertSame('B2:C3', $cell->arrayFormulaRange()); + } +} diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/MergeRangeTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/MergeRangeTest.php new file mode 100644 index 0000000000..7280e5d30d --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Ods/MergeRangeTest.php @@ -0,0 +1,30 @@ +spreadsheet = $reader->load($filename); + } + + public function testAutoFilterRange(): void + { + $worksheet = $this->spreadsheet->getActiveSheet(); + + $mergeRanges = $worksheet->getMergeCells(); + self::assertArrayHasKey('B2:C3', $mergeRanges); + } +} diff --git a/tests/PhpSpreadsheetTests/Writer/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Writer/Ods/ArrayFormulaTest.php new file mode 100644 index 0000000000..1314c1445f --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Ods/ArrayFormulaTest.php @@ -0,0 +1,23 @@ +getActiveSheet(); + $worksheet->setCellValue('B2', '={2,3}*{4;5}', true, $arrayFormulaRange); + + $reloaded = $this->writeAndReload($spreadsheet, 'Ods'); + + $cell = $reloaded->getActiveSheet()->getCell('B2'); + self::assertTrue($cell->isArrayFormula()); + self::assertSame($arrayFormulaRange, $cell->arrayFormulaRange()); + } +} diff --git a/tests/PhpSpreadsheetTests/Writer/Ods/MergeRangeTest.php b/tests/PhpSpreadsheetTests/Writer/Ods/MergeRangeTest.php new file mode 100644 index 0000000000..30ca697006 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Writer/Ods/MergeRangeTest.php @@ -0,0 +1,24 @@ +getActiveSheet(); + $worksheet->setCellValue('B2', "Merge Range {$mergeRange}"); + $worksheet->mergeCells($mergeRange); + + $reloaded = $this->writeAndReload($spreadsheet, 'Ods'); + + $cell = $reloaded->getActiveSheet()->getCell('B2'); + self::assertTrue($cell->isInMergeRange()); + self::assertSame($mergeRange, $cell->getMergeRange()); + } +} diff --git a/tests/data/Reader/Ods/ArrayFormulaTest.ods b/tests/data/Reader/Ods/ArrayFormulaTest.ods new file mode 100644 index 0000000000000000000000000000000000000000..8ea5f7f4ab3c1d35487a673f5e6dcbe660c9c61e GIT binary patch literal 8443 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 CbRVPu literal 0 HcmV?d00001 diff --git a/tests/data/Reader/Ods/MergeRangeTest.ods b/tests/data/Reader/Ods/MergeRangeTest.ods new file mode 100644 index 0000000000000000000000000000000000000000..49b3739f2507c8b26cadde15ab3c90590d0b337d GIT binary patch literal 9075 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ᨮSZ%NF}T0*#a@wTT`cvwR6)g<3Cku#Bf6zBUahXY-E z98Fp}z)m<2cQ+mHa!S8uB@rI&=A-mhxlF12De+`f8F7hmy57*R89`{-X|RN6lS5O3 z)Fr~gxE?0=WY3roFK%^*0uqHXmMt?BK(urN%;{Tq32ur!m2b)&*|C>rUC)OpRjw@@AD*9n>%yibfGZi#zyqv~pB?IO+AOX74@3F-RW)DRFw!fE>k_gYiVwTB%v z*2SEOPc6Ntk#ceFKk-&G!@^_NlG_I{3%<3}uZ_D^xb zs}CuKV5mHz+>PZE$I<=rc=x5p*~iEiRi7!+q1=_{^3Ih7{bafLnLATV&3+F;qDQHW zoo9+d$u&L;3cNbqXB9)lR1J_=2r76=V<4ztiRUmY8A$mnXX|nucLu=jvVlN<@=2DzuPw*{NG;R-v9v4q|xuD zk7@o{>HfL@@1B1j1;5`%`~vB_^8I_1Gl}=RwP2e65zh}w_oE>n# zn+Rqc{vFSErTq6Oe=WxUz}Wu+n7%gZbgeUq$$Td;M4qIjiV?w`Z8Jf2i+%bNpSgEs*Aw~zgi td4Eom0QJxNw|{&7$R20R{M`cRf5X!{8n_t20stVv`~fkfv&V3D_di-ex1|68 literal 0 HcmV?d00001 From 1574f483ac1b69296ef49f697480b785c0a93c9d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Feb 2022 10:51:06 +0100 Subject: [PATCH 37/94] Resolve `translateSeparator()` method to handle separators (row and column) for array functions as well as for function argument separators; and cleanly handle nesting levels Note that this method is used when translating Excel functions between en and other locale languages, as well as when converting formulae between different spreadsheet formats (e.g. Ods to Excel) Nor is this a perfect solution, as there may still be issues when function calls have array arguments that themselves contain function calls; but it's still better than the current logic --- phpstan-baseline.neon | 2 +- .../Calculation/Calculation.php | 102 ++++++++++-------- tests/data/Calculation/Translations.php | 5 + 3 files changed, 65 insertions(+), 44 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index f32cfbab87..7c1826687a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -167,7 +167,7 @@ parameters: - message: "#^Parameter \\#3 \\$formula of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:translateSeparator\\(\\) expects string, string\\|null given\\.$#" - count: 2 + count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php - diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 6ddd7422af..f4a88973f5 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -50,8 +50,10 @@ class Calculation const RETURN_ARRAY_AS_VALUE = 'value'; const RETURN_ARRAY_AS_ARRAY = 'array'; - const FORMULA_OPEN_FUNCTION_BRACE = '{'; - const FORMULA_CLOSE_FUNCTION_BRACE = '}'; + const FORMULA_OPEN_FUNCTION_BRACE = '('; + const FORMULA_CLOSE_FUNCTION_BRACE = ')'; + const FORMULA_OPEN_MATRIX_BRACE = '{'; + const FORMULA_CLOSE_MATRIX_BRACE = '}'; const FORMULA_STRING_QUOTE = '"'; private static $returnArrayAsType = self::RETURN_ARRAY_AS_VALUE; @@ -3099,30 +3101,28 @@ public function setLocale(string $locale) return false; } - /** - * @param string $fromSeparator - * @param string $toSeparator - * @param string $formula - * @param bool $inBraces - * - * @return string - */ - public static function translateSeparator($fromSeparator, $toSeparator, $formula, &$inBraces) - { + public static function translateSeparator( + string $fromSeparator, + string $toSeparator, + string $formula, + int &$inBracesLevel, + string $openBrace = self::FORMULA_OPEN_FUNCTION_BRACE, + string $closeBrace = self::FORMULA_CLOSE_FUNCTION_BRACE + ): string { $strlen = mb_strlen($formula); for ($i = 0; $i < $strlen; ++$i) { $chr = mb_substr($formula, $i, 1); switch ($chr) { - case self::FORMULA_OPEN_FUNCTION_BRACE: - $inBraces = true; + case $openBrace: + ++$inBracesLevel; break; - case self::FORMULA_CLOSE_FUNCTION_BRACE: - $inBraces = false; + case $closeBrace: + --$inBracesLevel; break; case $fromSeparator: - if (!$inBraces) { + if ($inBracesLevel > 0) { $formula = mb_substr($formula, 0, $i) . $toSeparator . mb_substr($formula, $i + 1); } } @@ -3131,31 +3131,47 @@ public static function translateSeparator($fromSeparator, $toSeparator, $formula return $formula; } - /** - * @param string[] $from - * @param string[] $to - * @param string $formula - * @param string $fromSeparator - * @param string $toSeparator - * - * @return string - */ - private static function translateFormula(array $from, array $to, $formula, $fromSeparator, $toSeparator) + private static function translateFormulaBlock( + array $from, + array $to, + string $formula, + int &$inFunctionBracesLevel, + int &$inMatrixBracesLevel, + string $fromSeparator, + string $toSeparator + ): string { + // Function Names + $formula = preg_replace($from, $to, $formula); + + // Temporarily adjust matrix separators so that they won't be confused with function arguments + $formula = self::translateSeparator(';', '|', $formula, $inMatrixBracesLevel, self::FORMULA_OPEN_MATRIX_BRACE, self::FORMULA_CLOSE_MATRIX_BRACE); + $formula = self::translateSeparator(',', '!', $formula, $inMatrixBracesLevel, self::FORMULA_OPEN_MATRIX_BRACE, self::FORMULA_CLOSE_MATRIX_BRACE); + // Function Argument Separators + $formula = self::translateSeparator($fromSeparator, $toSeparator, $formula, $inFunctionBracesLevel); + // Restore matrix separators + $formula = self::translateSeparator('|', ';', $formula, $inMatrixBracesLevel, self::FORMULA_OPEN_MATRIX_BRACE, self::FORMULA_CLOSE_MATRIX_BRACE); + $formula = self::translateSeparator('!', ',', $formula, $inMatrixBracesLevel, self::FORMULA_OPEN_MATRIX_BRACE, self::FORMULA_CLOSE_MATRIX_BRACE); + + return $formula; + } + + private static function translateFormula(array $from, array $to, string $formula, string $fromSeparator, string $toSeparator): string { - // Convert any Excel function names to the required language + // Convert any Excel function names and constant names to the required language; + // and adjust function argument separators if (self::$localeLanguage !== 'en_us') { - $inBraces = false; - // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators + $inFunctionBracesLevel = 0; + $inMatrixBracesLevel = 0; + // If there is the possibility of separators within a quoted string, then we treat them as literals if (strpos($formula, self::FORMULA_STRING_QUOTE) !== false) { - // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded - // the formula + // So instead we skip replacing in any quoted strings by only replacing in every other array element + // after we've exploded the formula $temp = explode(self::FORMULA_STRING_QUOTE, $formula); $i = false; foreach ($temp as &$value) { - // Only count/replace in alternating array entries + // Only adjust in alternating array entries if ($i = !$i) { - $value = preg_replace($from, $to, $value); - $value = self::translateSeparator($fromSeparator, $toSeparator, $value, $inBraces); + $value = self::translateFormulaBlock($from, $to, $value, $inFunctionBracesLevel, $inMatrixBracesLevel, $fromSeparator, $toSeparator); } } unset($value); @@ -3163,8 +3179,7 @@ private static function translateFormula(array $from, array $to, $formula, $from $formula = implode(self::FORMULA_STRING_QUOTE, $temp); } else { // If there's no quoted strings, then we do a simple count/replace - $formula = preg_replace($from, $to, $formula); - $formula = self::translateSeparator($fromSeparator, $toSeparator, $formula, $inBraces); + $formula = self::translateFormulaBlock($from, $to, $formula, $inFunctionBracesLevel, $inMatrixBracesLevel, $fromSeparator, $toSeparator); } } @@ -3177,6 +3192,7 @@ private static function translateFormula(array $from, array $to, $formula, $from public function _translateFormulaToLocale($formula) { + // Build list of function names and constants for translation if (self::$functionReplaceFromExcel === null) { self::$functionReplaceFromExcel = []; foreach (array_keys(self::$localeFunctions) as $excelFunctionName) { @@ -3813,11 +3829,11 @@ private function showTypeDetails($value) */ private function convertMatrixReferences($formula) { - static $matrixReplaceFrom = [self::FORMULA_OPEN_FUNCTION_BRACE, ';', self::FORMULA_CLOSE_FUNCTION_BRACE]; + static $matrixReplaceFrom = [self::FORMULA_OPEN_MATRIX_BRACE, ';', self::FORMULA_CLOSE_MATRIX_BRACE]; static $matrixReplaceTo = ['MKMATRIX(MKMATRIX(', '),MKMATRIX(', '))']; // Convert any Excel matrix references to the MKMATRIX() function - if (strpos($formula, self::FORMULA_OPEN_FUNCTION_BRACE) !== false) { + if (strpos($formula, self::FORMULA_OPEN_MATRIX_BRACE) !== false) { // If there is the possibility of braces within a quoted string, then we don't treat those as matrix indicators if (strpos($formula, self::FORMULA_STRING_QUOTE) !== false) { // So instead we skip replacing in any quoted strings by only replacing in every other array element after we've exploded @@ -3829,8 +3845,8 @@ private function convertMatrixReferences($formula) foreach ($temp as &$value) { // Only count/replace in alternating array entries if ($i = !$i) { - $openCount += substr_count($value, self::FORMULA_OPEN_FUNCTION_BRACE); - $closeCount += substr_count($value, self::FORMULA_CLOSE_FUNCTION_BRACE); + $openCount += substr_count($value, self::FORMULA_OPEN_MATRIX_BRACE); + $closeCount += substr_count($value, self::FORMULA_CLOSE_MATRIX_BRACE); $value = str_replace($matrixReplaceFrom, $matrixReplaceTo, $value); } } @@ -3839,8 +3855,8 @@ private function convertMatrixReferences($formula) $formula = implode(self::FORMULA_STRING_QUOTE, $temp); } else { // If there's no quoted strings, then we do a simple count/replace - $openCount = substr_count($formula, self::FORMULA_OPEN_FUNCTION_BRACE); - $closeCount = substr_count($formula, self::FORMULA_CLOSE_FUNCTION_BRACE); + $openCount = substr_count($formula, self::FORMULA_OPEN_MATRIX_BRACE); + $closeCount = substr_count($formula, self::FORMULA_CLOSE_MATRIX_BRACE); $formula = str_replace($matrixReplaceFrom, $matrixReplaceTo, $formula); } // Trap for mismatched braces and trigger an appropriate error diff --git a/tests/data/Calculation/Translations.php b/tests/data/Calculation/Translations.php index aaf6e3f2c1..604c672179 100644 --- a/tests/data/Calculation/Translations.php +++ b/tests/data/Calculation/Translations.php @@ -75,4 +75,9 @@ 'tr', '=WORKDAY.INTL(B1)', ], + [ + '=STØRST(ABS({2,-3;-4,5}); ABS{-2,3;4,-5})', + 'nb', + '=MAX(ABS({2,-3;-4,5}), ABS{-2,3;4,-5})', + ], ]; From 9413f00497a26ab562dfebe8c6481bbc06bff761 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Feb 2022 12:21:35 +0100 Subject: [PATCH 38/94] Some Refactoring of the Ods Reader, moving all formula and address translation from Ods to Excel into a separate class to eliminate code duplication --- src/PhpSpreadsheet/Reader/Ods.php | 33 +----------- src/PhpSpreadsheet/Reader/Ods/AutoFilter.php | 4 +- src/PhpSpreadsheet/Reader/Ods/BaseLoader.php | 27 ++++++++++ .../Reader/Ods/DefinedNames.php | 10 ++-- .../{BaseReader.php => FormulaTranslator.php} | 53 ++++++++++--------- 5 files changed, 64 insertions(+), 63 deletions(-) create mode 100644 src/PhpSpreadsheet/Reader/Ods/BaseLoader.php rename src/PhpSpreadsheet/Reader/Ods/{BaseReader.php => FormulaTranslator.php} (64%) diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index 8d6bfd53cd..c110861223 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -6,11 +6,11 @@ use DOMDocument; use DOMElement; use DOMNode; -use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; use PhpOffice\PhpSpreadsheet\Cell\DataType; use PhpOffice\PhpSpreadsheet\Reader\Ods\AutoFilter; use PhpOffice\PhpSpreadsheet\Reader\Ods\DefinedNames; +use PhpOffice\PhpSpreadsheet\Reader\Ods\FormulaTranslator; use PhpOffice\PhpSpreadsheet\Reader\Ods\PageSettings; use PhpOffice\PhpSpreadsheet\Reader\Ods\Properties as DocumentProperties; use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner; @@ -515,7 +515,7 @@ public function loadIntoExisting($filename, Spreadsheet $spreadsheet) if ($hasCalculatedValue) { $type = DataType::TYPE_FORMULA; $cellDataFormula = substr($cellDataFormula, strpos($cellDataFormula, ':=') + 1); - $cellDataFormula = $this->convertToExcelFormulaValue($cellDataFormula); + $cellDataFormula = FormulaTranslator::convertToExcelFormulaValue($cellDataFormula); } if ($cellData->hasAttributeNS($tableNs, 'number-columns-repeated')) { @@ -725,35 +725,6 @@ private function parseRichText($is) return $value; } - private function convertToExcelFormulaValue(string $openOfficeFormula): string - { - $temp = explode('"', $openOfficeFormula); - $tKey = false; - foreach ($temp as &$value) { - // Only replace in alternate array entries (i.e. non-quoted blocks) - if ($tKey = !$tKey) { - // Cell range reference in another sheet - $value = preg_replace('/\[\$?([^\.]+)\.([^\.]+):\.([^\.]+)\]/miu', '$1!$2:$3', $value); - // Cell reference in another sheet - $value = preg_replace('/\[\$?([^\.]+)\.([^\.]+)\]/miu', '$1!$2', $value ?? ''); - // Cell range reference - $value = preg_replace('/\[\.([^\.]+):\.([^\.]+)\]/miu', '$1:$2', $value ?? ''); - // Simple cell reference - $value = preg_replace('/\[\.([^\.]+)\]/miu', '$1', $value ?? ''); - // Convert references to defined names/formulae - $value = str_replace('$$', '', $value ?? ''); - - $value = Calculation::translateSeparator(';', ',', $value, $inBraces); - $value = preg_replace('/COM\.MICROSOFT\./ui', '_xlfn.', $value); - } - } - - // Then rebuild the formula string - $excelFormula = implode('"', $temp); - - return $excelFormula; - } - private function processMergedCells( DOMElement $cellData, string $tableNs, diff --git a/src/PhpSpreadsheet/Reader/Ods/AutoFilter.php b/src/PhpSpreadsheet/Reader/Ods/AutoFilter.php index bdc8b3ffc3..1f5f975dec 100644 --- a/src/PhpSpreadsheet/Reader/Ods/AutoFilter.php +++ b/src/PhpSpreadsheet/Reader/Ods/AutoFilter.php @@ -5,7 +5,7 @@ use DOMElement; use DOMNode; -class AutoFilter extends BaseReader +class AutoFilter extends BaseLoader { public function read(DOMElement $workbookData): void { @@ -20,7 +20,7 @@ protected function readAutoFilters(DOMElement $workbookData): void foreach ($autofilters->childNodes as $autofilter) { $autofilterRange = $this->getAttributeValue($autofilter, 'target-range-address'); if ($autofilterRange !== null) { - $baseAddress = $this->convertToExcelAddressValue($autofilterRange); + $baseAddress = FormulaTranslator::convertToExcelAddressValue($autofilterRange); $this->spreadsheet->getActiveSheet()->setAutoFilter($baseAddress); } } diff --git a/src/PhpSpreadsheet/Reader/Ods/BaseLoader.php b/src/PhpSpreadsheet/Reader/Ods/BaseLoader.php new file mode 100644 index 0000000000..b06691f42a --- /dev/null +++ b/src/PhpSpreadsheet/Reader/Ods/BaseLoader.php @@ -0,0 +1,27 @@ +spreadsheet = $spreadsheet; + $this->tableNs = $tableNs; + } + + abstract public function read(DOMElement $workbookData): void; +} diff --git a/src/PhpSpreadsheet/Reader/Ods/DefinedNames.php b/src/PhpSpreadsheet/Reader/Ods/DefinedNames.php index 6810a3c726..e0ab8900aa 100644 --- a/src/PhpSpreadsheet/Reader/Ods/DefinedNames.php +++ b/src/PhpSpreadsheet/Reader/Ods/DefinedNames.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\DefinedName; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; -class DefinedNames extends BaseReader +class DefinedNames extends BaseLoader { public function read(DOMElement $workbookData): void { @@ -25,8 +25,8 @@ protected function readDefinedRanges(DOMElement $workbookData): void $baseAddress = $definedNameElement->getAttributeNS($this->tableNs, 'base-cell-address'); $range = $definedNameElement->getAttributeNS($this->tableNs, 'cell-range-address'); - $baseAddress = $this->convertToExcelAddressValue($baseAddress); - $range = $this->convertToExcelAddressValue($range); + $baseAddress = FormulaTranslator::convertToExcelAddressValue($baseAddress); + $range = FormulaTranslator::convertToExcelAddressValue($range); $this->addDefinedName($baseAddress, $definedName, $range); } @@ -43,9 +43,9 @@ protected function readDefinedExpressions(DOMElement $workbookData): void $baseAddress = $definedNameElement->getAttributeNS($this->tableNs, 'base-cell-address'); $expression = $definedNameElement->getAttributeNS($this->tableNs, 'expression'); - $baseAddress = $this->convertToExcelAddressValue($baseAddress); + $baseAddress = FormulaTranslator::convertToExcelAddressValue($baseAddress); $expression = substr($expression, strpos($expression, ':=') + 1); - $expression = $this->convertToExcelFormulaValue($expression); + $expression = FormulaTranslator::convertToExcelFormulaValue($expression); $this->addDefinedName($baseAddress, $definedName, $expression); } diff --git a/src/PhpSpreadsheet/Reader/Ods/BaseReader.php b/src/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php similarity index 64% rename from src/PhpSpreadsheet/Reader/Ods/BaseReader.php rename to src/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php index 9059bb7310..f2ad1a3dff 100644 --- a/src/PhpSpreadsheet/Reader/Ods/BaseReader.php +++ b/src/PhpSpreadsheet/Reader/Ods/FormulaTranslator.php @@ -2,31 +2,11 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Ods; -use DOMElement; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Spreadsheet; -abstract class BaseReader +class FormulaTranslator { - /** - * @var Spreadsheet - */ - protected $spreadsheet; - - /** - * @var string - */ - protected $tableNs; - - public function __construct(Spreadsheet $spreadsheet, string $tableNs) - { - $this->spreadsheet = $spreadsheet; - $this->tableNs = $tableNs; - } - - abstract public function read(DOMElement $workbookData): void; - - protected function convertToExcelAddressValue(string $openOfficeAddress): string + public static function convertToExcelAddressValue(string $openOfficeAddress): string { $excelAddress = $openOfficeAddress; @@ -46,13 +26,16 @@ protected function convertToExcelAddressValue(string $openOfficeAddress): string return $excelAddress ?? ''; } - protected function convertToExcelFormulaValue(string $openOfficeFormula): string + public static function convertToExcelFormulaValue(string $openOfficeFormula): string { - $temp = explode('"', $openOfficeFormula); + $temp = explode(Calculation::FORMULA_STRING_QUOTE, $openOfficeFormula); $tKey = false; + $inMatrixBracesLevel = 0; + $inFunctionBracesLevel = 0; foreach ($temp as &$value) { // @var string $value // Only replace in alternate array entries (i.e. non-quoted blocks) + // so that conversion isn't done in string values if ($tKey = !$tKey) { // Cell range reference in another sheet $value = preg_replace('/\[\$?([^\.]+)\.([^\.]+):\.([^\.]+)\]/miu', '$1!$2:$3', $value); @@ -65,7 +48,27 @@ protected function convertToExcelFormulaValue(string $openOfficeFormula): string // Convert references to defined names/formulae $value = str_replace('$$', '', $value ?? ''); - $value = Calculation::translateSeparator(';', ',', $value, $inBraces); + // Convert ODS function argument separators to Excel function argument separators + $value = Calculation::translateSeparator(';', ',', $value, $inFunctionBracesLevel); + + // Convert ODS matrix separators to Excel matrix separators + $value = Calculation::translateSeparator( + ';', + ',', + $value, + $inMatrixBracesLevel, + Calculation::FORMULA_OPEN_MATRIX_BRACE, + Calculation::FORMULA_CLOSE_MATRIX_BRACE + ); + $value = Calculation::translateSeparator( + '|', + ';', + $value, + $inMatrixBracesLevel, + Calculation::FORMULA_OPEN_MATRIX_BRACE, + Calculation::FORMULA_CLOSE_MATRIX_BRACE + ); + $value = preg_replace('/COM\.MICROSOFT\./ui', '', $value); } } From e1f278bb2031fef2bfe63018b60c9a84d475270c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Feb 2022 12:45:20 +0100 Subject: [PATCH 39/94] Unit tests for reading/writing array formulae from Ods --- tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php index b3b6b00bf0..db99dfbb56 100644 --- a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Reader\Ods; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PHPUnit\Framework\TestCase; @@ -20,12 +21,14 @@ protected function setUp(): void $this->spreadsheet = $reader->load($filename); } - public function testAutoFilterRange(): void + public function testArrayFormulaReader(): void { $worksheet = $this->spreadsheet->getActiveSheet(); $cell = $worksheet->getCell('B2'); self::assertTrue($cell->isArrayFormula()); self::assertSame('B2:C3', $cell->arrayFormulaRange()); + Calculation::getInstance($this->spreadsheet)->flushInstance(); + self::assertSame('={2,3}*{4;5}', $cell->getValue()); } } From cff8303f1b95cb6cccb983c4fc56de803c3a52c0 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Feb 2022 14:15:49 +0100 Subject: [PATCH 40/94] Re-merge from baseline --- phpstan-baseline.neon | 5 +++++ src/PhpSpreadsheet/Reader/Ods.php | 4 ++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 7c1826687a..4023dcf1e6 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2170,6 +2170,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Html.php + - + message: "#^Call to an undefined method DOMNode\\:\\:getElementsByTagNameNS\\(\\)\\.$#" + count: 2 + path: src/PhpSpreadsheet/Reader/Ods.php + - message: "#^Cannot call method children\\(\\) on SimpleXMLElement\\|false\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index c110861223..4d4730af7a 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -625,7 +625,7 @@ private function processSettings(ZipArchive $zip, Spreadsheet $spreadsheet): voi } } - private function activeSheet(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void + private function activeSheet(DOMNode $settings, Spreadsheet $spreadsheet, string $configNs): void { /** @var DOMElement $t */ foreach ($settings->getElementsByTagNameNS($configNs, 'config-item') as $t) { @@ -641,7 +641,7 @@ private function activeSheet(DOMElement $settings, Spreadsheet $spreadsheet, str } } - private function selectedCells(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void + private function selectedCells(DOMNode $settings, Spreadsheet $spreadsheet, string $configNs): void { /** @var DOMElement $t */ foreach ($settings->getElementsByTagNameNS($configNs, 'config-item-map-named') as $t) { From 55be3b4b5a7c7493ad156a62b9494f1cc5e201a2 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Feb 2022 22:05:44 +0100 Subject: [PATCH 41/94] Minor typehint fixes --- src/PhpSpreadsheet/Reader/Ods.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php index 4d4730af7a..c110861223 100644 --- a/src/PhpSpreadsheet/Reader/Ods.php +++ b/src/PhpSpreadsheet/Reader/Ods.php @@ -625,7 +625,7 @@ private function processSettings(ZipArchive $zip, Spreadsheet $spreadsheet): voi } } - private function activeSheet(DOMNode $settings, Spreadsheet $spreadsheet, string $configNs): void + private function activeSheet(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void { /** @var DOMElement $t */ foreach ($settings->getElementsByTagNameNS($configNs, 'config-item') as $t) { @@ -641,7 +641,7 @@ private function activeSheet(DOMNode $settings, Spreadsheet $spreadsheet, string } } - private function selectedCells(DOMNode $settings, Spreadsheet $spreadsheet, string $configNs): void + private function selectedCells(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void { /** @var DOMElement $t */ foreach ($settings->getElementsByTagNameNS($configNs, 'config-item-map-named') as $t) { From f64e2c240822e1451c6b97ff6da12ae3d4bff02a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 27 Feb 2022 22:19:12 +0100 Subject: [PATCH 42/94] Prep-work for handling matrix arithmetic in the calc engine, with some basic unit tests --- .../Calculation/Calculation.php | 2 ++ .../Calculation/ArrayFormulaTest.php | 22 ++++++++++++++++++ .../Reader/Ods/ArrayFormulaTest.php | 10 ++++++-- tests/data/Reader/Ods/ArrayFormulaTest.ods | Bin 8443 -> 11949 bytes 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index f4a88973f5..740defd1b1 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -3364,6 +3364,7 @@ public function calculateCellValue(?Cell $cell = null, bool $resetLog = true, bo try { $result = self::unwrapResult($this->_calculateFormulaValue($cell->getValue(), $cell->getCoordinate(), $cell)); + $cellAddress = array_pop($this->cellStack); $this->spreadsheet->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); } catch (\Exception $e) { @@ -4942,6 +4943,7 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null) return $this->raiseFormulaError('internal error'); } $output = $stack->pop(); + $output = $output['value']; return $output; diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index ef8c398248..d6e0dae17b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -73,4 +73,26 @@ public function providerArrayFormulae(): array ], ]; } + + /** + * @dataProvider providerArrayArithmetic + * + * @param mixed $expectedResult + */ + public function testArrayArithmetic(string $formula, $expectedResult): void + { + $result = Calculation::getInstance()->_calculateFormulaValue($formula); + var_dump($result); + self::assertEquals($expectedResult, $result); + } + + public function providerArrayArithmetic(): array + { + return [ + [ + '={2,3}*{4;5}', + [[8, 12], [10, 15]], + ], + ]; + } } diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php index db99dfbb56..b4107c2a6f 100644 --- a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php @@ -2,7 +2,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Reader\Ods; -use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Reader\Ods; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PHPUnit\Framework\TestCase; @@ -28,7 +27,14 @@ public function testArrayFormulaReader(): void $cell = $worksheet->getCell('B2'); self::assertTrue($cell->isArrayFormula()); self::assertSame('B2:C3', $cell->arrayFormulaRange()); - Calculation::getInstance($this->spreadsheet)->flushInstance(); self::assertSame('={2,3}*{4;5}', $cell->getValue()); + var_dump($worksheet->getCell('B2')->getValue()); +// var_dump($worksheet->getCell('B2')->getCalculatedValue(true, true)); // Is currently resetting the range to NULLs + var_dump($worksheet->getCell('C2')->getValue()); +// var_dump($worksheet->getCell('C2')->getCalculatedValue()); + var_dump($worksheet->getCell('B3')->getValue()); +// var_dump($worksheet->getCell('B3')->getCalculatedValue()); + var_dump($worksheet->getCell('C3')->getValue()); +// var_dump($worksheet->getCell('C3')->getCalculatedValue()); } } diff --git a/tests/data/Reader/Ods/ArrayFormulaTest.ods b/tests/data/Reader/Ods/ArrayFormulaTest.ods index 8ea5f7f4ab3c1d35487a673f5e6dcbe660c9c61e..f34c5b5da925458ae97b972bf3f12dc605b4fdcc 100644 GIT binary patch delta 6942 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 Date: Fri, 4 Mar 2022 16:12:14 +0100 Subject: [PATCH 43/94] Suppress tests that we know will fail (for the moment) --- phpstan-baseline.neon | 5 ----- .../Calculation/ArrayFormulaTest.php | 4 ++-- .../Reader/Ods/ArrayFormulaTest.php | 22 +++++++++---------- 3 files changed, 13 insertions(+), 18 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 7212e8dc79..374494a53f 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2140,11 +2140,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Html.php - - - message: "#^Call to an undefined method DOMNode\\:\\:getElementsByTagNameNS\\(\\)\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Ods.php - - message: "#^Cannot call method children\\(\\) on SimpleXMLElement\\|false\\.$#" count: 1 diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index d6e0dae17b..88643c182b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -82,8 +82,8 @@ public function providerArrayFormulae(): array public function testArrayArithmetic(string $formula, $expectedResult): void { $result = Calculation::getInstance()->_calculateFormulaValue($formula); - var_dump($result); - self::assertEquals($expectedResult, $result); +// var_dump($result); +// self::assertEquals($expectedResult, $result); } public function providerArrayArithmetic(): array diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php index b4107c2a6f..6c9bb4b417 100644 --- a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php @@ -25,16 +25,16 @@ public function testArrayFormulaReader(): void $worksheet = $this->spreadsheet->getActiveSheet(); $cell = $worksheet->getCell('B2'); - self::assertTrue($cell->isArrayFormula()); - self::assertSame('B2:C3', $cell->arrayFormulaRange()); - self::assertSame('={2,3}*{4;5}', $cell->getValue()); - var_dump($worksheet->getCell('B2')->getValue()); -// var_dump($worksheet->getCell('B2')->getCalculatedValue(true, true)); // Is currently resetting the range to NULLs - var_dump($worksheet->getCell('C2')->getValue()); -// var_dump($worksheet->getCell('C2')->getCalculatedValue()); - var_dump($worksheet->getCell('B3')->getValue()); -// var_dump($worksheet->getCell('B3')->getCalculatedValue()); - var_dump($worksheet->getCell('C3')->getValue()); -// var_dump($worksheet->getCell('C3')->getCalculatedValue()); +// self::assertTrue($cell->isArrayFormula()); +// self::assertSame('B2:C3', $cell->arrayFormulaRange()); +// self::assertSame('={2,3}*{4;5}', $cell->getValue()); +// var_dump($worksheet->getCell('B2')->getValue()); +//// var_dump($worksheet->getCell('B2')->getCalculatedValue(true, true)); // Is currently resetting the range to NULLs +// var_dump($worksheet->getCell('C2')->getValue()); +//// var_dump($worksheet->getCell('C2')->getCalculatedValue()); +// var_dump($worksheet->getCell('B3')->getValue()); +//// var_dump($worksheet->getCell('B3')->getCalculatedValue()); +// var_dump($worksheet->getCell('C3')->getValue()); +//// var_dump($worksheet->getCell('C3')->getCalculatedValue()); } } From fcc55a703b011021f61c022300dc8768dc987de5 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 4 Mar 2022 22:07:13 +0100 Subject: [PATCH 44/94] Fix for calculating array operations in the calculation engine (with tests) --- .../Calculation/Calculation.php | 6 ++++- .../Calculation/ArrayFormulaTest.php | 23 +++++++++++++++++-- 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 291850917d..3374be279d 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -3614,7 +3614,7 @@ private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1) [$matrix1Rows, $matrix1Columns] = self::getMatrixDimensions($operand1); [$matrix2Rows, $matrix2Columns] = self::getMatrixDimensions($operand2); if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { - $resize = 1; + $resize = 2; } if ($resize == 2) { @@ -5025,10 +5025,14 @@ private function executeNumericBinaryOperation($operand1, $operand2, $operation, try { // Convert operand 1 from a PHP array to a matrix +// $matrix = new \Matrix\Matrix($operand1); $matrix = new Shared\JAMA\Matrix($operand1); // Perform the required operation against the operand 1 matrix, passing in operand 2 $matrixResult = $matrix->$matrixFunction($operand2); $result = $matrixResult->getArray(); +// $matrixResult = $matrix->$matrixFunction($operand2); +// $result = $matrixResult->toArray(); +// var_dump($operand1, $matrixFunction, $operand2, $result); } catch (\Exception $ex) { $this->debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index 88643c182b..ce2de44dba 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -82,17 +82,36 @@ public function providerArrayFormulae(): array public function testArrayArithmetic(string $formula, $expectedResult): void { $result = Calculation::getInstance()->_calculateFormulaValue($formula); -// var_dump($result); -// self::assertEquals($expectedResult, $result); + self::assertEquals($expectedResult, $result); } public function providerArrayArithmetic(): array { return [ + [ + '={2,3}+{4;5}', + [[6, 7], [7, 8]], + ], + [ + '={2,3}-{4;5}', + [[-2, -1], [-3, -2]], + ], [ '={2,3}*{4;5}', [[8, 12], [10, 15]], ], + [ + '={2,3}/{4;5}', + [[0.5, 0.75], [0.4, 0.6]], + ], + [ + '={2,3}^{4;5}', + [[16, 81], [32, 243]], + ], + [ + '={"A",",B"}&{"C";";D"}', + [['AC', ',BC'], ['A;D', ',B;D']], + ], ]; } } From e4b7d73a9a7ccbfe35634bb5e5663392c893313f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 4 Mar 2022 22:08:10 +0100 Subject: [PATCH 45/94] Unit tests for reading array formulae in Ods files --- .../Reader/Ods/ArrayFormulaTest.php | 20 +++++++++---------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php index 6c9bb4b417..02bf0080f2 100644 --- a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php @@ -25,16 +25,14 @@ public function testArrayFormulaReader(): void $worksheet = $this->spreadsheet->getActiveSheet(); $cell = $worksheet->getCell('B2'); -// self::assertTrue($cell->isArrayFormula()); -// self::assertSame('B2:C3', $cell->arrayFormulaRange()); -// self::assertSame('={2,3}*{4;5}', $cell->getValue()); -// var_dump($worksheet->getCell('B2')->getValue()); -//// var_dump($worksheet->getCell('B2')->getCalculatedValue(true, true)); // Is currently resetting the range to NULLs -// var_dump($worksheet->getCell('C2')->getValue()); -//// var_dump($worksheet->getCell('C2')->getCalculatedValue()); -// var_dump($worksheet->getCell('B3')->getValue()); -//// var_dump($worksheet->getCell('B3')->getCalculatedValue()); -// var_dump($worksheet->getCell('C3')->getValue()); -//// var_dump($worksheet->getCell('C3')->getCalculatedValue()); + self::assertTrue($cell->isArrayFormula()); + self::assertSame('B2:C3', $cell->arrayFormulaRange()); + self::assertSame('={2,3}*{4;5}', $cell->getValue()); + self::assertSame([[8, 12], [10, 15]], $cell->getCalculatedValue(true, true)); + self::assertSame(8, $cell->getCalculatedValue()); + self::assertSame(8, $cell->getCalculatedValue()); + self::assertSame(12, $worksheet->getCell('C2')->getCalculatedValue()); + self::assertSame(10, $worksheet->getCell('B3')->getCalculatedValue()); + self::assertSame(15, $worksheet->getCell('C3')->getCalculatedValue()); } } From 3dbc7ddd25db44719c83815dd3a552f22a1b9e57 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 4 Mar 2022 22:09:14 +0100 Subject: [PATCH 46/94] Handle aray formulae in the Gnumeric Reader (with unit tests) --- src/PhpSpreadsheet/Reader/Gnumeric.php | 32 ++++++- .../Reader/Gnumeric/ArrayFormulaTest.php | 81 ++++++++++++++++++ .../Reader/Gnumeric/ArrayFormulaTest.gnumeric | Bin 0 -> 1856 bytes 3 files changed, 109 insertions(+), 4 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Reader/Gnumeric/ArrayFormulaTest.php create mode 100644 tests/data/Reader/Gnumeric/ArrayFormulaTest.gnumeric diff --git a/src/PhpSpreadsheet/Reader/Gnumeric.php b/src/PhpSpreadsheet/Reader/Gnumeric.php index d3b2039e4e..122a7c16ef 100644 --- a/src/PhpSpreadsheet/Reader/Gnumeric.php +++ b/src/PhpSpreadsheet/Reader/Gnumeric.php @@ -516,15 +516,24 @@ private function loadCell( ): void { $ValueType = $cellAttributes->ValueType; $ExprID = (string) $cellAttributes->ExprID; + + $rows = (int) ($cellAttributes->Rows ?? 0); + $cols = (int) ($cellAttributes->Cols ?? 0); + $type = DataType::TYPE_FORMULA; + $isArrayFormula = ($rows > 0 || $cols > 0); + $arrayFormulaRange = $isArrayFormula ? $this->getArrayFormulaRange($column, $row, $cols, $rows) : null; + if ($ExprID > '') { if (((string) $cell) > '') { + // Formula $this->expressions[$ExprID] = [ 'column' => $cellAttributes->Col, 'row' => $cellAttributes->Row, 'formula' => (string) $cell, ]; } else { + // "Shared" Formula $expression = $this->expressions[$ExprID]; $cell = $this->referenceHelper->updateFormulaReferences( @@ -535,22 +544,37 @@ private function loadCell( $worksheetName ); } - $type = DataType::TYPE_FORMULA; - } else { + } elseif ($isArrayFormula === false) { $vtype = (string) $ValueType; if (array_key_exists($vtype, self::$mappings['dataType'])) { $type = self::$mappings['dataType'][$vtype]; } - if ($vtype === '20') { // Boolean + if ($vtype === '20') { // Boolean $cell = $cell == 'TRUE'; } } - $this->spreadsheet->getActiveSheet()->getCell($column . $row)->setValueExplicit((string) $cell, $type); + $this->spreadsheet->getActiveSheet() + ->getCell($column . $row) + ->setValueExplicit((string) $cell, $type, $isArrayFormula, $arrayFormulaRange); + if (isset($cellAttributes->ValueFormat)) { $this->spreadsheet->getActiveSheet()->getCell($column . $row) ->getStyle()->getNumberFormat() ->setFormatCode((string) $cellAttributes->ValueFormat); } } + + private function getArrayFormulaRange(string $column, int $row, int $cols, int $rows): string + { + $arrayFormulaRange = $column . $row; + $arrayFormulaRange .= ':' . + Coordinate::stringFromColumnIndex( + Coordinate::columnIndexFromString($column) + + $cols - 1 + ) . + (string) ($row + $rows - 1); + + return $arrayFormulaRange; + } } diff --git a/tests/PhpSpreadsheetTests/Reader/Gnumeric/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Gnumeric/ArrayFormulaTest.php new file mode 100644 index 0000000000..99d12a613f --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Gnumeric/ArrayFormulaTest.php @@ -0,0 +1,81 @@ +spreadsheet = $reader->load($filename); + } + + /** + * @dataProvider arrayFormulaReaderProvider + */ + public function testArrayFormulaReader( + string $cellAddress, + string $expectedRange, + string $expectedFormula, + array $expectedValue + ): void { + $worksheet = $this->spreadsheet->getActiveSheet(); + + $cell = $worksheet->getCell($cellAddress); + self::assertTrue($cell->isArrayFormula()); + self::assertSame($expectedRange, $cell->arrayFormulaRange()); + self::assertSame($expectedFormula, $cell->getValue()); + self::assertSame($expectedValue, $cell->getCalculatedValue(true, true)); +// self::assertSame(8, $cell->getCalculatedValue()); +// self::assertSame(8, $cell->getCalculatedValue()); +// self::assertSame(12, $worksheet->getCell('C2')->getCalculatedValue()); +// self::assertSame(10, $worksheet->getCell('B3')->getCalculatedValue()); +// self::assertSame(15, $worksheet->getCell('C3')->getCalculatedValue()); + } + + public function arrayFormulaReaderProvider(): array + { + return [ + [ + 'D1', + 'D1:E2', + '=A1:B1*A1:A2', + [[4, 6], [8, 12]], + ], + [ + 'D4', + 'D4:E5', + '=A4:B4*A4:A5', + [[9, 12], [15, 20]], + ], + [ + 'D7', + 'D7:E8', + '=A7:B7*A7:A8', + [[16, 20], [24, 30]], + ], + [ + 'D10', + 'D10:E11', + '=A10:B10*A10:A11', + [[25, 30], [35, 42]], + ], + [ + 'D13', + 'D13:E14', + '=A13:B13*A13:A14', + [[36, 42], [48, 56]], + ], + ]; + } +} diff --git a/tests/data/Reader/Gnumeric/ArrayFormulaTest.gnumeric b/tests/data/Reader/Gnumeric/ArrayFormulaTest.gnumeric new file mode 100644 index 0000000000000000000000000000000000000000..d2bc20d3bcd6cb609fcd89019135c89fdd388585 GIT binary patch literal 1856 zcmV-G2fz3qiwFP!000001I<`%Q{y%e{(is0b!Ym48HkvTMd zEfN*ka%F{=`}JK(w&OTw2&FSEAA+>nl^(5jAFX`+%X37HN6b^g;(=)&S*C&GfQ2Mp z4$NEc{P45+%kb0jGLD=tj6Wp%#{#{(`YAy9&PI= z6rq{vKBr_$_o=0{nwDiZe!ZH^gB6a@A&FCg;sAqHN}N;)CoDihVXIxLfApM&=J1nY zD42J8GsY-k!3wry8dvB~#-Y`OCW%$EXBy{gO6892<`Hxog}o~TCyTYfsT5U(T9!#; z6yag+mOFx<94B3|Cx68_`Nm>_sGkO$QMy3Re&7KafQD9cGbG%(jZb{I-Yst}}(2ppE+I5%<1+KwWKET<`nAHJ8> zcE8_msL@~sauA`7%LW%>Kb%THSLD(n?|;o z674n3%&*yyoVhrRFmOTyPHtMw=AqR(wAxBkqB9KX4n7CRjAFE)cq}l_XjJjxb0J7U zVu4;E@ECY78PY3ooftTxfTyMmhk0yFRke=)w0P)N@2wmYVAiOF&$ z24=5qS3#y#aK;%)6N+BW8IQo1sq)<=3Gr9VS<$)RBrH0xjZ2I|%nJ$Zq$J5^yj}}P z1)M6+XPx;=v;ZfZV9K7pBcEy9AipCiSrAIZ%fP&tUitIO(a7`f#`E#Xcrx~W)6L1q zG$b@YBri9JOUE*|s6=_O?AvLTY#=7UeAw2*S+Al1`y1M=LPK`T8ebWUhS~h8T}6=Q zk}|47ROZSXPGaG^kQ=+)SmDPXXQT5UcKETRmavq_z#h68wnDH$v*VLD5h`c;9uXA3 z3Gt`D)=d1Y-LKpKI^K;W-EzBfEutt?R^eOTsR9!n51WSw?2BtD>n-I)59N*u@ z1fnvEbTVz}FPIQ4dY1{s_o6W9HQ&_dGAZ6;uu`e`9*cVh7xI1x3M^8P*O9nH;Yy0hJh(gHQ&6yX&>oun#xVvOpr4@MboidcJ$=jqgU9 z7I!Qehw~qXzF5J&vzk}Ss(M5oi%O4#alsK0x%Osc+eY)eF@Yc+nDSW>h7^$fgrel< z-#z!_57Wq4d_I6sS6@ z?6}kGtEVX<6d9%||9VM3qM9198X*Hv9=~A+c zHT+9=GQODl7o+KD=1$;_Esfpjv6E}hyS_4wFB~Nveimxg`3ko4;IVU}`!go8l1dFi zJgAneOk%A8Z`TJLs*4=T0}v}Ilo&X_q>U34Kn;Bke@^iOtb+uENW68QOFM8Q;KVT$ zXmo3QC=VJXu+es*QqGZ;XM(k zn$|d7^OSKFBrP-RWzkcOxZJ1|Z>^emYi**b?e@$D^QN~=LGWkx=C9^iM9+B|h< zv;kyO&ni{lw6=GwTko)L$w-zJcvA^fV>oba=fpmMUw0oQcI`ge@37w8M`sV~R_)sR zc%fCh_CCm4ulum=oU{+%*WG6y?b?03$9i`k-94 z)vMjdK3?e6?xVMdb^k->*Z_Ft2lF3!K?HkpEqKFM6wIsJ*;VPf`6{^NnQt9#W6b33_2`VR$Uj#iwgmZ%{@b zp)|c>A*Om6^^Ri;ild?rFMp3j(C%8rrzG{Df$o&WQ@m7I&qx~R4Dx}_Q%_oawz(ajA%P5i&En8Qi);d|oqt>%e)=2u9Y#6Q7ytllnwB;I literal 0 HcmV?d00001 From b67841a3dd8e82034e6b9aaf72153a876cc3637a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 4 Mar 2022 23:07:11 +0100 Subject: [PATCH 47/94] Additional Gnumeric Reader array formula unit tests --- .../Reader/Gnumeric/ArrayFormulaTest.php | 8 +++++++- .../Reader/Gnumeric/ArrayFormulaTest.gnumeric | Bin 1856 -> 1941 bytes 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/PhpSpreadsheetTests/Reader/Gnumeric/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Gnumeric/ArrayFormulaTest.php index 99d12a613f..60a0496b70 100644 --- a/tests/PhpSpreadsheetTests/Reader/Gnumeric/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Gnumeric/ArrayFormulaTest.php @@ -34,7 +34,7 @@ public function testArrayFormulaReader( $cell = $worksheet->getCell($cellAddress); self::assertTrue($cell->isArrayFormula()); self::assertSame($expectedRange, $cell->arrayFormulaRange()); - self::assertSame($expectedFormula, $cell->getValue()); + self::assertSame($expectedFormula, strtoupper($cell->getValue())); self::assertSame($expectedValue, $cell->getCalculatedValue(true, true)); // self::assertSame(8, $cell->getCalculatedValue()); // self::assertSame(8, $cell->getCalculatedValue()); @@ -52,6 +52,12 @@ public function arrayFormulaReaderProvider(): array '=A1:B1*A1:A2', [[4, 6], [8, 12]], ], + [ + 'G1', + 'G1:J1', + '=SIN({-1,0,1,2})', + [[-0.8414709848078965, 0.0, 0.8414709848078965, 0.9092974268256817]], + ], [ 'D4', 'D4:E5', diff --git a/tests/data/Reader/Gnumeric/ArrayFormulaTest.gnumeric b/tests/data/Reader/Gnumeric/ArrayFormulaTest.gnumeric index d2bc20d3bcd6cb609fcd89019135c89fdd388585..b4f7c1a2e7e095202773be47a66f49e708195a70 100644 GIT binary patch literal 1941 zcmV;G2Wt2qiwFP!000001I<`%Z{s!+{=UCL)d58tY+_4(i`CeLk~oP0#|dmDd)-4J z&=O;_kwlfE6Q@Q0`wdA+mgQBVGzau{0f!vU3?B}M4~IJWc@qZO6J`ma(Lgtjn!1J~ zkNPB94)id~4N0coa zPe${|=f0lmZW6Mi``nURX0vHD{(U`}dn+8GLlPw%MIHvLgjk6bPN;{t#8x>~|7er= z`tXycNtpL)G1@4m-U^naYuD&E%AjRJlSH!F)3u9r5Qr5U<`HxoxxLLfBa1c1i4c{A zN|s6^6yjkPmV1JqEh|~kXLm&z`GZCr1#aRo8Uzc(P8zvI(Zv%A)_Ca5?nX*M_0`0U zZ_NBR(7^6;;{AVMi73ZH?AF@s=u9Q&^VxUeVl zS_n!anY}0U;emJ<7VW`_iTGiNIZDr@8XD+p7FiS}B#{Ubi+dK0ag>=@MQuwGM0%zJ z5rfD@z%QU{8G_ui5TY~Z!mb7(P zHZ=NHr)zb3VE7HibZ<)_a>33v=7e>I0&g8iFF`fn{7_hWgH;V9rlMn3J#U%~|h;S>k-`5W??!VU6!l8^-n2!9#qm(y!^el;37?)`W^J{?cS z&M&Gt8R?pU28hJv*0kWizC$H4ipAJY%VYyN0p`QL8cus91z6wEXyqEBTh#bUX*f*% z%XS$-l1YlFa#4{hZyAZWYs1;t=f)C0{%bb6_->CM3u-Y(_ZY0?QGAcZ1BDB@o<(*DO5sz4 z0_2M|{t^R)#+Z3P*k}p2&bF;Mw^6ct5~DD`ObbCFWrfvS3QHh?>QVfJBbPk5Gzwna zguethsa6hY1m!aWUai*g8G=2m9OmM1yfOt;Vo(l383f_3){?_6+(^qDiD1Ip*?8)> z_L(!jA1PYgv!o36f9Sh>1?x_0UL`B*5wR`uc*K-(h6vBJwrQCYp2MA8u|kMS@{pJ4&sm^(awD? z>>!MQ6Gu>>1v^X4QwvU#qANo(sKq()E0TjJ=5lHZg9*%%IN!#Xt%;MaZ+l5Xb9$b7ZIS3;s6{ya23H$NMn&A)!E;m@dy zOZy$x`*G>iur{}A8Es-VJ{OLLgAi?gC@rMUN?MgGsk29|%9YfKL+kY&Zd<4A1NgP; zM5SH1j`vvaucKSTy8EGQ=zb_0y06EuXPx#A;MYE`;j34W{p){d z|N3t*O%tf5c_9AUhEeBySJP&lP#D#`S!Wjw^F!O1oBzFi%+0HU*@9rU4#Z#Es7035 z3{@){)fCm=H{VKjZ%O$UpP(1I=9)ueRg2q3`F^Lt6IANg)W?CEMm}rlBEVtZzeXE} zgwXCb^Dk@ieFxnsjiz`hv7VE}Q{RQ`HK+24n7Lar6wV4aeBo19>C0D=f5o~RpCgVm bRRmz)L5tLZ($2m$4?q1EMsj!|;TZq`&|I!J literal 1856 zcmV-G2fz3qiwFP!000001I<`%Q{y%e{(is0b!Ym48HkvTMd zEfN*ka%F{=`}JK(w&OTw2&FSEAA+>nl^(5jAFX`+%X37HN6b^g;(=)&S*C&GfQ2Mp z4$NEc{P45+%kb0jGLD=tj6Wp%#{#{(`YAy9&PI= z6rq{vKBr_$_o=0{nwDiZe!ZH^gB6a@A&FCg;sAqHN}N;)CoDihVXIxLfApM&=J1nY zD42J8GsY-k!3wry8dvB~#-Y`OCW%$EXBy{gO6892<`Hxog}o~TCyTYfsT5U(T9!#; z6yag+mOFx<94B3|Cx68_`Nm>_sGkO$QMy3Re&7KafQD9cGbG%(jZb{I-Yst}}(2ppE+I5%<1+KwWKET<`nAHJ8> zcE8_msL@~sauA`7%LW%>Kb%THSLD(n?|;o z674n3%&*yyoVhrRFmOTyPHtMw=AqR(wAxBkqB9KX4n7CRjAFE)cq}l_XjJjxb0J7U zVu4;E@ECY78PY3ooftTxfTyMmhk0yFRke=)w0P)N@2wmYVAiOF&$ z24=5qS3#y#aK;%)6N+BW8IQo1sq)<=3Gr9VS<$)RBrH0xjZ2I|%nJ$Zq$J5^yj}}P z1)M6+XPx;=v;ZfZV9K7pBcEy9AipCiSrAIZ%fP&tUitIO(a7`f#`E#Xcrx~W)6L1q zG$b@YBri9JOUE*|s6=_O?AvLTY#=7UeAw2*S+Al1`y1M=LPK`T8ebWUhS~h8T}6=Q zk}|47ROZSXPGaG^kQ=+)SmDPXXQT5UcKETRmavq_z#h68wnDH$v*VLD5h`c;9uXA3 z3Gt`D)=d1Y-LKpKI^K;W-EzBfEutt?R^eOTsR9!n51WSw?2BtD>n-I)59N*u@ z1fnvEbTVz}FPIQ4dY1{s_o6W9HQ&_dGAZ6;uu`e`9*cVh7xI1x3M^8P*O9nH;Yy0hJh(gHQ&6yX&>oun#xVvOpr4@MboidcJ$=jqgU9 z7I!Qehw~qXzF5J&vzk}Ss(M5oi%O4#alsK0x%Osc+eY)eF@Yc+nDSW>h7^$fgrel< z-#z!_57Wq4d_I6sS6@ z?6}kGtEVX<6d9%||9VM3qM9198X*Hv9=~A+c zHT+9=GQODl7o+KD=1$;_Esfpjv6E}hyS_4wFB~Nveimxg`3ko4;IVU}`!go8l1dFi zJgAneOk%A8Z`TJLs*4=T0}v}Ilo&X_q>U34Kn;Bke@^iOtb+uENW68QOFM8Q;KVT$ zXmo3QC=VJXu+es*QqGZ;XM(k zn$|d7^OSKFBrP-RWzkcOxZJ1|Z>^emYi**b?e@$D^QN~=LGWkx=C9^iM9+B|h< zv;kyO&ni{lw6=GwTko)L$w-zJcvA^fV>oba=fpmMUw0oQcI`ge@37w8M`sV~R_)sR zc%fCh_CCm4ulum=oU{+%*WG6y?b?03$9i`k-94 z)vMjdK3?e6?xVMdb^k->*Z_Ft2lF3!K?HkpEqKFM6wIsJ*;VPf`6{^NnQt9#W6b33_2`VR$Uj#iwgmZ%{@b zp)|c>A*Om6^^Ri;ild?rFMp3j(C%8rrzG{Df$o&WQ@m7I&qx~R4Dx}_Q%_oawz(ajA%P5i&En8Qi);d|oqt>%e)=2u9Y#6Q7ytllnwB;I From d6b6a110ecb99055dc58abcc5d7b1fcd67bd7fc5 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 5 Mar 2022 10:37:43 +0100 Subject: [PATCH 48/94] Additional array formula tests for Ods Reader --- .../Reader/Ods/ArrayFormulaTest.php | 74 +++++++++++++++--- tests/data/Reader/Ods/ArrayFormulaTest.ods | Bin 11949 -> 14534 bytes 2 files changed, 63 insertions(+), 11 deletions(-) diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php index 02bf0080f2..08f8a7d140 100644 --- a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php @@ -20,19 +20,71 @@ protected function setUp(): void $this->spreadsheet = $reader->load($filename); } - public function testArrayFormulaReader(): void - { + /** + * @dataProvider arrayFormulaReaderProvider + * + * @param mixed $expectedValue + */ + public function testArrayFormulaReader( + string $cellAddress, + string $expectedRange, + string $expectedFormula, + $expectedValue + ): void { $worksheet = $this->spreadsheet->getActiveSheet(); - $cell = $worksheet->getCell('B2'); + $cell = $worksheet->getCell($cellAddress); self::assertTrue($cell->isArrayFormula()); - self::assertSame('B2:C3', $cell->arrayFormulaRange()); - self::assertSame('={2,3}*{4;5}', $cell->getValue()); - self::assertSame([[8, 12], [10, 15]], $cell->getCalculatedValue(true, true)); - self::assertSame(8, $cell->getCalculatedValue()); - self::assertSame(8, $cell->getCalculatedValue()); - self::assertSame(12, $worksheet->getCell('C2')->getCalculatedValue()); - self::assertSame(10, $worksheet->getCell('B3')->getCalculatedValue()); - self::assertSame(15, $worksheet->getCell('C3')->getCalculatedValue()); + self::assertSame($expectedRange, $cell->arrayFormulaRange()); + self::assertSame($expectedFormula, strtoupper($cell->getValue())); + self::assertSame($expectedValue, $cell->getCalculatedValue(true, true)); + } + + public function arrayFormulaReaderProvider(): array + { + return [ + [ + 'B2', + 'B2:C3', + '={2,3}*{4;5}', + [[8, 12], [10, 15]], + ], + [ + 'E1', + 'E1:H1', + '=SIN({-1,0,1,2})', + [[-0.8414709848078965, 0.0, 0.8414709848078965, 0.9092974268256817]], + ], + [ + 'E3', + 'E3', + '=MAX(SIN({-1,0,1,2}))', + 0.90929742682568, + ], + [ + 'D5', + 'D5:E6', + '=A5:B5*A5:A6', + [[4, 6], [8, 12]], + ], + [ + 'D8', + 'D8:E9', + '=A8:B8*A8:A9', + [[9, 12], [15, 20]], + ], + [ + 'D11', + 'D11:E12', + '=A11:B11*A11:A12', + [[16, 20], [24, 30]], + ], + [ + 'D14', + 'D14:E15', + '=A14:B14*A14:A15', + [[25, 30], [35, 42]], + ], + ]; } } diff --git a/tests/data/Reader/Ods/ArrayFormulaTest.ods b/tests/data/Reader/Ods/ArrayFormulaTest.ods index f34c5b5da925458ae97b972bf3f12dc605b4fdcc..84b5cd02a2e00241ecac09ec974974d129b8ee3d 100644 GIT binary patch delta 12549 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 EU-RQa`2YX_ From 85130dcdce62f9e8987b588db9d6fb2a02c9ae4d Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 5 Mar 2022 10:44:24 +0100 Subject: [PATCH 49/94] Precision in unit test float value --- tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php index 08f8a7d140..e38176405f 100644 --- a/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Ods/ArrayFormulaTest.php @@ -59,7 +59,7 @@ public function arrayFormulaReaderProvider(): array 'E3', 'E3', '=MAX(SIN({-1,0,1,2}))', - 0.90929742682568, + 0.9092974268256817, ], [ 'D5', From 4a562617cc07ee8991f67b89cd39a83a6b2aa7b8 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 5 Mar 2022 15:59:34 +0100 Subject: [PATCH 50/94] Reverse `$asArray` and `$resetLog` arguments for calcuation methods; `$asArray` should have priority as a userland argument, whereas `$resetLog` is primarily for developer debugging --- .../Calculation/Calculation.php | 22 ++++++++++--------- src/PhpSpreadsheet/Cell/Cell.php | 4 ++-- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 3374be279d..c7d78ca03c 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -19,6 +19,7 @@ use ReflectionClassConstant; use ReflectionMethod; use ReflectionParameter; +use Throwable; class Calculation { @@ -3322,10 +3323,10 @@ public static function unwrapResult($value) * * @return mixed */ - public function calculate(?Cell $cell = null) + public function calculate(?Cell $cell = null, bool $asArray = false, bool $resetLog = true) { try { - return $this->calculateCellValue($cell); + return $this->calculateCellValue($cell, $asArray, $resetLog); } catch (\Exception $e) { throw new Exception($e->getMessage()); } @@ -3339,7 +3340,7 @@ public function calculate(?Cell $cell = null) * * @return mixed */ - public function calculateCellValue(?Cell $cell = null, bool $resetLog = true, bool $asArray = false) + public function calculateCellValue(?Cell $cell = null, bool $asArray = false, bool $resetLog = true) { if ($cell === null) { return null; @@ -5026,14 +5027,15 @@ private function executeNumericBinaryOperation($operand1, $operand2, $operation, try { // Convert operand 1 from a PHP array to a matrix // $matrix = new \Matrix\Matrix($operand1); +// var_dump($operand1, $matrixFunction, $operand2); $matrix = new Shared\JAMA\Matrix($operand1); // Perform the required operation against the operand 1 matrix, passing in operand 2 $matrixResult = $matrix->$matrixFunction($operand2); $result = $matrixResult->getArray(); -// $matrixResult = $matrix->$matrixFunction($operand2); // $result = $matrixResult->toArray(); -// var_dump($operand1, $matrixFunction, $operand2, $result); - } catch (\Exception $ex) { +// var_dump('=>', $result); + } catch (Throwable $ex) { +// var_dump($ex->getMessage()); $this->debugLog->writeDebugLog('JAMA Matrix Exception: ', $ex->getMessage()); $result = '#VALUE!'; } @@ -5145,7 +5147,7 @@ public function extractCellRange(&$range = 'A1', ?Worksheet $worksheet = null, $ // Single cell in range sscanf($aReferences[0], '%[A-Z]%d', $currentCol, $currentRow); if ($worksheet->cellExists($aReferences[0])) { - $returnValue[$currentRow][$currentCol] = $worksheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + $returnValue[$currentRow][$currentCol] = $worksheet->getCell($aReferences[0])->getCalculatedValue(false, $resetLog); } else { $returnValue[$currentRow][$currentCol] = null; } @@ -5157,7 +5159,7 @@ public function extractCellRange(&$range = 'A1', ?Worksheet $worksheet = null, $ // Extract range sscanf($reference, '%[A-Z]%d', $currentCol, $currentRow); if ($worksheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $worksheet->getCell($reference)->getCalculatedValue($resetLog); + $returnValue[$currentRow][$currentCol] = $worksheet->getCell($reference)->getCalculatedValue(false, $resetLog); } else { $returnValue[$currentRow][$currentCol] = null; } @@ -5210,7 +5212,7 @@ public function extractNamedRange(string &$range = 'A1', ?Worksheet $worksheet = // Single cell (or single column or row) in range [$currentCol, $currentRow] = Coordinate::coordinateFromString($aReferences[0]); if ($worksheet->cellExists($aReferences[0])) { - $returnValue[$currentRow][$currentCol] = $worksheet->getCell($aReferences[0])->getCalculatedValue($resetLog); + $returnValue[$currentRow][$currentCol] = $worksheet->getCell($aReferences[0])->getCalculatedValue(true, $resetLog); } else { $returnValue[$currentRow][$currentCol] = null; } @@ -5220,7 +5222,7 @@ public function extractNamedRange(string &$range = 'A1', ?Worksheet $worksheet = // Extract range [$currentCol, $currentRow] = Coordinate::coordinateFromString($reference); if ($worksheet->cellExists($reference)) { - $returnValue[$currentRow][$currentCol] = $worksheet->getCell($reference)->getCalculatedValue($resetLog); + $returnValue[$currentRow][$currentCol] = $worksheet->getCell($reference)->getCalculatedValue(true, $resetLog); } else { $returnValue[$currentRow][$currentCol] = null; } diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 085e895fe2..715525d843 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -394,7 +394,7 @@ private function processArrayResult( * * @return mixed */ - public function getCalculatedValue(bool $resetLog = true, bool $asArray = false) + public function getCalculatedValue(bool $asArray = false, bool $resetLog = true) { if ($this->dataType === DataType::TYPE_FORMULA) { try { @@ -407,7 +407,7 @@ public function getCalculatedValue(bool $resetLog = true, bool $asArray = false) $result = Calculation::getInstance( $this->getWorksheet()->getParent() - )->calculateCellValue($this, $resetLog, $asArray); + )->calculateCellValue($this, $asArray, $resetLog); $worksheet->getCell($coordinate); From 9c99f2f2107d8d83e269b1946e8f6ee85c0d9a5b Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 5 Mar 2022 16:52:29 +0100 Subject: [PATCH 51/94] Fix arguments for calculation call in `anchorarray()` pseudo-functin --- .../Calculation/Internal/ExcelArrayPseudoFunctions.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php index c7af11dc28..be77cf1671 100644 --- a/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php +++ b/src/PhpSpreadsheet/Calculation/Internal/ExcelArrayPseudoFunctions.php @@ -46,7 +46,7 @@ public static function anchorArray(string $cellReference, Cell $cell): array } $calcEngine = Calculation::getInstance($worksheet->getParent()); - $result = $calcEngine->calculateCellValue($referenceCell, false, true); + $result = $calcEngine->calculateCellValue($referenceCell, true, false); if (!is_array($result)) { $result = [[$result]]; } From 6b0d724a532b8bc5111c86b97b2fa5ce1382f8bd Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 7 Mar 2022 16:10:17 +0100 Subject: [PATCH 52/94] Additional unit tests for array operations (in preparation for a switch away from using Jama for handling matrix operations) --- .../Calculation/ArrayFormulaTest.php | 180 ++++++++++++++++-- 1 file changed, 168 insertions(+), 12 deletions(-) diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index ce2de44dba..0bfa756b3d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -88,30 +88,186 @@ public function testArrayArithmetic(string $formula, $expectedResult): void public function providerArrayArithmetic(): array { return [ - [ - '={2,3}+{4;5}', + // Addition + 'Addition: row vector 2 + column vector 2' => [ + '={2,3} + {4;5}', [[6, 7], [7, 8]], ], - [ - '={2,3}-{4;5}', + 'Addition: square matrix 2x2 + 2x2' => [ + '={1,2;3,4} + {-2,4;-6,8}', + [[-1, 6], [-3, 12]], + ], + 'Addition: row vector + row vector' => [ + '={1,2,3} + {4,5,6}', + [[5, 7, 9]], + ], + 'Addition: column vector + column vector' => [ + '={1;2;3} + {4;5;6}', + [[5], [7], [9]], + ], + 'Addition: row vector + column vector' => [ + '={1,2,3} + {4;5;6}', + [[5, 6, 7], [6, 7, 8], [7, 8, 9]], + ], + 'Addition: column vector + row vector' => [ + '={1;2;3} + {4,5,6}', + [[5, 6, 7], [6, 7, 8], [7, 8, 9]], + ], + 'Addition: matrix 3x2 + 3x2' => [ + '={1,2,3;4,5,6} + {7,8,9;10,11,12}', + [[8, 10, 12], [14, 16, 18]], + ], + 'Addition: matrix 2x3 + 2x3' => [ + '={1,4;2,5;3,6} + {7,10;8,11;9,12}', + [[8, 14], [10, 16], [12, 18]], + ], + // Subtraction + 'Subtraction: row vector 2 - column vector 2' => [ + '={2,3} - {4;5}', [[-2, -1], [-3, -2]], ], - [ - '={2,3}*{4;5}', + 'Subtraction: square matrix 2x2 - 2x2' => [ + '={1,2;3,4} - {-2,4;-6,8}', + [[3, -2], [9, -4]], + ], + 'Subtraction: row vector - row vector' => [ + '={1,2,3} - {4,5,6}', + [[-3, -3, -3]], + ], + 'Subtraction: column vector - column vector' => [ + '={1;2;3} - {4;5;6}', + [[-3], [-3], [-3]], + ], + 'Subtraction: row vector - column vector' => [ + '={1,2,3} - {4;5;6}', + [[-3, -2, -1], [-4, -3, -2], [-5, -4, -3]], + ], + 'Subtraction: column vector - row vector' => [ + '={1;2;3} - {4,5,6}', + [[-3, -4, -5], [-2, -3, -4], [-1, -2, -3]], + ], + 'Subtraction: matrix 3x2 - 3x2' => [ + '={1,2,3;4,5,6} - {7,8,9;10,11,12}', + [[-6, -6, -6], [-6, -6, -6]], + ], + 'Subtraction: matrix 2x3 - 2x3' => [ + '={1,4;2,5;3,6} - {7,10;8,11;9,12}', + [[-6, -6], [-6, -6], [-6, -6]], + ], + // Multiplication + 'Multiplication: square matrix 2x2 * 2x2' => [ + '={1,2;3,4} * {-2,4;-6,8}', + [[-2, 8], [-18, 32]], + ], + 'Multiplication: row vector * row vector' => [ + '={1,2,3} * {4,5,6}', + [[4, 10, 18]], + ], + 'Multiplication: column vector * column vector' => [ + '={1;2;3} * {4;5;6}', + [[4], [10], [18]], + ], + 'Multiplication: row vector * column vector' => [ + '={1,2,3} * {4;5;6}', + [[4, 8, 12], [5, 10, 15], [6, 12, 18]], + ], + 'Multiplication: column vector * row vector' => [ + '={1;2;3} * {4,5,6}', + [[4, 5, 6], [8, 10, 12], [12, 15, 18]], + ], + 'Multiplication: matrix 3x2 * 3x2' => [ + '={1,2,3;4,5,6} * {7,8,9;10,11,12}', + [[7, 16, 27], [40, 55, 72]], + ], + 'Multiplication: matrix 2x3 * 2x3' => [ + '={1,4;2,5;3,6} * {7,10;8,11;9,12}', + [[7, 40], [16, 55], [27, 72]], + ], + 'Multiplication: row vector 2 * column vector 2' => [ + '={2,3} * {4;5}', [[8, 12], [10, 15]], ], - [ - '={2,3}/{4;5}', + // Division + 'Division: square matrix 2x2 / 2x2' => [ + '={1,2;3,4} / {-2,4;-6,8}', + [[-0.5, 0.5], [-0.5, 0.5]], + ], + 'Division: row vector / row vector' => [ + '={1,2,3} / {4,5,6}', + [[0.25, 0.4, 0.5]], + ], + 'Division: column vector / column vector' => [ + '={1;2;3} / {4;5;6}', + [[0.25], [0.4], [0.5]], + ], + 'Division: row vector / column vector' => [ + '={1,2,3} / {4;5;6}', + [[0.25, 0.5, 0.75], [0.2, 0.4, 0.6], [0.16666666666667, 0.33333333333333, 0.5]], + ], + 'Division: column vector / row vector' => [ + '={1;2;3} / {4,5,6}', + [[0.25, 0.2, 0.16666666666667], [0.5, 0.4, 0.33333333333333], [0.75, 0.6, 0.5]], + ], + 'Division: matrix 3x2 / 3x2' => [ + '={1,2,3;4,5,6} / {7,8,9;10,11,12}', + [[0.142857142857143, 0.25, 0.33333333333333], [0.4, 0.45454545454545, 0.5]], + ], + 'Division: matrix 2x3 / 2x3' => [ + '={1,4;2,5;3,6} / {7,10;8,11;9,12}', + [[0.142857142857143, 0.4], [0.25, 0.45454545454545], [0.33333333333333, 0.5]], + ], + 'Division: row vector 2 / column vector 2' => [ + '={2,3} / {4;5}', [[0.5, 0.75], [0.4, 0.6]], ], - [ - '={2,3}^{4;5}', + // Power + 'Power: square matrix 2x2 ^ 2x2' => [ + '={1,2;3,4} ^ {-2,4;-6,8}', + [[1, 16], [0.00137174211248, 65536]], + ], + 'Power: row vector ^ row vector' => [ + '={1,2,3} ^ {4,5,6}', + [[1, 32, 729]], + ], + 'Power: column vector / column vector' => [ + '={1;2;3} ^ {4;5;6}', + [[1], [32], [729]], + ], + 'Power: row vector ^ column vector' => [ + '={1,2,3} ^ {4;5;6}', + [[1, 16, 81], [1, 32, 243], [1, 64, 729]], + ], + 'Power: column vector ^ row vector' => [ + '={1;2;3} ^ {4,5,6}', + [[1, 1, 1], [16, 32, 64], [81, 243, 729]], + ], + 'Power: matrix 3x2 ^ 3x2' => [ + '={1,2,3;4,5,6} ^ {7,8,9;10,11,12}', + [[1, 256, 19683], [1048576, 48828125, 2176782336]], + ], + 'Power: matrix 2x3 ^ 2x3' => [ + '={1,4;2,5;3,6} ^ {7,10;8,11;9,12}', + [[1, 1048576], [256, 48828125], [19683, 2176782336]], + ], + 'Power: row vector 2 ^ column vector 2' => [ + '={2,3} ^ {4;5}', [[16, 81], [32, 243]], ], - [ - '={"A",",B"}&{"C";";D"}', + // Concatenation + 'Concatenation: row vector 2 & column vector 2' => [ + '={"A",",B"} & {"C";";D"}', [['AC', ',BC'], ['A;D', ',B;D']], ], + // Unary Negation + 'Unary Negation: square matrix - 2x2' => [ + '= - {-2,4;-6,8}', + [[2, -4], [6, -8]], + ], + // Percentage + 'Percentage: square matrix % 2x2' => [ + '={-2,4;-6,8} %', + [[-0.02, 0.04], [-0.06, 0.08]], + ], ]; } } From 96453e0ad07e5a316cc1be1ec339dcbfba226b84 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 9 Mar 2022 13:51:55 +0100 Subject: [PATCH 53/94] Fix to identify spillage cells from their arrayFormulaRange value --- src/PhpSpreadsheet/Cell/Cell.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 715525d843..209115bfe2 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -532,7 +532,7 @@ public function arrayFormulaRange(): ?string return $formulaAttributes['ref'] ?? null; } - return null; + return $this->arrayFormulaRange; } /** From 8ed2bab963273f5f9771ef2e6206e28b4cb0f96e Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 9 Mar 2022 17:08:57 +0100 Subject: [PATCH 54/94] Modifications to FORMULATEXT() to return correct values for cells in array formula (wrapped in `{}` braces) and for cells within the spillage area of an array formula that should return the arra formula even though they're not the actual formula cell --- .../Calculation/Calculation.php | 45 ++++++++++++------- .../Calculation/LookupRef/Formula.php | 28 +++++++++--- .../Functions/LookupRef/FormulaTextTest.php | 17 +++++++ 3 files changed, 70 insertions(+), 20 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index ca0c5a5167..9d082931c0 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Calculation; +use Matrix\Matrix; use PhpOffice\PhpSpreadsheet\Calculation\Engine\BranchPruner; use PhpOffice\PhpSpreadsheet\Calculation\Engine\CyclicReferenceStack; use PhpOffice\PhpSpreadsheet\Calculation\Engine\Logger; @@ -4544,28 +4545,32 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null) break; case '+': // Addition - $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'plusEquals', $stack); +// $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'plusEquals', $stack); + $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'add', $stack); if (isset($storeKey)) { $branchStore[$storeKey] = $result; } break; case '-': // Subtraction - $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'minusEquals', $stack); +// $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'minusEquals', $stack); + $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'subtract', $stack); if (isset($storeKey)) { $branchStore[$storeKey] = $result; } break; case '*': // Multiplication - $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'arrayTimesEquals', $stack); +// $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'arrayTimesEquals', $stack); + $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'multiply', $stack); if (isset($storeKey)) { $branchStore[$storeKey] = $result; } break; case '/': // Division - $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'arrayRightDivide', $stack); +// $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'arrayRightDivide', $stack); + $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'divideby', $stack); if (isset($storeKey)) { $branchStore[$storeKey] = $result; } @@ -4653,13 +4658,20 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null) self::checkMatrixOperands($arg, $multiplier, 2); try { - $matrix1 = new Shared\JAMA\Matrix($arg); - $matrixResult = $matrix1->arrayTimesEquals($multiplier); - $result = $matrixResult->getArray(); - } catch (\Exception $ex) { - $this->debugLog->writeDebugLog('JAMA Matrix Exception: %s', $ex->getMessage()); + $matrix1 = new Matrix($arg); + $matrixResult = $matrix1->multiply($multiplier); + $result = $matrixResult->toArray(); + } catch (\Matrix\Exception $ex) { + $this->debugLog->writeDebugLog('Matrix Exception: %s', $ex->getMessage()); $result = '#VALUE!'; } +// $matrix1 = new Shared\JAMA\Matrix($arg); +// $matrixResult = $matrix1->arrayTimesEquals($multiplier); +// $result = $matrixResult->getArray(); +// } catch (\Exception $ex) { +// $this->debugLog->writeDebugLog('JAMA Matrix Exception: %s', $ex->getMessage()); +// $result = '#VALUE!'; +// } $this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($result)); $stack->push('Value', $result); if (isset($storeKey)) { @@ -5025,18 +5037,21 @@ private function executeNumericBinaryOperation($operand1, $operand2, $operation, self::checkMatrixOperands($operand1, $operand2, 2); try { - // Convert operand 1 from a PHP array to a matrix -// $matrix = new \Matrix\Matrix($operand1); // var_dump($operand1, $matrixFunction, $operand2); - $matrix = new Shared\JAMA\Matrix($operand1); + // Convert operand 1 from a PHP array to a matrix + $matrix = new Matrix($operand1); + /** @var Matrix $matrixResult */ // Perform the required operation against the operand 1 matrix, passing in operand 2 $matrixResult = $matrix->$matrixFunction($operand2); - $result = $matrixResult->getArray(); -// $result = $matrixResult->toArray(); + $result = $matrixResult->toArray(); +// $matrix = new Shared\JAMA\Matrix($operand1); + // Perform the required operation against the operand 1 matrix, passing in operand 2 +// $matrixResult = $matrix->$matrixFunction($operand2); +// $result = $matrixResult->getArray(); // var_dump('=>', $result); } catch (Throwable $ex) { // var_dump($ex->getMessage()); - $this->debugLog->writeDebugLog('JAMA Matrix Exception: %s', $ex->getMessage()); + $this->debugLog->writeDebugLog('Matrix Exception: %s', $ex->getMessage()); $result = '#VALUE!'; } } else { diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php b/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php index 834fe52a1a..f3b304f85e 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php @@ -5,6 +5,8 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\Cell; +use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Formula { @@ -30,14 +32,30 @@ public static function text($cellReference = '', ?Cell $cell = null) ? $cell->getWorksheet()->getParent()->getSheetByName($worksheetName) : $cell->getWorksheet(); - if ( - $worksheet === null || - !$worksheet->cellExists($cellReference) || - !$worksheet->getCell($cellReference)->isFormula() - ) { + if ($worksheet === null || $worksheet->cellExists($cellReference) === false) { + return ExcelError::NA(); + } + + $arrayFormulaRange = $worksheet->getCell($cellReference)->arrayFormulaRange(); + if ($worksheet->getCell($cellReference)->isArrayFormula() || $arrayFormulaRange !== null) { + /** @var string $arrayFormulaRange */ + return self::arrayFormula($worksheet, $arrayFormulaRange); + } + + if ($worksheet->getCell($cellReference)->isFormula() === false) { return ExcelError::NA(); } return $worksheet->getCell($cellReference)->getValue(); } + + private static function arrayFormula(Worksheet $worksheet, string $arrayFormulaRange): string + { + [$arrayFormulaRange] = Coordinate::splitRange($arrayFormulaRange); + [$arrayFormulaCell] = $arrayFormulaRange; + + $arrayFormula = $worksheet->getCell($arrayFormulaCell)->getValue(); + + return "{{$arrayFormula}}"; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php index ccd689b1d6..f16241a6cf 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php @@ -34,4 +34,21 @@ public function testNoCell(): void { self::assertSame('#REF!', Formula::text('B5')); } + + public function testArrayFormula(): void + { + $sheet = $this->getSheet(); + $sheet->setCellValue('B2', '=SEQUENCE(3,3)', true, 'B2:D4'); + + // Execute the calculation to populate the spillage cells + $sheet->getCell('B2')->getCalculatedValue(true); + $sheet->setCellValue('A1', '=FORMULATEXT(B2)'); + $sheet->setCellValue('E5', '=FORMULATEXT(D4)'); + + $result1 = $sheet->getCell('A1')->getCalculatedValue(); + self::assertSame('{=SEQUENCE(3,3)}', $result1, 'Formula Cell'); + + $result2 = $sheet->getCell('E5')->getCalculatedValue(); + self::assertSame('{=SEQUENCE(3,3)}', $result2, 'Spill Range Cell'); + } } From b1eb0e2fefb456a37c79e2b1e0a7df4193f2ab36 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 9 Mar 2022 17:18:14 +0100 Subject: [PATCH 55/94] More unit tests for MMULT() function, to ensure correct calculation compared to using array arguments with the multiplication operator --- tests/data/Calculation/MathTrig/MMULT.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/data/Calculation/MathTrig/MMULT.php b/tests/data/Calculation/MathTrig/MMULT.php index 7b424d589f..3bb60a2449 100644 --- a/tests/data/Calculation/MathTrig/MMULT.php +++ b/tests/data/Calculation/MathTrig/MMULT.php @@ -90,6 +90,11 @@ [6], ], ], + [ + [[-14, 20], [-30, 44]], + [[1, 2], [3, 4]], + [[-2, 4], [-6, 8]], + ], [ '#VALUE!', // null in first array [ From 5f79b74bc8f388f171b11d2a9eff3f4ce29e8b76 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 9 Mar 2022 17:56:19 +0100 Subject: [PATCH 56/94] Revert "Modifications to FORMULATEXT() to return correct values for cells in array formula (wrapped in `{}` braces) and for cells within the spillage area of an array formula that should return the arra formula even though they're not the actual formula cell" This reverts commit 8ed2bab963273f5f9771ef2e6206e28b4cb0f96e. --- .../Calculation/Calculation.php | 45 +++++++------------ .../Calculation/LookupRef/Formula.php | 28 +++--------- .../Functions/LookupRef/FormulaTextTest.php | 17 ------- 3 files changed, 20 insertions(+), 70 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 9d082931c0..ca0c5a5167 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -2,7 +2,6 @@ namespace PhpOffice\PhpSpreadsheet\Calculation; -use Matrix\Matrix; use PhpOffice\PhpSpreadsheet\Calculation\Engine\BranchPruner; use PhpOffice\PhpSpreadsheet\Calculation\Engine\CyclicReferenceStack; use PhpOffice\PhpSpreadsheet\Calculation\Engine\Logger; @@ -4545,32 +4544,28 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null) break; case '+': // Addition -// $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'plusEquals', $stack); - $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'add', $stack); + $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'plusEquals', $stack); if (isset($storeKey)) { $branchStore[$storeKey] = $result; } break; case '-': // Subtraction -// $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'minusEquals', $stack); - $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'subtract', $stack); + $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'minusEquals', $stack); if (isset($storeKey)) { $branchStore[$storeKey] = $result; } break; case '*': // Multiplication -// $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'arrayTimesEquals', $stack); - $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'multiply', $stack); + $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'arrayTimesEquals', $stack); if (isset($storeKey)) { $branchStore[$storeKey] = $result; } break; case '/': // Division -// $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'arrayRightDivide', $stack); - $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'divideby', $stack); + $result = $this->executeNumericBinaryOperation($operand1, $operand2, $token, 'arrayRightDivide', $stack); if (isset($storeKey)) { $branchStore[$storeKey] = $result; } @@ -4658,20 +4653,13 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null) self::checkMatrixOperands($arg, $multiplier, 2); try { - $matrix1 = new Matrix($arg); - $matrixResult = $matrix1->multiply($multiplier); - $result = $matrixResult->toArray(); - } catch (\Matrix\Exception $ex) { - $this->debugLog->writeDebugLog('Matrix Exception: %s', $ex->getMessage()); + $matrix1 = new Shared\JAMA\Matrix($arg); + $matrixResult = $matrix1->arrayTimesEquals($multiplier); + $result = $matrixResult->getArray(); + } catch (\Exception $ex) { + $this->debugLog->writeDebugLog('JAMA Matrix Exception: %s', $ex->getMessage()); $result = '#VALUE!'; } -// $matrix1 = new Shared\JAMA\Matrix($arg); -// $matrixResult = $matrix1->arrayTimesEquals($multiplier); -// $result = $matrixResult->getArray(); -// } catch (\Exception $ex) { -// $this->debugLog->writeDebugLog('JAMA Matrix Exception: %s', $ex->getMessage()); -// $result = '#VALUE!'; -// } $this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($result)); $stack->push('Value', $result); if (isset($storeKey)) { @@ -5037,21 +5025,18 @@ private function executeNumericBinaryOperation($operand1, $operand2, $operation, self::checkMatrixOperands($operand1, $operand2, 2); try { -// var_dump($operand1, $matrixFunction, $operand2); // Convert operand 1 from a PHP array to a matrix - $matrix = new Matrix($operand1); - /** @var Matrix $matrixResult */ +// $matrix = new \Matrix\Matrix($operand1); +// var_dump($operand1, $matrixFunction, $operand2); + $matrix = new Shared\JAMA\Matrix($operand1); // Perform the required operation against the operand 1 matrix, passing in operand 2 $matrixResult = $matrix->$matrixFunction($operand2); - $result = $matrixResult->toArray(); -// $matrix = new Shared\JAMA\Matrix($operand1); - // Perform the required operation against the operand 1 matrix, passing in operand 2 -// $matrixResult = $matrix->$matrixFunction($operand2); -// $result = $matrixResult->getArray(); + $result = $matrixResult->getArray(); +// $result = $matrixResult->toArray(); // var_dump('=>', $result); } catch (Throwable $ex) { // var_dump($ex->getMessage()); - $this->debugLog->writeDebugLog('Matrix Exception: %s', $ex->getMessage()); + $this->debugLog->writeDebugLog('JAMA Matrix Exception: %s', $ex->getMessage()); $result = '#VALUE!'; } } else { diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php b/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php index f3b304f85e..834fe52a1a 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php @@ -5,8 +5,6 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\Cell; -use PhpOffice\PhpSpreadsheet\Cell\Coordinate; -use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Formula { @@ -32,30 +30,14 @@ public static function text($cellReference = '', ?Cell $cell = null) ? $cell->getWorksheet()->getParent()->getSheetByName($worksheetName) : $cell->getWorksheet(); - if ($worksheet === null || $worksheet->cellExists($cellReference) === false) { - return ExcelError::NA(); - } - - $arrayFormulaRange = $worksheet->getCell($cellReference)->arrayFormulaRange(); - if ($worksheet->getCell($cellReference)->isArrayFormula() || $arrayFormulaRange !== null) { - /** @var string $arrayFormulaRange */ - return self::arrayFormula($worksheet, $arrayFormulaRange); - } - - if ($worksheet->getCell($cellReference)->isFormula() === false) { + if ( + $worksheet === null || + !$worksheet->cellExists($cellReference) || + !$worksheet->getCell($cellReference)->isFormula() + ) { return ExcelError::NA(); } return $worksheet->getCell($cellReference)->getValue(); } - - private static function arrayFormula(Worksheet $worksheet, string $arrayFormulaRange): string - { - [$arrayFormulaRange] = Coordinate::splitRange($arrayFormulaRange); - [$arrayFormulaCell] = $arrayFormulaRange; - - $arrayFormula = $worksheet->getCell($arrayFormulaCell)->getValue(); - - return "{{$arrayFormula}}"; - } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php index f16241a6cf..ccd689b1d6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php @@ -34,21 +34,4 @@ public function testNoCell(): void { self::assertSame('#REF!', Formula::text('B5')); } - - public function testArrayFormula(): void - { - $sheet = $this->getSheet(); - $sheet->setCellValue('B2', '=SEQUENCE(3,3)', true, 'B2:D4'); - - // Execute the calculation to populate the spillage cells - $sheet->getCell('B2')->getCalculatedValue(true); - $sheet->setCellValue('A1', '=FORMULATEXT(B2)'); - $sheet->setCellValue('E5', '=FORMULATEXT(D4)'); - - $result1 = $sheet->getCell('A1')->getCalculatedValue(); - self::assertSame('{=SEQUENCE(3,3)}', $result1, 'Formula Cell'); - - $result2 = $sheet->getCell('E5')->getCalculatedValue(); - self::assertSame('{=SEQUENCE(3,3)}', $result2, 'Spill Range Cell'); - } } From 5ea78ae8341b20e39757d19e70e461965bfeb6b1 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 9 Mar 2022 18:01:32 +0100 Subject: [PATCH 57/94] Modifications to FORMULATEXT() to return correct values for cells in array formula (wrapped in `{}` braces) and for cells within the spillage area of an array formula that should return the array formula even though they're not the actual formula cell --- .../Calculation/LookupRef/Formula.php | 27 +++++++++++++++---- .../Functions/LookupRef/FormulaTextTest.php | 17 ++++++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php b/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php index 834fe52a1a..390212eedd 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Formula.php @@ -5,6 +5,8 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Cell\Cell; +use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Formula { @@ -30,14 +32,29 @@ public static function text($cellReference = '', ?Cell $cell = null) ? $cell->getWorksheet()->getParent()->getSheetByName($worksheetName) : $cell->getWorksheet(); - if ( - $worksheet === null || - !$worksheet->cellExists($cellReference) || - !$worksheet->getCell($cellReference)->isFormula() - ) { + if ($worksheet === null || $worksheet->cellExists($cellReference) === false) { + return ExcelError::NA(); + } + + $arrayFormulaRange = $worksheet->getCell($cellReference)->arrayFormulaRange(); + if ($arrayFormulaRange !== null) { + return self::arrayFormula($worksheet, $arrayFormulaRange); + } + + if ($worksheet->getCell($cellReference)->isFormula() === false) { return ExcelError::NA(); } return $worksheet->getCell($cellReference)->getValue(); } + + private static function arrayFormula(Worksheet $worksheet, string $arrayFormulaRange): string + { + [$arrayFormulaRange] = Coordinate::splitRange($arrayFormulaRange); + [$arrayFormulaCell] = $arrayFormulaRange; + + $arrayFormula = $worksheet->getCell($arrayFormulaCell)->getValue(); + + return "{{$arrayFormula}}"; + } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php index ccd689b1d6..f16241a6cf 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FormulaTextTest.php @@ -34,4 +34,21 @@ public function testNoCell(): void { self::assertSame('#REF!', Formula::text('B5')); } + + public function testArrayFormula(): void + { + $sheet = $this->getSheet(); + $sheet->setCellValue('B2', '=SEQUENCE(3,3)', true, 'B2:D4'); + + // Execute the calculation to populate the spillage cells + $sheet->getCell('B2')->getCalculatedValue(true); + $sheet->setCellValue('A1', '=FORMULATEXT(B2)'); + $sheet->setCellValue('E5', '=FORMULATEXT(D4)'); + + $result1 = $sheet->getCell('A1')->getCalculatedValue(); + self::assertSame('{=SEQUENCE(3,3)}', $result1, 'Formula Cell'); + + $result2 = $sheet->getCell('E5')->getCalculatedValue(); + self::assertSame('{=SEQUENCE(3,3)}', $result2, 'Spill Range Cell'); + } } From be5736107fb89afe68ac80549aefa8a26e5b74ec Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 10 Mar 2022 10:15:18 +0100 Subject: [PATCH 58/94] Additional unit tests for array/scalar operations --- .../Calculation/ArrayFormulaTest.php | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index 0bfa756b3d..fc4ad7d682 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -93,6 +93,10 @@ public function providerArrayArithmetic(): array '={2,3} + {4;5}', [[6, 7], [7, 8]], ], + 'Addition: square matrix 2x2 + scalar' => [ + '={1,2;3,4} + 1', + [[2, 3], [4, 5]], + ], 'Addition: square matrix 2x2 + 2x2' => [ '={1,2;3,4} + {-2,4;-6,8}', [[-1, 6], [-3, 12]], @@ -126,6 +130,10 @@ public function providerArrayArithmetic(): array '={2,3} - {4;5}', [[-2, -1], [-3, -2]], ], + 'Subtraction: square matrix 2x2 - scalar' => [ + '={1,2;3,4} - 1', + [[0, 1], [2, 3]], + ], 'Subtraction: square matrix 2x2 - 2x2' => [ '={1,2;3,4} - {-2,4;-6,8}', [[3, -2], [9, -4]], @@ -159,6 +167,10 @@ public function providerArrayArithmetic(): array '={1,2;3,4} * {-2,4;-6,8}', [[-2, 8], [-18, 32]], ], + 'Multiplication: square matrix 2x2 * scalar' => [ + '={1,2;3,4} * 2', + [[2, 4], [6, 8]], + ], 'Multiplication: row vector * row vector' => [ '={1,2,3} * {4,5,6}', [[4, 10, 18]], @@ -192,6 +204,10 @@ public function providerArrayArithmetic(): array '={1,2;3,4} / {-2,4;-6,8}', [[-0.5, 0.5], [-0.5, 0.5]], ], + 'Division: square matrix 2x2 / scalar' => [ + '={1,2;3,4} / 0.5', + [[2, 4], [6, 8]], + ], 'Division: row vector / row vector' => [ '={1,2,3} / {4,5,6}', [[0.25, 0.4, 0.5]], @@ -225,6 +241,10 @@ public function providerArrayArithmetic(): array '={1,2;3,4} ^ {-2,4;-6,8}', [[1, 16], [0.00137174211248, 65536]], ], + 'Power: square matrix 2x2 ^ scalar' => [ + '={1,2;3,4} ^ 2', + [[1, 4], [9, 16]], + ], 'Power: row vector ^ row vector' => [ '={1,2,3} ^ {4,5,6}', [[1, 32, 729]], @@ -258,6 +278,15 @@ public function providerArrayArithmetic(): array '={"A",",B"} & {"C";";D"}', [['AC', ',BC'], ['A;D', ',B;D']], ], + 'Concatenation: 2x2 matrix & scalar' => [ + '={"A","B";"C","D"} & "E"', + [['AE', 'BE'], ['CE', 'DE']], + ], + 'Concatenation: scalar & 2x2 matrix' => [ + '="E" & {"A","B";"C","D"}', + [['EA', 'EB'], ['EC', 'ED']], + ], + // Unary Negation 'Unary Negation: square matrix - 2x2' => [ '= - {-2,4;-6,8}', From 96ac7169b9a25e4b5b36f6bcc5ee8317c9404eae Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 10 Mar 2022 14:42:03 +0100 Subject: [PATCH 59/94] Fix sizing adjustments for reflective matrices (vectors increase to match as a square matrix, non-vectors reduce to a minimum matching square) --- phpstan-baseline.neon | 50 ----------------- .../Calculation/Calculation.php | 51 +++++++---------- src/PhpSpreadsheet/Worksheet/Worksheet.php | 2 +- .../Calculation/ArrayFormulaTest.php | 56 +++++++++++++++++++ 4 files changed, 78 insertions(+), 81 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 28e5d7be48..a3a9bcce6d 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -60,26 +60,6 @@ parameters: count: 6 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has parameter \\$formula with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has parameter \\$formula with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:dataTestReference\\(\\) has no return type specified\\.$#" count: 1 @@ -90,41 +70,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:getTokensAsString\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:getTokensAsString\\(\\) has parameter \\$tokens with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:localeFunc\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:localeFunc\\(\\) has parameter \\$function with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has parameter \\$operand with no type specified\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has parameter \\$stack with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Offset 'type' does not exist on array\\|null\\.$#" count: 3 diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index ca0c5a5167..2204031b28 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -2872,7 +2872,7 @@ public static function getFALSE(): string * * @return bool Success or failure */ - public static function setArrayReturnType($returnType) + public static function setArrayReturnType(string $returnType): bool { if ( ($returnType == self::RETURN_ARRAY_AS_VALUE) || @@ -2892,17 +2892,15 @@ public static function setArrayReturnType($returnType) * * @return string $returnType Array return type */ - public static function getArrayReturnType() + public static function getArrayReturnType(): string { return self::$returnArrayAsType; } /** * Is calculation caching enabled? - * - * @return bool */ - public function getCalculationCacheEnabled() + public function getCalculationCacheEnabled(): bool { return $this->calculationCacheEnabled; } @@ -2944,10 +2942,8 @@ public function clearCalculationCache(): void /** * Clear calculation cache for a specified worksheet. - * - * @param string $worksheetName */ - public function clearCalculationCacheForWorksheet($worksheetName): void + public function clearCalculationCacheForWorksheet(string $worksheetName): void { if (isset($this->calculationCache[$worksheetName])) { unset($this->calculationCache[$worksheetName]); @@ -2956,13 +2952,10 @@ public function clearCalculationCacheForWorksheet($worksheetName): void /** * Rename calculation cache for a specified worksheet. - * - * @param string $fromWorksheetName - * @param string $toWorksheetName */ - public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksheetName): void + public function renameCalculationCacheForWorksheet(?string $fromWorksheetName, string $toWorksheetName): void { - if (isset($this->calculationCache[$fromWorksheetName])) { + if ($fromWorksheetName !== null && isset($this->calculationCache[$fromWorksheetName])) { $this->calculationCache[$toWorksheetName] = &$this->calculationCache[$fromWorksheetName]; unset($this->calculationCache[$fromWorksheetName]); } @@ -2971,7 +2964,7 @@ public function renameCalculationCacheForWorksheet($fromWorksheetName, $toWorksh /** * Enable/disable calculation cache. * - * @param mixed $enabled + * @param bool $enabled */ public function setBranchPruningEnabled($enabled): void { @@ -2991,10 +2984,8 @@ public function disableBranchPruning(): void /** * Get the currently defined locale code. - * - * @return string */ - public function getLocale() + public function getLocale(): string { return self::$localeLanguage; } @@ -3018,10 +3009,8 @@ private function getLocaleFile(string $localeDir, string $locale, string $langua * Set the locale code. * * @param string $locale The locale to use for formula translation, eg: 'en_us' - * - * @return bool */ - public function setLocale(string $locale) + public function setLocale(string $locale): bool { // Identify our locale and language $language = $locale = strtolower($locale); @@ -3191,7 +3180,7 @@ private static function translateFormula(array $from, array $to, string $formula private static $functionReplaceToLocale; - public function _translateFormulaToLocale($formula) + public function _translateFormulaToLocale(string $formula): string { // Build list of function names and constants for translation if (self::$functionReplaceFromExcel === null) { @@ -3227,7 +3216,7 @@ public function _translateFormulaToLocale($formula) private static $functionReplaceToExcel; - public function _translateFormulaToEnglish($formula) + public function _translateFormulaToEnglish(string $formula): string { if (self::$functionReplaceFromLocale === null) { self::$functionReplaceFromLocale = []; @@ -3252,7 +3241,7 @@ public function _translateFormulaToEnglish($formula) return self::translateFormula(self::$functionReplaceFromLocale, self::$functionReplaceToExcel, $formula, self::$localeArgumentSeparator, ','); } - public static function localeFunc($function) + public static function localeFunc(string $function): string { if (self::$localeLanguage !== 'en_us') { $functionName = trim($function, '('); @@ -3596,7 +3585,7 @@ public function _calculateFormulaValue($formula, $cellID = null, ?Cell $cell = n * 1 = shrink to fit * 2 = extend to fit * - * @return array + * @return array */ private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1) { @@ -3615,7 +3604,9 @@ private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1) [$matrix1Rows, $matrix1Columns] = self::getMatrixDimensions($operand1); [$matrix2Rows, $matrix2Columns] = self::getMatrixDimensions($operand2); if (($matrix1Rows == $matrix2Columns) && ($matrix2Rows == $matrix1Columns)) { - $resize = 2; + // Vectors increase size to match to build a square matrix; + // Non-vectors reduce size to a square that reflects min(rows1, rows2) and min(cols1, cols2) + $resize = ($matrix1Rows === 1 || $matrix2Rows === 1) ? 2 : 1; } if ($resize == 2) { @@ -3634,7 +3625,7 @@ private static function checkMatrixOperands(&$operand1, &$operand2, $resize = 1) * * @param array $matrix matrix operand * - * @return int[] An array comprising the number of rows, and number of columns + * @return array An array comprising the number of rows, and number of columns */ public static function getMatrixDimensions(array &$matrix) { @@ -3747,7 +3738,7 @@ private static function resizeMatricesExtend(&$matrix1, &$matrix2, $matrix1Rows, /** * Format details of an operand for display in the log (based on operand type). * - * @param mixed $value First matrix operand + * @param mixed $value Operand value * * @return mixed */ @@ -3787,7 +3778,7 @@ private function showValue($value) /** * Format type and details of an operand for display in the log (based on operand type). * - * @param mixed $value First matrix operand + * @param mixed $value Operand value * * @return null|string */ @@ -4889,7 +4880,7 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null) return $output; } - private function validateBinaryOperand(&$operand, &$stack) + private function validateBinaryOperand(&$operand, Stack &$stack): bool { if (is_array($operand)) { if ((count($operand, COUNT_RECURSIVE) - count($operand)) == 1) { @@ -5357,7 +5348,7 @@ private function addCellReference(array $args, $passCellReference, $functionCall return $args; } - private function getTokensAsString($tokens) + private function getTokensAsString(array $tokens): string { $tokensStr = array_map(function ($token) { $value = $token['value'] ?? 'no value'; diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 6e6845f0a6..64131d998c 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -839,7 +839,7 @@ public function getTitle() * * @return $this */ - public function setTitle($title, $updateFormulaCellReferences = true, $validate = true) + public function setTitle(string $title, bool $updateFormulaCellReferences = true, bool $validate = true) { // Is this a 'rename' or not? if ($this->getTitle() == $title) { diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index fc4ad7d682..f368999177 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -125,6 +125,14 @@ public function providerArrayArithmetic(): array '={1,4;2,5;3,6} + {7,10;8,11;9,12}', [[8, 14], [10, 16], [12, 18]], ], + 'Addition: matrix 3x2 + 2x3' => [ + '={1,2,3;4,5,6} + {7,10;8,11;9,12}', + [[8, 12], [12, 16]], + ], + 'Addition: matrix 2x3 + 3x2' => [ + '={7,10;8,11;9,12} + {1,2,3;4,5,6}', + [[8, 12], [12, 16]], + ], // Subtraction 'Subtraction: row vector 2 - column vector 2' => [ '={2,3} - {4;5}', @@ -162,6 +170,14 @@ public function providerArrayArithmetic(): array '={1,4;2,5;3,6} - {7,10;8,11;9,12}', [[-6, -6], [-6, -6], [-6, -6]], ], + 'Subtraction: matrix 3x2 - 2x3' => [ + '={1,2,3;4,5,6} - {7,10;8,11;9,12}', + [[-6, -8], [-4, -6]], + ], + 'Subtraction: matrix 2x3 - 3x2' => [ + '={7,10;8,11;9,12} - {1,2,3;4,5,6}', + [[6, 8], [4, 6]], + ], // Multiplication 'Multiplication: square matrix 2x2 * 2x2' => [ '={1,2;3,4} * {-2,4;-6,8}', @@ -199,6 +215,14 @@ public function providerArrayArithmetic(): array '={2,3} * {4;5}', [[8, 12], [10, 15]], ], + 'Multiplication: matrix 3x2 * 2x3' => [ + '={1,2,3;4,5,6} * {7,10;8,11;9,12}', + [[7, 20], [32, 55]], + ], + 'Multiplication: matrix 2x3 * 3x2' => [ + '={7,10;8,11;9,12} * {1,2,3;4,5,6}', + [[7, 20], [32, 55]], + ], // Division 'Division: square matrix 2x2 / 2x2' => [ '={1,2;3,4} / {-2,4;-6,8}', @@ -236,6 +260,14 @@ public function providerArrayArithmetic(): array '={2,3} / {4;5}', [[0.5, 0.75], [0.4, 0.6]], ], + 'Division: matrix 3x2 / 2x3' => [ + '={1,2,3;4,5,6} / {7,10;8,11;9,12}', + [[0.14285714285714, 0.2], [0.5, 0.45454545454545]], + ], + 'Division: matrix 2x3 / 3x2' => [ + '={7,10;8,11;9,12} / {1,2,3;4,5,6}', + [[7, 5], [2, 2.2]], + ], // Power 'Power: square matrix 2x2 ^ 2x2' => [ '={1,2;3,4} ^ {-2,4;-6,8}', @@ -273,11 +305,27 @@ public function providerArrayArithmetic(): array '={2,3} ^ {4;5}', [[16, 81], [32, 243]], ], + 'Power: matrix 3x2 ^ 2x3' => [ + '={1,2,3;4,5,6} ^ {7,10;8,11;9,12}', + [[1, 1024], [65536, 48828125]], + ], + 'Power: matrix 2x3 ^ 3x2' => [ + '={7,10;8,11;9,12} ^ {1,2,3;4,5,6}', + [[7, 100], [4096, 161051]], + ], // Concatenation 'Concatenation: row vector 2 & column vector 2' => [ '={"A",",B"} & {"C";";D"}', [['AC', ',BC'], ['A;D', ',B;D']], ], + 'Concatenation: matrix 3x2 & 3x2' => [ + '={"A","B","C";"D","E","F"} & {"G","H","I";"J","K","L"}', + [['AG', 'BH', 'CI'], ['DJ', 'EK', 'FL']], + ], + 'Concatenation: matrix 2x3 & 2x3' => [ + '={"A","B";"C","D";"E","F"} & {"G","H";"I","J";"K","L"}', + [['AG', 'BH'], ['CI', 'DJ'], ['EK', 'FL']], + ], 'Concatenation: 2x2 matrix & scalar' => [ '={"A","B";"C","D"} & "E"', [['AE', 'BE'], ['CE', 'DE']], @@ -286,6 +334,14 @@ public function providerArrayArithmetic(): array '="E" & {"A","B";"C","D"}', [['EA', 'EB'], ['EC', 'ED']], ], + 'Concatenation: 2x2 & 2x1 vector' => [ + '={"A","B";"C","D"} & {"E","F"}', + [['AE', 'BF'], ['CE', 'DF']], + ], + 'Concatenation: 2x2 & 1x2 vector' => [ + '={"A","B";"C","D"} & {"E";"F"}', + [['AE', 'BE'], ['CF', 'DF']], + ], // Unary Negation 'Unary Negation: square matrix - 2x2' => [ From ec3281b779e05d951e11a1effd56e5c2df819275 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 13 Mar 2022 12:00:00 +0100 Subject: [PATCH 60/94] Resolve phpstan --- src/PhpSpreadsheet/Calculation/Calculation.php | 1 - 1 file changed, 1 deletion(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index e213736d20..c67b4aa1eb 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -4509,7 +4509,6 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null) if ($operand2Data['reference'] === null) { if ((trim($operand2Data['value']) != '') && (is_numeric($operand2Data['value']))) { $operand2Data['reference'] = $cell->getColumn() . $operand2Data['value']; - // @phpstan-ignore-next-line } elseif (trim($operand2Data['reference']) == '') { $operand2Data['reference'] = $cell->getCoordinate(); } else { From 925c730c3b51c0259f50024bf0fecd787ef22fa8 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 14 Mar 2022 15:57:12 +0100 Subject: [PATCH 61/94] Some more unit tests for array functions and spillage; and updates to documentation --- docs/topics/calculation-engine.md | 2 + docs/topics/recipes.md | 40 +++++++++++++++++++ .../Functions/MathTrig/SequenceTest.php | 24 +++++++++++ 3 files changed, 66 insertions(+) diff --git a/docs/topics/calculation-engine.md b/docs/topics/calculation-engine.md index 4ce407ee4b..f44af4790b 100644 --- a/docs/topics/calculation-engine.md +++ b/docs/topics/calculation-engine.md @@ -44,6 +44,8 @@ $spreadsheet->getActiveSheet()->getCell('E11')->arrayFormulaRange(); which returns a string containing a cell reference (e.g. `E11`) or a cell range reference (e.g. `E11:G13`). +For more details on working with array formulae, see the [the recipes documentationn](./recipes.md/#array-formulae). + ### Adjustments to formulae when Inserting/Deleting Columns/Rows Another nice feature of PhpSpreadsheet's formula parser, is that it can diff --git a/docs/topics/recipes.md b/docs/topics/recipes.md index f9b56a02c5..dd7077abb5 100644 --- a/docs/topics/recipes.md +++ b/docs/topics/recipes.md @@ -239,6 +239,46 @@ $spreadsheet->getActiveSheet() ); ``` +Simply setting an array formula in a cell and specifying the range won't populate the spillage area for that formula. +```php +$spreadsheet->getActiveSheet() + ->setCellValue( + 'A10', + '=SEQUENCE(3,3)', + true, + 'A1:C3' + ); + +// Will return a null, because the formula for A1 hasn't been calculated to populate the spillage area +$result = $spreadsheet->getActiveSheet()->getCell('C3')->getValue(); +``` +To do that, we need to retrieve the calculated value for the cell. +```php +$spreadsheet->getActiveSheet() + ->setCellValue( + 'A10', + '=SEQUENCE(3,3)', + true, + 'A1:C3' + ); + +$spreadsheet->getActiveSheet()->getCell('A1')->getCalculatedValue(); + +// Will return 9, because the formula for A1 has now been calculated, and the spillage area is populated +$result = $spreadsheet->getActiveSheet()->getCell('C3')->getValue(); +``` +When we call `getCalculatedValue()` for a cell that contains an array formula, PhpSpreadsheet returns the single value that would appear in that cell in MS Excel. +```php +// Will return integer 1, the value for that cell within the array +$a1result = $spreadsheet->getActiveSheet()->getCell('A1')->getCalculatedValue(); +``` + +If we want to return the full array, then we need to call `getCalculatedValue()` with an additional argument, a boolean `true` to return the value as an array. +```php +// Will return an array [[1, 2, 3], [4, 5, 6], [7, 8, 9]] +$a1result = $spreadsheet->getActiveSheet()->getCell('A1')->getCalculatedValue(true); +``` + --- Excel365 introduced a number of new functions that return arrays of results. diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php index d2ba3345cb..93e20ed9ed 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php @@ -22,4 +22,28 @@ public function providerSEQUENCE(): array { return require 'tests/data/Calculation/MathTrig/SEQUENCE.php'; } + + public function testSequenceAsCellFormula() + { + $sheet = $this->getSheet(); + $sheet->getCell('B2')->setValue('=SEQUENCE(3,3,9,-1)', true, 'B2:D4'); + + $result = $sheet->getCell('B2')->getCalculatedValue(); + self::assertSame(9, $result); + + // Check that spillage area has been populated + self::assertSame(5, $sheet->getCell('C3')->getCalculatedValue()); + } + + public function testSequenceAsCellFormulaAsArray() + { + $sheet = $this->getSheet(); + $sheet->getCell('B2')->setValue('=SEQUENCE(3,3,9,-1)', true, 'B2:D4'); + + $result = $sheet->getCell('B2')->getCalculatedValue(true); + self::assertSame([[9, 8, 7], [6, 5, 4], [3, 2, 1]], $result); + + // Check that spillage area has been populated + self::assertSame(5, $sheet->getCell('C3')->getCalculatedValue()); + } } From 222b79b88bf18e53dc8cf7207161138da194e8f2 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 17 Mar 2022 14:11:26 +0100 Subject: [PATCH 62/94] Ensure that master can still merge in cleanly... knowing that if I don't do this reasonably regularly, then merge conflicts could easily become a problem --- phpstan-baseline.neon | 6 ++++++ .../Calculation/Functions/MathTrig/SequenceTest.php | 4 ++-- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1b3d73bad8..2f44e9f7dc 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -4215,6 +4215,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Worksheet/AutoFilter.php + - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\CellIterator\\:\\:adjustForExistingOnlyRange\\(\\) has no return type specified\\.$#" count: 1 @@ -5494,3 +5499,4 @@ parameters: message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Xlfn\\:\\:addXlfn\\(\\) should return string but returns string\\|null\\.$#" count: 1 path: src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php + diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php index 93e20ed9ed..9358e99e39 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SequenceTest.php @@ -23,7 +23,7 @@ public function providerSEQUENCE(): array return require 'tests/data/Calculation/MathTrig/SEQUENCE.php'; } - public function testSequenceAsCellFormula() + public function testSequenceAsCellFormula(): void { $sheet = $this->getSheet(); $sheet->getCell('B2')->setValue('=SEQUENCE(3,3,9,-1)', true, 'B2:D4'); @@ -35,7 +35,7 @@ public function testSequenceAsCellFormula() self::assertSame(5, $sheet->getCell('C3')->getCalculatedValue()); } - public function testSequenceAsCellFormulaAsArray() + public function testSequenceAsCellFormulaAsArray(): void { $sheet = $this->getSheet(); $sheet->getCell('B2')->setValue('=SEQUENCE(3,3,9,-1)', true, 'B2:D4'); From 2acb3fe4cffd674a4fc84d1dce8ed67a65398169 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 18 Mar 2022 17:14:06 +0100 Subject: [PATCH 63/94] Update branch and some additional unit tests --- .../Calculation/ArrayFormulaTest.php | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index f368999177..5c68fe6bfe 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -71,6 +71,24 @@ public function providerArrayFormulae(): array '=IFS(FALSE, {1,2,3}, TRUE, {4,5,6})', [[4, 5, 6]], ], + [ + '=UNIQUE( + {"Grant";"Barbara";"Frances";"Alicia";"Alicia";"Lynn";"Barbara";"Anthony";"Anthony";"Frances"} + &" "& + {"Fife";"Pruitt";"Horn";"Barrett";"Barrett";"Larson";"Pruitt";"Snook";"Snook";"Horn"} + )', + [['Grant Fife'], ['Barbara Pruitt'], ['Frances Horn'], ['Alicia Barrett'], ['Lynn Larson'], ['Anthony Snook']], + ], + [ + '=UNIQUE( + {"Grant";"Barbara";"Frances";"Alicia";"Alicia";"Lynn";"Barbara";"Anthony";"Anthony";"Frances"} + &" "& + {"Fife";"Pruitt";"Horn";"Barrett";"Barrett";"Larson";"Pruitt";"Snook";"Snook";"Horn"}, + false, + true + )', + [['Grant Fife'], ['Lynn Larson']], + ], ]; } From ca940c61e0eba21e5fd11a04735f159daa36545f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 19 Mar 2022 13:28:24 +0100 Subject: [PATCH 64/94] Re-baseline --- phpstan-baseline.neon | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 38c15dbcf5..f98bd14306 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2300,6 +2300,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Xls.php + - + message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\\\|string given\\.$#" + count: 1 + path: src/PhpSpreadsheet/Reader/Xls.php + - message: "#^Parameter \\#2 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\IReadFilter\\:\\:readCell\\(\\) expects int, string given\\.$#" count: 1 From 6602dd6dbc79783fb025acb616b9a2946d2b8257 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 24 Mar 2022 22:09:40 +0100 Subject: [PATCH 65/94] More unit tests --- .../Calculation/LookupRef/Filter.php | 2 +- .../Functions/LookupRef/FilterTest.php | 50 ++++++++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Filter.php b/src/PhpSpreadsheet/Calculation/LookupRef/Filter.php index 6d2015319a..74fa8321d0 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Filter.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Filter.php @@ -29,7 +29,7 @@ public static function filter($lookupArray, $matchArray, $ifEmpty = null) return $ifEmpty ?? ExcelError::CALC(); } - return array_values($result); + return array_values(array_map('array_values', $result)); } private static function enumerateArrayKeys(array $sortArray): array diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FilterTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FilterTest.php index 710a42e09d..0c806b1688 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FilterTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FilterTest.php @@ -2,8 +2,10 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef; +use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Filter; +use PhpOffice\PhpSpreadsheet\Spreadsheet; use PHPUnit\Framework\TestCase; class FilterTest extends TestCase @@ -15,7 +17,7 @@ public function testFilterByRow(): void ['East', 'Tom', 'Apple', 6830], ['East', 'Fritz', 'Apple', 4394], ['South', 'Sal', 'Apple', 1310], - ['South', 'Hector', 'Apple', 98144], + ['South', 'Hector', 'Apple', 8144], ]; $result = Filter::filter($this->sampleDataForRow(), $criteria); self::assertSame($expectedResult, $result); @@ -52,6 +54,50 @@ public function testFilterEmpty(): void self::assertSame($expectedResult, $result); } + public function testFilterWithAndLogic(): void + { + $expectedResult = [ + ['East', 'Tom', 'Apple', 6830], + ['East', 'Fritz', 'Banana', 6274], + ]; + + $spreadsheet = new Spreadsheet(); + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->fromArray($this->sampleDataForRow(), null, 'C3', true); + + // East AND >6,000 + $formula = '=FILTER(C3:F18,(C3:C18="East")*(F3:F18>6000))'; + $worksheet->setCellValue('H1', $formula, true, 'H1:K2'); + $result = $worksheet->getCell('H1')->getCalculatedValue(true); + + self::assertSame($expectedResult, $result); + } + + public function testFilterWithOrLogic(): void + { + $expectedResult = [ + ['East', 'Tom', 'Apple', 6830], + ['East', 'Fritz', 'Apple', 4394], + ['West', 'Sravan', 'Grape', 7195], + ['East', 'Tom', 'Banana', 4213], + ['North', 'Amy', 'Grape', 6420], + ['East', 'Fritz', 'Banana', 6274], + ['North', 'Xi', 'Grape', 7580], + ['South', 'Hector', 'Apple', 8144], + ]; + + $spreadsheet = new Spreadsheet(); + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->fromArray($this->sampleDataForRow(), null, 'C3', true); + + // East OR >6,000 + $formula = '=FILTER(C3:F18,(C3:C18="East")+(F3:F18>6000))'; + $worksheet->setCellValue('H1', $formula, true, 'H1:K8'); + $result = $worksheet->getCell('H1')->getCalculatedValue(true); + + self::assertSame($expectedResult, $result); + } + protected function sampleDataForRow(): array { return [ @@ -70,7 +116,7 @@ protected function sampleDataForRow(): array ['East', 'Fritz', 'Banana', 6274], ['West', 'Sravan', 'Pear', 4894], ['North', 'Xi', 'Grape', 7580], - ['South', 'Hector', 'Apple', 98144], + ['South', 'Hector', 'Apple', 8144], ]; } From a3130ef0d1bfe2c5ba2d61ceeb729119281321b4 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 25 Mar 2022 13:50:06 +0100 Subject: [PATCH 66/94] Flag functions as spillage functions. We may be able to use this to determine whether a calculated value should automatically spill, and so know if we needed to set the arrayFormulaRange automatically as Excel itself does. The next step after that would be handling #SPILL! errors --- src/PhpSpreadsheet/Calculation/Calculation.php | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 1137e5524d..2f44277868 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -1043,6 +1043,7 @@ class Calculation 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => [LookupRef\Filter::class, 'filter'], 'argumentCount' => '2-3', + 'spillageFunction' => true, ], 'FILTERXML' => [ 'category' => Category::CATEGORY_WEB, @@ -2083,6 +2084,7 @@ class Calculation 'category' => Category::CATEGORY_MATH_AND_TRIG, 'functionCall' => [MathTrig\Random::class, 'randArray'], 'argumentCount' => '0-5', + 'spillageFunction' => true, ], 'RANDBETWEEN' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, @@ -2225,6 +2227,7 @@ class Calculation 'category' => Category::CATEGORY_MATH_AND_TRIG, 'functionCall' => [MathTrig\MatrixFunctions::class, 'sequence'], 'argumentCount' => '1-4', + 'spillageFunction' => true, ], 'SERIESSUM' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, @@ -2285,11 +2288,13 @@ class Calculation 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => [LookupRef\Sort::class, 'sort'], 'argumentCount' => '1-4', + 'spillageFunction' => true, ], 'SORTBY' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => [LookupRef\Sort::class, 'sortBy'], 'argumentCount' => '2+', + 'spillageFunction' => true, ], 'SQRT' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, @@ -2586,6 +2591,7 @@ class Calculation 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => [LookupRef\Unique::class, 'unique'], 'argumentCount' => '1+', + 'spillageFunction' => true, ], 'UPPER' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, From 1014a03352002954824737e501fe2ef5062e7a2c Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 12 Apr 2022 09:46:17 +0200 Subject: [PATCH 67/94] Resolve merge conflicts --- phpstan-baseline.neon | 15 +++++---------- .../Functions/LookupRef/FilterTest.php | 1 - 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 773aabc5e1..273f061353 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2070,16 +2070,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Reader/Ods.php - - - message: "#^Parameter \\#1 \\$settings of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:lookForActiveSheet\\(\\) expects DOMElement, DOMElement\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods.php - - - - message: "#^Parameter \\#1 \\$settings of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:lookForSelectedCells\\(\\) expects DOMElement, DOMElement\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Ods.php - - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 @@ -4280,6 +4270,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Worksheet/Worksheet.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 2 + path: src/PhpSpreadsheet/Worksheet/Worksheet.php + - message: "#^If condition is always true\\.$#" count: 2 diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FilterTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FilterTest.php index 0c806b1688..1bedea900c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FilterTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/FilterTest.php @@ -2,7 +2,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef; -use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Filter; use PhpOffice\PhpSpreadsheet\Spreadsheet; From e41c4280f60c461074b3ee243da10765233a4a4a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 24 Apr 2022 21:46:15 +0200 Subject: [PATCH 68/94] Initial creation of the version 2.0 Development branch Start removing some of the deprecations, starting with the old Excel Function implementations. --- phpstan-baseline.neon | 85 - .../Calculation/Calculation.php | 4 +- src/PhpSpreadsheet/Calculation/Database.php | 440 ---- src/PhpSpreadsheet/Calculation/DateTime.php | 915 --------- .../Calculation/Engineering.php | 1446 ------------- src/PhpSpreadsheet/Calculation/Financial.php | 1430 ------------- src/PhpSpreadsheet/Calculation/Functions.php | 377 ---- src/PhpSpreadsheet/Calculation/Logical.php | 314 --- src/PhpSpreadsheet/Calculation/LookupRef.php | 416 ---- src/PhpSpreadsheet/Calculation/MathTrig.php | 1520 -------------- .../Calculation/Statistical.php | 1820 ----------------- src/PhpSpreadsheet/Calculation/TextData.php | 448 ---- src/PhpSpreadsheet/Calculation/Web.php | 27 - .../Calculation/Engine/RangeTest.php | 4 +- .../Functions/Database/DAverageTest.php | 4 +- .../Functions/Database/DCountATest.php | 4 +- .../Functions/Database/DCountTest.php | 4 +- .../Functions/Database/DGetTest.php | 4 +- .../Functions/Database/DMaxTest.php | 4 +- .../Functions/Database/DMinTest.php | 4 +- .../Functions/Database/DProductTest.php | 30 +- .../Functions/Database/DStDevPTest.php | 4 +- .../Functions/Database/DStDevTest.php | 4 +- .../Functions/Database/DSumTest.php | 4 +- .../Functions/Database/DVarPTest.php | 4 +- .../Functions/Database/DVarTest.php | 4 +- .../Functions/DateTime/MovedFunctionsTest.php | 63 - .../Functions/DeprecatedExcelErrorTest.php | 55 - .../Functions/Engineering/BesselITest.php | 4 +- .../Functions/Engineering/BesselJTest.php | 4 +- .../Functions/Engineering/BesselKTest.php | 4 +- .../Functions/Engineering/BesselYTest.php | 4 +- .../Functions/Engineering/ComplexTest.php | 10 +- .../Functions/Engineering/ConvertUoMTest.php | 14 +- .../Functions/Engineering/DeltaTest.php | 4 +- .../Functions/Engineering/ErfCTest.php | 4 +- .../Functions/Engineering/ErfPreciseTest.php | 4 +- .../Functions/Engineering/ErfTest.php | 4 +- .../Functions/Engineering/GeStepTest.php | 4 +- .../Functions/Engineering/ImAbsTest.php | 4 +- .../Functions/Engineering/ImArgumentTest.php | 4 +- .../Functions/Engineering/ImConjugateTest.php | 4 +- .../Functions/Engineering/ImCosTest.php | 4 +- .../Functions/Engineering/ImCoshTest.php | 4 +- .../Functions/Engineering/ImCotTest.php | 4 +- .../Functions/Engineering/ImCscTest.php | 4 +- .../Functions/Engineering/ImCschTest.php | 4 +- .../Functions/Engineering/ImDivTest.php | 4 +- .../Functions/Engineering/ImExpTest.php | 4 +- .../Functions/Engineering/ImLnTest.php | 4 +- .../Functions/Engineering/ImLog10Test.php | 4 +- .../Functions/Engineering/ImLog2Test.php | 4 +- .../Functions/Engineering/ImPowerTest.php | 4 +- .../Functions/Engineering/ImProductTest.php | 4 +- .../Functions/Engineering/ImRealTest.php | 4 +- .../Functions/Engineering/ImSecTest.php | 4 +- .../Functions/Engineering/ImSechTest.php | 4 +- .../Functions/Engineering/ImSinTest.php | 4 +- .../Functions/Engineering/ImSinhTest.php | 4 +- .../Functions/Engineering/ImSqrtTest.php | 4 +- .../Functions/Engineering/ImSubTest.php | 4 +- .../Functions/Engineering/ImSumTest.php | 4 +- .../Functions/Engineering/ImTanTest.php | 4 +- .../Functions/Engineering/ImaginaryTest.php | 4 +- .../Engineering/MovedBitwiseTest.php | 24 - .../Engineering/MovedFunctionsTest.php | 31 - .../Engineering/ParseComplexTest.php | 28 - .../Functions/Financial/AccrintMTest.php | 4 +- .../Functions/Financial/AccrintTest.php | 4 +- .../Functions/Financial/AmorDegRcTest.php | 4 +- .../Functions/Financial/AmorLincTest.php | 4 +- .../Functions/Financial/CoupDayBsTest.php | 4 +- .../Functions/Financial/CoupDaysNcTest.php | 4 +- .../Functions/Financial/CoupDaysTest.php | 4 +- .../Functions/Financial/CoupNcdTest.php | 4 +- .../Functions/Financial/CoupNumTest.php | 4 +- .../Functions/Financial/CoupPcdTest.php | 4 +- .../Functions/Financial/CumIpmtTest.php | 4 +- .../Functions/Financial/CumPrincTest.php | 4 +- .../Functions/Financial/DbTest.php | 4 +- .../Functions/Financial/DdbTest.php | 4 +- .../Functions/Financial/DiscTest.php | 4 +- .../Functions/Financial/DollarDeTest.php | 8 +- .../Functions/Financial/DollarFrTest.php | 8 +- .../Functions/Financial/EffectTest.php | 4 +- .../Functions/Financial/FvScheduleTest.php | 4 +- .../Functions/Financial/FvTest.php | 18 +- .../Functions/Financial/IPmtTest.php | 4 +- .../Functions/Financial/IntRateTest.php | 4 +- .../Functions/Financial/IrrTest.php | 4 +- .../Functions/Financial/IsPmtTest.php | 4 +- .../Functions/Financial/MirrTest.php | 4 +- .../Functions/Financial/NPerTest.php | 18 +- .../Functions/Financial/NominalTest.php | 4 +- .../Functions/Financial/NpvTest.php | 4 +- .../Functions/Financial/PDurationTest.php | 14 +- .../Functions/Financial/PmtTest.php | 8 +- .../Functions/Financial/PpmtTest.php | 4 +- .../Functions/Financial/PriceDiscTest.php | 4 +- .../Functions/Financial/PriceMatTest.php | 4 +- .../Functions/Financial/PriceTest.php | 6 +- .../Functions/Financial/PvTest.php | 18 +- .../Functions/Financial/RateTest.php | 4 +- .../Functions/Financial/ReceivedTest.php | 4 +- .../Functions/Financial/RriTest.php | 10 +- .../Functions/Financial/SlnTest.php | 4 +- .../Functions/Financial/SydTest.php | 4 +- .../Functions/Financial/TBillEqTest.php | 4 +- .../Functions/Financial/TBillPriceTest.php | 4 +- .../Functions/Financial/TBillYieldTest.php | 4 +- .../Functions/Financial/XNpvTest.php | 4 +- .../Functions/Financial/YieldDiscTest.php | 4 +- .../Functions/Financial/YieldMatTest.php | 4 +- .../Functions/Information/ErrorTypeTest.php | 5 +- .../Functions/Information/IsBlankTest.php | 6 +- .../Functions/Information/IsErrTest.php | 6 +- .../Functions/Information/IsErrorTest.php | 6 +- .../Functions/Information/IsEvenTest.php | 6 +- .../Functions/Information/IsLogicalTest.php | 6 +- .../Functions/Information/IsNaTest.php | 6 +- .../Functions/Information/IsNonTextTest.php | 6 +- .../Functions/Information/IsNumberTest.php | 6 +- .../Functions/Information/IsOddTest.php | 6 +- .../Functions/Information/IsTextTest.php | 6 +- .../Functions/Information/NTest.php | 6 +- .../Functions/Information/NullTest.php | 4 +- .../Functions/Information/TypeTest.php | 6 +- .../Calculation/Functions/Logical/AndTest.php | 4 +- .../Functions/Logical/FalseTest.php | 4 +- .../Functions/Logical/IfErrorTest.php | 4 +- .../Functions/Logical/IfNaTest.php | 4 +- .../Calculation/Functions/Logical/IfTest.php | 10 +- .../Calculation/Functions/Logical/IfsTest.php | 4 +- .../Calculation/Functions/Logical/NotTest.php | 6 +- .../Calculation/Functions/Logical/OrTest.php | 4 +- .../Functions/Logical/SwitchTest.php | 4 +- .../Functions/Logical/TrueTest.php | 4 +- .../Calculation/Functions/Logical/XorTest.php | 4 +- .../Functions/LookupRef/AddressTest.php | 4 +- .../Functions/LookupRef/ChooseTest.php | 4 +- .../Functions/LookupRef/ColumnTest.php | 4 +- .../Functions/LookupRef/ColumnsTest.php | 4 +- .../Functions/LookupRef/HLookupTest.php | 6 +- .../Functions/LookupRef/IndexTest.php | 4 +- .../Functions/LookupRef/IndirectTest.php | 10 - .../Functions/LookupRef/LookupTest.php | 4 +- .../Functions/LookupRef/MatchTest.php | 4 +- .../LookupRef/MovedFunctionsTest.php | 29 - .../Functions/LookupRef/RowTest.php | 4 +- .../Functions/LookupRef/RowsTest.php | 4 +- .../Functions/LookupRef/VLookupTest.php | 4 +- .../Functions/MathTrig/MovedFunctionsTest.php | 111 - .../Functions/Statistical/AveDevTest.php | 4 +- .../Functions/Statistical/AverageATest.php | 4 +- .../Functions/Statistical/AverageIfTest.php | 4 +- .../Functions/Statistical/AverageTest.php | 4 +- .../Functions/Statistical/BetaDistTest.php | 4 +- .../Functions/Statistical/BetaInvTest.php | 4 +- .../Statistical/BinomDistRangeTest.php | 4 +- .../Functions/Statistical/BinomDistTest.php | 4 +- .../Functions/Statistical/BinomInvTest.php | 4 +- .../Statistical/ChiDistLeftTailTest.php | 4 +- .../Statistical/ChiDistRightTailTest.php | 4 +- .../Statistical/ChiInvLeftTailTest.php | 6 +- .../Statistical/ChiInvRightTailTest.php | 6 +- .../Functions/Statistical/ChiTestTest.php | 4 +- .../Functions/Statistical/ConfidenceTest.php | 4 +- .../Functions/Statistical/CorrelTest.php | 4 +- .../Functions/Statistical/CountATest.php | 4 +- .../Functions/Statistical/CountBlankTest.php | 4 +- .../Functions/Statistical/CountIfTest.php | 4 +- .../Functions/Statistical/CountIfsTest.php | 4 +- .../Functions/Statistical/CountTest.php | 10 +- .../Functions/Statistical/CovarTest.php | 4 +- .../Functions/Statistical/DevSqTest.php | 4 +- .../Functions/Statistical/ExponDistTest.php | 4 +- .../Functions/Statistical/FDistTest.php | 4 +- .../Functions/Statistical/FisherInvTest.php | 4 +- .../Functions/Statistical/FisherTest.php | 4 +- .../Functions/Statistical/ForecastTest.php | 4 +- .../Functions/Statistical/GammaDistTest.php | 4 +- .../Functions/Statistical/GammaInvTest.php | 4 +- .../Functions/Statistical/GammaLnTest.php | 4 +- .../Functions/Statistical/GammaTest.php | 4 +- .../Functions/Statistical/GaussTest.php | 4 +- .../Functions/Statistical/GeoMeanTest.php | 4 +- .../Functions/Statistical/GrowthTest.php | 8 +- .../Functions/Statistical/HarMeanTest.php | 4 +- .../Functions/Statistical/HypGeomDistTest.php | 4 +- .../Functions/Statistical/InterceptTest.php | 4 +- .../Functions/Statistical/KurtTest.php | 4 +- .../Functions/Statistical/LargeTest.php | 4 +- .../Functions/Statistical/LinEstTest.php | 4 +- .../Functions/Statistical/LogEstTest.php | 4 +- .../Functions/Statistical/LogInvTest.php | 4 +- .../Statistical/LogNormDist2Test.php | 4 +- .../Functions/Statistical/LogNormDistTest.php | 4 +- .../Functions/Statistical/MaxATest.php | 4 +- .../Functions/Statistical/MaxIfsTest.php | 4 +- .../Functions/Statistical/MaxTest.php | 4 +- .../Functions/Statistical/MedianTest.php | 4 +- .../Functions/Statistical/MinATest.php | 4 +- .../Functions/Statistical/MinIfsTest.php | 4 +- .../Functions/Statistical/MinTest.php | 4 +- .../Statistical/NegBinomDistTest.php | 4 +- .../Functions/Statistical/NormDistTest.php | 4 +- .../Functions/Statistical/NormInvTest.php | 4 +- .../Functions/Statistical/NormSDist2Test.php | 4 +- .../Functions/Statistical/NormSDistTest.php | 4 +- .../Functions/Statistical/NormSInvTest.php | 4 +- .../Functions/Statistical/PercentRankTest.php | 4 +- .../Functions/Statistical/PercentileTest.php | 4 +- .../Functions/Statistical/PermutTest.php | 4 +- .../Functions/Statistical/PoissonTest.php | 4 +- .../Functions/Statistical/QuartileTest.php | 4 +- .../Functions/Statistical/RankTest.php | 4 +- .../Functions/Statistical/RsqTest.php | 4 +- .../Functions/Statistical/SkewTest.php | 4 +- .../Functions/Statistical/SlopeTest.php | 4 +- .../Functions/Statistical/SmallTest.php | 4 +- .../Functions/Statistical/StDevATest.php | 6 +- .../Functions/Statistical/StDevPATest.php | 6 +- .../Functions/Statistical/StDevPTest.php | 6 +- .../Functions/Statistical/StDevTest.php | 6 +- .../Functions/Statistical/StandardizeTest.php | 4 +- .../Functions/Statistical/SteyxTest.php | 4 +- .../Functions/Statistical/TDistTest.php | 4 +- .../Functions/Statistical/TinvTest.php | 4 +- .../Functions/Statistical/TrendTest.php | 8 +- .../Functions/Statistical/TrimMeanTest.php | 4 +- .../Functions/Statistical/VarATest.php | 6 +- .../Functions/Statistical/VarPATest.php | 6 +- .../Functions/Statistical/VarPTest.php | 6 +- .../Functions/Statistical/VarTest.php | 6 +- .../Functions/Statistical/WeibullTest.php | 4 +- .../Functions/Statistical/ZTestTest.php | 4 +- .../Functions/TextData/DeprecatedTest.php | 44 - .../Calculation/Functions/TextData/TTest.php | 4 +- .../Functions/Web/UrlEncodeTest.php | 4 +- .../Functions/Web/WebServiceTest.php | 8 +- .../Calculation/FunctionsTest.php | 7 - .../DocumentGeneratorTest.php | 8 +- 242 files changed, 513 insertions(+), 10198 deletions(-) delete mode 100644 src/PhpSpreadsheet/Calculation/Database.php delete mode 100644 src/PhpSpreadsheet/Calculation/DateTime.php delete mode 100644 src/PhpSpreadsheet/Calculation/Engineering.php delete mode 100644 src/PhpSpreadsheet/Calculation/Financial.php delete mode 100644 src/PhpSpreadsheet/Calculation/Logical.php delete mode 100644 src/PhpSpreadsheet/Calculation/LookupRef.php delete mode 100644 src/PhpSpreadsheet/Calculation/MathTrig.php delete mode 100644 src/PhpSpreadsheet/Calculation/Statistical.php delete mode 100644 src/PhpSpreadsheet/Calculation/TextData.php delete mode 100644 src/PhpSpreadsheet/Calculation/Web.php delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/DeprecatedExcelErrorTest.php delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/MovedBitwiseTest.php delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/MovedFunctionsTest.php delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ParseComplexTest.php delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MovedFunctionsTest.php delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MovedFunctionsTest.php delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/TextData/DeprecatedTest.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index bdbbf4a89e..69b14f1ef4 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -245,51 +245,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DMAX\\(\\) should return float but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DMIN\\(\\) should return float but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DPRODUCT\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DSTDEV\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DSTDEVP\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DSUM\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DVAR\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\:\\:DVARP\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - - - message: "#^Parameter \\#2 \\$field of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\\\DCountA\\:\\:evaluate\\(\\) expects int\\|string, int\\|string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Database.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\\\DatabaseAbstract\\:\\:buildCondition\\(\\) has parameter \\$criterion with no type specified\\.$#" count: 1 @@ -395,21 +350,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/ExceptionHandler.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:ISPMT\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Financial.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:ISPMT\\(\\) has parameter \\$args with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Financial.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:NPV\\(\\) has parameter \\$args with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Financial.php - - message: "#^Parameter \\#1 \\$year of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:isLeapYear\\(\\) expects int\\|string, array\\|int\\|string given\\.$#" count: 1 @@ -630,16 +570,6 @@ parameters: count: 3 path: src/PhpSpreadsheet/Calculation/Logical/Operations.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\:\\:CHOOSE\\(\\) has parameter \\$chooseArgs with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\:\\:OFFSET\\(\\) should return array\\|string but returns array\\|int\\|string\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/LookupRef.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Address\\:\\:sheetName\\(\\) has no return type specified\\.$#" count: 1 @@ -835,16 +765,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\:\\:MAXIFS\\(\\) should return float but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\:\\:MINIFS\\(\\) should return float but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Averages\\:\\:filterArguments\\(\\) has no return type specified\\.$#" count: 1 @@ -1125,11 +1045,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\:\\:CONCATENATE\\(\\) has parameter \\$args with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/TextData.php - - message: "#^Variable \\$value on left side of \\?\\? always exists and is not nullable\\.$#" count: 4 diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 26ef79460f..423cf9db0e 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -2752,7 +2752,7 @@ class Calculation ], 'NAME.ERROR' => [ 'argumentCount' => '*', - 'functionCall' => [Functions::class, 'NAME'], + 'functionCall' => [Information\ExcelError::class, 'NAME'], ], 'WILDCARDMATCH' => [ 'argumentCount' => '2', @@ -4655,7 +4655,7 @@ private function processTokenStack($tokens, $cellID = null, ?Cell $cell = null) } if (count(Functions::flattenArray($cellIntersect)) === 0) { $this->debugLog->writeDebugLog('Evaluation Result is %s', $this->showTypeDetails($cellIntersect)); - $stack->push('Error', Functions::null(), null); + $stack->push('Error', ExcelError::null(), null); } else { $cellRef = Coordinate::stringFromColumnIndex(min($oCol) + 1) . min($oRow) . ':' . Coordinate::stringFromColumnIndex(max($oCol) + 1) . max($oRow); diff --git a/src/PhpSpreadsheet/Calculation/Database.php b/src/PhpSpreadsheet/Calculation/Database.php deleted file mode 100644 index 6503167475..0000000000 --- a/src/PhpSpreadsheet/Calculation/Database.php +++ /dev/null @@ -1,440 +0,0 @@ -getMessage(); - } - } - - /** - * DATETIMENOW. - * - * Returns the current date and time. - * The NOW function is useful when you need to display the current date and time on a worksheet or - * calculate a value based on the current date and time, and have that value updated each time you - * open the worksheet. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date - * and time format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. - * - * Excel Function: - * NOW() - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Current::now() - * Use the now method in the DateTimeExcel\Current class instead - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function DATETIMENOW() - { - return DateTimeExcel\Current::now(); - } - - /** - * DATENOW. - * - * Returns the current date. - * The NOW function is useful when you need to display the current date and time on a worksheet or - * calculate a value based on the current date and time, and have that value updated each time you - * open the worksheet. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date - * and time format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. - * - * Excel Function: - * TODAY() - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Current::today() - * Use the today method in the DateTimeExcel\Current class instead - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function DATENOW() - { - return DateTimeExcel\Current::today(); - } - - /** - * DATE. - * - * The DATE function returns a value that represents a particular date. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date - * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. - * - * - * Excel Function: - * DATE(year,month,day) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Date::fromYMD() - * Use the fromYMD method in the DateTimeExcel\Date class instead - * - * PhpSpreadsheet is a lot more forgiving than MS Excel when passing non numeric values to this function. - * A Month name or abbreviation (English only at this point) such as 'January' or 'Jan' will still be accepted, - * as will a day value with a suffix (e.g. '21st' rather than simply 21); again only English language. - * - * @param int $year The value of the year argument can include one to four digits. - * Excel interprets the year argument according to the configured - * date system: 1900 or 1904. - * If year is between 0 (zero) and 1899 (inclusive), Excel adds that - * value to 1900 to calculate the year. For example, DATE(108,1,2) - * returns January 2, 2008 (1900+108). - * If year is between 1900 and 9999 (inclusive), Excel uses that - * value as the year. For example, DATE(2008,1,2) returns January 2, - * 2008. - * If year is less than 0 or is 10000 or greater, Excel returns the - * #NUM! error value. - * @param int $month A positive or negative integer representing the month of the year - * from 1 to 12 (January to December). - * If month is greater than 12, month adds that number of months to - * the first month in the year specified. For example, DATE(2008,14,2) - * returns the serial number representing February 2, 2009. - * If month is less than 1, month subtracts the magnitude of that - * number of months, plus 1, from the first month in the year - * specified. For example, DATE(2008,-3,2) returns the serial number - * representing September 2, 2007. - * @param int $day A positive or negative integer representing the day of the month - * from 1 to 31. - * If day is greater than the number of days in the month specified, - * day adds that number of days to the first day in the month. For - * example, DATE(2008,1,35) returns the serial number representing - * February 4, 2008. - * If day is less than 1, day subtracts the magnitude that number of - * days, plus one, from the first day of the month specified. For - * example, DATE(2008,1,-15) returns the serial number representing - * December 16, 2007. - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function DATE($year = 0, $month = 1, $day = 1) - { - return DateTimeExcel\Date::fromYMD($year, $month, $day); - } - - /** - * TIME. - * - * The TIME function returns a value that represents a particular time. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time - * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. - * - * Excel Function: - * TIME(hour,minute,second) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Time::fromHMS() - * Use the fromHMS method in the DateTimeExcel\Time class instead - * - * @param int $hour A number from 0 (zero) to 32767 representing the hour. - * Any value greater than 23 will be divided by 24 and the remainder - * will be treated as the hour value. For example, TIME(27,0,0) = - * TIME(3,0,0) = .125 or 3:00 AM. - * @param int $minute A number from 0 to 32767 representing the minute. - * Any value greater than 59 will be converted to hours and minutes. - * For example, TIME(0,750,0) = TIME(12,30,0) = .520833 or 12:30 PM. - * @param int $second A number from 0 to 32767 representing the second. - * Any value greater than 59 will be converted to hours, minutes, - * and seconds. For example, TIME(0,0,2000) = TIME(0,33,22) = .023148 - * or 12:33:20 AM - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function TIME($hour = 0, $minute = 0, $second = 0) - { - return DateTimeExcel\Time::fromHMS($hour, $minute, $second); - } - - /** - * DATEVALUE. - * - * Returns a value that represents a particular date. - * Use DATEVALUE to convert a date represented by a text string to an Excel or PHP date/time stamp - * value. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the date - * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. - * - * Excel Function: - * DATEVALUE(dateValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\DateValue::fromString() - * Use the fromString method in the DateTimeExcel\DateValue class instead - * - * @param string $dateValue Text that represents a date in a Microsoft Excel date format. - * For example, "1/30/2008" or "30-Jan-2008" are text strings within - * quotation marks that represent dates. Using the default date - * system in Excel for Windows, date_text must represent a date from - * January 1, 1900, to December 31, 9999. Using the default date - * system in Excel for the Macintosh, date_text must represent a date - * from January 1, 1904, to December 31, 9999. DATEVALUE returns the - * #VALUE! error value if date_text is out of this range. - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function DATEVALUE($dateValue) - { - return DateTimeExcel\DateValue::fromString($dateValue); - } - - /** - * TIMEVALUE. - * - * Returns a value that represents a particular time. - * Use TIMEVALUE to convert a time represented by a text string to an Excel or PHP date/time stamp - * value. - * - * NOTE: When used in a Cell Formula, MS Excel changes the cell format so that it matches the time - * format of your regional settings. PhpSpreadsheet does not change cell formatting in this way. - * - * Excel Function: - * TIMEVALUE(timeValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\TimeValue::fromString() - * Use the fromString method in the DateTimeExcel\TimeValue class instead - * - * @param string $timeValue A text string that represents a time in any one of the Microsoft - * Excel time formats; for example, "6:45 PM" and "18:45" text strings - * within quotation marks that represent time. - * Date information in time_text is ignored. - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function TIMEVALUE($timeValue) - { - return DateTimeExcel\TimeValue::fromString($timeValue); - } - - /** - * DATEDIF. - * - * Excel Function: - * DATEDIF(startdate, enddate, unit) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Difference::interval() - * Use the interval method in the DateTimeExcel\Difference class instead - * - * @param mixed $startDate Excel date serial value, PHP date/time stamp, PHP DateTime object - * or a standard date string - * @param mixed $endDate Excel date serial value, PHP date/time stamp, PHP DateTime object - * or a standard date string - * @param array|string $unit - * - * @return array|int|string Interval between the dates - */ - public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') - { - return DateTimeExcel\Difference::interval($startDate, $endDate, $unit); - } - - /** - * DAYS. - * - * Returns the number of days between two dates - * - * Excel Function: - * DAYS(endDate, startDate) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Days::between() - * Use the between method in the DateTimeExcel\Days class instead - * - * @param array|DateTimeInterface|float|int|string $endDate Excel date serial value (float), - * PHP date timestamp (integer), PHP DateTime object, or a standard date string - * @param array|DateTimeInterface|float|int|string $startDate Excel date serial value (float), - * PHP date timestamp (integer), PHP DateTime object, or a standard date string - * - * @return array|int|string Number of days between start date and end date or an error - */ - public static function DAYS($endDate = 0, $startDate = 0) - { - return DateTimeExcel\Days::between($endDate, $startDate); - } - - /** - * DAYS360. - * - * Returns the number of days between two dates based on a 360-day year (twelve 30-day months), - * which is used in some accounting calculations. Use this function to help compute payments if - * your accounting system is based on twelve 30-day months. - * - * Excel Function: - * DAYS360(startDate,endDate[,method]) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Days360::between() - * Use the between method in the DateTimeExcel\Days360 class instead - * - * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param array|bool $method US or European Method - * FALSE or omitted: U.S. (NASD) method. If the starting date is - * the last day of a month, it becomes equal to the 30th of the - * same month. If the ending date is the last day of a month and - * the starting date is earlier than the 30th of a month, the - * ending date becomes equal to the 1st of the next month; - * otherwise the ending date becomes equal to the 30th of the - * same month. - * TRUE: European method. Starting dates and ending dates that - * occur on the 31st of a month become equal to the 30th of the - * same month. - * - * @return array|int|string Number of days between start date and end date - */ - public static function DAYS360($startDate = 0, $endDate = 0, $method = false) - { - return DateTimeExcel\Days360::between($startDate, $endDate, $method); - } - - /** - * YEARFRAC. - * - * Calculates the fraction of the year represented by the number of whole days between two dates - * (the start_date and the end_date). - * Use the YEARFRAC worksheet function to identify the proportion of a whole year's benefits or - * obligations to assign to a specific term. - * - * Excel Function: - * YEARFRAC(startDate,endDate[,method]) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\YearFrac::fraction() - * Use the fraction method in the DateTimeExcel\YearFrac class instead - * - * See https://lists.oasis-open.org/archives/office-formula/200806/msg00039.html - * for description of algorithm used in Excel - * - * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param array|int $method Method used for the calculation - * 0 or omitted US (NASD) 30/360 - * 1 Actual/actual - * 2 Actual/360 - * 3 Actual/365 - * 4 European 30/360 - * - * @return array|float|string fraction of the year, or a string containing an error - */ - public static function YEARFRAC($startDate = 0, $endDate = 0, $method = 0) - { - return DateTimeExcel\YearFrac::fraction($startDate, $endDate, $method); - } - - /** - * NETWORKDAYS. - * - * Returns the number of whole working days between start_date and end_date. Working days - * exclude weekends and any dates identified in holidays. - * Use NETWORKDAYS to calculate employee benefits that accrue based on the number of days - * worked during a specific term. - * - * Excel Function: - * NETWORKDAYS(startDate,endDate[,holidays[,holiday[,...]]]) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\NetworkDays::count() - * Use the count method in the DateTimeExcel\NetworkDays class instead - * - * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param mixed $dateArgs - * - * @return array|int|string Interval between the dates - */ - public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) - { - return DateTimeExcel\NetworkDays::count($startDate, $endDate, ...$dateArgs); - } - - /** - * WORKDAY. - * - * Returns the date that is the indicated number of working days before or after a date (the - * starting date). Working days exclude weekends and any dates identified as holidays. - * Use WORKDAY to exclude weekends or holidays when you calculate invoice due dates, expected - * delivery times, or the number of days of work performed. - * - * Excel Function: - * WORKDAY(startDate,endDays[,holidays[,holiday[,...]]]) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\WorkDay::date() - * Use the date method in the DateTimeExcel\WorkDay class instead - * - * @param mixed $startDate Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param int $endDays The number of nonweekend and nonholiday days before or after - * startDate. A positive value for days yields a future date; a - * negative value yields a past date. - * @param mixed $dateArgs - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function WORKDAY($startDate, $endDays, ...$dateArgs) - { - return DateTimeExcel\WorkDay::date($startDate, $endDays, ...$dateArgs); - } - - /** - * DAYOFMONTH. - * - * Returns the day of the month, for a specified date. The day is given as an integer - * ranging from 1 to 31. - * - * Excel Function: - * DAY(dateValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\DateParts::day() - * Use the day method in the DateTimeExcel\DateParts class instead - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * - * @return array|int|string Day of the month - */ - public static function DAYOFMONTH($dateValue = 1) - { - return DateTimeExcel\DateParts::day($dateValue); - } - - /** - * WEEKDAY. - * - * Returns the day of the week for a specified date. The day is given as an integer - * ranging from 0 to 7 (dependent on the requested style). - * - * Excel Function: - * WEEKDAY(dateValue[,style]) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Week::day() - * Use the day method in the DateTimeExcel\Week class instead - * - * @param float|int|string $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param int $style A number that determines the type of return value - * 1 or omitted Numbers 1 (Sunday) through 7 (Saturday). - * 2 Numbers 1 (Monday) through 7 (Sunday). - * 3 Numbers 0 (Monday) through 6 (Sunday). - * - * @return array|int|string Day of the week value - */ - public static function WEEKDAY($dateValue = 1, $style = 1) - { - return DateTimeExcel\Week::day($dateValue, $style); - } - - /** - * STARTWEEK_SUNDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_SUNDAY instead - */ - const STARTWEEK_SUNDAY = 1; - - /** - * STARTWEEK_MONDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY instead - */ - const STARTWEEK_MONDAY = 2; - - /** - * STARTWEEK_MONDAY_ALT. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY_ALT instead - */ - const STARTWEEK_MONDAY_ALT = 11; - - /** - * STARTWEEK_TUESDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_TUESDAY instead - */ - const STARTWEEK_TUESDAY = 12; - - /** - * STARTWEEK_WEDNESDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_WEDNESDAY instead - */ - const STARTWEEK_WEDNESDAY = 13; - - /** - * STARTWEEK_THURSDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_THURSDAY instead - */ - const STARTWEEK_THURSDAY = 14; - - /** - * STARTWEEK_FRIDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_FRIDAY instead - */ - const STARTWEEK_FRIDAY = 15; - - /** - * STARTWEEK_SATURDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_SATURDAY instead - */ - const STARTWEEK_SATURDAY = 16; - - /** - * STARTWEEK_SUNDAY_ALT. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_SUNDAY_ALT instead - */ - const STARTWEEK_SUNDAY_ALT = 17; - - /** - * DOW_SUNDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\DOW_SUNDAY instead - */ - const DOW_SUNDAY = 1; - - /** - * DOW_MONDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\DOW_MONDAY instead - */ - const DOW_MONDAY = 2; - - /** - * DOW_TUESDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\DOW_TUESDAY instead - */ - const DOW_TUESDAY = 3; - - /** - * DOW_WEDNESDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\DOW_WEDNESDAY instead - */ - const DOW_WEDNESDAY = 4; - - /** - * DOW_THURSDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\DOW_THURSDAY instead - */ - const DOW_THURSDAY = 5; - - /** - * DOW_FRIDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\DOW_FRIDAY instead - */ - const DOW_FRIDAY = 6; - - /** - * DOW_SATURDAY. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\DOW_SATURDAY instead - */ - const DOW_SATURDAY = 7; - - /** - * STARTWEEK_MONDAY_ISO. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\STARTWEEK_MONDAY_ISO instead - */ - const STARTWEEK_MONDAY_ISO = 21; - - /** - * METHODARR. - * - * @Deprecated 1.18.0 - * - * @see Use DateTimeExcel\Constants\METHODARR instead - */ - const METHODARR = [ - self::STARTWEEK_SUNDAY => self::DOW_SUNDAY, - self::DOW_MONDAY, - self::STARTWEEK_MONDAY_ALT => self::DOW_MONDAY, - self::DOW_TUESDAY, - self::DOW_WEDNESDAY, - self::DOW_THURSDAY, - self::DOW_FRIDAY, - self::DOW_SATURDAY, - self::DOW_SUNDAY, - self::STARTWEEK_MONDAY_ISO => self::STARTWEEK_MONDAY_ISO, - ]; - - /** - * WEEKNUM. - * - * Returns the week of the year for a specified date. - * The WEEKNUM function considers the week containing January 1 to be the first week of the year. - * However, there is a European standard that defines the first week as the one with the majority - * of days (four or more) falling in the new year. This means that for years in which there are - * three days or less in the first week of January, the WEEKNUM function returns week numbers - * that are incorrect according to the European standard. - * - * Excel Function: - * WEEKNUM(dateValue[,style]) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Week::number(() - * Use the number method in the DateTimeExcel\Week class instead - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param int $method Week begins on Sunday or Monday - * 1 or omitted Week begins on Sunday. - * 2 Week begins on Monday. - * 11 Week begins on Monday. - * 12 Week begins on Tuesday. - * 13 Week begins on Wednesday. - * 14 Week begins on Thursday. - * 15 Week begins on Friday. - * 16 Week begins on Saturday. - * 17 Week begins on Sunday. - * 21 ISO (Jan. 4 is week 1, begins on Monday). - * - * @return array|int|string Week Number - */ - public static function WEEKNUM($dateValue = 1, $method = self::STARTWEEK_SUNDAY) - { - return DateTimeExcel\Week::number($dateValue, $method); - } - - /** - * ISOWEEKNUM. - * - * Returns the ISO 8601 week number of the year for a specified date. - * - * Excel Function: - * ISOWEEKNUM(dateValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Week::isoWeekNumber() - * Use the isoWeekNumber method in the DateTimeExcel\Week class instead - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * - * @return array|int|string Week Number - */ - public static function ISOWEEKNUM($dateValue = 1) - { - return DateTimeExcel\Week::isoWeekNumber($dateValue); - } - - /** - * MONTHOFYEAR. - * - * Returns the month of a date represented by a serial number. - * The month is given as an integer, ranging from 1 (January) to 12 (December). - * - * Excel Function: - * MONTH(dateValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\DateParts::month() - * Use the month method in the DateTimeExcel\DateParts class instead - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * - * @return array|int|string Month of the year - */ - public static function MONTHOFYEAR($dateValue = 1) - { - return DateTimeExcel\DateParts::month($dateValue); - } - - /** - * YEAR. - * - * Returns the year corresponding to a date. - * The year is returned as an integer in the range 1900-9999. - * - * Excel Function: - * YEAR(dateValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\DateParts::year() - * Use the ear method in the DateTimeExcel\DateParts class instead - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * - * @return array|int|string Year - */ - public static function YEAR($dateValue = 1) - { - return DateTimeExcel\DateParts::year($dateValue); - } - - /** - * HOUROFDAY. - * - * Returns the hour of a time value. - * The hour is given as an integer, ranging from 0 (12:00 A.M.) to 23 (11:00 P.M.). - * - * Excel Function: - * HOUR(timeValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\TimeParts::hour() - * Use the hour method in the DateTimeExcel\TimeParts class instead - * - * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard time string - * - * @return array|int|string Hour - */ - public static function HOUROFDAY($timeValue = 0) - { - return DateTimeExcel\TimeParts::hour($timeValue); - } - - /** - * MINUTE. - * - * Returns the minutes of a time value. - * The minute is given as an integer, ranging from 0 to 59. - * - * Excel Function: - * MINUTE(timeValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\TimeParts::minute() - * Use the minute method in the DateTimeExcel\TimeParts class instead - * - * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard time string - * - * @return array|int|string Minute - */ - public static function MINUTE($timeValue = 0) - { - return DateTimeExcel\TimeParts::minute($timeValue); - } - - /** - * SECOND. - * - * Returns the seconds of a time value. - * The second is given as an integer in the range 0 (zero) to 59. - * - * Excel Function: - * SECOND(timeValue) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\TimeParts::second() - * Use the second method in the DateTimeExcel\TimeParts class instead - * - * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard time string - * - * @return array|int|string Second - */ - public static function SECOND($timeValue = 0) - { - return DateTimeExcel\TimeParts::second($timeValue); - } - - /** - * EDATE. - * - * Returns the serial number that represents the date that is the indicated number of months - * before or after a specified date (the start_date). - * Use EDATE to calculate maturity dates or due dates that fall on the same day of the month - * as the date of issue. - * - * Excel Function: - * EDATE(dateValue,adjustmentMonths) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Month::adjust() - * Use the adjust method in the DateTimeExcel\Edate class instead - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param int $adjustmentMonths The number of months before or after start_date. - * A positive value for months yields a future date; - * a negative value yields a past date. - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function EDATE($dateValue = 1, $adjustmentMonths = 0) - { - return DateTimeExcel\Month::adjust($dateValue, $adjustmentMonths); - } - - /** - * EOMONTH. - * - * Returns the date value for the last day of the month that is the indicated number of months - * before or after start_date. - * Use EOMONTH to calculate maturity dates or due dates that fall on the last day of the month. - * - * Excel Function: - * EOMONTH(dateValue,adjustmentMonths) - * - * @Deprecated 1.18.0 - * - * @See DateTimeExcel\Month::lastDay() - * Use the lastDay method in the DateTimeExcel\EoMonth class instead - * - * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), - * PHP DateTime object, or a standard date string - * @param int $adjustmentMonths The number of months before or after start_date. - * A positive value for months yields a future date; - * a negative value yields a past date. - * - * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, - * depending on the value of the ReturnDateType flag - */ - public static function EOMONTH($dateValue = 1, $adjustmentMonths = 0) - { - return DateTimeExcel\Month::lastDay($dateValue, $adjustmentMonths); - } -} diff --git a/src/PhpSpreadsheet/Calculation/Engineering.php b/src/PhpSpreadsheet/Calculation/Engineering.php deleted file mode 100644 index d70b32d6ab..0000000000 --- a/src/PhpSpreadsheet/Calculation/Engineering.php +++ /dev/null @@ -1,1446 +0,0 @@ - $complex->getReal(), - 'imaginary' => $complex->getImaginary(), - 'suffix' => $complex->getSuffix(), - ]; - } - - /** - * BESSELI. - * - * Returns the modified Bessel function In(x), which is equivalent to the Bessel function evaluated - * for purely imaginary arguments - * - * Excel Function: - * BESSELI(x,ord) - * - * @Deprecated 1.17.0 - * - * @see Use the BESSELI() method in the Engineering\BesselI class instead - * - * @param float $x The value at which to evaluate the function. - * If x is nonnumeric, BESSELI returns the #VALUE! error value. - * @param int $ord The order of the Bessel function. - * If ord is not an integer, it is truncated. - * If $ord is nonnumeric, BESSELI returns the #VALUE! error value. - * If $ord < 0, BESSELI returns the #NUM! error value. - * - * @return array|float|string Result, or a string containing an error - */ - public static function BESSELI($x, $ord) - { - return Engineering\BesselI::BESSELI($x, $ord); - } - - /** - * BESSELJ. - * - * Returns the Bessel function - * - * Excel Function: - * BESSELJ(x,ord) - * - * @Deprecated 1.17.0 - * - * @see Use the BESSELJ() method in the Engineering\BesselJ class instead - * - * @param float $x The value at which to evaluate the function. - * If x is nonnumeric, BESSELJ returns the #VALUE! error value. - * @param int $ord The order of the Bessel function. If n is not an integer, it is truncated. - * If $ord is nonnumeric, BESSELJ returns the #VALUE! error value. - * If $ord < 0, BESSELJ returns the #NUM! error value. - * - * @return array|float|string Result, or a string containing an error - */ - public static function BESSELJ($x, $ord) - { - return Engineering\BesselJ::BESSELJ($x, $ord); - } - - /** - * BESSELK. - * - * Returns the modified Bessel function Kn(x), which is equivalent to the Bessel functions evaluated - * for purely imaginary arguments. - * - * Excel Function: - * BESSELK(x,ord) - * - * @Deprecated 1.17.0 - * - * @see Use the BESSELK() method in the Engineering\BesselK class instead - * - * @param float $x The value at which to evaluate the function. - * If x is nonnumeric, BESSELK returns the #VALUE! error value. - * @param int $ord The order of the Bessel function. If n is not an integer, it is truncated. - * If $ord is nonnumeric, BESSELK returns the #VALUE! error value. - * If $ord < 0, BESSELK returns the #NUM! error value. - * - * @return array|float|string Result, or a string containing an error - */ - public static function BESSELK($x, $ord) - { - return Engineering\BesselK::BESSELK($x, $ord); - } - - /** - * BESSELY. - * - * Returns the Bessel function, which is also called the Weber function or the Neumann function. - * - * Excel Function: - * BESSELY(x,ord) - * - * @Deprecated 1.17.0 - * - * @see Use the BESSELY() method in the Engineering\BesselY class instead - * - * @param float $x The value at which to evaluate the function. - * If x is nonnumeric, BESSELY returns the #VALUE! error value. - * @param int $ord The order of the Bessel function. If n is not an integer, it is truncated. - * If $ord is nonnumeric, BESSELY returns the #VALUE! error value. - * If $ord < 0, BESSELY returns the #NUM! error value. - * - * @return array|float|string Result, or a string containing an error - */ - public static function BESSELY($x, $ord) - { - return Engineering\BesselY::BESSELY($x, $ord); - } - - /** - * BINTODEC. - * - * Return a binary value as decimal. - * - * Excel Function: - * BIN2DEC(x) - * - * @Deprecated 1.17.0 - * - * @see Use the toDecimal() method in the Engineering\ConvertBinary class instead - * - * @param mixed $x The binary number (as a string) that you want to convert. The number - * cannot contain more than 10 characters (10 bits). The most significant - * bit of number is the sign bit. The remaining 9 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - * If number is not a valid binary number, or if number contains more than - * 10 characters (10 bits), BIN2DEC returns the #NUM! error value. - * - * @return array|string - */ - public static function BINTODEC($x) - { - return Engineering\ConvertBinary::toDecimal($x); - } - - /** - * BINTOHEX. - * - * Return a binary value as hex. - * - * Excel Function: - * BIN2HEX(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toHex() method in the Engineering\ConvertBinary class instead - * - * @param mixed $x The binary number (as a string) that you want to convert. The number - * cannot contain more than 10 characters (10 bits). The most significant - * bit of number is the sign bit. The remaining 9 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - * If number is not a valid binary number, or if number contains more than - * 10 characters (10 bits), BIN2HEX returns the #NUM! error value. - * @param mixed $places The number of characters to use. If places is omitted, BIN2HEX uses the - * minimum number of characters necessary. Places is useful for padding the - * return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, BIN2HEX returns the #VALUE! error value. - * If places is negative, BIN2HEX returns the #NUM! error value. - * - * @return array|string - */ - public static function BINTOHEX($x, $places = null) - { - return Engineering\ConvertBinary::toHex($x, $places); - } - - /** - * BINTOOCT. - * - * Return a binary value as octal. - * - * Excel Function: - * BIN2OCT(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toOctal() method in the Engineering\ConvertBinary class instead - * - * @param mixed $x The binary number (as a string) that you want to convert. The number - * cannot contain more than 10 characters (10 bits). The most significant - * bit of number is the sign bit. The remaining 9 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - * If number is not a valid binary number, or if number contains more than - * 10 characters (10 bits), BIN2OCT returns the #NUM! error value. - * @param mixed $places The number of characters to use. If places is omitted, BIN2OCT uses the - * minimum number of characters necessary. Places is useful for padding the - * return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, BIN2OCT returns the #VALUE! error value. - * If places is negative, BIN2OCT returns the #NUM! error value. - * - * @return array|string - */ - public static function BINTOOCT($x, $places = null) - { - return Engineering\ConvertBinary::toOctal($x, $places); - } - - /** - * DECTOBIN. - * - * Return a decimal value as binary. - * - * Excel Function: - * DEC2BIN(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toBinary() method in the Engineering\ConvertDecimal class instead - * - * @param mixed $x The decimal integer you want to convert. If number is negative, - * valid place values are ignored and DEC2BIN returns a 10-character - * (10-bit) binary number in which the most significant bit is the sign - * bit. The remaining 9 bits are magnitude bits. Negative numbers are - * represented using two's-complement notation. - * If number < -512 or if number > 511, DEC2BIN returns the #NUM! error - * value. - * If number is nonnumeric, DEC2BIN returns the #VALUE! error value. - * If DEC2BIN requires more than places characters, it returns the #NUM! - * error value. - * @param mixed $places The number of characters to use. If places is omitted, DEC2BIN uses - * the minimum number of characters necessary. Places is useful for - * padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, DEC2BIN returns the #VALUE! error value. - * If places is zero or negative, DEC2BIN returns the #NUM! error value. - * - * @return array|string - */ - public static function DECTOBIN($x, $places = null) - { - return Engineering\ConvertDecimal::toBinary($x, $places); - } - - /** - * DECTOHEX. - * - * Return a decimal value as hex. - * - * Excel Function: - * DEC2HEX(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toHex() method in the Engineering\ConvertDecimal class instead - * - * @param mixed $x The decimal integer you want to convert. If number is negative, - * places is ignored and DEC2HEX returns a 10-character (40-bit) - * hexadecimal number in which the most significant bit is the sign - * bit. The remaining 39 bits are magnitude bits. Negative numbers - * are represented using two's-complement notation. - * If number < -549,755,813,888 or if number > 549,755,813,887, - * DEC2HEX returns the #NUM! error value. - * If number is nonnumeric, DEC2HEX returns the #VALUE! error value. - * If DEC2HEX requires more than places characters, it returns the - * #NUM! error value. - * @param mixed $places The number of characters to use. If places is omitted, DEC2HEX uses - * the minimum number of characters necessary. Places is useful for - * padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, DEC2HEX returns the #VALUE! error value. - * If places is zero or negative, DEC2HEX returns the #NUM! error value. - * - * @return array|string - */ - public static function DECTOHEX($x, $places = null) - { - return Engineering\ConvertDecimal::toHex($x, $places); - } - - /** - * DECTOOCT. - * - * Return an decimal value as octal. - * - * Excel Function: - * DEC2OCT(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toOctal() method in the Engineering\ConvertDecimal class instead - * - * @param mixed $x The decimal integer you want to convert. If number is negative, - * places is ignored and DEC2OCT returns a 10-character (30-bit) - * octal number in which the most significant bit is the sign bit. - * The remaining 29 bits are magnitude bits. Negative numbers are - * represented using two's-complement notation. - * If number < -536,870,912 or if number > 536,870,911, DEC2OCT - * returns the #NUM! error value. - * If number is nonnumeric, DEC2OCT returns the #VALUE! error value. - * If DEC2OCT requires more than places characters, it returns the - * #NUM! error value. - * @param mixed $places The number of characters to use. If places is omitted, DEC2OCT uses - * the minimum number of characters necessary. Places is useful for - * padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, DEC2OCT returns the #VALUE! error value. - * If places is zero or negative, DEC2OCT returns the #NUM! error value. - * - * @return array|string - */ - public static function DECTOOCT($x, $places = null) - { - return Engineering\ConvertDecimal::toOctal($x, $places); - } - - /** - * HEXTOBIN. - * - * Return a hex value as binary. - * - * Excel Function: - * HEX2BIN(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toBinary() method in the Engineering\ConvertHex class instead - * - * @param mixed $x the hexadecimal number (as a string) that you want to convert. - * Number cannot contain more than 10 characters. - * The most significant bit of number is the sign bit (40th bit from the right). - * The remaining 9 bits are magnitude bits. - * Negative numbers are represented using two's-complement notation. - * If number is negative, HEX2BIN ignores places and returns a 10-character binary number. - * If number is negative, it cannot be less than FFFFFFFE00, - * and if number is positive, it cannot be greater than 1FF. - * If number is not a valid hexadecimal number, HEX2BIN returns the #NUM! error value. - * If HEX2BIN requires more than places characters, it returns the #NUM! error value. - * @param mixed $places The number of characters to use. If places is omitted, - * HEX2BIN uses the minimum number of characters necessary. Places - * is useful for padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, HEX2BIN returns the #VALUE! error value. - * If places is negative, HEX2BIN returns the #NUM! error value. - * - * @return array|string - */ - public static function HEXTOBIN($x, $places = null) - { - return Engineering\ConvertHex::toBinary($x, $places); - } - - /** - * HEXTODEC. - * - * Return a hex value as decimal. - * - * Excel Function: - * HEX2DEC(x) - * - * @Deprecated 1.17.0 - * - * @see Use the toDecimal() method in the Engineering\ConvertHex class instead - * - * @param mixed $x The hexadecimal number (as a string) that you want to convert. This number cannot - * contain more than 10 characters (40 bits). The most significant - * bit of number is the sign bit. The remaining 39 bits are magnitude - * bits. Negative numbers are represented using two's-complement - * notation. - * If number is not a valid hexadecimal number, HEX2DEC returns the - * #NUM! error value. - * - * @return array|string - */ - public static function HEXTODEC($x) - { - return Engineering\ConvertHex::toDecimal($x); - } - - /** - * HEXTOOCT. - * - * Return a hex value as octal. - * - * Excel Function: - * HEX2OCT(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toOctal() method in the Engineering\ConvertHex class instead - * - * @param mixed $x The hexadecimal number (as a string) that you want to convert. Number cannot - * contain more than 10 characters. The most significant bit of - * number is the sign bit. The remaining 39 bits are magnitude - * bits. Negative numbers are represented using two's-complement - * notation. - * If number is negative, HEX2OCT ignores places and returns a - * 10-character octal number. - * If number is negative, it cannot be less than FFE0000000, and - * if number is positive, it cannot be greater than 1FFFFFFF. - * If number is not a valid hexadecimal number, HEX2OCT returns - * the #NUM! error value. - * If HEX2OCT requires more than places characters, it returns - * the #NUM! error value. - * @param mixed $places The number of characters to use. If places is omitted, HEX2OCT - * uses the minimum number of characters necessary. Places is - * useful for padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, HEX2OCT returns the #VALUE! error - * value. - * If places is negative, HEX2OCT returns the #NUM! error value. - * - * @return array|string - */ - public static function HEXTOOCT($x, $places = null) - { - return Engineering\ConvertHex::toOctal($x, $places); - } - - /** - * OCTTOBIN. - * - * Return an octal value as binary. - * - * Excel Function: - * OCT2BIN(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toBinary() method in the Engineering\ConvertOctal class instead - * - * @param mixed $x The octal number you want to convert. Number may not - * contain more than 10 characters. The most significant - * bit of number is the sign bit. The remaining 29 bits - * are magnitude bits. Negative numbers are represented - * using two's-complement notation. - * If number is negative, OCT2BIN ignores places and returns - * a 10-character binary number. - * If number is negative, it cannot be less than 7777777000, - * and if number is positive, it cannot be greater than 777. - * If number is not a valid octal number, OCT2BIN returns - * the #NUM! error value. - * If OCT2BIN requires more than places characters, it - * returns the #NUM! error value. - * @param mixed $places The number of characters to use. If places is omitted, - * OCT2BIN uses the minimum number of characters necessary. - * Places is useful for padding the return value with - * leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, OCT2BIN returns the #VALUE! - * error value. - * If places is negative, OCT2BIN returns the #NUM! error - * value. - * - * @return array|string - */ - public static function OCTTOBIN($x, $places = null) - { - return Engineering\ConvertOctal::toBinary($x, $places); - } - - /** - * OCTTODEC. - * - * Return an octal value as decimal. - * - * Excel Function: - * OCT2DEC(x) - * - * @Deprecated 1.17.0 - * - * @see Use the toDecimal() method in the Engineering\ConvertOctal class instead - * - * @param mixed $x The octal number you want to convert. Number may not contain - * more than 10 octal characters (30 bits). The most significant - * bit of number is the sign bit. The remaining 29 bits are - * magnitude bits. Negative numbers are represented using - * two's-complement notation. - * If number is not a valid octal number, OCT2DEC returns the - * #NUM! error value. - * - * @return array|string - */ - public static function OCTTODEC($x) - { - return Engineering\ConvertOctal::toDecimal($x); - } - - /** - * OCTTOHEX. - * - * Return an octal value as hex. - * - * Excel Function: - * OCT2HEX(x[,places]) - * - * @Deprecated 1.17.0 - * - * @see Use the toHex() method in the Engineering\ConvertOctal class instead - * - * @param mixed $x The octal number you want to convert. Number may not contain - * more than 10 octal characters (30 bits). The most significant - * bit of number is the sign bit. The remaining 29 bits are - * magnitude bits. Negative numbers are represented using - * two's-complement notation. - * If number is negative, OCT2HEX ignores places and returns a - * 10-character hexadecimal number. - * If number is not a valid octal number, OCT2HEX returns the - * #NUM! error value. - * If OCT2HEX requires more than places characters, it returns - * the #NUM! error value. - * @param mixed $places The number of characters to use. If places is omitted, OCT2HEX - * uses the minimum number of characters necessary. Places is useful - * for padding the return value with leading 0s (zeros). - * If places is not an integer, it is truncated. - * If places is nonnumeric, OCT2HEX returns the #VALUE! error value. - * If places is negative, OCT2HEX returns the #NUM! error value. - * - * @return array|string - */ - public static function OCTTOHEX($x, $places = null) - { - return Engineering\ConvertOctal::toHex($x, $places); - } - - /** - * COMPLEX. - * - * Converts real and imaginary coefficients into a complex number of the form x +/- yi or x +/- yj. - * - * Excel Function: - * COMPLEX(realNumber,imaginary[,suffix]) - * - * @Deprecated 1.18.0 - * - * @see Use the COMPLEX() method in the Engineering\Complex class instead - * - * @param array|float $realNumber the real coefficient of the complex number - * @param array|float $imaginary the imaginary coefficient of the complex number - * @param array|string $suffix The suffix for the imaginary component of the complex number. - * If omitted, the suffix is assumed to be "i". - * - * @return array|string - */ - public static function COMPLEX($realNumber = 0.0, $imaginary = 0.0, $suffix = 'i') - { - return Engineering\Complex::COMPLEX($realNumber, $imaginary, $suffix); - } - - /** - * IMAGINARY. - * - * Returns the imaginary coefficient of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMAGINARY(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMAGINARY() method in the Engineering\Complex class instead - * - * @param string $complexNumber the complex number for which you want the imaginary - * coefficient - * - * @return array|float|string - */ - public static function IMAGINARY($complexNumber) - { - return Engineering\Complex::IMAGINARY($complexNumber); - } - - /** - * IMREAL. - * - * Returns the real coefficient of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMREAL(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMREAL() method in the Engineering\Complex class instead - * - * @param string $complexNumber the complex number for which you want the real coefficient - * - * @return array|float|string - */ - public static function IMREAL($complexNumber) - { - return Engineering\Complex::IMREAL($complexNumber); - } - - /** - * IMABS. - * - * Returns the absolute value (modulus) of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMABS(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMABS() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the absolute value - * - * @return array|float|string - */ - public static function IMABS($complexNumber) - { - return ComplexFunctions::IMABS($complexNumber); - } - - /** - * IMARGUMENT. - * - * Returns the argument theta of a complex number, i.e. the angle in radians from the real - * axis to the representation of the number in polar coordinates. - * - * Excel Function: - * IMARGUMENT(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMARGUMENT() method in the Engineering\ComplexFunctions class instead - * - * @param array|string $complexNumber the complex number for which you want the argument theta - * - * @return array|float|string - */ - public static function IMARGUMENT($complexNumber) - { - return ComplexFunctions::IMARGUMENT($complexNumber); - } - - /** - * IMCONJUGATE. - * - * Returns the complex conjugate of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMCONJUGATE(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMARGUMENT() method in the Engineering\ComplexFunctions class instead - * - * @param array|string $complexNumber the complex number for which you want the conjugate - * - * @return array|string - */ - public static function IMCONJUGATE($complexNumber) - { - return ComplexFunctions::IMCONJUGATE($complexNumber); - } - - /** - * IMCOS. - * - * Returns the cosine of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMCOS(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMCOS() method in the Engineering\ComplexFunctions class instead - * - * @param array|string $complexNumber the complex number for which you want the cosine - * - * @return array|float|string - */ - public static function IMCOS($complexNumber) - { - return ComplexFunctions::IMCOS($complexNumber); - } - - /** - * IMCOSH. - * - * Returns the hyperbolic cosine of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMCOSH(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMCOSH() method in the Engineering\ComplexFunctions class instead - * - * @param array|string $complexNumber the complex number for which you want the hyperbolic cosine - * - * @return array|float|string - */ - public static function IMCOSH($complexNumber) - { - return ComplexFunctions::IMCOSH($complexNumber); - } - - /** - * IMCOT. - * - * Returns the cotangent of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMCOT(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMCOT() method in the Engineering\ComplexFunctions class instead - * - * @param array|string $complexNumber the complex number for which you want the cotangent - * - * @return array|float|string - */ - public static function IMCOT($complexNumber) - { - return ComplexFunctions::IMCOT($complexNumber); - } - - /** - * IMCSC. - * - * Returns the cosecant of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMCSC(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMCSC() method in the Engineering\ComplexFunctions class instead - * - * @param array|string $complexNumber the complex number for which you want the cosecant - * - * @return array|float|string - */ - public static function IMCSC($complexNumber) - { - return ComplexFunctions::IMCSC($complexNumber); - } - - /** - * IMCSCH. - * - * Returns the hyperbolic cosecant of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMCSCH(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMCSCH() method in the Engineering\ComplexFunctions class instead - * - * @param array|string $complexNumber the complex number for which you want the hyperbolic cosecant - * - * @return array|float|string - */ - public static function IMCSCH($complexNumber) - { - return ComplexFunctions::IMCSCH($complexNumber); - } - - /** - * IMSIN. - * - * Returns the sine of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMSIN(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMSIN() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the sine - * - * @return array|float|string - */ - public static function IMSIN($complexNumber) - { - return ComplexFunctions::IMSIN($complexNumber); - } - - /** - * IMSINH. - * - * Returns the hyperbolic sine of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMSINH(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMSINH() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the hyperbolic sine - * - * @return array|float|string - */ - public static function IMSINH($complexNumber) - { - return ComplexFunctions::IMSINH($complexNumber); - } - - /** - * IMSEC. - * - * Returns the secant of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMSEC(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMSEC() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the secant - * - * @return array|float|string - */ - public static function IMSEC($complexNumber) - { - return ComplexFunctions::IMSEC($complexNumber); - } - - /** - * IMSECH. - * - * Returns the hyperbolic secant of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMSECH(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMSECH() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the hyperbolic secant - * - * @return array|float|string - */ - public static function IMSECH($complexNumber) - { - return ComplexFunctions::IMSECH($complexNumber); - } - - /** - * IMTAN. - * - * Returns the tangent of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMTAN(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMTAN() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the tangent - * - * @return array|float|string - */ - public static function IMTAN($complexNumber) - { - return ComplexFunctions::IMTAN($complexNumber); - } - - /** - * IMSQRT. - * - * Returns the square root of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMSQRT(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMSQRT() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the square root - * - * @return array|string - */ - public static function IMSQRT($complexNumber) - { - return ComplexFunctions::IMSQRT($complexNumber); - } - - /** - * IMLN. - * - * Returns the natural logarithm of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMLN(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMLN() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the natural logarithm - * - * @return array|string - */ - public static function IMLN($complexNumber) - { - return ComplexFunctions::IMLN($complexNumber); - } - - /** - * IMLOG10. - * - * Returns the common logarithm (base 10) of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMLOG10(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMLOG10() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the common logarithm - * - * @return array|string - */ - public static function IMLOG10($complexNumber) - { - return ComplexFunctions::IMLOG10($complexNumber); - } - - /** - * IMLOG2. - * - * Returns the base-2 logarithm of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMLOG2(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMLOG2() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the base-2 logarithm - * - * @return array|string - */ - public static function IMLOG2($complexNumber) - { - return ComplexFunctions::IMLOG2($complexNumber); - } - - /** - * IMEXP. - * - * Returns the exponential of a complex number in x + yi or x + yj text format. - * - * Excel Function: - * IMEXP(complexNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMEXP() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number for which you want the exponential - * - * @return array|string - */ - public static function IMEXP($complexNumber) - { - return ComplexFunctions::IMEXP($complexNumber); - } - - /** - * IMPOWER. - * - * Returns a complex number in x + yi or x + yj text format raised to a power. - * - * Excel Function: - * IMPOWER(complexNumber,realNumber) - * - * @Deprecated 1.18.0 - * - * @see Use the IMPOWER() method in the Engineering\ComplexFunctions class instead - * - * @param string $complexNumber the complex number you want to raise to a power - * @param float $realNumber the power to which you want to raise the complex number - * - * @return array|string - */ - public static function IMPOWER($complexNumber, $realNumber) - { - return ComplexFunctions::IMPOWER($complexNumber, $realNumber); - } - - /** - * IMDIV. - * - * Returns the quotient of two complex numbers in x + yi or x + yj text format. - * - * Excel Function: - * IMDIV(complexDividend,complexDivisor) - * - * @Deprecated 1.18.0 - * - * @see Use the IMDIV() method in the Engineering\ComplexOperations class instead - * - * @param string $complexDividend the complex numerator or dividend - * @param string $complexDivisor the complex denominator or divisor - * - * @return array|string - */ - public static function IMDIV($complexDividend, $complexDivisor) - { - return ComplexOperations::IMDIV($complexDividend, $complexDivisor); - } - - /** - * IMSUB. - * - * Returns the difference of two complex numbers in x + yi or x + yj text format. - * - * Excel Function: - * IMSUB(complexNumber1,complexNumber2) - * - * @Deprecated 1.18.0 - * - * @see Use the IMSUB() method in the Engineering\ComplexOperations class instead - * - * @param string $complexNumber1 the complex number from which to subtract complexNumber2 - * @param string $complexNumber2 the complex number to subtract from complexNumber1 - * - * @return array|string - */ - public static function IMSUB($complexNumber1, $complexNumber2) - { - return ComplexOperations::IMSUB($complexNumber1, $complexNumber2); - } - - /** - * IMSUM. - * - * Returns the sum of two or more complex numbers in x + yi or x + yj text format. - * - * Excel Function: - * IMSUM(complexNumber[,complexNumber[,...]]) - * - * @Deprecated 1.18.0 - * - * @see Use the IMSUM() method in the Engineering\ComplexOperations class instead - * - * @param string ...$complexNumbers Series of complex numbers to add - * - * @return string - */ - public static function IMSUM(...$complexNumbers) - { - return ComplexOperations::IMSUM(...$complexNumbers); - } - - /** - * IMPRODUCT. - * - * Returns the product of two or more complex numbers in x + yi or x + yj text format. - * - * Excel Function: - * IMPRODUCT(complexNumber[,complexNumber[,...]]) - * - * @Deprecated 1.18.0 - * - * @see Use the IMPRODUCT() method in the Engineering\ComplexOperations class instead - * - * @param string ...$complexNumbers Series of complex numbers to multiply - * - * @return string - */ - public static function IMPRODUCT(...$complexNumbers) - { - return ComplexOperations::IMPRODUCT(...$complexNumbers); - } - - /** - * DELTA. - * - * Tests whether two values are equal. Returns 1 if number1 = number2; returns 0 otherwise. - * Use this function to filter a set of values. For example, by summing several DELTA - * functions you calculate the count of equal pairs. This function is also known as the - * Kronecker Delta function. - * - * Excel Function: - * DELTA(a[,b]) - * - * @Deprecated 1.17.0 - * - * @see Use the DELTA() method in the Engineering\Compare class instead - * - * @param float $a the first number - * @param float $b The second number. If omitted, b is assumed to be zero. - * - * @return array|int|string (string in the event of an error) - */ - public static function DELTA($a, $b = 0) - { - return Engineering\Compare::DELTA($a, $b); - } - - /** - * GESTEP. - * - * Excel Function: - * GESTEP(number[,step]) - * - * Returns 1 if number >= step; returns 0 (zero) otherwise - * Use this function to filter a set of values. For example, by summing several GESTEP - * functions you calculate the count of values that exceed a threshold. - * - * @Deprecated 1.17.0 - * - * @see Use the GESTEP() method in the Engineering\Compare class instead - * - * @param float $number the value to test against step - * @param float $step The threshold value. If you omit a value for step, GESTEP uses zero. - * - * @return array|int|string (string in the event of an error) - */ - public static function GESTEP($number, $step = 0) - { - return Engineering\Compare::GESTEP($number, $step); - } - - /** - * BITAND. - * - * Returns the bitwise AND of two integer values. - * - * Excel Function: - * BITAND(number1, number2) - * - * @Deprecated 1.17.0 - * - * @see Use the BITAND() method in the Engineering\BitWise class instead - * - * @param int $number1 - * @param int $number2 - * - * @return array|int|string - */ - public static function BITAND($number1, $number2) - { - return Engineering\BitWise::BITAND($number1, $number2); - } - - /** - * BITOR. - * - * Returns the bitwise OR of two integer values. - * - * Excel Function: - * BITOR(number1, number2) - * - * @Deprecated 1.17.0 - * - * @see Use the BITOR() method in the Engineering\BitWise class instead - * - * @param int $number1 - * @param int $number2 - * - * @return array|int|string - */ - public static function BITOR($number1, $number2) - { - return Engineering\BitWise::BITOR($number1, $number2); - } - - /** - * BITXOR. - * - * Returns the bitwise XOR of two integer values. - * - * Excel Function: - * BITXOR(number1, number2) - * - * @Deprecated 1.17.0 - * - * @see Use the BITXOR() method in the Engineering\BitWise class instead - * - * @param int $number1 - * @param int $number2 - * - * @return array|int|string - */ - public static function BITXOR($number1, $number2) - { - return Engineering\BitWise::BITXOR($number1, $number2); - } - - /** - * BITLSHIFT. - * - * Returns the number value shifted left by shift_amount bits. - * - * Excel Function: - * BITLSHIFT(number, shift_amount) - * - * @Deprecated 1.17.0 - * - * @see Use the BITLSHIFT() method in the Engineering\BitWise class instead - * - * @param int $number - * @param int $shiftAmount - * - * @return array|float|int|string - */ - public static function BITLSHIFT($number, $shiftAmount) - { - return Engineering\BitWise::BITLSHIFT($number, $shiftAmount); - } - - /** - * BITRSHIFT. - * - * Returns the number value shifted right by shift_amount bits. - * - * Excel Function: - * BITRSHIFT(number, shift_amount) - * - * @Deprecated 1.17.0 - * - * @see Use the BITRSHIFT() method in the Engineering\BitWise class instead - * - * @param int $number - * @param int $shiftAmount - * - * @return array|float|int|string - */ - public static function BITRSHIFT($number, $shiftAmount) - { - return Engineering\BitWise::BITRSHIFT($number, $shiftAmount); - } - - /** - * ERF. - * - * Returns the error function integrated between the lower and upper bound arguments. - * - * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, - * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was - * improved, so that it can now calculate the function for both positive and negative ranges. - * PhpSpreadsheet follows Excel 2010 behaviour, and accepts negative arguments. - * - * Excel Function: - * ERF(lower[,upper]) - * - * @Deprecated 1.17.0 - * - * @see Use the ERF() method in the Engineering\Erf class instead - * - * @param float $lower lower bound for integrating ERF - * @param float $upper upper bound for integrating ERF. - * If omitted, ERF integrates between zero and lower_limit - * - * @return array|float|string - */ - public static function ERF($lower, $upper = null) - { - return Engineering\Erf::ERF($lower, $upper); - } - - /** - * ERFPRECISE. - * - * Returns the error function integrated between the lower and upper bound arguments. - * - * Excel Function: - * ERF.PRECISE(limit) - * - * @Deprecated 1.17.0 - * - * @see Use the ERFPRECISE() method in the Engineering\Erf class instead - * - * @param float $limit bound for integrating ERF - * - * @return array|float|string - */ - public static function ERFPRECISE($limit) - { - return Engineering\Erf::ERFPRECISE($limit); - } - - /** - * ERFC. - * - * Returns the complementary ERF function integrated between x and infinity - * - * Note: In Excel 2007 or earlier, if you input a negative value for the lower bound argument, - * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was - * improved, so that it can now calculate the function for both positive and negative x values. - * PhpSpreadsheet follows Excel 2010 behaviour, and accepts nagative arguments. - * - * Excel Function: - * ERFC(x) - * - * @Deprecated 1.17.0 - * - * @see Use the ERFC() method in the Engineering\ErfC class instead - * - * @param float $x The lower bound for integrating ERFC - * - * @return array|float|string - */ - public static function ERFC($x) - { - return Engineering\ErfC::ERFC($x); - } - - /** - * getConversionGroups - * Returns a list of the different conversion groups for UOM conversions. - * - * @Deprecated 1.16.0 - * - * @see Use the getConversionCategories() method in the Engineering\ConvertUOM class instead - * - * @return array - */ - public static function getConversionGroups() - { - return Engineering\ConvertUOM::getConversionCategories(); - } - - /** - * getConversionGroupUnits - * Returns an array of units of measure, for a specified conversion group, or for all groups. - * - * @Deprecated 1.16.0 - * - * @see Use the getConversionCategoryUnits() method in the ConvertUOM class instead - * - * @param null|mixed $category - * - * @return array - */ - public static function getConversionGroupUnits($category = null) - { - return Engineering\ConvertUOM::getConversionCategoryUnits($category); - } - - /** - * getConversionGroupUnitDetails. - * - * @Deprecated 1.16.0 - * - * @see Use the getConversionCategoryUnitDetails() method in the ConvertUOM class instead - * - * @param null|mixed $category - * - * @return array - */ - public static function getConversionGroupUnitDetails($category = null) - { - return Engineering\ConvertUOM::getConversionCategoryUnitDetails($category); - } - - /** - * getConversionMultipliers - * Returns an array of the Multiplier prefixes that can be used with Units of Measure in CONVERTUOM(). - * - * @Deprecated 1.16.0 - * - * @see Use the getConversionMultipliers() method in the ConvertUOM class instead - * - * @return mixed[] - */ - public static function getConversionMultipliers() - { - return Engineering\ConvertUOM::getConversionMultipliers(); - } - - /** - * getBinaryConversionMultipliers. - * - * Returns an array of the additional Multiplier prefixes that can be used with Information Units of Measure - * in CONVERTUOM(). - * - * @Deprecated 1.16.0 - * - * @see Use the getBinaryConversionMultipliers() method in the ConvertUOM class instead - * - * @return mixed[] - */ - public static function getBinaryConversionMultipliers() - { - return Engineering\ConvertUOM::getBinaryConversionMultipliers(); - } - - /** - * CONVERTUOM. - * - * Converts a number from one measurement system to another. - * For example, CONVERT can translate a table of distances in miles to a table of distances - * in kilometers. - * - * Excel Function: - * CONVERT(value,fromUOM,toUOM) - * - * @Deprecated 1.16.0 - * - * @see Use the CONVERT() method in the ConvertUOM class instead - * - * @param float|int $value the value in fromUOM to convert - * @param string $fromUOM the units for value - * @param string $toUOM the units for the result - * - * @return array|float|string - */ - public static function CONVERTUOM($value, $fromUOM, $toUOM) - { - return Engineering\ConvertUOM::CONVERT($value, $fromUOM, $toUOM); - } -} diff --git a/src/PhpSpreadsheet/Calculation/Financial.php b/src/PhpSpreadsheet/Calculation/Financial.php deleted file mode 100644 index 4215a5163d..0000000000 --- a/src/PhpSpreadsheet/Calculation/Financial.php +++ /dev/null @@ -1,1430 +0,0 @@ -getWorksheet(); diff --git a/src/PhpSpreadsheet/Calculation/Logical.php b/src/PhpSpreadsheet/Calculation/Logical.php deleted file mode 100644 index d5d993ae3a..0000000000 --- a/src/PhpSpreadsheet/Calculation/Logical.php +++ /dev/null @@ -1,314 +0,0 @@ - ['=COUNT(A1:B3 A1:C2)', 4], 'Sum with UNION #2' => ['=SUM(A1:A3,C1:C3)', 48], 'Count with UNION #2' => ['=COUNT(A1:A3,C1:C3)', 6], - 'Sum with INTERSECTION #2 - No Intersect' => ['=SUM(A1:A3 C1:C3)', Functions::null()], + 'Sum with INTERSECTION #2 - No Intersect' => ['=SUM(A1:A3 C1:C3)', ExcelError::null()], 'Count with INTERSECTION #2 - No Intersect' => ['=COUNT(A1:A3 C1:C3)', 0], 'Sum with UNION #3' => ['=SUM(A1:B2,B2:C3)', 64], 'Count with UNION #3' => ['=COUNT(A1:B2,B2:C3)', 8], diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DAverageTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DAverageTest.php index 8be895ebd7..245636a38d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DAverageTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DAverageTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DAverage; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDAverage($expectedResult, $database, $field, $criteria): void { - $result = Database::DAVERAGE($database, $field, $criteria); + $result = DAverage::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountATest.php index c7d704268a..d140f44a03 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountATest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DCountA; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDCountA($expectedResult, $database, $field, $criteria): void { - $result = Database::DCOUNTA($database, $field, $criteria); + $result = DCountA::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountTest.php index f1df35ae7c..3c2e820bea 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DCount; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDCount($expectedResult, $database, $field, $criteria): void { - $result = Database::DCOUNT($database, $field, $criteria); + $result = DCount::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DGetTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DGetTest.php index 6df9c1bd71..4237b392a5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DGetTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DGetTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DGet; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testDGet($expectedResult, $database, $field, $criteria): void { - $result = Database::DGET($database, $field, $criteria); + $result = DGet::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMaxTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMaxTest.php index 25f957dafa..97f8668bf8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMaxTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMaxTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DMax; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDMax($expectedResult, $database, $field, $criteria): void { - $result = Database::DMAX($database, $field, $criteria); + $result = DMax::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMinTest.php index ca32d2879f..702c2571a9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMinTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DMin; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDMin($expectedResult, $database, $field, $criteria): void { - $result = Database::DMIN($database, $field, $criteria); + $result = DMin::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DProductTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DProductTest.php index 7567b44f23..c4804b9be4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DProductTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DProductTest.php @@ -2,8 +2,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; -use PhpOffice\PhpSpreadsheet\Calculation\DateTime; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DProduct; +use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Helpers as DateTimeHelper; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testDProduct($expectedResult, $database, $field, $criteria): void { - $result = Database::DPRODUCT($database, $field, $criteria); + $result = DProduct::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } @@ -45,18 +45,18 @@ private function database2(): array { return [ ['Name', 'Date', 'Test', 'Score'], - ['Gary', DateTime::getDateValue('01-Jan-2017'), 'Test1', 4], - ['Gary', DateTime::getDateValue('01-Jan-2017'), 'Test2', 4], - ['Gary', DateTime::getDateValue('01-Jan-2017'), 'Test3', 3], - ['Gary', DateTime::getDateValue('05-Jan-2017'), 'Test1', 3], - ['Gary', DateTime::getDateValue('05-Jan-2017'), 'Test2', 4], - ['Gary', DateTime::getDateValue('05-Jan-2017'), 'Test3', 3], - ['Kev', DateTime::getDateValue('02-Jan-2017'), 'Test1', 2], - ['Kev', DateTime::getDateValue('02-Jan-2017'), 'Test2', 3], - ['Kev', DateTime::getDateValue('02-Jan-2017'), 'Test3', 5], - ['Kev', DateTime::getDateValue('05-Jan-2017'), 'Test1', 3], - ['Kev', DateTime::getDateValue('05-Jan-2017'), 'Test2', 2], - ['Kev', DateTime::getDateValue('05-Jan-2017'), 'Test3', 5], + ['Gary', DateTimeHelper::getDateValue('01-Jan-2017'), 'Test1', 4], + ['Gary', DateTimeHelper::getDateValue('01-Jan-2017'), 'Test2', 4], + ['Gary', DateTimeHelper::getDateValue('01-Jan-2017'), 'Test3', 3], + ['Gary', DateTimeHelper::getDateValue('05-Jan-2017'), 'Test1', 3], + ['Gary', DateTimeHelper::getDateValue('05-Jan-2017'), 'Test2', 4], + ['Gary', DateTimeHelper::getDateValue('05-Jan-2017'), 'Test3', 3], + ['Kev', DateTimeHelper::getDateValue('02-Jan-2017'), 'Test1', 2], + ['Kev', DateTimeHelper::getDateValue('02-Jan-2017'), 'Test2', 3], + ['Kev', DateTimeHelper::getDateValue('02-Jan-2017'), 'Test3', 5], + ['Kev', DateTimeHelper::getDateValue('05-Jan-2017'), 'Test1', 3], + ['Kev', DateTimeHelper::getDateValue('05-Jan-2017'), 'Test2', 2], + ['Kev', DateTimeHelper::getDateValue('05-Jan-2017'), 'Test3', 5], ]; } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevPTest.php index e62602e324..829f29f4c1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevPTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevPTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DStDevP; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDStDevP($expectedResult, $database, $field, $criteria): void { - $result = Database::DSTDEVP($database, $field, $criteria); + $result = DStDevP::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevTest.php index f0837e8134..10f3ace58b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DStDev; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDStDev($expectedResult, $database, $field, $criteria): void { - $result = Database::DSTDEV($database, $field, $criteria); + $result = DStDev::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DSumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DSumTest.php index 0cce63d811..b4b41b5e3c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DSumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DSumTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DSum; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDSum($expectedResult, $database, $field, $criteria): void { - $result = Database::DSUM($database, $field, $criteria); + $result = DSum::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarPTest.php index 1e9a8e276c..946dfa1257 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarPTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarPTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DVarP; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDVarP($expectedResult, $database, $field, $criteria): void { - $result = Database::DVARP($database, $field, $criteria); + $result = DVarP::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarTest.php index c62f13b48d..1a2f880e55 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Database; -use PhpOffice\PhpSpreadsheet\Calculation\Database; +use PhpOffice\PhpSpreadsheet\Calculation\Database\DVar; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDVar($expectedResult, $database, $field, $criteria): void { - $result = Database::DVAR($database, $field, $criteria); + $result = DVar::evaluate($database, $field, $criteria); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php deleted file mode 100644 index d14f7d7d24..0000000000 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php +++ /dev/null @@ -1,63 +0,0 @@ -format('s'); - $nowResult = DateTime::DATETIMENOW(); - $todayResult = DateTime::DATENOW(); - $dtEnd = new DateTimeImmutable(); - $endSecond = $dtEnd->format('s'); - } while ($startSecond !== $endSecond); - self::assertSame(DateTime::DAYOFMONTH($nowResult), DateTime::DAYOFMONTH($todayResult)); - } -} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DeprecatedExcelErrorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DeprecatedExcelErrorTest.php deleted file mode 100644 index 48a3dcf07d..0000000000 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DeprecatedExcelErrorTest.php +++ /dev/null @@ -1,55 +0,0 @@ - [ - [Functions::class, 'null'], - ExcelError::null(), - ], - 'NAN' => [ - [Functions::class, 'NAN'], - ExcelError::NAN(), - ], - 'NA' => [ - [Functions::class, 'NA'], - ExcelError::NA(), - ], - 'NAME' => [ - [Functions::class, 'NAME'], - ExcelError::NAME(), - ], - 'REF' => [ - [Functions::class, 'REF'], - ExcelError::REF(), - ], - 'VALUE' => [ - [Functions::class, 'VALUE'], - ExcelError::VALUE(), - ], - 'DIV0' => [ - [Functions::class, 'DIV0'], - ExcelError::DIV0(), - ], - ]; - } -} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php index 6e9673a880..4652b56519 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\BesselI; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testBESSELI($expectedResult, ...$args): void { - $result = Engineering::BESSELI(...$args); + $result = BesselI::BESSELI(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php index 16002ae5d0..11f11ccb4b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\BesselJ; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testBESSELJ($expectedResult, ...$args): void { - $result = Engineering::BESSELJ(...$args); + $result = BesselJ::BESSELJ(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php index 11e0885e21..a7d45ef6e9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\BesselK; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testBESSELK($expectedResult, ...$args): void { - $result = Engineering::BESSELK(...$args); + $result = BesselK::BESSELK(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php index 47f05e986f..2f0a0ca68b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\BesselY; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testBESSELY($expectedResult, ...$args): void { - $result = Engineering::BESSELY(...$args); + $result = BesselY::BESSELY(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php index 827654add3..bbdab5e814 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Complex; use PHPUnit\Framework\TestCase; class ComplexTest extends TestCase @@ -16,13 +16,13 @@ class ComplexTest extends TestCase public function testCOMPLEX($expectedResult, ...$args): void { if (count($args) === 0) { - $result = Engineering::COMPLEX(); + $result = Complex::COMPLEX(); } elseif (count($args) === 1) { - $result = Engineering::COMPLEX($args[0]); + $result = Complex::COMPLEX($args[0]); } elseif (count($args) === 2) { - $result = Engineering::COMPLEX($args[0], $args[1]); + $result = Complex::COMPLEX($args[0], $args[1]); } else { - $result = Engineering::COMPLEX($args[0], $args[1], $args[2]); + $result = Complex::COMPLEX($args[0], $args[1], $args[2]); } self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php index 9a448824ee..679bcc8b3f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ConvertUOM; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -16,31 +16,31 @@ protected function setUp(): void public function testGetConversionGroups(): void { - $result = Engineering::getConversionGroups(); + $result = ConvertUOM::getConversionCategories(); self::assertIsArray($result); } public function testGetConversionGroupUnits(): void { - $result = Engineering::getConversionGroupUnits(); + $result = ConvertUOM::getConversionCategoryUnits(); self::assertIsArray($result); } public function testGetConversionGroupUnitDetails(): void { - $result = Engineering::getConversionGroupUnitDetails(); + $result = ConvertUOM::getConversionCategoryUnitDetails(); self::assertIsArray($result); } public function testGetConversionMultipliers(): void { - $result = Engineering::getConversionMultipliers(); + $result = ConvertUOM::getConversionMultipliers(); self::assertIsArray($result); } public function testGetBinaryConversionMultipliers(): void { - $result = Engineering::getBinaryConversionMultipliers(); + $result = ConvertUOM::getBinaryConversionMultipliers(); self::assertIsArray($result); } @@ -51,7 +51,7 @@ public function testGetBinaryConversionMultipliers(): void */ public function testCONVERTUOM($expectedResult, ...$args): void { - $result = Engineering::CONVERTUOM(...$args); + $result = ConvertUOM::CONVERT(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php index 41d809cac1..c1c6b6f305 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Compare; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDELTA($expectedResult, $a, $b): void { - $result = Engineering::DELTA($a, $b); + $result = Compare::DELTA($a, $b); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php index f0a721c7d5..b79a2efa62 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ErfC; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testERFC($expectedResult, $lower): void { - $result = Engineering::ERFC($lower); + $result = ErfC::ERFC($lower); self::assertEquals($expectedResult, $result); self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php index dc3ee84cb0..411b462abe 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Erf; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testERFPRECISE($expectedResult, $limit): void { - $result = Engineering::ERFPRECISE($limit); + $result = Erf::ERFPRECISE($limit); self::assertEquals($expectedResult, $result); self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php index 4d13d47d7a..cdde57b017 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Erf; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -25,7 +25,7 @@ protected function setUp(): void */ public function testERF($expectedResult, $lower, $upper = null): void { - $result = Engineering::ERF($lower, $upper); + $result = Erf::ERF($lower, $upper); self::assertEquals($expectedResult, $result); self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php index 4e5b8ec5f2..612133774d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Compare; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testGESTEP($expectedResult, $a, $b): void { - $result = Engineering::GESTEP($a, $b); + $result = Compare::GESTEP($a, $b); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php index 417ee5c4e7..884c311ea4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testIMABS($expectedResult, $value): void { - $result = Engineering::IMABS($value); + $result = ComplexFunctions::IMABS($value); self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php index 359352b41c..14dc533a84 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testIMARGUMENT($expectedResult, $value): void { - $result = Engineering::IMARGUMENT($value); + $result = ComplexFunctions::IMARGUMENT($value); self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php index 7326bb7f12..4dfa00eab6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCONJUGATE($expectedResult, $value): void { - $result = Engineering::IMCONJUGATE($value); + $result = ComplexFunctions::IMCONJUGATE($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php index d9d8514b78..69d9cd54d7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCOS($expectedResult, $value): void { - $result = Engineering::IMCOS($value); + $result = ComplexFunctions::IMCOS($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php index 0d0466a1c6..5bd464fecb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCOSH($expectedResult, $value): void { - $result = Engineering::IMCOSH($value); + $result = ComplexFunctions::IMCOSH($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php index 7e178ed28c..095a0ac283 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCOT($expectedResult, $value): void { - $result = Engineering::IMCOT($value); + $result = ComplexFunctions::IMCOT($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php index bb1ca92b91..32f0e80358 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCSC($expectedResult, $value): void { - $result = Engineering::IMCSC($value); + $result = ComplexFunctions::IMCSC($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php index 5d5575fbf3..4fbdf843a7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCSCH($expectedResult, $value): void { - $result = Engineering::IMCSCH($value); + $result = ComplexFunctions::IMCSCH($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php index 58e9154b7d..7e51a2491a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexOperations; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -30,7 +30,7 @@ protected function setUp(): void */ public function testIMDIV($expectedResult, ...$args): void { - $result = Engineering::IMDIV(...$args); + $result = ComplexOperations::IMDIV(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php index 5fc2dd2a80..f717725a5b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMEXP($expectedResult, $value): void { - $result = Engineering::IMEXP($value); + $result = ComplexFunctions::IMEXP($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php index ad157ecb70..fe55645488 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMLN($expectedResult, $value): void { - $result = Engineering::IMLN($value); + $result = ComplexFunctions::IMLN($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php index 47503f5e85..206c1e6d65 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMLOG10($expectedResult, $value): void { - $result = Engineering::IMLOG10($value); + $result = ComplexFunctions::IMLOG10($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php index 2ea38872d3..58e94c9b68 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMLOG2($expectedResult, $value): void { - $result = Engineering::IMLOG2($value); + $result = ComplexFunctions::IMLOG2($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php index af4f5cf908..cb841ba891 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -30,7 +30,7 @@ protected function setUp(): void */ public function testIMPOWER($expectedResult, ...$args): void { - $result = Engineering::IMPOWER(...$args); + $result = ComplexFunctions::IMPOWER(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php index 845d436fd1..8f798bf2a1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexOperations; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -29,7 +29,7 @@ protected function setUp(): void */ public function testIMPRODUCT($expectedResult, ...$args): void { - $result = Engineering::IMPRODUCT(...$args); + $result = ComplexOperations::IMPRODUCT(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php index b12837e75d..e88c73575b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Complex; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testIMREAL($expectedResult, $value): void { - $result = Engineering::IMREAL($value); + $result = Complex::IMREAL($value); self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php index 33880aad22..8ad7c6ba31 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSEC($expectedResult, $value): void { - $result = Engineering::IMSEC($value); + $result = ComplexFunctions::IMSEC($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php index bf4285a268..6c214a346b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSECH($expectedResult, $value): void { - $result = Engineering::IMSECH($value); + $result = ComplexFunctions::IMSECH($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php index 515ebc47cb..4e7881ba57 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSIN($expectedResult, $value): void { - $result = Engineering::IMSIN($value); + $result = ComplexFunctions::IMSIN($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php index c6db788939..7d5c86ec7a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSINH($expectedResult, $value): void { - $result = Engineering::IMSINH($value); + $result = ComplexFunctions::IMSINH($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php index 261cf51ae2..9b53ed5476 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSQRT($expectedResult, $value): void { - $result = Engineering::IMSQRT($value); + $result = ComplexFunctions::IMSQRT($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php index a8d1d1d772..b85519eca9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexOperations; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -30,7 +30,7 @@ protected function setUp(): void */ public function testIMSUB($expectedResult, ...$args): void { - $result = Engineering::IMSUB(...$args); + $result = ComplexOperations::IMSUB(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php index 0620c68431..e4cd1ec706 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexOperations; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -29,7 +29,7 @@ protected function setUp(): void */ public function testIMSUM($expectedResult, ...$args): void { - $result = Engineering::IMSUM(...$args); + $result = ComplexOperations::IMSUM(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php index ca66b2b851..895211e5fe 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ComplexFunctions; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheetTests\Custom\ComplexAssert; use PHPUnit\Framework\TestCase; @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMTAN($expectedResult, $value): void { - $result = Engineering::IMTAN($value); + $result = ComplexFunctions::IMTAN($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php index 59ad1eb8c7..abf919d264 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; +use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Complex; use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PHPUnit\Framework\TestCase; @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testIMAGINARY($expectedResult, $value): void { - $result = Engineering::IMAGINARY($value); + $result = Complex::IMAGINARY($value); self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/MovedBitwiseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/MovedBitwiseTest.php deleted file mode 100644 index 457db0d30d..0000000000 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/MovedBitwiseTest.php +++ /dev/null @@ -1,24 +0,0 @@ -getFormula()); } } - - public function testDeprecatedCall(): void - { - $sheet = $this->getSheet(); - $sheet->getCell('A1')->setValue('A2'); - $sheet->getCell('A2')->setValue('This is it'); - $result = \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDIRECT('A2', $sheet->getCell('A1')); - $result = \PhpOffice\PhpSpreadsheet\Calculation\Functions::flattenSingleValue($result); - self::assertSame('This is it', $result); - } } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php index c2cf4dae6c..4df1277ceb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\LookupRef; +use PhpOffice\PhpSpreadsheet\Calculation\LookupRef\Lookup; use PHPUnit\Framework\TestCase; class LookupTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testLOOKUP($expectedResult, ...$args): void { - $result = LookupRef::LOOKUP(...$args); + $result = Lookup::LOOKUP(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php index f8e8fa46a9..ed4f4b022a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\LookupRef; +use PhpOffice\PhpSpreadsheet\Calculation\LookupRef\ExcelMatch; use PHPUnit\Framework\TestCase; class MatchTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testMATCH($expectedResult, ...$args): void { - $result = LookupRef::MATCH(...$args); + $result = ExcelMatch::MATCH(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MovedFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MovedFunctionsTest.php deleted file mode 100644 index 007ce1d2b8..0000000000 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MovedFunctionsTest.php +++ /dev/null @@ -1,29 +0,0 @@ -2')); - self::assertEquals(2, MathTrig::SUMIFS( - [[1], [1], [1]], - [['Y'], ['Y'], ['N']], - '=Y', - [['H'], ['H'], ['H']], - '=H' - )); - self::assertEquals(17, MathTrig::SUMPRODUCT([1, 2, 3], [5, 0, 4])); - self::assertEquals(21, MathTrig::SUMSQ(1, 2, 4)); - self::assertEquals(-20, MathTrig::SUMX2MY2([1, 2], [3, 4])); - self::assertEquals(30, MathTrig::SUMX2PY2([1, 2], [3, 4])); - self::assertEquals(8, MathTrig::SUMXMY2([1, 2], [3, 4])); - self::assertEquals(0, MathTrig::builtinTAN(0)); - self::assertEquals(0, MathTrig::builtinTANH(0)); - self::assertEquals(70, MathTrig::TRUNC(79.2, -1)); - self::assertEquals(1, MathTrig::returnSign(79.2)); - self::assertEquals(80, MathTrig::getEven(79.2)); - $nullVal = null; - MathTrig::nullFalseTrueToNumber($nullVal); - self::assertSame(0, $nullVal); - $nullVal = true; - MathTrig::nullFalseTrueToNumber($nullVal); - self::assertSame(1, $nullVal); - } -} diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AveDevTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AveDevTest.php index ea3df6bbea..572c19104e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AveDevTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AveDevTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages; use PHPUnit\Framework\TestCase; class AveDevTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAVEDEV($expectedResult, ...$args): void { - $result = Statistical::AVEDEV(...$args); + $result = Averages::averageDeviations(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageATest.php index fec65c2810..013e15400d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageATest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages; use PHPUnit\Framework\TestCase; class AverageATest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAVERAGEA($expectedResult, ...$args): void { - $result = Statistical::AVERAGEA(...$args); + $result = Averages::averageA(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php index c9648d433d..e36037890e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional; use PHPUnit\Framework\TestCase; class AverageIfTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAVERAGEIF($expectedResult, ...$args): void { - $result = Statistical::AVERAGEIF(...$args); + $result = Conditional::AVERAGEIF(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageTest.php index d5e617a98d..63663a6630 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages; use PHPUnit\Framework\TestCase; class AverageTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAVERAGE($expectedResult, ...$args): void { - $result = Statistical::AVERAGE(...$args); + $result = Averages::average(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php index 02f05c5466..6947ac78c6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Beta; use PHPUnit\Framework\TestCase; class BetaDistTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testBETADIST($expectedResult, ...$args): void { - $result = Statistical::BETADIST(...$args); + $result = Beta::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php index ba3705a130..7d5426e853 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Beta; use PHPUnit\Framework\TestCase; class BetaInvTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testBETAINV($expectedResult, ...$args): void { - $result = Statistical::BETAINV(...$args); + $result = Beta::inverse(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php index da617fab58..d9da3827fc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Binomial; use PHPUnit\Framework\TestCase; class BinomDistRangeTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testBINOMDISTRANGE($expectedResult, ...$args): void { - $result = Statistical\Distributions\Binomial::range(...$args); + $result = Binomial::range(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php index 94689538bb..a86a500075 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Binomial; use PHPUnit\Framework\TestCase; class BinomDistTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testBINOMDIST($expectedResult, ...$args): void { - $result = Statistical::BINOMDIST(...$args); + $result = Binomial::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php index 6ea2b55baf..3d2c22f13c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Binomial; use PHPUnit\Framework\TestCase; class BinomInvTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testBINOMINV($expectedResult, ...$args): void { - $result = Statistical::CRITBINOM(...$args); + $result = Binomial::inverse(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php index eb334b25b9..c2d2721a16 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\ChiSquared; use PHPUnit\Framework\TestCase; class ChiDistLeftTailTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testCHIDIST($expectedResult, ...$args): void { - $result = Statistical\Distributions\ChiSquared::distributionLeftTail(...$args); + $result = ChiSquared::distributionLeftTail(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php index 5cd210ef79..2e9a57d9d0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\ChiSquared; use PHPUnit\Framework\TestCase; class ChiDistRightTailTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testCHIDIST($expectedResult, ...$args): void { - $result = Statistical::CHIDIST(...$args); + $result = ChiSquared::distributionRightTail(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php index c4fe1e9444..a7f96d3d50 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\ChiSquared; use PHPUnit\Framework\TestCase; class ChiInvLeftTailTest extends TestCase @@ -23,9 +23,9 @@ protected function setUp(): void */ public function testCHIINV($expectedResult, $probability, $degrees): void { - $result = Statistical\Distributions\ChiSquared::inverseLeftTail($probability, $degrees); + $result = ChiSquared::inverseLeftTail($probability, $degrees); if (!is_string($expectedResult)) { - $reverse = Statistical\Distributions\ChiSquared::distributionLeftTail($result, $degrees, true); + $reverse = ChiSquared::distributionLeftTail($result, $degrees, true); self::assertEqualsWithDelta($probability, $reverse, 1E-12); } self::assertEqualsWithDelta($expectedResult, $result, 1E-12); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php index 629466e2c9..818059b60c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\ChiSquared; use PHPUnit\Framework\TestCase; class ChiInvRightTailTest extends TestCase @@ -23,9 +23,9 @@ protected function setUp(): void */ public function testCHIINV($expectedResult, $probability, $degrees): void { - $result = Statistical::CHIINV($probability, $degrees); + $result = ChiSquared::inverseRightTail($probability, $degrees); if (!is_string($expectedResult)) { - $reverse = Statistical\Distributions\ChiSquared::distributionRightTail($result, $degrees); + $reverse = ChiSquared::distributionRightTail($result, $degrees); self::assertEqualsWithDelta($probability, $reverse, 1E-12); } self::assertEqualsWithDelta($expectedResult, $result, 1E-12); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiTestTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiTestTest.php index ed608d5849..c6d43a7681 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiTestTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiTestTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\ChiSquared; use PHPUnit\Framework\TestCase; class ChiTestTest extends TestCase @@ -16,7 +16,7 @@ class ChiTestTest extends TestCase */ public function testCHITEST($expectedResult, $actual, $expected): void { - $result = Statistical\Distributions\ChiSquared::test($actual, $expected); + $result = ChiSquared::test($actual, $expected); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php index b7a4607c4c..6ed59dd1fc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Confidence; use PHPUnit\Framework\TestCase; class ConfidenceTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testCONFIDENCE($expectedResult, ...$args): void { - $result = Statistical::CONFIDENCE(...$args); + $result = Confidence::CONFIDENCE(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php index adadf422f6..9b7baf4bcc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class CorrelTest extends TestCase @@ -22,7 +22,7 @@ protected function setUp(): void */ public function testCORREL($expectedResult, $xargs, $yargs): void { - $result = Statistical::CORREL($xargs, $yargs); + $result = Trends::CORREL($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountATest.php index 0e53015885..091045858d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountATest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts; use PHPUnit\Framework\TestCase; class CountATest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUNTA($expectedResult, ...$args): void { - $result = Statistical::COUNTA(...$args); + $result = Counts::COUNTA(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php index 24667a6b15..e6aff66424 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts; use PHPUnit\Framework\TestCase; class CountBlankTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUNTBLANK($expectedResult, ...$args): void { - $result = Statistical::COUNTBLANK(...$args); + $result = Counts::COUNTBLANK(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfTest.php index c42d7eef1c..359ba7dbe4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional; use PHPUnit\Framework\TestCase; class CountIfTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUNTIF($expectedResult, ...$args): void { - $result = Statistical::COUNTIF(...$args); + $result = Conditional::COUNTIF(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfsTest.php index a68d7240dd..7bfeb21bcd 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfsTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional; use PHPUnit\Framework\TestCase; class CountIfsTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUNTIFS($expectedResult, ...$args): void { - $result = Statistical::COUNTIFS(...$args); + $result = Conditional::COUNTIFS(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountTest.php index 07f4f91840..85cce083fe 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Counts; use PHPUnit\Framework\TestCase; class CountTest extends TestCase @@ -31,7 +31,7 @@ protected function tearDown(): void */ public function testBasicCOUNT($expectedResult, ...$args): void { - $result = Statistical::COUNT(...$args); + $result = Counts::COUNT(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -47,7 +47,7 @@ public function providerBasicCOUNT(): array */ public function testExcelCOUNT($expectedResult, ...$args): void { - $result = Statistical::COUNT(...$args); + $result = Counts::COUNT(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -65,7 +65,7 @@ public function testOpenOfficeCOUNT($expectedResult, ...$args): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::COUNT(...$args); + $result = Counts::COUNT(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -83,7 +83,7 @@ public function testGnumericCOUNT($expectedResult, ...$args): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC); - $result = Statistical::COUNT(...$args); + $result = Counts::COUNT(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CovarTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CovarTest.php index e85c6f923b..9cf6bd000e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CovarTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CovarTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class CovarTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOVAR($expectedResult, ...$args): void { - $result = Statistical::COVAR(...$args); + $result = Trends::COVAR(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/DevSqTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/DevSqTest.php index 2db2930046..d7069c9dbc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/DevSqTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/DevSqTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Deviations; use PHPUnit\Framework\TestCase; class DevSqTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testDEVSQ($expectedResult, ...$args): void { - $result = Statistical::DEVSQ(...$args); + $result = Deviations::sumSquares(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php index 0d80aa3553..8c5e700ad4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Exponential; use PHPUnit\Framework\TestCase; class ExponDistTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testEXPONDIST($expectedResult, ...$args): void { - $result = Statistical::EXPONDIST(...$args); + $result = Exponential::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php index 97af9cf8f3..2569d3aea3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\F; use PHPUnit\Framework\TestCase; class FDistTest extends TestCase @@ -15,7 +15,7 @@ class FDistTest extends TestCase */ public function testFDIST($expectedResult, ...$args): void { - $result = Statistical::FDIST2(...$args); + $result = F::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php index 44f9c348a7..4ddd59a308 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Fisher; use PHPUnit\Framework\TestCase; class FisherInvTest extends TestCase @@ -22,7 +22,7 @@ protected function setUp(): void */ public function testFISHERINV($expectedResult, $value): void { - $result = Statistical::FISHERINV($value); + $result = Fisher::inverse($value); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php index a3750b6f38..b61420509e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Fisher; use PHPUnit\Framework\TestCase; class FisherTest extends TestCase @@ -22,7 +22,7 @@ protected function setUp(): void */ public function testFISHER($expectedResult, $value): void { - $result = Statistical::FISHER($value); + $result = Fisher::distribution($value); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php index 7f190093d0..62030b01be 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class ForecastTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testFORECAST($expectedResult, ...$args): void { - $result = Statistical::FORECAST(...$args); + $result = Trends::FORECAST(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php index 3ed71725ab..65ec99e309 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Gamma; use PHPUnit\Framework\TestCase; class GammaDistTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testGAMMADIST($expectedResult, ...$args): void { - $result = Statistical::GAMMADIST(...$args); + $result = Gamma::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php index d3e7c13c62..9f86829e18 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Gamma; use PHPUnit\Framework\TestCase; class GammaInvTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testGAMMAINV($expectedResult, ...$args): void { - $result = Statistical::GAMMAINV(...$args); + $result = Gamma::inverse(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php index 5b444e8007..4f0f918ba6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Gamma; use PHPUnit\Framework\TestCase; class GammaLnTest extends TestCase @@ -22,7 +22,7 @@ protected function setUp(): void */ public function testGAMMALN($expectedResult, $value): void { - $result = Statistical::GAMMALN($value); + $result = Gamma::ln($value); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php index 8372ab327e..5aa58687ae 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Gamma; use PHPUnit\Framework\TestCase; class GammaTest extends TestCase @@ -16,7 +16,7 @@ class GammaTest extends TestCase */ public function testGAMMA($expectedResult, $testValue): void { - $result = Statistical::GAMMAFunction($testValue); + $result = Gamma::gamma($testValue); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php index 0914b829ca..0616d3f0e7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StandardNormal; use PHPUnit\Framework\TestCase; class GaussTest extends TestCase @@ -16,7 +16,7 @@ class GaussTest extends TestCase */ public function testGAUSS($expectedResult, $testValue): void { - $result = Statistical::GAUSS($testValue); + $result = StandardNormal::gauss($testValue); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GeoMeanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GeoMeanTest.php index 859212f53b..a62f32eee5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GeoMeanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GeoMeanTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages\Mean; use PHPUnit\Framework\TestCase; class GeoMeanTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testGEOMEAN($expectedResult, ...$args): void { - $result = Statistical::GEOMEAN(...$args); + $result = Mean::geometric(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GrowthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GrowthTest.php index a796c370ed..9b0f0a72aa 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GrowthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GrowthTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class GrowthTest extends TestCase @@ -21,11 +21,11 @@ protected function setUp(): void public function testGROWTH($expectedResult, array $yValues, array $xValues, ?array $newValues = null, ?bool $const = null): void { if ($newValues === null) { - $result = Statistical::GROWTH($yValues, $xValues); + $result = Trends::GROWTH($yValues, $xValues); } elseif ($const === null) { - $result = Statistical::GROWTH($yValues, $xValues, $newValues); + $result = Trends::GROWTH($yValues, $xValues, $newValues); } else { - $result = Statistical::GROWTH($yValues, $xValues, $newValues, $const); + $result = Trends::GROWTH($yValues, $xValues, $newValues, $const); } self::assertEqualsWithDelta($expectedResult, $result[0], 1E-12); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HarMeanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HarMeanTest.php index 2dbc0cba81..8855c53388 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HarMeanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HarMeanTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages\Mean; use PHPUnit\Framework\TestCase; class HarMeanTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testHARMEAN($expectedResult, ...$args): void { - $result = Statistical::HARMEAN(...$args); + $result = Mean::harmonic(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php index ecd7218d4d..fe43338dcd 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\HyperGeometric; use PHPUnit\Framework\TestCase; class HypGeomDistTest extends TestCase @@ -15,7 +15,7 @@ class HypGeomDistTest extends TestCase */ public function testHYPGEOMDIST($expectedResult, ...$args): void { - $result = Statistical::HYPGEOMDIST(...$args); + $result = HyperGeometric::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/InterceptTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/InterceptTest.php index 9ccea5cb0c..9643dcccfd 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/InterceptTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/InterceptTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class InterceptTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testINTERCEPT($expectedResult, array $xargs, array $yargs): void { - $result = Statistical::INTERCEPT($xargs, $yargs); + $result = Trends::INTERCEPT($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/KurtTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/KurtTest.php index d793736a52..6652b88d31 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/KurtTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/KurtTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Deviations; use PHPUnit\Framework\TestCase; class KurtTest extends TestCase @@ -14,7 +14,7 @@ class KurtTest extends TestCase */ public function testKURT($expectedResult, ...$args): void { - $result = Statistical::KURT(...$args); + $result = Deviations::kurtosis(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LargeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LargeTest.php index 18694210a0..64828e341a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LargeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LargeTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Size; use PHPUnit\Framework\TestCase; class LargeTest extends TestCase @@ -16,7 +16,7 @@ class LargeTest extends TestCase */ public function testLARGE($expectedResult, $values, $position): void { - $result = Statistical::LARGE($values, $position); + $result = Size::large($values, $position); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LinEstTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LinEstTest.php index 539d915f6d..131ee7a052 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LinEstTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LinEstTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class LinEstTest extends TestCase @@ -17,7 +17,7 @@ class LinEstTest extends TestCase */ public function testLINEST(array $expectedResult, $yValues, $xValues, $const, $stats): void { - $result = Statistical::LINEST($yValues, $xValues, $const, $stats); + $result = Trends::LINEST($yValues, $xValues, $const, $stats); self::assertIsArray($result); $elements = count($expectedResult); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogEstTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogEstTest.php index 1537de69a1..916eedefb3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogEstTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogEstTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class LogEstTest extends TestCase @@ -17,7 +17,7 @@ class LogEstTest extends TestCase */ public function testLOGEST(array $expectedResult, $yValues, $xValues, $const, $stats): void { - $result = Statistical::LOGEST($yValues, $xValues, $const, $stats); + $result = Trends::LOGEST($yValues, $xValues, $const, $stats); self::assertIsArray($result); $elements = count($expectedResult); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php index 0ae547b8e7..69fb3c0539 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\LogNormal; use PHPUnit\Framework\TestCase; class LogInvTest extends TestCase @@ -15,7 +15,7 @@ class LogInvTest extends TestCase */ public function testLOGINV($expectedResult, ...$args): void { - $result = Statistical::LOGINV(...$args); + $result = LogNormal::inverse(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php index 3d2fac44eb..25c1a50fed 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\LogNormal; use PHPUnit\Framework\TestCase; class LogNormDist2Test extends TestCase @@ -15,7 +15,7 @@ class LogNormDist2Test extends TestCase */ public function testLOGNORMDIST2($expectedResult, ...$args): void { - $result = Statistical::LOGNORMDIST2(...$args); + $result = LogNormal::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php index 7fbac2f8b0..fc3b4f14bb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\LogNormal; use PHPUnit\Framework\TestCase; class LogNormDistTest extends TestCase @@ -15,7 +15,7 @@ class LogNormDistTest extends TestCase */ public function testLOGNORMDIST($expectedResult, ...$args): void { - $result = Statistical::LOGNORMDIST(...$args); + $result = LogNormal::cumulative(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxATest.php index ce338e84ca..135a3a9324 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxATest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum; use PHPUnit\Framework\TestCase; class MaxATest extends TestCase @@ -14,7 +14,7 @@ class MaxATest extends TestCase */ public function testMAXA($expectedResult, ...$args): void { - $result = Statistical::MAXA(...$args); + $result = Maximum::maxA(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxIfsTest.php index d4c00a4ba1..d1d6a19a98 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxIfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxIfsTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional; use PHPUnit\Framework\TestCase; class MaxIfsTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testMAXIFS($expectedResult, ...$args): void { - $result = Statistical::MAXIFS(...$args); + $result = Conditional::MAXIFS(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxTest.php index cd329aa9ea..0b5b03e9b5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Maximum; use PHPUnit\Framework\TestCase; class MaxTest extends TestCase @@ -14,7 +14,7 @@ class MaxTest extends TestCase */ public function testMAX($expectedResult, ...$args): void { - $result = Statistical::MAX(...$args); + $result = Maximum::max(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MedianTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MedianTest.php index 68e46e189b..aaa82a4ee5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MedianTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MedianTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages; use PHPUnit\Framework\TestCase; class MedianTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testMEDIAN($expectedResult, ...$args): void { - $result = Statistical::MEDIAN(...$args); + $result = Averages::median(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinATest.php index f24d1ca2bf..a5e5af9121 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinATest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum; use PHPUnit\Framework\TestCase; class MinATest extends TestCase @@ -14,7 +14,7 @@ class MinATest extends TestCase */ public function testMINA($expectedResult, ...$args): void { - $result = Statistical::MINA(...$args); + $result = Minimum::minA(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinIfsTest.php index 201e9e744e..cac400c336 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinIfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinIfsTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Conditional; use PHPUnit\Framework\TestCase; class MinIfsTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testMINIFS($expectedResult, ...$args): void { - $result = Statistical::MINIFS(...$args); + $result = Conditional::MINIFS(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinTest.php index a5a1658826..09afae2aad 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Minimum; use PHPUnit\Framework\TestCase; class MinTest extends TestCase @@ -14,7 +14,7 @@ class MinTest extends TestCase */ public function testMIN($expectedResult, ...$args): void { - $result = Statistical::MIN(...$args); + $result = Minimum::min(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php index 2e73f8109e..b32f9cd92e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Binomial; use PHPUnit\Framework\TestCase; class NegBinomDistTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testNEGBINOMDIST($expectedResult, ...$args): void { - $result = Statistical::NEGBINOMDIST(...$args); + $result = Binomial::negative(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php index 367ce51155..f6c41665af 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Normal; use PHPUnit\Framework\TestCase; class NormDistTest extends TestCase @@ -15,7 +15,7 @@ class NormDistTest extends TestCase */ public function testNORMDIST($expectedResult, ...$args): void { - $result = Statistical::NORMDIST(...$args); + $result = Normal::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php index ca056a398d..dbd6f6889d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Normal; use PHPUnit\Framework\TestCase; class NormInvTest extends TestCase @@ -15,7 +15,7 @@ class NormInvTest extends TestCase */ public function testNORMINV($expectedResult, ...$args): void { - $result = Statistical::NORMINV(...$args); + $result = Normal::inverse(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDist2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDist2Test.php index 2c03b795dc..296f483405 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDist2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDist2Test.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StandardNormal; use PHPUnit\Framework\TestCase; class NormSDist2Test extends TestCase @@ -15,7 +15,7 @@ class NormSDist2Test extends TestCase */ public function testNORMSDIST2($expectedResult, ...$args): void { - $result = Statistical::NORMSDIST2(...$args); + $result = StandardNormal::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDistTest.php index a2fbf497ea..bc670a83bd 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDistTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StandardNormal; use PHPUnit\Framework\TestCase; class NormSDistTest extends TestCase @@ -16,7 +16,7 @@ class NormSDistTest extends TestCase */ public function testNORMSDIST($expectedResult, $testValue): void { - $result = Statistical::NORMSDIST($testValue); + $result = StandardNormal::cumulative($testValue); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSInvTest.php index a2465f15a7..bff1e40e54 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSInvTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StandardNormal; use PHPUnit\Framework\TestCase; class NormSInvTest extends TestCase @@ -16,7 +16,7 @@ class NormSInvTest extends TestCase */ public function testNORMSINV($expectedResult, $testValue): void { - $result = Statistical::NORMSINV($testValue); + $result = StandardNormal::inverse($testValue); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentRankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentRankTest.php index 4022ae40e5..6c5a20f392 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentRankTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentRankTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Percentiles; use PHPUnit\Framework\TestCase; class PercentRankTest extends TestCase @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testPERCENTRANK($expectedResult, $valueSet, $value, $digits = 3): void { - $result = Statistical::PERCENTRANK($valueSet, $value, $digits); + $result = Percentiles::PERCENTRANK($valueSet, $value, $digits); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentileTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentileTest.php index e4dadb74a0..938c3c9ea8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentileTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentileTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Percentiles; use PHPUnit\Framework\TestCase; class PercentileTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testPERCENTILE($expectedResult, ...$args): void { - $result = Statistical::PERCENTILE(...$args); + $result = Percentiles::PERCENTILE(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php index 1e2401a539..af68bf806a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Permutations; use PHPUnit\Framework\TestCase; class PermutTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testPERMUT($expectedResult, ...$args): void { - $result = Statistical::PERMUT(...$args); + $result = Permutations::PERMUT(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PoissonTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PoissonTest.php index 8df54c994f..7355c195a6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PoissonTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PoissonTest.php @@ -4,7 +4,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Poisson; use PHPUnit\Framework\TestCase; class PoissonTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testPOISSON($expectedResult, ...$args): void { - $result = Statistical::POISSON(...$args); + $result = Poisson::distribution(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/QuartileTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/QuartileTest.php index 33b3c599ee..5c6225738f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/QuartileTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/QuartileTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Percentiles; use PHPUnit\Framework\TestCase; class QuartileTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testQUARTILE($expectedResult, ...$args): void { - $result = Statistical::QUARTILE(...$args); + $result = Percentiles::QUARTILE(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RankTest.php index bbbac36fd1..4acae2620f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RankTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RankTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Percentiles; use PHPUnit\Framework\TestCase; class RankTest extends TestCase @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testRANK($expectedResult, $value, $valueSet, $order = 0): void { - $result = Statistical::RANK($value, $valueSet, $order); + $result = Percentiles::RANK($value, $valueSet, $order); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RsqTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RsqTest.php index a85bba06c6..cc89d7ce14 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RsqTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RsqTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class RsqTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testRSQ($expectedResult, array $xargs, array $yargs): void { - $result = Statistical::RSQ($xargs, $yargs); + $result = Trends::RSQ($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SkewTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SkewTest.php index 4415ec4a69..6da5543694 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SkewTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SkewTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Deviations; use PHPUnit\Framework\TestCase; class SkewTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testSKEW($expectedResult, array $args): void { - $result = Statistical::SKEW($args); + $result = Deviations::skew($args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SlopeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SlopeTest.php index 9bab264c9d..0be7a17462 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SlopeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SlopeTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class SlopeTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testSLOPE($expectedResult, array $xargs, array $yargs): void { - $result = Statistical::SLOPE($xargs, $yargs); + $result = Trends::SLOPE($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SmallTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SmallTest.php index 52c82f6bed..ef6d6c5ca3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SmallTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SmallTest.php @@ -2,7 +2,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Size; use PHPUnit\Framework\TestCase; class SmallTest extends TestCase @@ -16,7 +16,7 @@ class SmallTest extends TestCase */ public function testSMALL($expectedResult, $values, $position): void { - $result = Statistical::SMALL($values, $position); + $result = Size::small($values, $position); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php index 1de33a778d..dbb8bb1ab6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations; use PHPUnit\Framework\TestCase; class StDevATest extends TestCase @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testSTDEVA($expectedResult, $values): void { - $result = Statistical::STDEVA($values); + $result = StandardDeviations::STDEVA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsSTDEVA($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::STDEVA($values); + $result = StandardDeviations::STDEVA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php index f19f072e53..84aa21b545 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations; use PHPUnit\Framework\TestCase; class StDevPATest extends TestCase @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testSTDEVPA($expectedResult, $values): void { - $result = Statistical::STDEVPA($values); + $result = StandardDeviations::STDEVPA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsSTDEVPA($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::STDEVPA($values); + $result = StandardDeviations::STDEVPA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php index 39de961dd6..0bed3f055f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations; use PHPUnit\Framework\TestCase; class StDevPTest extends TestCase @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testSTDEVP($expectedResult, $values): void { - $result = Statistical::STDEVP($values); + $result = StandardDeviations::STDEVP($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsSTDEVP($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::STDEVP($values); + $result = StandardDeviations::STDEVP($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php index e99041096d..38ed4e240d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\StandardDeviations; use PHPUnit\Framework\TestCase; class StDevTest extends TestCase @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testSTDEV($expectedResult, $values): void { - $result = Statistical::STDEV($values); + $result = StandardDeviations::STDEV($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsSTDEV($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::STDEV($values); + $result = StandardDeviations::STDEV($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php index 2177cee5d2..9214e6e941 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Standardize; use PHPUnit\Framework\TestCase; class StandardizeTest extends TestCase @@ -15,7 +15,7 @@ class StandardizeTest extends TestCase */ public function testSTANDARDIZE($expectedResult, ...$args): void { - $result = Statistical::STANDARDIZE(...$args); + $result = Standardize::execute(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SteyxTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SteyxTest.php index cefc79c528..b8e23741c3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SteyxTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SteyxTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class SteyxTest extends TestCase @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testSTEYX($expectedResult, array $xargs, array $yargs): void { - $result = Statistical::STEYX($xargs, $yargs); + $result = Trends::STEYX($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TDistTest.php index 87ca19732b..065a9cccf4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TDistTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StudentT; use PHPUnit\Framework\TestCase; class TDistTest extends TestCase @@ -18,7 +18,7 @@ class TDistTest extends TestCase */ public function testTDIST($expectedResult, $value, $degrees, $tails): void { - $result = Statistical::TDIST($value, $degrees, $tails); + $result = StudentT::distribution($value, $degrees, $tails); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TinvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TinvTest.php index 1e6f81cfc8..e60395932f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TinvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TinvTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StudentT; use PHPUnit\Framework\TestCase; class TinvTest extends TestCase @@ -17,7 +17,7 @@ class TinvTest extends TestCase */ public function testTINV($expectedResult, $probability, $degrees): void { - $result = Statistical::TINV($probability, $degrees); + $result = StudentT::inverse($probability, $degrees); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrendTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrendTest.php index 2cb06b777c..9a8724b8ce 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrendTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrendTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Trends; use PHPUnit\Framework\TestCase; class TrendTest extends TestCase @@ -21,11 +21,11 @@ protected function setUp(): void public function testTREND($expectedResult, array $yValues, array $xValues, ?array $newValues = null, ?bool $const = null): void { if ($newValues === null) { - $result = Statistical::TREND($yValues, $xValues); + $result = Trends::TREND($yValues, $xValues); } elseif ($const === null) { - $result = Statistical::TREND($yValues, $xValues, $newValues); + $result = Trends::TREND($yValues, $xValues, $newValues); } else { - $result = Statistical::TREND($yValues, $xValues, $newValues, $const); + $result = Trends::TREND($yValues, $xValues, $newValues, $const); } self::assertEqualsWithDelta($expectedResult, $result[0], 1E-12); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrimMeanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrimMeanTest.php index 54d7576a46..d9ae9feaa9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrimMeanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrimMeanTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Averages\Mean; use PHPUnit\Framework\TestCase; class TrimMeanTest extends TestCase @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testTRIMMEAN($expectedResult, array $args, $percentage): void { - $result = Statistical::TRIMMEAN($args, $percentage); + $result = Mean::trim($args, $percentage); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php index a0bf818234..45ccf7ba4c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances; use PHPUnit\Framework\TestCase; class VarATest extends TestCase @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testVARA($expectedResult, $values): void { - $result = Statistical::VARA($values); + $result = Variances::VARA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsVARA($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::VARA($values); + $result = Variances::VARA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php index 88304d8eea..2adfd7c132 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances; use PHPUnit\Framework\TestCase; class VarPATest extends TestCase @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testVARPA($expectedResult, $values): void { - $result = Statistical::VARPA($values); + $result = Variances::VARPA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsVARPA($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::VARPA($values); + $result = Variances::VARPA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php index 1a0475eb09..69b7c8d64b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances; use PHPUnit\Framework\TestCase; class VarPTest extends TestCase @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testVARP($expectedResult, $values): void { - $result = Statistical::VARP($values); + $result = Variances::VARP($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsVARP($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::VARP($values); + $result = Variances::VARP($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php index 5fc163b50d..6a33c04a60 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Variances; use PHPUnit\Framework\TestCase; class VarTest extends TestCase @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testVAR($expectedResult, $values): void { - $result = Statistical::VARFunc($values); + $result = Variances::VAR($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsVAR($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Statistical::VARFunc($values); + $result = Variances::VAR($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/WeibullTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/WeibullTest.php index ec8c2ec68f..8e26e1f00f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/WeibullTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/WeibullTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\Weibull; use PHPUnit\Framework\TestCase; class WeibullTest extends TestCase @@ -19,7 +19,7 @@ class WeibullTest extends TestCase */ public function testWEIBULL($expectedResult, $value, $alpha, $beta, $cumulative): void { - $result = Statistical::WEIBULL($value, $alpha, $beta, $cumulative); + $result = Weibull::distribution($value, $alpha, $beta, $cumulative); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ZTestTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ZTestTest.php index de094f74ac..446bdc98ba 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ZTestTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ZTestTest.php @@ -3,7 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Statistical; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Statistical; +use PhpOffice\PhpSpreadsheet\Calculation\Statistical\Distributions\StandardNormal; use PHPUnit\Framework\TestCase; class ZTestTest extends TestCase @@ -18,7 +18,7 @@ class ZTestTest extends TestCase */ public function testZTEST($expectedResult, $dataSet, $value, $sigma = null): void { - $result = Statistical::ZTEST($dataSet, $value, $sigma); + $result = StandardNormal::zTest($dataSet, $value, $sigma); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/DeprecatedTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/DeprecatedTest.php deleted file mode 100644 index 49ac421b84..0000000000 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/DeprecatedTest.php +++ /dev/null @@ -1,44 +0,0 @@ -expectExceptionMessage('HTTP client must be configured via Settings::setHttpClient() to be able to use WEBSERVICE function.'); - Web::WEBSERVICE('https://example.com'); + WebService::WEBSERVICE('https://example.com'); } } diff --git a/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php index 9ea624008a..dbb3667f1f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php @@ -3,7 +3,6 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Information\ExcelError; use PHPUnit\Framework\TestCase; class FunctionsTest extends TestCase @@ -88,12 +87,6 @@ public function providerIfCondition(): array return require 'tests/data/Calculation/Functions/IF_CONDITION.php'; } - public function testDeprecatedIsFormula(): void - { - $result = Functions::isFormula('="STRING"'); - self::assertEquals(ExcelError::REF(), $result); - } - public function testScalar(): void { $value = 'scalar'; diff --git a/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php b/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php index bb5535776f..2edf0d7400 100644 --- a/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php +++ b/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php @@ -33,7 +33,7 @@ public function providerGenerateFunctionListByName(): array [ [ 'ABS' => ['category' => Cat::CATEGORY_MATH_AND_TRIG, 'functionCall' => 'abs'], - 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical::class, 'logicalAnd']], + 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical\Operations::class, 'logicalAnd']], 'IFS' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Functions::class, 'DUMMY']], ], <<<'EXPECTED' @@ -44,7 +44,7 @@ public function providerGenerateFunctionListByName(): array Excel Function | Category | PhpSpreadsheet Function -------------------------|--------------------------------|-------------------------------------- ABS | CATEGORY_MATH_AND_TRIG | abs -AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalAnd +AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical\Operations::logicalAnd ## I @@ -64,7 +64,7 @@ public function providerGenerateFunctionListByCategory(): array [ [ 'ABS' => ['category' => Cat::CATEGORY_MATH_AND_TRIG, 'functionCall' => 'abs'], - 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical::class, 'logicalAnd']], + 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical\Operations::class, 'logicalAnd']], 'IFS' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Functions::class, 'DUMMY']], ], <<<'EXPECTED' @@ -104,7 +104,7 @@ public function providerGenerateFunctionListByCategory(): array Excel Function | PhpSpreadsheet Function -------------------------|-------------------------------------- -AND | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalAnd +AND | \PhpOffice\PhpSpreadsheet\Calculation\Logical\Operations::logicalAnd IFS | **Not yet Implemented** ## CATEGORY_LOOKUP_AND_REFERENCE From 703604c9b590ab2d8901e4e8686f7f692214936e Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 25 Apr 2022 11:21:27 +0200 Subject: [PATCH 69/94] Remove Reader/Writer deprecations --- src/PhpSpreadsheet/Reader/Html.php | 41 +----------------------------- src/PhpSpreadsheet/Reader/Slk.php | 39 ---------------------------- src/PhpSpreadsheet/Writer/Html.php | 39 ---------------------------- 3 files changed, 1 insertion(+), 118 deletions(-) diff --git a/src/PhpSpreadsheet/Reader/Html.php b/src/PhpSpreadsheet/Reader/Html.php index 15c9f62546..1392298789 100644 --- a/src/PhpSpreadsheet/Reader/Html.php +++ b/src/PhpSpreadsheet/Reader/Html.php @@ -26,13 +26,6 @@ class Html extends BaseReader */ const TEST_SAMPLE_SIZE = 2048; - /** - * Input encoding. - * - * @var string - */ - protected $inputEncoding = 'ANSI'; - /** * Sheet index to read. * @@ -210,38 +203,6 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet return $this->loadIntoExisting($filename, $spreadsheet); } - /** - * Set input encoding. - * - * @param string $inputEncoding Input encoding, eg: 'ANSI' - * - * @return $this - * - * @codeCoverageIgnore - * - * @deprecated no use is made of this property - */ - public function setInputEncoding($inputEncoding) - { - $this->inputEncoding = $inputEncoding; - - return $this; - } - - /** - * Get input encoding. - * - * @return string - * - * @codeCoverageIgnore - * - * @deprecated no use is made of this property - */ - public function getInputEncoding() - { - return $this->inputEncoding; - } - // Data Array used for testing only, should write to Spreadsheet object on completion of tests /** @var array */ @@ -255,7 +216,7 @@ public function getInputEncoding() protected function setTableStartColumn(string $column): string { - if ($this->tableLevel == 0) { + if ($this->tableLevel === 0) { $column = 'A'; } ++$this->tableLevel; diff --git a/src/PhpSpreadsheet/Reader/Slk.php b/src/PhpSpreadsheet/Reader/Slk.php index c33f020221..ae7da709fe 100644 --- a/src/PhpSpreadsheet/Reader/Slk.php +++ b/src/PhpSpreadsheet/Reader/Slk.php @@ -12,13 +12,6 @@ class Slk extends BaseReader { - /** - * Input encoding. - * - * @var string - */ - private $inputEncoding = 'ANSI'; - /** * Sheet index to read. * @@ -97,38 +90,6 @@ private function canReadOrBust(string $filename): void $this->openFile($filename); } - /** - * Set input encoding. - * - * @deprecated no use is made of this property - * - * @param string $inputEncoding Input encoding, eg: 'ANSI' - * - * @return $this - * - * @codeCoverageIgnore - */ - public function setInputEncoding($inputEncoding) - { - $this->inputEncoding = $inputEncoding; - - return $this; - } - - /** - * Get input encoding. - * - * @deprecated no use is made of this property - * - * @return string - * - * @codeCoverageIgnore - */ - public function getInputEncoding() - { - return $this->inputEncoding; - } - /** * Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns). * diff --git a/src/PhpSpreadsheet/Writer/Html.php b/src/PhpSpreadsheet/Writer/Html.php index 629e3c0ce4..dc52371532 100644 --- a/src/PhpSpreadsheet/Writer/Html.php +++ b/src/PhpSpreadsheet/Writer/Html.php @@ -63,13 +63,6 @@ class Html extends BaseWriter */ private $useInlineCss = false; - /** - * Use embedded CSS? - * - * @var bool - */ - private $useEmbeddedCSS = true; - /** * Array of CSS styles. * @@ -1596,38 +1589,6 @@ public function setUseInlineCss($useInlineCss) return $this; } - /** - * Get use embedded CSS? - * - * @return bool - * - * @codeCoverageIgnore - * - * @deprecated no longer used - */ - public function getUseEmbeddedCSS() - { - return $this->useEmbeddedCSS; - } - - /** - * Set use embedded CSS? - * - * @param bool $useEmbeddedCSS - * - * @return $this - * - * @codeCoverageIgnore - * - * @deprecated no longer used - */ - public function setUseEmbeddedCSS($useEmbeddedCSS) - { - $this->useEmbeddedCSS = $useEmbeddedCSS; - - return $this; - } - /** * Add color to formatted string as inline style. * From 0998e72a2eb40b7bffd1538951bc9cee4b83b082 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 26 Apr 2022 19:48:59 +0200 Subject: [PATCH 70/94] Eliminate underscore prefix in method names... no longer needed as an indicator that a method should be internal only --- docs/topics/recipes.md | 2 +- phpstan-baseline.neon | 20 ------------------- .../Calculation/Calculation.php | 16 +++++++-------- .../Calculation/Database/DatabaseAbstract.php | 2 +- .../Calculation/MathTrig/Arabic.php | 2 +- .../Calculation/MathTrig/Roman.php | 2 +- src/PhpSpreadsheet/Chart/DataSeriesValues.php | 2 +- src/PhpSpreadsheet/Shared/StringHelper.php | 2 +- .../Calculation/ArrayFormulaTest.php | 2 +- .../Calculation/CalculationErrorTest.php | 6 +++--- .../Calculation/CalculationTest.php | 4 ++-- .../Functions/DateTime/DateDifTest.php | 2 +- .../Functions/DateTime/DateTest.php | 4 ++-- .../Functions/DateTime/DateValueTest.php | 2 +- .../Functions/DateTime/DayTest.php | 2 +- .../Functions/DateTime/Days360Test.php | 2 +- .../Functions/DateTime/DaysTest.php | 2 +- .../Functions/DateTime/EDateTest.php | 2 +- .../Functions/DateTime/EoMonthTest.php | 2 +- .../Functions/DateTime/HourTest.php | 2 +- .../Functions/DateTime/IsoWeekNumTest.php | 2 +- .../Functions/DateTime/MinuteTest.php | 2 +- .../Functions/DateTime/MonthTest.php | 2 +- .../Functions/DateTime/NetworkDaysTest.php | 2 +- .../Functions/DateTime/SecondTest.php | 2 +- .../Functions/DateTime/TimeTest.php | 4 ++-- .../Functions/DateTime/TimeValueTest.php | 2 +- .../Functions/DateTime/WeekDayTest.php | 2 +- .../Functions/DateTime/WeekNumTest.php | 2 +- .../Functions/DateTime/WorkDayTest.php | 2 +- .../Functions/DateTime/YearFracTest.php | 2 +- .../Functions/DateTime/YearTest.php | 2 +- .../Functions/Engineering/BesselITest.php | 2 +- .../Functions/Engineering/BesselJTest.php | 2 +- .../Functions/Engineering/BesselKTest.php | 2 +- .../Functions/Engineering/BesselYTest.php | 2 +- .../Functions/Engineering/Bin2DecTest.php | 2 +- .../Functions/Engineering/Bin2HexTest.php | 2 +- .../Functions/Engineering/Bin2OctTest.php | 2 +- .../Functions/Engineering/BitAndTest.php | 2 +- .../Functions/Engineering/BitLShiftTest.php | 2 +- .../Functions/Engineering/BitOrTest.php | 2 +- .../Functions/Engineering/BitRShiftTest.php | 2 +- .../Functions/Engineering/BitXorTest.php | 2 +- .../Functions/Engineering/ComplexTest.php | 2 +- .../Functions/Engineering/ConvertUoMTest.php | 2 +- .../Functions/Engineering/Dec2BinTest.php | 2 +- .../Functions/Engineering/Dec2HexTest.php | 2 +- .../Functions/Engineering/Dec2OctTest.php | 2 +- .../Functions/Engineering/DeltaTest.php | 2 +- .../Functions/Engineering/ErfCTest.php | 2 +- .../Functions/Engineering/ErfPreciseTest.php | 2 +- .../Functions/Engineering/ErfTest.php | 2 +- .../Functions/Engineering/GeStepTest.php | 2 +- .../Functions/Engineering/Hex2BinTest.php | 2 +- .../Functions/Engineering/Hex2DecTest.php | 2 +- .../Functions/Engineering/Hex2OctTest.php | 2 +- .../Functions/Engineering/ImAbsTest.php | 2 +- .../Functions/Engineering/ImArgumentTest.php | 2 +- .../Functions/Engineering/ImConjugateTest.php | 2 +- .../Functions/Engineering/ImCosTest.php | 2 +- .../Functions/Engineering/ImCoshTest.php | 2 +- .../Functions/Engineering/ImCotTest.php | 2 +- .../Functions/Engineering/ImCscTest.php | 2 +- .../Functions/Engineering/ImCschTest.php | 2 +- .../Functions/Engineering/ImDivTest.php | 2 +- .../Functions/Engineering/ImExpTest.php | 2 +- .../Functions/Engineering/ImLnTest.php | 2 +- .../Functions/Engineering/ImLog10Test.php | 2 +- .../Functions/Engineering/ImLog2Test.php | 2 +- .../Functions/Engineering/ImPowerTest.php | 2 +- .../Functions/Engineering/ImRealTest.php | 2 +- .../Functions/Engineering/ImSecTest.php | 2 +- .../Functions/Engineering/ImSechTest.php | 2 +- .../Functions/Engineering/ImSinTest.php | 2 +- .../Functions/Engineering/ImSinhTest.php | 2 +- .../Functions/Engineering/ImSqrtTest.php | 2 +- .../Functions/Engineering/ImSubTest.php | 2 +- .../Functions/Engineering/ImTanTest.php | 2 +- .../Functions/Engineering/ImaginaryTest.php | 2 +- .../Functions/Engineering/Oct2BinTest.php | 2 +- .../Functions/Engineering/Oct2DecTest.php | 2 +- .../Functions/Engineering/Oct2HexTest.php | 2 +- .../Functions/Financial/DollarDeTest.php | 2 +- .../Functions/Information/ErrorTypeTest.php | 2 +- .../Functions/Information/IsBlankTest.php | 2 +- .../Functions/Information/IsErrTest.php | 2 +- .../Functions/Information/IsErrorTest.php | 2 +- .../Functions/Information/IsEvenTest.php | 2 +- .../Functions/Information/IsFormulaTest.php | 2 +- .../Functions/Information/IsLogicalTest.php | 2 +- .../Functions/Information/IsNaTest.php | 2 +- .../Functions/Information/IsNonTextTest.php | 2 +- .../Functions/Information/IsNumberTest.php | 2 +- .../Functions/Information/IsOddTest.php | 2 +- .../Functions/Information/IsTextTest.php | 2 +- .../Functions/Logical/IfErrorTest.php | 2 +- .../Functions/Logical/IfNaTest.php | 2 +- .../Calculation/Functions/Logical/NotTest.php | 2 +- .../Functions/LookupRef/AddressTest.php | 2 +- .../Functions/LookupRef/ChooseTest.php | 2 +- .../Functions/LookupRef/ColumnsTest.php | 2 +- .../Functions/LookupRef/HLookupTest.php | 2 +- .../Functions/LookupRef/IndexTest.php | 2 +- .../Functions/LookupRef/LookupTest.php | 2 +- .../Functions/LookupRef/MatchTest.php | 2 +- .../Functions/LookupRef/RowsTest.php | 2 +- .../Functions/LookupRef/VLookupTest.php | 2 +- .../Functions/MathTrig/AbsTest.php | 2 +- .../Functions/MathTrig/AcosTest.php | 2 +- .../Functions/MathTrig/AcoshTest.php | 2 +- .../Functions/MathTrig/AcotTest.php | 2 +- .../Functions/MathTrig/AcothTest.php | 2 +- .../Functions/MathTrig/ArabicTest.php | 2 +- .../Functions/MathTrig/AsinTest.php | 2 +- .../Functions/MathTrig/AsinhTest.php | 2 +- .../Functions/MathTrig/Atan2Test.php | 2 +- .../Functions/MathTrig/AtanTest.php | 2 +- .../Functions/MathTrig/AtanhTest.php | 2 +- .../Functions/MathTrig/BaseTest.php | 2 +- .../Functions/MathTrig/CeilingMathTest.php | 2 +- .../Functions/MathTrig/CeilingPreciseTest.php | 2 +- .../Functions/MathTrig/CeilingTest.php | 2 +- .../Functions/MathTrig/CombinATest.php | 2 +- .../Functions/MathTrig/CombinTest.php | 2 +- .../Functions/MathTrig/CosTest.php | 2 +- .../Functions/MathTrig/CoshTest.php | 2 +- .../Functions/MathTrig/CotTest.php | 2 +- .../Functions/MathTrig/CothTest.php | 2 +- .../Functions/MathTrig/CscTest.php | 2 +- .../Functions/MathTrig/CschTest.php | 2 +- .../Functions/MathTrig/DegreesTest.php | 2 +- .../Functions/MathTrig/EvenTest.php | 2 +- .../Functions/MathTrig/ExpTest.php | 2 +- .../Functions/MathTrig/FactDoubleTest.php | 2 +- .../Functions/MathTrig/FactTest.php | 2 +- .../Functions/MathTrig/FloorMathTest.php | 2 +- .../Functions/MathTrig/FloorPreciseTest.php | 2 +- .../Functions/MathTrig/FloorTest.php | 2 +- .../Functions/MathTrig/IntTest.php | 2 +- .../Calculation/Functions/MathTrig/LnTest.php | 2 +- .../Functions/MathTrig/Log10Test.php | 2 +- .../Functions/MathTrig/LogTest.php | 2 +- .../Functions/MathTrig/MRoundTest.php | 2 +- .../Functions/MathTrig/ModTest.php | 2 +- .../Functions/MathTrig/OddTest.php | 2 +- .../Functions/MathTrig/PowerTest.php | 2 +- .../Functions/MathTrig/QuotientTest.php | 2 +- .../Functions/MathTrig/RadiansTest.php | 2 +- .../Functions/MathTrig/RandBetweenTest.php | 2 +- .../Functions/MathTrig/RomanTest.php | 2 +- .../Functions/MathTrig/RoundDownTest.php | 2 +- .../Functions/MathTrig/RoundTest.php | 2 +- .../Functions/MathTrig/RoundUpTest.php | 2 +- .../Functions/MathTrig/SecTest.php | 2 +- .../Functions/MathTrig/SechTest.php | 2 +- .../Functions/MathTrig/SeriesSumTest.php | 2 +- .../Functions/MathTrig/SignTest.php | 2 +- .../Functions/MathTrig/SinTest.php | 2 +- .../Functions/MathTrig/SinhTest.php | 2 +- .../Functions/MathTrig/SqrtPiTest.php | 2 +- .../Functions/MathTrig/SqrtTest.php | 2 +- .../Functions/MathTrig/TanTest.php | 2 +- .../Functions/MathTrig/TanhTest.php | 2 +- .../Functions/MathTrig/TruncTest.php | 2 +- .../Functions/Statistical/BetaDistTest.php | 2 +- .../Functions/Statistical/BetaInvTest.php | 2 +- .../Statistical/BinomDistRangeTest.php | 2 +- .../Functions/Statistical/BinomDistTest.php | 2 +- .../Functions/Statistical/BinomInvTest.php | 2 +- .../Statistical/ChiDistLeftTailTest.php | 2 +- .../Statistical/ChiDistRightTailTest.php | 2 +- .../Statistical/ChiInvLeftTailTest.php | 2 +- .../Statistical/ChiInvRightTailTest.php | 2 +- .../Functions/Statistical/ConfidenceTest.php | 2 +- .../Functions/Statistical/ExponDistTest.php | 2 +- .../Functions/Statistical/FDistTest.php | 2 +- .../Functions/Statistical/FisherInvTest.php | 2 +- .../Functions/Statistical/FisherTest.php | 2 +- .../Functions/Statistical/ForecastTest.php | 2 +- .../Functions/Statistical/GammaDistTest.php | 2 +- .../Functions/Statistical/GammaInvTest.php | 2 +- .../Functions/Statistical/GammaLnTest.php | 2 +- .../Functions/Statistical/GammaTest.php | 2 +- .../Functions/Statistical/GaussTest.php | 2 +- .../Functions/Statistical/HypGeomDistTest.php | 2 +- .../Functions/Statistical/LogInvTest.php | 2 +- .../Statistical/LogNormDist2Test.php | 2 +- .../Functions/Statistical/LogNormDistTest.php | 2 +- .../Statistical/NegBinomDistTest.php | 2 +- .../Functions/Statistical/NormDistTest.php | 2 +- .../Functions/Statistical/NormInvTest.php | 2 +- .../Functions/Statistical/NormSDist2Test.php | 2 +- .../Functions/Statistical/NormSDistTest.php | 2 +- .../Functions/Statistical/NormSInvTest.php | 2 +- .../Functions/Statistical/PermutTest.php | 2 +- .../Statistical/PermutationATest.php | 2 +- .../Functions/Statistical/PoissonTest.php | 2 +- .../Functions/Statistical/StandardizeTest.php | 2 +- .../Functions/Statistical/TDistTest.php | 2 +- .../Functions/Statistical/TinvTest.php | 2 +- .../Functions/Statistical/WeibullTest.php | 2 +- .../Functions/Statistical/ZTestTest.php | 2 +- .../Functions/TextData/CharTest.php | 2 +- .../Functions/TextData/CleanTest.php | 2 +- .../Functions/TextData/CodeTest.php | 2 +- .../Functions/TextData/DollarTest.php | 2 +- .../Functions/TextData/ExactTest.php | 2 +- .../Functions/TextData/FindTest.php | 2 +- .../Functions/TextData/FixedTest.php | 2 +- .../Functions/TextData/LeftTest.php | 2 +- .../Functions/TextData/LenTest.php | 2 +- .../Functions/TextData/LowerTest.php | 2 +- .../Functions/TextData/MidTest.php | 2 +- .../Functions/TextData/NumberValueTest.php | 2 +- .../Functions/TextData/ProperTest.php | 2 +- .../Functions/TextData/ReplaceTest.php | 2 +- .../Functions/TextData/ReptTest.php | 2 +- .../Functions/TextData/RightTest.php | 2 +- .../Functions/TextData/SearchTest.php | 2 +- .../Functions/TextData/SubstituteTest.php | 2 +- .../Calculation/Functions/TextData/TTest.php | 2 +- .../Functions/TextData/TextJoinTest.php | 2 +- .../Functions/TextData/TextTest.php | 2 +- .../Functions/TextData/TrimTest.php | 2 +- .../Functions/TextData/UpperTest.php | 2 +- .../Functions/TextData/ValueTest.php | 2 +- .../Calculation/TranslationTest.php | 4 ++-- 228 files changed, 240 insertions(+), 260 deletions(-) diff --git a/docs/topics/recipes.md b/docs/topics/recipes.md index f25a911931..176cd21c79 100644 --- a/docs/topics/recipes.md +++ b/docs/topics/recipes.md @@ -187,7 +187,7 @@ internal English coding. ```php $formula = $spreadsheet->getActiveSheet()->getCell('B8')->getValue(); -$translatedFormula = \PhpOffice\PhpSpreadsheet\Calculation\Calculation::getInstance()->_translateFormulaToLocale($formula); +$translatedFormula = \PhpOffice\PhpSpreadsheet\Calculation\Calculation::getInstance()->translateFormulaToLocale($formula); ``` You can also create a formula using the function names and argument diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 69b14f1ef4..36e150ba1a 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -55,26 +55,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has parameter \\$formula with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has parameter \\$formula with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:dataTestReference\\(\\) has no return type specified\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 423cf9db0e..2c22d872a0 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -294,7 +294,7 @@ class Calculation ], 'ARABIC' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Arabic::class, 'evaluate'], + 'functionCall' => [MathTrig\Arabic::class, 'toRoman'], 'argumentCount' => '1', ], 'AREAS' => [ @@ -2141,7 +2141,7 @@ class Calculation ], 'ROMAN' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [MathTrig\Roman::class, 'evaluate'], + 'functionCall' => [MathTrig\Roman::class, 'toArabic'], 'argumentCount' => '1,2', ], 'ROUND' => [ @@ -3176,7 +3176,7 @@ private static function translateFormula(array $from, array $to, string $formula private static $functionReplaceToLocale; - public function _translateFormulaToLocale($formula) + public function translateFormulaToLocale(string $formula): string { // Build list of function names and constants for translation if (self::$functionReplaceFromExcel === null) { @@ -3212,7 +3212,7 @@ public function _translateFormulaToLocale($formula) private static $functionReplaceToExcel; - public function _translateFormulaToEnglish($formula) + public function translateFormulaToEnglish(string $formula): string { if (self::$functionReplaceFromLocale === null) { self::$functionReplaceFromLocale = []; @@ -3350,7 +3350,7 @@ public function calculateCellValue(?Cell $cell = null, $resetLog = true) ]; try { - $result = self::unwrapResult($this->_calculateFormulaValue($cell->getValue(), $cell->getCoordinate(), $cell)); + $result = self::unwrapResult($this->calculateFormulaValue($cell->getValue(), $cell->getCoordinate(), $cell)); $cellAddress = array_pop($this->cellStack); $this->spreadsheet->getSheetByName($cellAddress['sheet'])->getCell($cellAddress['cell']); } catch (\Exception $e) { @@ -3447,7 +3447,7 @@ public function calculateFormula($formula, $cellID = null, ?Cell $cell = null) // Execute the calculation try { - $result = self::unwrapResult($this->_calculateFormulaValue($formula, $cellID, $cell)); + $result = self::unwrapResult($this->calculateFormulaValue($formula, $cellID, $cell)); } catch (\Exception $e) { throw new Exception($e->getMessage()); } @@ -3500,7 +3500,7 @@ public function saveValueToCache($cellReference, $cellValue): void * * @return mixed */ - public function _calculateFormulaValue($formula, $cellID = null, ?Cell $cell = null) + public function calculateFormulaValue($formula, $cellID = null, ?Cell $cell = null) { $cellValue = null; @@ -5431,7 +5431,7 @@ private function evaluateDefinedName(Cell $cell, DefinedName $namedRange, Worksh $recursiveCalculator = new self($this->spreadsheet); $recursiveCalculator->getDebugLog()->setWriteDebugLog($this->getDebugLog()->getWriteDebugLog()); $recursiveCalculator->getDebugLog()->setEchoDebugLog($this->getDebugLog()->getEchoDebugLog()); - $result = $recursiveCalculator->_calculateFormulaValue($definedNameValue, $recursiveCalculationCellAddress, $recursiveCalculationCell); + $result = $recursiveCalculator->calculateFormulaValue($definedNameValue, $recursiveCalculationCellAddress, $recursiveCalculationCell); if ($this->getDebugLog()->getWriteDebugLog()) { $this->debugLog->mergeDebugLog(array_slice($recursiveCalculator->getDebugLog()->getLog(), 3)); diff --git a/src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php b/src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php index 3c8b176fba..69e68f7b60 100644 --- a/src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php +++ b/src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php @@ -142,7 +142,7 @@ private static function executeQuery(array $database, string $query, array $crit } // evaluate the criteria against the row data - $result = Calculation::getInstance()->_calculateFormulaValue('=' . $conditions); + $result = Calculation::getInstance()->calculateFormulaValue('=' . $conditions); // If the row failed to meet the criteria, remove it from the database if ($result !== true) { diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php b/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php index ee4885057f..237e516e73 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php @@ -79,7 +79,7 @@ private static function strSplit(string $roman): array * If an array of numbers is passed as the argument, then the returned result will also be an array * with the same dimensions */ - public static function evaluate($roman) + public static function toRoman($roman) { if (is_array($roman)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $roman); diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Roman.php b/src/PhpSpreadsheet/Calculation/MathTrig/Roman.php index 05415481c3..491e9aabc1 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Roman.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Roman.php @@ -825,7 +825,7 @@ public static function calculateRoman(int $aValue, int $style): string * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function evaluate($aValue, $style = 0) + public static function toArabic($aValue, $style = 0) { if (is_array($aValue) || is_array($style)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $aValue, $style); diff --git a/src/PhpSpreadsheet/Chart/DataSeriesValues.php b/src/PhpSpreadsheet/Chart/DataSeriesValues.php index 88063336bf..03ac979d47 100644 --- a/src/PhpSpreadsheet/Chart/DataSeriesValues.php +++ b/src/PhpSpreadsheet/Chart/DataSeriesValues.php @@ -357,7 +357,7 @@ public function refresh(Worksheet $worksheet, $flatten = true): void if ($this->dataSource !== null) { $calcEngine = Calculation::getInstance($worksheet->getParent()); $newDataValues = Calculation::unwrapResult( - $calcEngine->_calculateFormulaValue( + $calcEngine->calculateFormulaValue( '=' . $this->dataSource, null, $worksheet->getCell('A1') diff --git a/src/PhpSpreadsheet/Shared/StringHelper.php b/src/PhpSpreadsheet/Shared/StringHelper.php index 9970a21150..b0415f82d0 100644 --- a/src/PhpSpreadsheet/Shared/StringHelper.php +++ b/src/PhpSpreadsheet/Shared/StringHelper.php @@ -565,7 +565,7 @@ public static function convertToNumberIfFraction(&$operand) if (preg_match('/^' . self::STRING_REGEXP_FRACTION . '$/i', $operand, $match)) { $sign = ($match[1] == '-') ? '-' : '+'; $fractionFormula = '=' . $sign . $match[2] . $sign . $match[3]; - $operand = Calculation::getInstance()->_calculateFormulaValue($fractionFormula); + $operand = Calculation::getInstance()->calculateFormulaValue($fractionFormula); return true; } diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index ef8c398248..4f0b4d9068 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -40,7 +40,7 @@ protected function tearDown(): void */ public function testArrayFormula(string $formula, $expectedResult): void { - $result = Calculation::getInstance()->_calculateFormulaValue($formula); + $result = Calculation::getInstance()->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/CalculationErrorTest.php b/tests/PhpSpreadsheetTests/Calculation/CalculationErrorTest.php index 23ee5ba86b..a883cec290 100644 --- a/tests/PhpSpreadsheetTests/Calculation/CalculationErrorTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/CalculationErrorTest.php @@ -14,7 +14,7 @@ public function testCalculationException(): void $this->expectException(CalcException::class); $this->expectExceptionMessage('Formula Error:'); $calculation = Calculation::getInstance(); - $result = $calculation->_calculateFormulaValue('=SUM('); + $result = $calculation->calculateFormulaValue('=SUM('); self::assertFalse($result); } @@ -25,7 +25,7 @@ public function testCalculationError(): void $error = false; try { - $calculation->_calculateFormulaValue('=SUM('); + $calculation->calculateFormulaValue('=SUM('); } catch (Throwable $e) { self::assertSame("Formula Error: Expecting ')'", $e->getMessage()); self::assertSame('PHPUnit\\Framework\\Error\\Error', get_class($e)); @@ -47,7 +47,7 @@ public function testCalculationErrorTrulySuppressed(): void $calculation = Calculation::getInstance(); $calculation->suppressFormulaErrors = true; set_error_handler([self::class, 'errhandler2']); - $result = $calculation->_calculateFormulaValue('=SUM('); + $result = $calculation->calculateFormulaValue('=SUM('); restore_error_handler(); self::assertFalse($result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php b/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php index 6a03fa1d1e..d097144aa1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php @@ -45,11 +45,11 @@ protected function tearDown(): void public function testBinaryComparisonOperation($formula, $expectedResultExcel, $expectedResultOpenOffice): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); - $resultExcel = Calculation::getInstance()->_calculateFormulaValue($formula); + $resultExcel = Calculation::getInstance()->calculateFormulaValue($formula); self::assertEquals($expectedResultExcel, $resultExcel, 'should be Excel compatible'); Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $resultOpenOffice = Calculation::getInstance()->_calculateFormulaValue($formula); + $resultOpenOffice = Calculation::getInstance()->calculateFormulaValue($formula); self::assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible'); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php index 77af98ee49..55c5d723e2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php @@ -37,7 +37,7 @@ public function testDateDifArray(array $expectedResult, string $startDate, strin } else { $formula = "=DATEDIF({$startDate}, {$endDate}, {$methods})"; } - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php index 952664094c..d7d27980e7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php @@ -67,7 +67,7 @@ public function testDateArray(array $expectedResult, string $year, string $month $calculation = Calculation::getInstance(); $formula = "=DATE({$year}, {$month}, {$day})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } @@ -136,7 +136,7 @@ public function testDateArrayException(string $year, string $month, string $day) $this->expectExceptionMessage('Formulae with more than two array arguments are not supported'); $formula = "=DATE({$year}, {$month}, {$day})"; - $calculation->_calculateFormulaValue($formula); + $calculation->calculateFormulaValue($formula); } public function providerDateArrayException(): array diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php index 1a3790e872..7a4b53eb97 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php @@ -82,7 +82,7 @@ public function testDateValueArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=DATEVALUE({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php index 8f5e947b2f..03245b2605 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php @@ -52,7 +52,7 @@ public function testDayArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=DAY({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php index 554d51530d..9fee06cfb7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php @@ -38,7 +38,7 @@ public function testDays360Array(array $expectedResult, string $startDate, strin } else { $formula = "=DAYS360({$startDate}, {$endDate}, {$methods})"; } - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php index 236b5178d7..ec48e39b60 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php @@ -52,7 +52,7 @@ public function testDaysArray(array $expectedResult, string $startDate, string $ $calculation = Calculation::getInstance(); $formula = "=DAYS({$startDate}, {$endDate})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php index 5b8479cb04..cb3db69a27 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php @@ -56,7 +56,7 @@ public function testEDateArray(array $expectedResult, string $dateValues, string $calculation = Calculation::getInstance(); $formula = "=EDATE({$dateValues}, {$methods})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php index 935b3cbc2f..8bb9df5277 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php @@ -55,7 +55,7 @@ public function testEoMonthArray(array $expectedResult, string $dateValues, stri $calculation = Calculation::getInstance(); $formula = "=EOMONTH({$dateValues}, {$methods})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php index c94451164e..d1fda4f2e0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php @@ -33,7 +33,7 @@ public function testHourArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=HOUR({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php index 1704bd6dd1..a6615ff623 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php @@ -55,7 +55,7 @@ public function testIsoWeekNumArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ISOWEEKNUM({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php index bebc79ed29..b20ca78f91 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php @@ -33,7 +33,7 @@ public function testMinuteArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=MINUTE({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php index 904492864c..ae7133c8da 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php @@ -33,7 +33,7 @@ public function testMonthArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=MONTH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php index d5378b3527..562fb29abb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php @@ -64,7 +64,7 @@ public function testNetWorkDaysArray(array $expectedResult, string $startDate, s } else { $formula = "=NETWORKDAYS({$startDate}, {$endDays}, {$holidays})"; } - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php index c5b808f234..a2c2b850b1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php @@ -33,7 +33,7 @@ public function testSecondArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=SECOND({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php index 88271fea3b..4fc3a0d893 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php @@ -71,7 +71,7 @@ public function testTimeArray(array $expectedResult, string $hour, string $minut $calculation = Calculation::getInstance(); $formula = "=TIME({$hour}, {$minute}, {$second})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } @@ -140,7 +140,7 @@ public function testTimeArrayException(string $hour, string $minute, string $sec $this->expectExceptionMessage('Formulae with more than two array arguments are not supported'); $formula = "=TIME({$hour}, {$minute}, {$second})"; - $calculation->_calculateFormulaValue($formula); + $calculation->calculateFormulaValue($formula); } public function providerTimeArrayException(): array diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php index 0eb235f7cc..3f2f379e5c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php @@ -58,7 +58,7 @@ public function testTimeValueArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=TIMEVALUE({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php index e8d90f5f6a..0fc6898a17 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php @@ -42,7 +42,7 @@ public function testWeekDayArray(array $expectedResult, string $dateValues, stri $calculation = Calculation::getInstance(); $formula = "=WEEKDAY({$dateValues}, {$styles})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php index b2a067e950..65b00516e0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php @@ -53,7 +53,7 @@ public function testWeekNumArray(array $expectedResult, string $dateValues, stri $calculation = Calculation::getInstance(); $formula = "=WEEKNUM({$dateValues}, {$methods})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php index 3b73828ff5..8580dbd231 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php @@ -64,7 +64,7 @@ public function testWorkDayArray(array $expectedResult, string $startDate, strin } else { $formula = "=WORKDAY({$startDate}, {$endDays}, {$holidays})"; } - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php index 9c78fbbe3c..7b68710556 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php @@ -56,7 +56,7 @@ public function testYearFracArray(array $expectedResult, string $startDate, stri } else { $formula = "=YEARFRAC({$startDate}, {$endDate}, {$methods})"; } - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php index 3e320c2416..0a77423d0f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php @@ -33,7 +33,7 @@ public function testYearArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=YEAR({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php index 4652b56519..9f16832811 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php @@ -40,7 +40,7 @@ public function testBesselIArray(array $expectedResult, string $value, string $o $calculation = Calculation::getInstance(); $formula = "=BESSELI({$value}, {$ord})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php index 11f11ccb4b..0eff38f47c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php @@ -40,7 +40,7 @@ public function testBesselJArray(array $expectedResult, string $value, string $o $calculation = Calculation::getInstance(); $formula = "=BESSELJ({$value}, {$ord})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php index a7d45ef6e9..28c4bffa62 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php @@ -40,7 +40,7 @@ public function testBesselKArray(array $expectedResult, string $value, string $o $calculation = Calculation::getInstance(); $formula = "=BESSELK({$value}, {$ord})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php index 2f0a0ca68b..414ea306c5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php @@ -40,7 +40,7 @@ public function testBesselYArray(array $expectedResult, string $value, string $o $calculation = Calculation::getInstance(); $formula = "=BESSELY({$value}, {$ord})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2DecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2DecTest.php index beb31bbb40..78622fad56 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2DecTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2DecTest.php @@ -100,7 +100,7 @@ public function testBin2DecArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=BIN2DEC({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2HexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2HexTest.php index ccb2ce7930..8cf87fdf6c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2HexTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2HexTest.php @@ -100,7 +100,7 @@ public function testBin2HexArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=BIN2HEX({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2OctTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2OctTest.php index 513901a840..213269581c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2OctTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2OctTest.php @@ -100,7 +100,7 @@ public function testBin2OctArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=BIN2OCT({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitAndTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitAndTest.php index d5d8a26a90..3f4336feaf 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitAndTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitAndTest.php @@ -40,7 +40,7 @@ public function testBitAndArray(array $expectedResult, string $number1, string $ $calculation = Calculation::getInstance(); $formula = "=BITAND({$number1}, {$number2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitLShiftTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitLShiftTest.php index 246299ac35..568e81ac95 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitLShiftTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitLShiftTest.php @@ -40,7 +40,7 @@ public function testBitLShiftArray(array $expectedResult, string $number, string $calculation = Calculation::getInstance(); $formula = "=BITLSHIFT({$number}, {$bits})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitOrTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitOrTest.php index 6addf05da6..54b016405e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitOrTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitOrTest.php @@ -40,7 +40,7 @@ public function testBitOrArray(array $expectedResult, string $number1, string $n $calculation = Calculation::getInstance(); $formula = "=BITOR({$number1}, {$number2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitRShiftTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitRShiftTest.php index 5c6f76c718..c7b7dafa82 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitRShiftTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitRShiftTest.php @@ -40,7 +40,7 @@ public function testBitRShiftArray(array $expectedResult, string $number, string $calculation = Calculation::getInstance(); $formula = "=BITRSHIFT({$number}, {$bits})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitXorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitXorTest.php index ed8f2065cc..0666d1e49c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitXorTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitXorTest.php @@ -40,7 +40,7 @@ public function testBitXorArray(array $expectedResult, string $number1, string $ $calculation = Calculation::getInstance(); $formula = "=BITXOR({$number1}, {$number2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php index bbdab5e814..cc7e0fc000 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php @@ -40,7 +40,7 @@ public function testComplexArray(array $expectedResult, string $real, string $im $calculation = Calculation::getInstance(); $formula = "=COMPLEX({$real}, {$imaginary})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php index 679bcc8b3f..1313b3ef7a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php @@ -68,7 +68,7 @@ public function testConvertUoMArray(array $expectedResult, string $value, string $calculation = Calculation::getInstance(); $formula = "=CONVERT({$value}, {$fromUoM}, {$toUoM})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2BinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2BinTest.php index db4c517d08..bfbe0f57d5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2BinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2BinTest.php @@ -100,7 +100,7 @@ public function testDec2BinArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=DEC2BIN({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2HexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2HexTest.php index 6200ac567c..9c72889e0c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2HexTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2HexTest.php @@ -108,7 +108,7 @@ public function testDec2HexArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=DEC2HEX({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2OctTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2OctTest.php index 2e6007c5e7..4511a6d9ba 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2OctTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2OctTest.php @@ -100,7 +100,7 @@ public function testDec2OctArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=DEC2OCT({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php index c1c6b6f305..4ad4fcc8f5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php @@ -40,7 +40,7 @@ public function testDeltaArray(array $expectedResult, string $a, string $b): voi $calculation = Calculation::getInstance(); $formula = "=DELTA({$a}, {$b})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php index b79a2efa62..3f2b9bea47 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php @@ -42,7 +42,7 @@ public function testErfCArray(array $expectedResult, string $lower): void $calculation = Calculation::getInstance(); $formula = "=ERFC({$lower})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php index 411b462abe..7040f6275a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php @@ -42,7 +42,7 @@ public function testErfPreciseArray(array $expectedResult, string $limit): void $calculation = Calculation::getInstance(); $formula = "=ERF.PRECISE({$limit})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php index cdde57b017..c23debeba1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php @@ -43,7 +43,7 @@ public function testErfArray(array $expectedResult, string $lower, string $upper $calculation = Calculation::getInstance(); $formula = "=ERF({$lower}, {$upper})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php index 612133774d..4cd612b14a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php @@ -40,7 +40,7 @@ public function testGeStepArray(array $expectedResult, string $a, string $b): vo $calculation = Calculation::getInstance(); $formula = "=GESTEP({$a}, {$b})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2BinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2BinTest.php index f70d1943d9..ccce1b9d45 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2BinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2BinTest.php @@ -103,7 +103,7 @@ public function testHex2BinArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=HEX2BIN({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2DecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2DecTest.php index 2e4ceeabb2..c96990fb76 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2DecTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2DecTest.php @@ -103,7 +103,7 @@ public function testHex2DecArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=HEX2DEC({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2OctTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2OctTest.php index 449925dfb4..312485e33e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2OctTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2OctTest.php @@ -100,7 +100,7 @@ public function testHex2OctArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=HEX2OCT({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php index 884c311ea4..1ffd3a290f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php @@ -41,7 +41,7 @@ public function testImAbsArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMABS({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php index 14dc533a84..f6800875ad 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php @@ -41,7 +41,7 @@ public function testImArgumentArray(array $expectedResult, string $complex): voi $calculation = Calculation::getInstance(); $formula = "=IMARGUMENT({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php index 4dfa00eab6..58288c66c6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php @@ -51,7 +51,7 @@ public function testImConjugateArray(array $expectedResult, string $complex): vo $calculation = Calculation::getInstance(); $formula = "=IMCONJUGATE({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php index 69d9cd54d7..f55d9ea622 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php @@ -51,7 +51,7 @@ public function testImCosArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMCOS({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php index 5bd464fecb..00a2ce6738 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php @@ -51,7 +51,7 @@ public function testImCoshArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMCOSH({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php index 095a0ac283..6cb2dbfa1b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php @@ -51,7 +51,7 @@ public function testImCotArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMCOT({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php index 32f0e80358..51ca29204c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php @@ -51,7 +51,7 @@ public function testImCscArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMCSC({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); // Avoid testing for excess precision foreach ($expectedResult as &$array) { foreach ($array as &$string) { diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php index 4fbdf843a7..d4328b5f12 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php @@ -51,7 +51,7 @@ public function testImCschArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMCSCH({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php index 7e51a2491a..0cf46c6330 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php @@ -50,7 +50,7 @@ public function testImDivArray(array $expectedResult, string $dividend, string $ $calculation = Calculation::getInstance(); $formula = "=IMDIV({$dividend}, {$divisor})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php index f717725a5b..5eb92b8cab 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php @@ -51,7 +51,7 @@ public function testImExpArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMEXP({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php index fe55645488..806432cd77 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php @@ -51,7 +51,7 @@ public function testImLnArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMLN({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php index 206c1e6d65..f22a025335 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php @@ -51,7 +51,7 @@ public function testImLog10Array(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMLOG10({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php index 58e94c9b68..69c398ff02 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php @@ -51,7 +51,7 @@ public function testImLog2Array(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMLOG2({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php index cb841ba891..fa5f7aff9a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php @@ -50,7 +50,7 @@ public function testImPowerArray(array $expectedResult, string $complex, string $calculation = Calculation::getInstance(); $formula = "=IMPOWER({$complex}, {$real})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php index e88c73575b..121dd61dee 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php @@ -41,7 +41,7 @@ public function testImRealArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMREAL({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php index 8ad7c6ba31..6da1bbec1c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php @@ -51,7 +51,7 @@ public function testImSecArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMSEC({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php index 6c214a346b..30eeacee0d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php @@ -51,7 +51,7 @@ public function testImSecHArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMSECH({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php index 4e7881ba57..78335c95fa 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php @@ -51,7 +51,7 @@ public function testImSinArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMSIN({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php index 7d5c86ec7a..da5ff29c00 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php @@ -51,7 +51,7 @@ public function testImSinHArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMSINH({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php index 9b53ed5476..2fea7106f5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php @@ -51,7 +51,7 @@ public function testImSqrtArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMSQRT({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php index b85519eca9..d2e9224368 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php @@ -50,7 +50,7 @@ public function testImSubArray(array $expectedResult, string $subidend, string $ $calculation = Calculation::getInstance(); $formula = "=IMSUB({$subidend}, {$subisor})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php index 895211e5fe..65bc54ae72 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php @@ -51,7 +51,7 @@ public function testImTanArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMTAN({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php index abf919d264..2d3e5d3a42 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php @@ -41,7 +41,7 @@ public function testImaginaryArray(array $expectedResult, string $complex): void $calculation = Calculation::getInstance(); $formula = "=IMAGINARY({$complex})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2BinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2BinTest.php index 39c8c1d97c..769f7d8db1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2BinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2BinTest.php @@ -100,7 +100,7 @@ public function testOct2BinArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=OCT2BIN({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2DecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2DecTest.php index e814e76df7..06f3efe224 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2DecTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2DecTest.php @@ -100,7 +100,7 @@ public function testOct2DecArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=OCT2DEC({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2HexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2HexTest.php index 0f38752f75..0ac32f8a8d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2HexTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2HexTest.php @@ -100,7 +100,7 @@ public function testOct2HexArray(array $expectedResult, string $value): void $calculation = Calculation::getInstance(); $formula = "=OCT2HEX({$value})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DollarDeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DollarDeTest.php index c92bf800e0..d7553a885d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DollarDeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DollarDeTest.php @@ -38,7 +38,7 @@ public function testDollarDeArray(array $expectedResult, string $argument1, stri $calculation = Calculation::getInstance(); $formula = "=DollarDe({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/ErrorTypeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/ErrorTypeTest.php index 686bbd5178..3158df869c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/ErrorTypeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/ErrorTypeTest.php @@ -39,7 +39,7 @@ public function testErrorTypeArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ERROR.TYPE({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsBlankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsBlankTest.php index 41dc4df774..c422c1283d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsBlankTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsBlankTest.php @@ -38,7 +38,7 @@ public function testIsBlankArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISBLANK({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrTest.php index d685be5391..e7bcbcb270 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrTest.php @@ -38,7 +38,7 @@ public function testIsErrArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISERR({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrorTest.php index 4ff0a43b32..8a6d20f601 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrorTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsErrorTest.php @@ -38,7 +38,7 @@ public function testIsErrorArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISERROR({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsEvenTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsEvenTest.php index 704cc2b22d..dd2bafa323 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsEvenTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsEvenTest.php @@ -40,7 +40,7 @@ public function testIsEvenArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISEVEN({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsFormulaTest.php index 03e9bb70d0..892c87cddc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsFormulaTest.php @@ -106,7 +106,7 @@ public function testIsFormulaArray(): void $calculation = Calculation::getInstance($spreadsheet); $formula = '=ISFORMULA(A1:A7)'; - $result = $calculation->_calculateFormulaValue($formula, 'C1', $sheet->getCell('C1')); + $result = $calculation->calculateFormulaValue($formula, 'C1', $sheet->getCell('C1')); self::assertEquals([true, false, true, false, true, false, false], $result); $spreadsheet->disconnectWorksheets(); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsLogicalTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsLogicalTest.php index 57a690e1a2..44434fe426 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsLogicalTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsLogicalTest.php @@ -38,7 +38,7 @@ public function testIsLogicalArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISLOGICAL({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNaTest.php index 6f9bdc4de0..08e1595388 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNaTest.php @@ -38,7 +38,7 @@ public function testIsNaArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISNA({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNonTextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNonTextTest.php index 876f78a116..31d1509a6b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNonTextTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNonTextTest.php @@ -38,7 +38,7 @@ public function testIsNonTextArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISNONTEXT({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNumberTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNumberTest.php index 3fb8cc64da..1f2781bab6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNumberTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsNumberTest.php @@ -38,7 +38,7 @@ public function testIsNumberArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISNUMBER({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsOddTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsOddTest.php index 0031d4cdd7..9629d591e9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsOddTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsOddTest.php @@ -40,7 +40,7 @@ public function testIsOddArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISODD({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsTextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsTextTest.php index 614bf2f896..51078061ba 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsTextTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Information/IsTextTest.php @@ -38,7 +38,7 @@ public function testIsTextArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=ISTEXT({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfErrorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfErrorTest.php index 8a0793c46e..c110fdcf7a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfErrorTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfErrorTest.php @@ -40,7 +40,7 @@ public function testIfErrorArray(array $expectedResult, string $argument1, strin $calculation = Calculation::getInstance(); $formula = "=IFERROR({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfNaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfNaTest.php index 84a178162a..3daabc6233 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfNaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfNaTest.php @@ -40,7 +40,7 @@ public function testIfNaArray(array $expectedResult, string $argument1, string $ $calculation = Calculation::getInstance(); $formula = "=IFNA({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/NotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/NotTest.php index 734536b05e..92445b88ae 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/NotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/NotTest.php @@ -36,7 +36,7 @@ public function testNotArray(array $expectedResult, string $argument1): void $calculation = Calculation::getInstance(); $formula = "=NOT({$argument1})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/AddressTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/AddressTest.php index 37437a68b7..a9c45aa5f6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/AddressTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/AddressTest.php @@ -38,7 +38,7 @@ public function testAddressArray(array $expectedResult, string $argument1, strin $calculation = Calculation::getInstance(); $formula = "=ADDRESS({$argument1}, {$argument2}, 4)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ChooseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ChooseTest.php index bd59d19956..891e2e7d42 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ChooseTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ChooseTest.php @@ -39,7 +39,7 @@ public function testChooseArray(array $expectedResult, string $values, array $se $selections = implode(',', $selections); $formula = "=CHOOSE({$values}, {$selections})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php index d7d099d288..fdfe1db5f1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php @@ -38,7 +38,7 @@ public function testColumnsArray(int $expectedResult, string $argument): void $calculation = Calculation::getInstance(); $formula = "=COLUMNS({$argument})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php index bfe7e38871..6570378e44 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php @@ -99,7 +99,7 @@ public function testHLookupArray(array $expectedResult, string $values, string $ $calculation = Calculation::getInstance(); $formula = "=HLOOKUP({$values}, {$database}, {$index}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php index 2323347913..f999f8de93 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php @@ -38,7 +38,7 @@ public function testIndexArray(array $expectedResult, string $matrix, string $ro $calculation = Calculation::getInstance(); $formula = "=INDEX({$matrix}, {$rows}, {$columns})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php index 4df1277ceb..dadaab1ae6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php @@ -38,7 +38,7 @@ public function testLookupArray(array $expectedResult, string $values, string $l $calculation = Calculation::getInstance(); $formula = "=LOOKUP({$values}, {$lookup}, {$return})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php index ed4f4b022a..02cee62a23 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php @@ -38,7 +38,7 @@ public function testMatchArray(array $expectedResult, string $values, string $se $calculation = Calculation::getInstance(); $formula = "=MATCH({$values}, {$selections}, 0)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php index 6468c17b9f..3c0c7e6ae8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php @@ -38,7 +38,7 @@ public function testRowsArray(int $expectedResult, string $argument): void $calculation = Calculation::getInstance(); $formula = "=ROWS({$argument})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php index 494462c756..d03d479039 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/VLookupTest.php @@ -38,7 +38,7 @@ public function testVLookupArray(array $expectedResult, string $values, string $ $calculation = Calculation::getInstance(); $formula = "=VLOOKUP({$values}, {$database}, {$index}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php index 23e0ae35cc..9376f1ca9b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AbsTest.php @@ -39,7 +39,7 @@ public function testAbsoluteArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ABS({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php index ebdc9130e5..bf6c107f32 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php @@ -34,7 +34,7 @@ public function testAcosArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ACOS({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php index f9ee3ef49f..cc5f8011ea 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php @@ -34,7 +34,7 @@ public function testAcoshArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ACOSH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php index 9f63ac9d13..f22f333d80 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php @@ -38,7 +38,7 @@ public function testAcotArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ACOT({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php index 8e2555e0a6..e6784f4745 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php @@ -38,7 +38,7 @@ public function testAcothArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ACOTH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php index 57f2717f4c..d1c1fb26a1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php @@ -35,7 +35,7 @@ public function testArabicArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ARABIC({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php index 87a6da394f..2368a11bfa 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php @@ -34,7 +34,7 @@ public function testAsinArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ASIN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php index c6fb5f3266..7ec5817e31 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php @@ -34,7 +34,7 @@ public function testAsinhArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ASINH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php index 2ff47b3b89..67cc04bada 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php @@ -35,7 +35,7 @@ public function testAtan2Array(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=ATAN2({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php index d79c8576ce..3a7eb8c709 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php @@ -34,7 +34,7 @@ public function testAtanArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ATAN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php index dad09ba2e7..a06dd3a671 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php @@ -34,7 +34,7 @@ public function testAtanhArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ATANH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php index ab863492e1..d6fcd7e166 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php @@ -53,7 +53,7 @@ public function testBaseArray(array $expectedResult, string $argument1, string $ $calculation = Calculation::getInstance(); $formula = "=BASE({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingMathTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingMathTest.php index aec3bd5546..d0a2f7a48a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingMathTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingMathTest.php @@ -38,7 +38,7 @@ public function testCeilingArray(array $expectedResult, string $argument1, strin $calculation = Calculation::getInstance(); $formula = "=CEILING.MATH({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingPreciseTest.php index 4fe50b7ff1..7c680279db 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingPreciseTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingPreciseTest.php @@ -38,7 +38,7 @@ public function testCeilingArray(array $expectedResult, string $argument1, strin $calculation = Calculation::getInstance(); $formula = "=CEILING.PRECISE({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php index 5adba7de2e..238d098e73 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php @@ -65,7 +65,7 @@ public function testCeilingArray(array $expectedResult, string $argument1, strin $calculation = Calculation::getInstance(); $formula = "=CEILING({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php index 7c2200a002..8f4dada3e8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php @@ -41,7 +41,7 @@ public function testCombinAArray(array $expectedResult, string $argument1, strin $calculation = Calculation::getInstance(); $formula = "=COMBINA({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php index 18e3eed6c4..203c9374a2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php @@ -41,7 +41,7 @@ public function testCombinArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=COMBIN({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php index 5b51fb0fef..54237e6699 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php @@ -34,7 +34,7 @@ public function testCosArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=COS({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php index f4135cc2a8..001f1bf128 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php @@ -34,7 +34,7 @@ public function testCoshArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=COSH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php index d2d1c4e2a4..25ad5e7bf8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php @@ -38,7 +38,7 @@ public function testCotArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=COT({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php index ec203a7801..52d0a5b403 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php @@ -38,7 +38,7 @@ public function testCothArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=COTH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php index 73ff086ee9..36d8c0bad4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php @@ -38,7 +38,7 @@ public function testCscArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=CSC({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php index 8ffb408ac3..099d40c5eb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php @@ -38,7 +38,7 @@ public function testCschArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=CSCH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php index 20d52853fc..f7f710b559 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php @@ -39,7 +39,7 @@ public function testDegreesArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=DEGREES({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php index 1dab09f273..465b67b69b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php @@ -34,7 +34,7 @@ public function testEvenArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=EVEN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php index 07014bd453..eb0be95278 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php @@ -41,7 +41,7 @@ public function testExpArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=EXP({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php index 34c9225151..a591bd6421 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php @@ -35,7 +35,7 @@ public function testFactDoubleArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=FACTDOUBLE({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php index 328773e080..03f1af9fa9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php @@ -69,7 +69,7 @@ public function testFactArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=FACT({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorMathTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorMathTest.php index 1bd37b8971..a8c89dd9de 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorMathTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorMathTest.php @@ -38,7 +38,7 @@ public function testFloorArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=FLOOR.MATH({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorPreciseTest.php index 247f989ad1..fa87cea324 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorPreciseTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorPreciseTest.php @@ -38,7 +38,7 @@ public function testFloorArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=FLOOR.PRECISE({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php index 135f1180a9..b96eaba0ed 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php @@ -65,7 +65,7 @@ public function testFloorArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=FLOOR({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php index 42a24af51e..60b24689b4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php @@ -38,7 +38,7 @@ public function testIntArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=INT({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LnTest.php index b300526a77..94e5889c81 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LnTest.php @@ -41,7 +41,7 @@ public function testLnArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=LN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Log10Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Log10Test.php index d78e589aea..639e2b49ec 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Log10Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Log10Test.php @@ -41,7 +41,7 @@ public function testLog10Array(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=LOG10({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LogTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LogTest.php index e05f245b27..5ec0aade99 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LogTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LogTest.php @@ -47,7 +47,7 @@ public function testLogArray(array $expectedResult, string $argument1, string $a $calculation = Calculation::getInstance(); $formula = "=LOG({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php index b9e48b90ee..64598fadd9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php @@ -38,7 +38,7 @@ public function testMRoundArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=MROUND({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php index 029f8392cd..bb8b538b4a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php @@ -47,7 +47,7 @@ public function testModArray(array $expectedResult, string $argument1, string $a $calculation = Calculation::getInstance(); $formula = "=MOD({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php index 8ef0e0f34b..e4384eb9a8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php @@ -34,7 +34,7 @@ public function testOddArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=ODD({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php index c9e35a3e78..5b3be52571 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php @@ -47,7 +47,7 @@ public function testPowerArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=POWER({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php index 1019b35f08..6efb187bb2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php @@ -47,7 +47,7 @@ public function testQuotientArray(array $expectedResult, string $argument1, stri $calculation = Calculation::getInstance(); $formula = "=QUOTIENT({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php index 5468528fbc..4d63fbfa75 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php @@ -39,7 +39,7 @@ public function testRadiansArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=RADIANS({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandBetweenTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandBetweenTest.php index 99cc1fa892..48ba4b1abe 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandBetweenTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandBetweenTest.php @@ -58,7 +58,7 @@ public function testRandBetweenArray( $calculation = Calculation::getInstance(); $formula = "=RandBetween({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertIsArray($result); self::assertCount($expectedRows, $result); self::assertIsArray($result[0]); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php index dbde63d189..f2bb3b1fb8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php @@ -35,7 +35,7 @@ public function testRomanArray(array $expectedResult, string $values, string $st $calculation = Calculation::getInstance(); $formula = "=ROMAN({$values}, {$styles})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php index 76ad3015c7..641a9fad0c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php @@ -38,7 +38,7 @@ public function testRoundDownArray(array $expectedResult, string $argument1, str $calculation = Calculation::getInstance(); $formula = "=ROUNDDOWN({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php index 710d5b0051..0a56ebb053 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php @@ -38,7 +38,7 @@ public function testRoundArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=ROUND({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php index d204a1fb83..4c28a0699f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php @@ -38,7 +38,7 @@ public function testRoundUpArray(array $expectedResult, string $argument1, strin $calculation = Calculation::getInstance(); $formula = "=ROUNDUP({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php index c7af031da2..4364d09941 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php @@ -38,7 +38,7 @@ public function testSecArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=SEC({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php index 402adf309e..8c63b3496b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php @@ -38,7 +38,7 @@ public function testSechArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=SECH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SeriesSumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SeriesSumTest.php index 04ef6ec307..89fa4cb995 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SeriesSumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SeriesSumTest.php @@ -53,7 +53,7 @@ public function testSeriesSumArray(array $expectedResult, string $x, string $n, $calculation = Calculation::getInstance(); $formula = "=SERIESSUM({$x}, {$n}, {$m}, {$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php index bef03503d9..a4d67e91ad 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php @@ -37,7 +37,7 @@ public function testSignArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=SIGN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php index ce7b29c39a..0369b9060f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php @@ -34,7 +34,7 @@ public function testSinArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=SIN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php index 1f64d18205..69046c3882 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php @@ -34,7 +34,7 @@ public function testSinhArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=SINH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php index 1eac23299f..2da7802b3f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php @@ -41,7 +41,7 @@ public function testSqrtPiArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=SQRTPI({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php index 1068afc880..94ce5a5303 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php @@ -39,7 +39,7 @@ public function testSqrtArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=SQRT({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php index 75993f620b..ae1aa78c62 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php @@ -34,7 +34,7 @@ public function testTanArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=TAN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php index b75a0457b8..91316bcefc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php @@ -34,7 +34,7 @@ public function testTanhArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=TANH({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TruncTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TruncTest.php index e1cb6ea5bb..5ee5cbdc56 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TruncTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TruncTest.php @@ -38,7 +38,7 @@ public function testTruncArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=TRUNC({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php index 6947ac78c6..714f04ccc4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaDistTest.php @@ -38,7 +38,7 @@ public function testBetaDistArray(array $expectedResult, string $argument1, stri $calculation = Calculation::getInstance(); $formula = "=BETADIST({$argument1}, {$argument2}, {$argument3})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php index 7d5426e853..50a93269a0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BetaInvTest.php @@ -38,7 +38,7 @@ public function testBetaInvArray(array $expectedResult, string $argument1, strin $calculation = Calculation::getInstance(); $formula = "=BETAINV({$argument1}, {$argument2}, {$argument3})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php index d9da3827fc..7cb5f552c5 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistRangeTest.php @@ -42,7 +42,7 @@ public function testBinomDistRangeArray( $calculation = Calculation::getInstance(); $formula = "=BINOM.DIST.RANGE({$trials}, {$probabilities}, {$successes})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php index a86a500075..e9672a148e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomDistTest.php @@ -42,7 +42,7 @@ public function testBinomDistArray( $calculation = Calculation::getInstance(); $formula = "=BINOMDIST({$values}, {$trials}, {$probabilities}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php index 3d2c22f13c..af5e2ad17c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/BinomInvTest.php @@ -42,7 +42,7 @@ public function testBinomInvArray( $calculation = Calculation::getInstance(); $formula = "=BINOM.INV({$trials}, {$probabilities}, {$alphas})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php index c2d2721a16..eeadf0f029 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistLeftTailTest.php @@ -38,7 +38,7 @@ public function testChiDistLeftTailArray(array $expectedResult, string $values, $calculation = Calculation::getInstance(); $formula = "=CHISQ.DIST({$values}, {$degrees}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php index 2e9a57d9d0..6e30566832 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiDistRightTailTest.php @@ -38,7 +38,7 @@ public function testChiDistRightTailArray(array $expectedResult, string $values, $calculation = Calculation::getInstance(); $formula = "=CHISQ.DIST.RT({$values}, {$degrees})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php index a7f96d3d50..c499fb0b56 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvLeftTailTest.php @@ -44,7 +44,7 @@ public function testChiInvLeftTailArray(array $expectedResult, string $probabili $calculation = Calculation::getInstance(); $formula = "=CHISQ.INV({$probabilities}, {$degrees})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php index 818059b60c..c1727b10f7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ChiInvRightTailTest.php @@ -44,7 +44,7 @@ public function testChiInvRightTailArray(array $expectedResult, string $probabil $calculation = Calculation::getInstance(); $formula = "=CHISQ.INV.RT({$probabilities}, {$degrees})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php index 6ed59dd1fc..6c20910261 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php @@ -38,7 +38,7 @@ public function testConfidenceArray(array $expectedResult, string $alpha, string $calculation = Calculation::getInstance(); $formula = "=CONFIDENCE({$alpha}, {$stdDev}, {$size})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php index 8c5e700ad4..d4d25528b6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ExponDistTest.php @@ -38,7 +38,7 @@ public function testExponDistArray(array $expectedResult, string $values, string $calculation = Calculation::getInstance(); $formula = "=EXPONDIST({$values}, {$lambdas}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php index 2569d3aea3..0fcd82c5aa 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FDistTest.php @@ -32,7 +32,7 @@ public function testFDistArray(array $expectedResult, string $values, string $u, $calculation = Calculation::getInstance(); $formula = "=F.DIST({$values}, {$u}, {$v}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php index 4ddd59a308..f2b6777d04 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherInvTest.php @@ -39,7 +39,7 @@ public function testFisherArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=FISHERINV({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php index b61420509e..06550e00f4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/FisherTest.php @@ -39,7 +39,7 @@ public function testFisherArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=FISHER({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php index 62030b01be..9d17fb06ed 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php @@ -38,7 +38,7 @@ public function testForecastArray(array $expectedResult, string $testValues, str $calculation = Calculation::getInstance(); $formula = "=FORECAST({$testValues}, {$yValues}, {$xValues})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php index 65ec99e309..7bba70b7bc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaDistTest.php @@ -38,7 +38,7 @@ public function testGammaDistArray(array $expectedResult, string $values, string $calculation = Calculation::getInstance(); $formula = "=GAMMA.DIST({$values}, {$alpha}, {$beta}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php index 9f86829e18..bc0b54c63a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaInvTest.php @@ -38,7 +38,7 @@ public function testGammaInvArray(array $expectedResult, string $values, string $calculation = Calculation::getInstance(); $formula = "=GAMMA.INV({$values}, {$alpha}, {$beta})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php index 4f0f918ba6..5d22c60dba 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaLnTest.php @@ -39,7 +39,7 @@ public function testGammaLnArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=GAMMALN({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php index 5aa58687ae..aa5ca819d1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GammaTest.php @@ -33,7 +33,7 @@ public function testGammaArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=GAMMA({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php index 0616d3f0e7..57333c771b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GaussTest.php @@ -33,7 +33,7 @@ public function testGaussArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=GAUSS({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php index fe43338dcd..6491fed255 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/HypGeomDistTest.php @@ -37,7 +37,7 @@ public function testHypGeomDistArray( $calculation = Calculation::getInstance(); $formula = "=HYPGEOMDIST({$sampleSuccesses}, {$sampleNumber}, {$populationSuccesses}, {$populationNumber})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php index 69fb3c0539..ccefac8903 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogInvTest.php @@ -32,7 +32,7 @@ public function testLogInvArray(array $expectedResult, string $probabilities, st $calculation = Calculation::getInstance(); $formula = "=LOGINV({$probabilities}, {$mean}, {$stdDev})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php index 25c1a50fed..d7a97819b1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDist2Test.php @@ -32,7 +32,7 @@ public function testLogNormDist2Array(array $expectedResult, string $values, str $calculation = Calculation::getInstance(); $formula = "=LOGNORM.DIST({$values}, {$mean}, {$stdDev}, true)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php index fc3b4f14bb..45e8d8eea9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogNormDistTest.php @@ -32,7 +32,7 @@ public function testLogNormDistArray(array $expectedResult, string $values, stri $calculation = Calculation::getInstance(); $formula = "=LOGNORMDIST({$values}, {$mean}, {$stdDev})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php index b32f9cd92e..725b2abb84 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NegBinomDistTest.php @@ -42,7 +42,7 @@ public function testNegBinomDistArray( $calculation = Calculation::getInstance(); $formula = "=NEGBINOMDIST({$failures}, {$successes}, {$probabilities})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php index f6c41665af..1bb0777e06 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormDistTest.php @@ -32,7 +32,7 @@ public function testNormDistArray(array $expectedResult, string $values, string $calculation = Calculation::getInstance(); $formula = "=NORMDIST({$values}, {$mean}, {$stdDev}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php index dbd6f6889d..137f992472 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormInvTest.php @@ -32,7 +32,7 @@ public function testNormInvArray(array $expectedResult, string $probabilities, s $calculation = Calculation::getInstance(); $formula = "=NORMINV({$probabilities}, {$mean}, {$stdDev})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDist2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDist2Test.php index 296f483405..e5be7ecf6a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDist2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDist2Test.php @@ -32,7 +32,7 @@ public function testNormSDist2Array(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=NORM.S.DIST({$values}, true)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDistTest.php index bc670a83bd..37708b21f8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSDistTest.php @@ -33,7 +33,7 @@ public function testNormSDistArray(array $expectedResult, string $values): void $calculation = Calculation::getInstance(); $formula = "=NORMSDIST({$values})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSInvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSInvTest.php index bff1e40e54..55c79b7df9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSInvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/NormSInvTest.php @@ -33,7 +33,7 @@ public function testNormSInvArray(array $expectedResult, string $probabilities): $calculation = Calculation::getInstance(); $formula = "=NORMSINV({$probabilities})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php index af68bf806a..eda12cbcfc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php @@ -38,7 +38,7 @@ public function testPermutArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=PERMUT({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php index e1c8835e26..acbcf1a85a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php @@ -38,7 +38,7 @@ public function testPermutationAArray(array $expectedResult, string $argument1, $calculation = Calculation::getInstance(); $formula = "=PERMUTATIONA({$argument1},{$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PoissonTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PoissonTest.php index 7355c195a6..a187710059 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PoissonTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PoissonTest.php @@ -38,7 +38,7 @@ public function testPoissonArray(array $expectedResult, string $values, string $ $calculation = Calculation::getInstance(); $formula = "=POISSON({$values}, {$mean}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php index 9214e6e941..ed97d2aaa4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StandardizeTest.php @@ -32,7 +32,7 @@ public function testStandardizeArray(array $expectedResult, string $argument1, s $calculation = Calculation::getInstance(); $formula = "=STANDARDIZE({$argument1}, {$argument2}, {$argument3})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TDistTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TDistTest.php index 065a9cccf4..3ff41a3a9c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TDistTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TDistTest.php @@ -35,7 +35,7 @@ public function testTDistArray(array $expectedResult, string $values, string $de $calculation = Calculation::getInstance(); $formula = "=TDIST({$values}, {$degrees}, {$tails})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TinvTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TinvTest.php index e60395932f..8c6e330de6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TinvTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TinvTest.php @@ -34,7 +34,7 @@ public function testTInvArray(array $expectedResult, string $values, string $deg $calculation = Calculation::getInstance(); $formula = "=TINV({$values}, {$degrees})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/WeibullTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/WeibullTest.php index 8e26e1f00f..43d807e442 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/WeibullTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/WeibullTest.php @@ -36,7 +36,7 @@ public function testWeibullArray(array $expectedResult, string $values, string $ $calculation = Calculation::getInstance(); $formula = "=WEIBULL({$values}, {$alpha}, {$beta}, false)"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ZTestTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ZTestTest.php index 446bdc98ba..b3a50e8ec0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ZTestTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ZTestTest.php @@ -35,7 +35,7 @@ public function testZTestArray(array $expectedResult, string $dataSet, string $m $calculation = Calculation::getInstance(); $formula = "=ZTEST({$dataSet}, {$m0})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CharTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CharTest.php index 5cdca68518..6bd104e606 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CharTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CharTest.php @@ -39,7 +39,7 @@ public function testCharArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=CHAR({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CleanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CleanTest.php index 4297d580c9..b17b39613f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CleanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CleanTest.php @@ -39,7 +39,7 @@ public function testCleanArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=CLEAN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CodeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CodeTest.php index 5075ad575a..44c9e9f017 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CodeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/CodeTest.php @@ -39,7 +39,7 @@ public function testCodeArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=CODE({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/DollarTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/DollarTest.php index e2b415dd31..529ba82e1b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/DollarTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/DollarTest.php @@ -44,7 +44,7 @@ public function testDollarArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=DOLLAR({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ExactTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ExactTest.php index fed029eb5b..c18ceb5270 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ExactTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ExactTest.php @@ -44,7 +44,7 @@ public function testExactArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=EXACT({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/FindTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/FindTest.php index 27ed3762e8..2e260175ad 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/FindTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/FindTest.php @@ -50,7 +50,7 @@ public function testFindArray(array $expectedResult, string $argument1, string $ $calculation = Calculation::getInstance(); $formula = "=FIND({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/FixedTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/FixedTest.php index 6c857956bd..62151009ef 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/FixedTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/FixedTest.php @@ -50,7 +50,7 @@ public function testFixedArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=FIXED({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LeftTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LeftTest.php index 7f709d64dc..81c092c8fd 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LeftTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LeftTest.php @@ -190,7 +190,7 @@ public function testLeftArray(array $expectedResult, string $argument1, string $ $calculation = Calculation::getInstance(); $formula = "=LEFT({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LenTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LenTest.php index 68f804d8e2..c2bf488b8e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LenTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LenTest.php @@ -39,7 +39,7 @@ public function testLenArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=LEN({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LowerTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LowerTest.php index 3b1918436d..e5f80e7fdc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LowerTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/LowerTest.php @@ -74,7 +74,7 @@ public function testLowerArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=LOWER({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/MidTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/MidTest.php index e4ff934302..830c6fe456 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/MidTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/MidTest.php @@ -212,7 +212,7 @@ public function testMidArray(array $expectedResult, string $argument1, string $a $calculation = Calculation::getInstance(); $formula = "=MID({$argument1}, {$argument2}, {$argument3})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/NumberValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/NumberValueTest.php index a100695f6f..f53c56cfae 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/NumberValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/NumberValueTest.php @@ -50,7 +50,7 @@ public function testNumberValueArray(array $expectedResult, string $argument1, s $calculation = Calculation::getInstance(); $formula = "=NumberValue({$argument1}, {$argument2}, {$argument3})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ProperTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ProperTest.php index d5e86c12a1..f34f76c042 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ProperTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ProperTest.php @@ -74,7 +74,7 @@ public function testProperArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=PROPER({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ReplaceTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ReplaceTest.php index c64c4fe18e..9c4cd81554 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ReplaceTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ReplaceTest.php @@ -62,7 +62,7 @@ public function testReplaceArray( $calculation = Calculation::getInstance(); $formula = "=REPLACE({$oldText}, {$start}, {$chars}, {$newText})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ReptTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ReptTest.php index a36324e115..c8d3ffba3d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ReptTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ReptTest.php @@ -44,7 +44,7 @@ public function testReptArray(array $expectedResult, string $argument1, string $ $calculation = Calculation::getInstance(); $formula = "=REPT({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/RightTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/RightTest.php index d8de3e42af..b386acb980 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/RightTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/RightTest.php @@ -190,7 +190,7 @@ public function testRightArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=RIGHT({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SearchTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SearchTest.php index 1cd5dccc56..2157c0e48f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SearchTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SearchTest.php @@ -50,7 +50,7 @@ public function testSearchArray(array $expectedResult, string $argument1, string $calculation = Calculation::getInstance(); $formula = "=SEARCH({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SubstituteTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SubstituteTest.php index dfb1e95233..31a427754b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SubstituteTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SubstituteTest.php @@ -57,7 +57,7 @@ public function testSubstituteArray(array $expectedResult, string $oldText, stri $calculation = Calculation::getInstance(); $formula = "=SUBSTITUTE({$oldText}, {$fromText}, {$toText})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TTest.php index a157d7fdfc..b95b75745d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TTest.php @@ -33,7 +33,7 @@ public function testTArray(array $expectedResult, string $argument): void $calculation = Calculation::getInstance(); $formula = "=T({$argument})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextJoinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextJoinTest.php index 8583433352..d08eea36b8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextJoinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextJoinTest.php @@ -43,7 +43,7 @@ public function testTextjoinArray(array $expectedResult, string $delimiter, stri $calculation = Calculation::getInstance(); $formula = "=TEXTJOIN({$delimiter}, {$blanks}, {$texts})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextTest.php index 38ad410f0b..effba0664a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextTest.php @@ -44,7 +44,7 @@ public function testTextArray(array $expectedResult, string $argument1, string $ $calculation = Calculation::getInstance(); $formula = "=TEXT({$argument1}, {$argument2})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TrimTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TrimTest.php index c9fe4d8124..df98447f1c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TrimTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TrimTest.php @@ -39,7 +39,7 @@ public function testTrimArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=TRIM({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php index da089ca78f..7382975c90 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php @@ -74,7 +74,7 @@ public function testUpperArray(array $expectedResult, string $array): void $calculation = Calculation::getInstance(); $formula = "=UPPER({$array})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ValueTest.php index cc7b362317..a67b95a5ae 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ValueTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ValueTest.php @@ -75,7 +75,7 @@ public function testValueArray(array $expectedResult, string $argument): void $calculation = Calculation::getInstance(); $formula = "=VALUE({$argument})"; - $result = $calculation->_calculateFormulaValue($formula); + $result = $calculation->calculateFormulaValue($formula); self::assertEqualsWithDelta($expectedResult, $result, 1.0e-14); } diff --git a/tests/PhpSpreadsheetTests/Calculation/TranslationTest.php b/tests/PhpSpreadsheetTests/Calculation/TranslationTest.php index e2384460b5..f4a6c51552 100644 --- a/tests/PhpSpreadsheetTests/Calculation/TranslationTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/TranslationTest.php @@ -43,10 +43,10 @@ public function testTranslation(string $expectedResult, string $locale, string $ self::markTestSkipped("Unable to set locale to {$locale}"); } - $translatedFormula = Calculation::getInstance()->_translateFormulaToLocale($formula); + $translatedFormula = Calculation::getInstance()->translateFormulaToLocale($formula); self::assertSame($expectedResult, $translatedFormula); - $restoredFormula = Calculation::getInstance()->_translateFormulaToEnglish($translatedFormula); + $restoredFormula = Calculation::getInstance()->translateFormulaToEnglish($translatedFormula); self::assertSame($formula, $restoredFormula); } From 78ea02a53a90941490821144d1fa288496b6bb59 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 11 May 2022 20:41:56 +0200 Subject: [PATCH 71/94] Update phpstan baseline --- phpstan-baseline.neon | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6fd7657193..116baa5e12 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -295,21 +295,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Engineering/ErfC.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:ISPMT\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Financial.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:ISPMT\\(\\) has parameter \\$args with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Financial.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:NPV\\(\\) has parameter \\$args with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Financial.php - - message: "#^Parameter \\#1 \\$year of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:isLeapYear\\(\\) expects int\\|string, array\\|int\\|string given\\.$#" count: 1 From e1e588815695ca4efca2cd0f848122080e24d22a Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 11 May 2022 21:44:24 +0200 Subject: [PATCH 72/94] PHP deprecation resolution --- phpstan-baseline.neon | 32 ++++++++++++++++---- src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php | 2 +- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index ccd2b6e808..2ec1014ace 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -155,6 +155,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Calculation.php + - + message: "#^Result of && is always false\\.$#" + count: 1 + path: src/PhpSpreadsheet/Calculation/Calculation.php + - message: "#^Static property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$instance \\(PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\) in isset\\(\\) is not nullable\\.$#" count: 1 @@ -1100,6 +1105,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Cell/Coordinate.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 2 + path: src/PhpSpreadsheet/Cell/Coordinate.php + - message: "#^Parameter \\#4 \\$currentRow of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:validateRange\\(\\) expects int, string given\\.$#" count: 1 @@ -2221,7 +2231,7 @@ parameters: path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\\\|string given\\.$#" + message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, array\\\\|string given\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Xls.php @@ -4052,7 +4062,7 @@ parameters: - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" - count: 1 + count: 2 path: src/PhpSpreadsheet/Worksheet/AutoFilter.php - @@ -4110,6 +4120,16 @@ parameters: count: 1 path: src/PhpSpreadsheet/Worksheet/SheetView.php + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 1 + path: src/PhpSpreadsheet/Worksheet/Table.php + + - + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 2 + path: src/PhpSpreadsheet/Worksheet/Validations.php + - message: "#^Cannot call method getCalculatedValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#" count: 1 @@ -4141,18 +4161,18 @@ parameters: path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + message: "#^If condition is always true\\.$#" count: 2 path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - message: "#^If condition is always true\\.$#" + message: "#^Left side of && is always true\\.$#" count: 2 path: src/PhpSpreadsheet/Worksheet/Worksheet.php - - message: "#^Left side of && is always true\\.$#" - count: 2 + message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:extractSheetTitle\\(\\) should return array\\\\|string but returns array\\\\|null\\.$#" + count: 1 path: src/PhpSpreadsheet/Worksheet/Worksheet.php - diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index 57232a0fe0..5f7d489ed8 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -1329,7 +1329,7 @@ private function writeCellFormula(XMLWriter $objWriter, string $cellValue, Cell $objWriter, $this->getParentWriter()->getOffice2003Compatibility() === false, 'v', - ($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue, 0, 1) !== '#') + ($this->getParentWriter()->getPreCalculateFormulas() && !is_array($calculatedValue) && substr($calculatedValue ?? '', 0, 1) !== '#') ? StringHelper::formatNumber($calculatedValue) : '0' ); } From feb769525274b2e3e92b13fc5795f249ef3b9ded Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 13 May 2022 10:19:29 +0200 Subject: [PATCH 73/94] Merge resolutions --- tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index 15be4a1d4e..8bccde185a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -99,7 +99,7 @@ public function providerArrayFormulae(): array */ public function testArrayArithmetic(string $formula, $expectedResult): void { - $result = Calculation::getInstance()->_calculateFormulaValue($formula); + $result = Calculation::getInstance()->calculateFormulaValue($formula); self::assertEquals($expectedResult, $result); } From b1d1ce7ec9fa92172604a4079b6716760d150465 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 28 May 2022 14:00:38 +0200 Subject: [PATCH 74/94] Re-baseline --- phpstan-baseline.neon | 32 +-------------------- src/PhpSpreadsheet/Calculation/MathTrig.php | 0 src/PhpSpreadsheet/Reader/Xls.php | 2 +- 3 files changed, 2 insertions(+), 32 deletions(-) delete mode 100644 src/PhpSpreadsheet/Calculation/MathTrig.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 07468f1410..3183297fc7 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -670,11 +670,6 @@ parameters: count: 2 path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - - - message: "#^Parameter \\#1 \\$columnAddress of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:columnIndexFromString\\(\\) expects string, string\\|null given\\.$#" - count: 4 - path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php - - message: "#^Binary operation \"/\" between array\\|float\\|int\\|string and array\\|float\\|int\\|string results in an error\\.$#" count: 2 @@ -1120,26 +1115,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:refresh\\(\\) has parameter \\$flatten with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:\\$dataSource \\(string\\) does not accept string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:\\$dataTypeValues has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:\\$fillColor \\(array\\\\|string\\) does not accept array\\\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - message: "#^Parameter \\#1 \\$angle of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setShadowAngle\\(\\) expects int, int\\|null given\\.$#" count: 1 @@ -2036,7 +2011,7 @@ parameters: path: src/PhpSpreadsheet/Reader/Xls.php - - message: "#^Parameter \\#1 \\$value of function count expects array\\|Countable, array\\\\|string given\\.$#" + message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\\\|string given\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Xls.php @@ -3625,11 +3600,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php - - - message: "#^Parameter \\#1 \\$format of function sprintf expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php - - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 2 diff --git a/src/PhpSpreadsheet/Calculation/MathTrig.php b/src/PhpSpreadsheet/Calculation/MathTrig.php deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/src/PhpSpreadsheet/Reader/Xls.php b/src/PhpSpreadsheet/Reader/Xls.php index 10f12dfec1..d922afbd68 100644 --- a/src/PhpSpreadsheet/Reader/Xls.php +++ b/src/PhpSpreadsheet/Reader/Xls.php @@ -1235,7 +1235,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet // Bar!$A$1:$IV$2 $explodes = Worksheet::extractSheetTitle($range, true); $sheetName = trim($explodes[0], "'"); - if (count($explodes) == 2) { + if (count($explodes) === 2) { if (strpos($explodes[1], ':') === false) { $explodes[1] = $explodes[1] . ':' . $explodes[1]; } From ba15a6837789489a35d32ff8f558d380e9caf029 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 18 Jun 2022 13:22:19 +0200 Subject: [PATCH 75/94] Merge from master, and rebase phpstan baseline --- phpstan-baseline.neon | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 6cccde091d..0799437553 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -670,16 +670,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/MathTrig/IntClass.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\:\\:MAXIFS\\(\\) should return float but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\:\\:MINIFS\\(\\) should return float but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Averages\\:\\:filterArguments\\(\\) has no return type specified\\.$#" count: 1 From a40c708d4c72f4c94d48250c5604039f27449c76 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 18 Jun 2022 15:04:54 +0200 Subject: [PATCH 76/94] Merge from 2.0 development, and rebase phpstan baseline --- phpstan-baseline.neon | 50 ------------------- .../Worksheet/WorksheetTest.php | 2 +- 2 files changed, 1 insertion(+), 51 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 1837c79d6e..99e27202f8 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1080,56 +1080,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - - message: "#^Parameter \\#1 \\$angle of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setShadowAngle\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Parameter \\#1 \\$color of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setGlowColor\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Parameter \\#1 \\$distance of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setShadowDistance\\(\\) expects float, float\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Parameter \\#2 \\$alpha of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setGlowColor\\(\\) expects int, int\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Parameter \\#3 \\$colorType of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setGlowColor\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$glowProperties has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$lineProperties has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$objectState has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$shadowProperties has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$softEdges has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/GridLines.php - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend\\:\\:\\$layout \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\|null\\.$#" count: 1 diff --git a/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php b/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php index 9959c79c42..bba2825c11 100644 --- a/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php +++ b/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php @@ -3,8 +3,8 @@ namespace PhpOffice\PhpSpreadsheetTests\Worksheet; use Exception; -use PhpOffice\PhpSpreadsheet\NamedRange; use PhpOffice\PhpSpreadsheet\Cell\DataType; +use PhpOffice\PhpSpreadsheet\NamedRange; use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Worksheet\CellIterator; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; From fd4e256108f36404711a274df21663fd5c074f62 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 5 Jul 2022 12:14:14 +0200 Subject: [PATCH 77/94] Rationalise the worksheet getHighestRowAndColumn() and getHighestDataRowAndColumn() methods, and return the cell address as a string rather than an array --- src/PhpSpreadsheet/Worksheet/Worksheet.php | 26 ++++++++++++++++------ 1 file changed, 19 insertions(+), 7 deletions(-) diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 628149a209..14152519ca 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -1067,7 +1067,7 @@ public function setProtection(Protection $protection) * * @return string Highest column name */ - public function getHighestColumn($row = null) + public function getHighestColumn($row = null): string { if ($row === null) { return Coordinate::stringFromColumnIndex($this->cachedHighestColumn); @@ -1084,7 +1084,7 @@ public function getHighestColumn($row = null) * * @return string Highest column name that contains data */ - public function getHighestDataColumn($row = null) + public function getHighestDataColumn($row = null): string { return $this->cellCollection->getHighestColumn($row); } @@ -1097,7 +1097,7 @@ public function getHighestDataColumn($row = null) * * @return int Highest row number */ - public function getHighestRow($column = null) + public function getHighestRow(?string $column = null): int { if ($column === null) { return $this->cachedHighestRow; @@ -1114,19 +1114,31 @@ public function getHighestRow($column = null) * * @return int Highest row number that contains data */ - public function getHighestDataRow($column = null) + public function getHighestDataRow(?string $column = null): int { return $this->cellCollection->getHighestRow($column); } + /** + * Get highest worksheet column and highest row. + * + * @return string Highest column name and highest row number + */ + public function getHighestRowAndColumn(): string + { + return $this->getHighestColumn() . $this->getHighestRow(); + } + /** * Get highest worksheet column and highest row that have cell records. * - * @return array Highest column name and highest row number + * @return string Highest column name and highest row number */ - public function getHighestRowAndColumn() + public function getHighestDataRowAndColumn(): string { - return $this->cellCollection->getHighestRowAndColumn(); + $highestRowAndColumn = $this->cellCollection->getHighestRowAndColumn(); + + return $highestRowAndColumn['column'] . $highestRowAndColumn['row']; } /** From ccd9aba5fc455ed0b42e7ef5dd25fc1b86984642 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Tue, 5 Jul 2022 14:36:34 +0200 Subject: [PATCH 78/94] Modify toArray() method to use highest data row/column rather than highest row/column --- composer.lock | 678 +++++++++++++----- src/PhpSpreadsheet/Worksheet/Worksheet.php | 5 +- .../Reader/Xlsx/XlsxTest.php | 4 +- 3 files changed, 509 insertions(+), 178 deletions(-) diff --git a/composer.lock b/composer.lock index 4ac9f6314a..1fed4dd093 100644 --- a/composer.lock +++ b/composer.lock @@ -51,33 +51,39 @@ "keywords": [ "html" ], + "support": { + "issues": "https://github.com/ezyang/htmlpurifier/issues", + "source": "https://github.com/ezyang/htmlpurifier/tree/v4.14.0" + }, "time": "2021-12-25T01:21:49+00:00" }, { "name": "maennchen/zipstream-php", - "version": "2.1.0", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/maennchen/ZipStream-PHP.git", - "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58" + "reference": "211e9ba1530ea5260b45d90c9ea252f56ec52729" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/c4c5803cc1f93df3d2448478ef79394a5981cc58", - "reference": "c4c5803cc1f93df3d2448478ef79394a5981cc58", + "url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/211e9ba1530ea5260b45d90c9ea252f56ec52729", + "reference": "211e9ba1530ea5260b45d90c9ea252f56ec52729", "shasum": "" }, "require": { "myclabs/php-enum": "^1.5", - "php": ">= 7.1", + "php": "^7.4 || ^8.0", "psr/http-message": "^1.0", "symfony/polyfill-mbstring": "^1.0" }, "require-dev": { "ext-zip": "*", - "guzzlehttp/guzzle": ">= 6.3", + "guzzlehttp/guzzle": "^6.5.3 || ^7.2.0", "mikey179/vfsstream": "^1.6", - "phpunit/phpunit": ">= 7.5" + "php-coveralls/php-coveralls": "^2.4", + "phpunit/phpunit": "^8.5.8 || ^9.4.2", + "vimeo/psalm": "^4.1" }, "type": "library", "autoload": { @@ -112,13 +118,17 @@ "stream", "zip" ], + "support": { + "issues": "https://github.com/maennchen/ZipStream-PHP/issues", + "source": "https://github.com/maennchen/ZipStream-PHP/tree/2.2.1" + }, "funding": [ { "url": "https://opencollective.com/zipstream", "type": "open_collective" } ], - "time": "2020-05-30T13:11:16+00:00" + "time": "2022-05-18T15:52:06+00:00" }, { "name": "markbaker/complex", @@ -165,6 +175,10 @@ "complex", "mathematics" ], + "support": { + "issues": "https://github.com/MarkBaker/PHPComplex/issues", + "source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.1" + }, "time": "2021-06-29T15:32:53+00:00" }, { @@ -217,6 +231,10 @@ "matrix", "vector" ], + "support": { + "issues": "https://github.com/MarkBaker/PHPMatrix/issues", + "source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.0" + }, "time": "2021-07-01T19:01:15+00:00" }, { @@ -263,6 +281,10 @@ "keywords": [ "enum" ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.3" + }, "funding": [ { "url": "https://github.com/mnapoli", @@ -322,6 +344,9 @@ "psr", "psr-18" ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, "time": "2020-06-29T06:28:15+00:00" }, { @@ -374,6 +399,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, "time": "2019-04-30T12:38:16+00:00" }, { @@ -424,6 +452,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { @@ -472,32 +503,38 @@ "psr-16", "simple-cache" ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, "time": "2017-10-23T01:57:42+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.23.1", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-mbstring": "*" + }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -535,6 +572,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -549,36 +589,36 @@ "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2022-05-24T11:49:31+00:00" } ], "packages-dev": [ { "name": "composer/pcre", - "version": "1.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2" + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/3d322d715c43a1ac36c7fe215fa59336265500f2", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2", + "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1", + "phpstan/phpstan": "^1.3", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5" + "symfony/phpunit-bridge": "^5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { @@ -604,6 +644,10 @@ "regex", "regular expression" ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.0.0" + }, "funding": [ { "url": "https://packagist.com", @@ -618,27 +662,27 @@ "type": "tidelift" } ], - "time": "2021-12-06T15:17:27+00:00" + "time": "2022-02-25T20:21:48+00:00" }, { "name": "composer/semver", - "version": "3.2.6", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "83e511e247de329283478496f7a1e114c9517506" + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", - "reference": "83e511e247de329283478496f7a1e114c9517506", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.54", + "phpstan/phpstan": "^1.4", "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", @@ -680,6 +724,11 @@ "validation", "versioning" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.3.2" + }, "funding": [ { "url": "https://packagist.com", @@ -694,31 +743,31 @@ "type": "tidelift" } ], - "time": "2021-10-25T11:34:17+00:00" + "time": "2022-04-01T19:23:25+00:00" }, { "name": "composer/xdebug-handler", - "version": "2.0.3", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6555461e76962fd0379c444c46fd558a0fcfb65e" + "reference": "ced299686f41dce890debac69273b47ffe98a40c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6555461e76962fd0379c444c46fd558a0fcfb65e", - "reference": "6555461e76962fd0379c444c46fd558a0fcfb65e", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", "shasum": "" }, "require": { - "composer/pcre": "^1", - "php": "^5.3.2 || ^7.0 || ^8.0", + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", "psr/log": "^1 || ^2 || ^3" }, "require-dev": { "phpstan/phpstan": "^1.0", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" + "symfony/phpunit-bridge": "^6.0" }, "type": "library", "autoload": { @@ -741,6 +790,11 @@ "Xdebug", "performance" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/xdebug-handler/issues", + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + }, "funding": [ { "url": "https://packagist.com", @@ -755,7 +809,7 @@ "type": "tidelift" } ], - "time": "2021-12-08T13:07:32+00:00" + "time": "2022-02-25T21:32:43+00:00" }, { "name": "dealerdirect/phpcodesniffer-composer-installer", @@ -784,6 +838,7 @@ "phpcompatibility/php-compatibility": "^9.0", "yoast/phpunit-polyfills": "^1.0" }, + "default-branch": true, "type": "composer-plugin", "extra": { "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" @@ -829,20 +884,24 @@ "stylecheck", "tests" ], + "support": { + "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "source": "https://github.com/PHPCSStandards/composer-installer" + }, "time": "2022-06-26T10:27:07+00:00" }, { "name": "doctrine/annotations", - "version": "1.13.2", + "version": "1.13.3", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08" + "reference": "648b0343343565c4a056bfc8392201385e8d89f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0", "shasum": "" }, "require": { @@ -854,9 +913,10 @@ "require-dev": { "doctrine/cache": "^1.11 || ^2.0", "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^0.12.20", + "phpstan/phpstan": "^1.4.10 || ^1.8.0", "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2" + "symfony/cache": "^4.4 || ^5.2", + "vimeo/psalm": "^4.10" }, "type": "library", "autoload": { @@ -897,7 +957,11 @@ "docblock", "parser" ], - "time": "2021-08-05T19:00:23+00:00" + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.13.3" + }, + "time": "2022-07-02T10:48:51+00:00" }, { "name": "doctrine/instantiator", @@ -949,6 +1013,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -967,32 +1035,28 @@ }, { "name": "doctrine/lexer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpstan/phpstan": "^0.11.8", - "phpunit/phpunit": "^8.2" + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" @@ -1025,6 +1089,10 @@ "parser", "php" ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.3" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -1039,7 +1107,7 @@ "type": "tidelift" } ], - "time": "2020-05-25T17:44:05+00:00" + "time": "2022-02-28T11:07:21+00:00" }, { "name": "dompdf/dompdf", @@ -1105,56 +1173,60 @@ ], "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", "homepage": "https://github.com/dompdf/dompdf", + "support": { + "issues": "https://github.com/dompdf/dompdf/issues", + "source": "https://github.com/dompdf/dompdf/tree/v2.0.0" + }, "time": "2022-06-21T21:14:57+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.4.0", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad" + "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", - "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", + "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", "shasum": "" }, "require": { "composer/semver": "^3.2", - "composer/xdebug-handler": "^2.0", - "doctrine/annotations": "^1.12", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^1.13", "ext-json": "*", "ext-tokenizer": "*", - "php": "^7.2.5 || ^8.0", + "php": "^7.4 || ^8.0", "php-cs-fixer/diff": "^2.0", - "symfony/console": "^4.4.20 || ^5.1.3 || ^6.0", - "symfony/event-dispatcher": "^4.4.20 || ^5.0 || ^6.0", - "symfony/filesystem": "^4.4.20 || ^5.0 || ^6.0", - "symfony/finder": "^4.4.20 || ^5.0 || ^6.0", - "symfony/options-resolver": "^4.4.20 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.23", - "symfony/polyfill-php81": "^1.23", - "symfony/process": "^4.4.20 || ^5.0 || ^6.0", - "symfony/stopwatch": "^4.4.20 || ^5.0 || ^6.0" + "symfony/polyfill-php80": "^1.25", + "symfony/polyfill-php81": "^1.25", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" }, "require-dev": { "justinrainbow/json-schema": "^5.2", "keradus/cli-executor": "^1.5", - "mikey179/vfsstream": "^1.6.8", + "mikey179/vfsstream": "^1.6.10", "php-coveralls/php-coveralls": "^2.5.2", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", "phpspec/prophecy": "^1.15", - "phpspec/prophecy-phpunit": "^1.1 || ^2.0", - "phpunit/phpunit": "^8.5.21 || ^9.5", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", "phpunitgoodpractices/polyfill": "^1.5", "phpunitgoodpractices/traits": "^1.9.1", - "symfony/phpunit-bridge": "^5.2.4 || ^6.0", - "symfony/yaml": "^4.4.20 || ^5.0 || ^6.0" + "symfony/phpunit-bridge": "^6.0", + "symfony/yaml": "^5.4 || ^6.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -1184,13 +1256,17 @@ } ], "description": "A tool to automatically fix PHP code style", + "support": { + "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.8.0" + }, "funding": [ { "url": "https://github.com/keradus", "type": "github" } ], - "time": "2021-12-11T16:25:08+00:00" + "time": "2022-03-18T17:20:59+00:00" }, { "name": "jpgraph/jpgraph", @@ -1230,6 +1306,10 @@ "jpgraph", "pie" ], + "support": { + "issues": "https://github.com/ztec/JpGraph/issues", + "source": "https://github.com/ztec/JpGraph/tree/4.x" + }, "abandoned": true, "time": "2017-02-23T09:44:15+00:00" }, @@ -1296,6 +1376,10 @@ "serializer", "xml" ], + "support": { + "issues": "https://github.com/Masterminds/html5-php/issues", + "source": "https://github.com/Masterminds/html5-php/tree/2.7.5" + }, "time": "2021-07-01T14:25:37+00:00" }, { @@ -1362,6 +1446,11 @@ "php", "utf-8" ], + "support": { + "docs": "http://mpdf.github.io", + "issues": "https://github.com/mpdf/mpdf/issues", + "source": "https://github.com/mpdf/mpdf" + }, "funding": [ { "url": "https://www.paypal.me/mpdf", @@ -1417,6 +1506,10 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", @@ -1475,6 +1568,10 @@ "parser", "php" ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + }, "time": "2022-05-31T20:59:12+00:00" }, { @@ -1520,6 +1617,11 @@ "pseudorandom", "random" ], + "support": { + "email": "info@paragonie.com", + "issues": "https://github.com/paragonie/random_compat/issues", + "source": "https://github.com/paragonie/random_compat" + }, "time": "2020-10-15T08:29:30+00:00" }, { @@ -1576,6 +1678,10 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, "time": "2021-07-20T11:28:43+00:00" }, { @@ -1623,6 +1729,10 @@ } ], "description": "Library for handling version information and constraints", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, "time": "2022-02-21T01:04:05+00:00" }, { @@ -1663,6 +1773,10 @@ ], "description": "A library to read, parse, export and make subsets of different types of font files.", "homepage": "https://github.com/PhenX/php-font-lib", + "support": { + "issues": "https://github.com/dompdf/php-font-lib/issues", + "source": "https://github.com/dompdf/php-font-lib/tree/0.5.4" + }, "time": "2021-12-17T19:44:54+00:00" }, { @@ -1705,6 +1819,10 @@ ], "description": "A library to read, parse and export to PDF SVG files.", "homepage": "https://github.com/PhenX/php-svg-lib", + "support": { + "issues": "https://github.com/dompdf/php-svg-lib/issues", + "source": "https://github.com/dompdf/php-svg-lib/tree/0.4.1" + }, "time": "2022-03-07T12:52:04+00:00" }, { @@ -1753,6 +1871,10 @@ "keywords": [ "diff" ], + "support": { + "issues": "https://github.com/PHP-CS-Fixer/diff/issues", + "source": "https://github.com/PHP-CS-Fixer/diff/tree/v2.0.2" + }, "time": "2020-10-14T08:32:19+00:00" }, { @@ -1803,6 +1925,10 @@ "stream", "uri" ], + "support": { + "issues": "https://github.com/php-http/message-factory/issues", + "source": "https://github.com/php-http/message-factory/tree/master" + }, "time": "2015-12-19T14:08:53+00:00" }, { @@ -1861,6 +1987,10 @@ "phpcs", "standards" ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibility" + }, "time": "2019-12-27T09:44:58+00:00" }, { @@ -1910,6 +2040,10 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { @@ -1963,6 +2097,10 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, "time": "2021-10-19T17:43:47+00:00" }, { @@ -2009,6 +2147,10 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + }, "time": "2022-03-15T21:29:03+00:00" }, { @@ -2072,6 +2214,10 @@ "spy", "stub" ], + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, "time": "2021-12-08T12:19:24+00:00" }, { @@ -2109,6 +2255,10 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.8.0" + }, "funding": [ { "url": "https://github.com/ondrejmirtes", @@ -2175,6 +2325,10 @@ "MIT" ], "description": "PHPUnit extensions and rules for PHPStan", + "support": { + "issues": "https://github.com/phpstan/phpstan-phpunit/issues", + "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.1.1" + }, "time": "2022-04-20T15:24:25+00:00" }, { @@ -2242,6 +2396,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2298,6 +2456,10 @@ "filesystem", "iterator" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2357,6 +2519,10 @@ "keywords": [ "process" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2412,6 +2578,10 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2467,6 +2637,10 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2561,6 +2735,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.21" + }, "funding": [ { "url": "https://phpunit.de/sponsors.html", @@ -2617,24 +2795,27 @@ "psr", "psr-6" ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, "time": "2016-08-06T20:24:11+00:00" }, { "name": "psr/container", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "type": "library", "autoload": { @@ -2661,7 +2842,11 @@ "container-interop", "psr" ], - "time": "2021-03-05T17:36:06+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" }, { "name": "psr/event-dispatcher", @@ -2707,6 +2892,10 @@ "psr", "psr-14" ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, "time": "2019-01-08T18:20:26+00:00" }, { @@ -2754,6 +2943,9 @@ "psr", "psr-3" ], + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, "time": "2021-05-03T11:20:27+00:00" }, { @@ -2803,6 +2995,10 @@ "parser", "stylesheet" ], + "support": { + "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues", + "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0" + }, "time": "2021-12-11T13:40:54+00:00" }, { @@ -2849,6 +3045,10 @@ ], "description": "Library for parsing CLI options", "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2901,6 +3101,10 @@ ], "description": "Collection of value objects that represent the PHP code units", "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2952,6 +3156,10 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3022,6 +3230,10 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3075,6 +3287,10 @@ ], "description": "Library for calculating the complexity of PHP code units", "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3137,6 +3353,10 @@ "unidiff", "unified diff" ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3196,6 +3416,10 @@ "environment", "hhvm" ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3269,6 +3493,10 @@ "export", "exporter" ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3329,6 +3557,10 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3382,6 +3614,10 @@ ], "description": "Library for counting the lines of code in PHP source code", "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3435,6 +3671,10 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3486,6 +3726,10 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3545,6 +3789,10 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3596,6 +3844,10 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3648,6 +3900,10 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3697,6 +3953,10 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3765,6 +4025,10 @@ "fpdi", "pdf" ], + "support": { + "issues": "https://github.com/Setasign/FPDI/issues", + "source": "https://github.com/Setasign/FPDI/tree/v2.3.6" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/setasign/fpdi", @@ -3822,20 +4086,25 @@ "phpcs", "standards" ], + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" + }, "time": "2022-06-18T07:21:10+00:00" }, { "name": "symfony/console", - "version": "v5.4.2", + "version": "v5.4.10", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e" + "reference": "4d671ab4ddac94ee439ea73649c69d9d200b5000" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a2c6b7ced2eb7799a35375fb9022519282b5405e", - "reference": "a2c6b7ced2eb7799a35375fb9022519282b5405e", + "url": "https://api.github.com/repos/symfony/console/zipball/4d671ab4ddac94ee439ea73649c69d9d200b5000", + "reference": "4d671ab4ddac94ee439ea73649c69d9d200b5000", "shasum": "" }, "require": { @@ -3904,6 +4173,9 @@ "console", "terminal" ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3918,20 +4190,20 @@ "type": "tidelift" } ], - "time": "2021-12-20T16:11:12+00:00" + "time": "2022-06-26T13:00:04+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/e8b495ea28c1d97b5e0c121748d6f9b53d075c66", + "reference": "e8b495ea28c1d97b5e0c121748d6f9b53d075c66", "shasum": "" }, "require": { @@ -3968,6 +4240,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.2" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3982,20 +4257,20 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.4.0", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "27d39ae126352b9fa3be5e196ccf4617897be3eb" + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/27d39ae126352b9fa3be5e196ccf4617897be3eb", - "reference": "27d39ae126352b9fa3be5e196ccf4617897be3eb", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", + "reference": "8e6ce1cc0279e3ff3c8ff0f43813bc88d21ca1bc", "shasum": "" }, "require": { @@ -4050,6 +4325,9 @@ ], "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.4.9" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4064,20 +4342,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T10:19:22+00:00" + "time": "2022-05-05T16:45:39+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/f98b54df6ad059855739db6fcbc2d36995283fe1", + "reference": "f98b54df6ad059855739db6fcbc2d36995283fe1", "shasum": "" }, "require": { @@ -4126,6 +4404,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.2" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4140,20 +4421,20 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/filesystem", - "version": "v5.4.0", + "version": "v5.4.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01" + "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/731f917dc31edcffec2c6a777f3698c33bea8f01", - "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/36a017fa4cce1eff1b8e8129ff53513abcef05ba", + "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba", "shasum": "" }, "require": { @@ -4187,6 +4468,9 @@ ], "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.9" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4201,20 +4485,20 @@ "type": "tidelift" } ], - "time": "2021-10-28T13:39:27+00:00" + "time": "2022-05-20T13:55:35+00:00" }, { "name": "symfony/finder", - "version": "v5.4.2", + "version": "v5.4.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "e77046c252be48c48a40816187ed527703c8f76c" + "reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/e77046c252be48c48a40816187ed527703c8f76c", - "reference": "e77046c252be48c48a40816187ed527703c8f76c", + "url": "https://api.github.com/repos/symfony/finder/zipball/9b630f3427f3ebe7cd346c277a1408b00249dad9", + "reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9", "shasum": "" }, "require": { @@ -4247,6 +4531,9 @@ ], "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.4.8" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4261,20 +4548,20 @@ "type": "tidelift" } ], - "time": "2021-12-15T11:06:13+00:00" + "time": "2022-04-15T08:07:45+00:00" }, { "name": "symfony/options-resolver", - "version": "v5.4.0", + "version": "v5.4.3", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "b0fb78576487af19c500aaddb269fd36701d4847" + "reference": "cc1147cb11af1b43f503ac18f31aa3bec213aba8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/b0fb78576487af19c500aaddb269fd36701d4847", - "reference": "b0fb78576487af19c500aaddb269fd36701d4847", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/cc1147cb11af1b43f503ac18f31aa3bec213aba8", + "reference": "cc1147cb11af1b43f503ac18f31aa3bec213aba8", "shasum": "" }, "require": { @@ -4313,6 +4600,9 @@ "configuration", "options" ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v5.4.3" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4327,7 +4617,7 @@ "type": "tidelift" } ], - "time": "2021-11-23T10:19:22+00:00" + "time": "2022-01-02T09:53:40+00:00" }, { "name": "symfony/polyfill-ctype", @@ -4392,6 +4682,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4410,16 +4703,16 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.23.1", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" + "reference": "433d05519ce6990bf3530fba6957499d327395c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", - "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", "shasum": "" }, "require": { @@ -4431,7 +4724,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4470,6 +4763,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4484,20 +4780,20 @@ "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.23.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", "shasum": "" }, "require": { @@ -4509,7 +4805,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4551,6 +4847,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4565,20 +4864,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.23.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/e440d35fa0286f77fb45b79a03fedbeda9307e85", + "reference": "e440d35fa0286f77fb45b79a03fedbeda9307e85", "shasum": "" }, "require": { @@ -4587,7 +4886,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4627,6 +4926,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.26.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4641,20 +4943,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.23.1", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", "shasum": "" }, "require": { @@ -4663,7 +4965,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4707,6 +5009,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4721,20 +5026,20 @@ "type": "tidelift" } ], - "time": "2021-07-28T13:41:28+00:00" + "time": "2022-05-10T07:21:04+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.23.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "e66119f3de95efc359483f810c4c3e6436279436" + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436", - "reference": "e66119f3de95efc359483f810c4c3e6436279436", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", "shasum": "" }, "require": { @@ -4743,7 +5048,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -4783,6 +5088,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4797,20 +5105,20 @@ "type": "tidelift" } ], - "time": "2021-05-21T13:25:03+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/process", - "version": "v5.4.2", + "version": "v5.4.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4" + "reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", - "reference": "2b3ba8722c4aaf3e88011be5e7f48710088fb5e4", + "url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3", + "reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3", "shasum": "" }, "require": { @@ -4842,6 +5150,9 @@ ], "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/process/tree/v5.4.8" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4856,26 +5167,26 @@ "type": "tidelift" } ], - "time": "2021-12-27T21:01:00+00:00" + "time": "2022-04-08T05:07:18+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.0", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/4b426aac47d6427cc1a1d0f7e2ac724627f5966c", + "reference": "4b426aac47d6427cc1a1d0f7e2ac724627f5966c", "shasum": "" }, "require": { "php": ">=7.2.5", "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" + "symfony/deprecation-contracts": "^2.1|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -4922,6 +5233,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.5.2" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4936,20 +5250,20 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:48:04+00:00" + "time": "2022-05-30T19:17:29+00:00" }, { "name": "symfony/stopwatch", - "version": "v5.4.0", + "version": "v5.4.5", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "208ef96122bfed82a8f3a61458a07113a08bdcfe" + "reference": "4d04b5c24f3c9a1a168a131f6cbe297155bc0d30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/208ef96122bfed82a8f3a61458a07113a08bdcfe", - "reference": "208ef96122bfed82a8f3a61458a07113a08bdcfe", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4d04b5c24f3c9a1a168a131f6cbe297155bc0d30", + "reference": "4d04b5c24f3c9a1a168a131f6cbe297155bc0d30", "shasum": "" }, "require": { @@ -4981,6 +5295,9 @@ ], "description": "Provides a way to profile code", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v5.4.5" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -4995,20 +5312,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T10:19:22+00:00" + "time": "2022-02-18T16:06:09+00:00" }, { "name": "symfony/string", - "version": "v5.4.2", + "version": "v5.4.10", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d" + "reference": "4432bc7df82a554b3e413a8570ce2fea90e94097" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", - "reference": "e6a5d5ecf6589c5247d18e0e74e30b11dfd51a3d", + "url": "https://api.github.com/repos/symfony/string/zipball/4432bc7df82a554b3e413a8570ce2fea90e94097", + "reference": "4432bc7df82a554b3e413a8570ce2fea90e94097", "shasum": "" }, "require": { @@ -5064,6 +5381,9 @@ "utf-8", "utf8" ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.4.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5078,7 +5398,7 @@ "type": "tidelift" } ], - "time": "2021-12-16T21:52:00+00:00" + "time": "2022-06-26T15:57:47+00:00" }, { "name": "tecnickcom/tcpdf", @@ -5140,6 +5460,10 @@ "pdf417", "qrcode" ], + "support": { + "issues": "https://github.com/tecnickcom/TCPDF/issues", + "source": "https://github.com/tecnickcom/TCPDF/tree/6.4.4" + }, "funding": [ { "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_donations¤cy_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20tcpdf%20project", @@ -5186,6 +5510,10 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, "funding": [ { "url": "https://github.com/theseer", @@ -5246,6 +5574,10 @@ "check", "validate" ], + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.11.0" + }, "time": "2022-06-03T18:03:27+00:00" } ], @@ -5273,5 +5605,5 @@ "ext-zlib": "*" }, "platform-dev": [], - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.3.0" } diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php index 14152519ca..683c9364fe 100644 --- a/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -3001,15 +3001,14 @@ public function toArray($nullValue = null, $calculateFormulas = true, $formatDat $this->garbageCollect(); // Identify the range that we need to extract from the worksheet - $maxCol = $this->getHighestColumn(); - $maxRow = $this->getHighestRow(); + $maxCell = $this->getHighestDataRowAndColumn(); if ($currentCellAddress !== null) { $this->getCell($currentCellAddress); } // Return - return $this->rangeToArray('A1:' . $maxCol . $maxRow, $nullValue, $calculateFormulas, $formatData, $returnCellRef); + return $this->rangeToArray('A1:' . $maxCell, $nullValue, $calculateFormulas, $formatData, $returnCellRef); } /** diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxTest.php index e1271b9a64..745da846fd 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/XlsxTest.php @@ -218,10 +218,10 @@ public function testLoadWithReadFilter(): void $reader = new Xlsx(); $reader->setReadFilter(new OddColumnReadFilter()); $data = $reader->load($filename)->getActiveSheet()->toArray(); - $ref = [1.0, null, 3.0, null, 5.0, null, 7.0, null, 9.0, null]; + $ref = [1, null, 3, null, 5, null, 7, null, 9]; for ($i = 0; $i < 10; ++$i) { - self::assertEquals($ref, \array_slice($data[$i], 0, 10, true)); + self::assertEquals($ref, \array_slice($data[$i], 0, 9, true)); } } From 3e493126919924fec13b7dfb29afa2c67c373c18 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 9 Jul 2022 16:43:15 +0200 Subject: [PATCH 79/94] Reset phpstan baseline after merge from 1.x --- phpstan-baseline.neon | 143 +++--------------------------------------- 1 file changed, 9 insertions(+), 134 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index db59915561..65789e1ebe 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -31,23 +31,8 @@ parameters: path: src/PhpSpreadsheet/Calculation/Calculation.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has parameter \\$formula with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Calculation.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has parameter \\$formula with no type specified\\.$#" - count: 1 + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" + count: 6 path: src/PhpSpreadsheet/Calculation/Calculation.php - @@ -1031,124 +1016,9 @@ parameters: path: src/PhpSpreadsheet/Cell/Coordinate.php - - message: "#^Call to an undefined method object\\:\\:render\\(\\)\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$legend \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$majorGridlines \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$minorGridlines \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$plotArea \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\PlotArea\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\PlotArea\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$title \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$worksheet \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$xAxis \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$xAxisLabel \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$yAxis \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:\\$yAxisLabel \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Chart.php - - - - message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues and null will always evaluate to false\\.$#" - count: 2 - path: src/PhpSpreadsheet/Chart/DataSeries.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend\\:\\:\\$layout \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Legend.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend\\:\\:\\$positionXLref has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Legend.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\PlotArea\\:\\:\\$layout \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/PlotArea.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Properties.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has parameter \\$elements with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Properties.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has parameter \\$properties with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Properties.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Properties.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has parameter \\$arrayKaySelector with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Properties.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has parameter \\$arraySelector with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Properties.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getShadowPresetsMap\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Properties.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getShadowPresetsMap\\(\\) has parameter \\$presetsOption with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Chart/Properties.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\:\\:\\$layout \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\|null\\.$#" + message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 - path: src/PhpSpreadsheet/Chart/Title.php + path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Memory\\:\\:\\$cache has no type specified\\.$#" @@ -2710,6 +2580,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/OLERead.php + - + message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_calculateFormulaValue\\(\\)\\.$#" + count: 1 + path: src/PhpSpreadsheet/Shared/StringHelper.php + - message: "#^Static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\TimeZone\\:\\:validateTimeZone\\(\\) is unused\\.$#" count: 1 From 08849a7eee16b4886790095afecd59e99781ec96 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sat, 9 Jul 2022 16:50:17 +0200 Subject: [PATCH 80/94] Changes required after merge from 1.x master, and reset phpstan baseline --- src/PhpSpreadsheet/Shared/StringHelper.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Shared/StringHelper.php b/src/PhpSpreadsheet/Shared/StringHelper.php index 030df66df8..5bec359398 100644 --- a/src/PhpSpreadsheet/Shared/StringHelper.php +++ b/src/PhpSpreadsheet/Shared/StringHelper.php @@ -554,7 +554,7 @@ public static function convertToNumberIfFraction(string &$operand): bool $sign = ($match[1] == '-') ? '-' : '+'; $wholePart = ($match[3] === '') ? '' : ($sign . $match[3]); $fractionFormula = '=' . $wholePart . $sign . $match[4]; - $operand = Calculation::getInstance()->_calculateFormulaValue($fractionFormula); + $operand = Calculation::getInstance()->calculateFormulaValue($fractionFormula); return true; } From 95cf51b412abc643e005ed8a4b53cced0abaabbb Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 10 Jul 2022 14:51:05 +0200 Subject: [PATCH 81/94] Modify the general settings ExcelCalendar to be simply a default, Create a new ExcelCalendar property for Spreadsheets, and modify the Xlsx and Xls Readers/Writers to maintain 1900 or 1904 calendar against the spreadsheet --- src/PhpSpreadsheet/Reader/Xls.php | 4 +-- src/PhpSpreadsheet/Reader/Xlsx.php | 4 +-- src/PhpSpreadsheet/Shared/Date.php | 4 +-- src/PhpSpreadsheet/Spreadsheet.php | 37 +++++++++++++++++++++ src/PhpSpreadsheet/Writer/Xls/Workbook.php | 6 ++-- src/PhpSpreadsheet/Writer/Xlsx/Workbook.php | 6 ++-- 6 files changed, 49 insertions(+), 12 deletions(-) diff --git a/src/PhpSpreadsheet/Reader/Xls.php b/src/PhpSpreadsheet/Reader/Xls.php index 9aee18ee18..98de1c029d 100644 --- a/src/PhpSpreadsheet/Reader/Xls.php +++ b/src/PhpSpreadsheet/Reader/Xls.php @@ -2026,9 +2026,9 @@ private function readDateMode(): void $this->pos += 4 + $length; // offset: 0; size: 2; 0 = base 1900, 1 = base 1904 - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); + $this->spreadsheet->setExcelCalendar(Date::CALENDAR_WINDOWS_1900); if (ord($recordData[0]) == 1) { - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); + $this->spreadsheet->setExcelCalendar(Date::CALENDAR_MAC_1904); } } diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index f793a66ae6..8f88f29412 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -681,11 +681,11 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet // Set base date if ($xmlWorkbookNS->workbookPr) { - Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); + $excel->setExcelCalendar(Date::CALENDAR_WINDOWS_1900); $attrs1904 = self::getAttributes($xmlWorkbookNS->workbookPr); if (isset($attrs1904['date1904'])) { if (self::boolean((string) $attrs1904['date1904'])) { - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); + $excel->setExcelCalendar(Date::CALENDAR_MAC_1904); } } } diff --git a/src/PhpSpreadsheet/Shared/Date.php b/src/PhpSpreadsheet/Shared/Date.php index 8cac2c63e8..6c43bca4a3 100644 --- a/src/PhpSpreadsheet/Shared/Date.php +++ b/src/PhpSpreadsheet/Shared/Date.php @@ -67,7 +67,7 @@ class Date protected static $defaultTimeZone; /** - * Set the Excel calendar (Windows 1900 or Mac 1904). + * Set the Excel Default Calendar (Windows 1900 or Mac 1904). * * @param int $baseYear Excel base date (1900 or 1904) * @@ -85,7 +85,7 @@ public static function setExcelCalendar($baseYear) } /** - * Return the Excel calendar (Windows 1900 or Mac 1904). + * Return the Excel Default Calendar (Windows 1900 or Mac 1904). * * @return int Excel base date (1900 or 1904) */ diff --git a/src/PhpSpreadsheet/Spreadsheet.php b/src/PhpSpreadsheet/Spreadsheet.php index 33b4fe0c4d..904a8437e4 100644 --- a/src/PhpSpreadsheet/Spreadsheet.php +++ b/src/PhpSpreadsheet/Spreadsheet.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Shared\Date; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Iterator; @@ -52,6 +53,14 @@ class Spreadsheet */ private $workSheetCollection = []; + /** + * Base calendar year to use for calculations + * Value is either CALENDAR_WINDOWS_1900 (1900) or CALENDAR_MAC_1904 (1904). + * + * @var int + */ + protected $excelCalendar = Date::CALENDAR_WINDOWS_1900; + /** * Calculation Engine. * @@ -199,6 +208,34 @@ class Spreadsheet */ private $tabRatio = 600; + /** + * Set the Excel Calendar (Windows 1900 or Mac 1904). + * + * @param int $baseYear Excel base date (1900 or 1904) + * + * @return bool Success or failure + */ + public function setExcelCalendar(int $baseYear): bool + { + if (($baseYear == Date::CALENDAR_WINDOWS_1900) || ($baseYear == Date::CALENDAR_MAC_1904)) { + $this->excelCalendar = $baseYear; + + return true; + } + + return false; + } + + /** + * Return the Excel Calendar (Windows 1900 or Mac 1904). + * + * @return int Excel base date (1900 or 1904) + */ + public function getExcelCalendar(): int + { + return $this->excelCalendar; + } + /** * The workbook has macros ? * diff --git a/src/PhpSpreadsheet/Writer/Xls/Workbook.php b/src/PhpSpreadsheet/Writer/Xls/Workbook.php index ccffa181b6..876f2bded0 100644 --- a/src/PhpSpreadsheet/Writer/Xls/Workbook.php +++ b/src/PhpSpreadsheet/Writer/Xls/Workbook.php @@ -960,9 +960,9 @@ private function writeDateMode(): void $record = 0x0022; // Record identifier $length = 0x0002; // Bytes to follow - $f1904 = (Date::getExcelCalendar() === Date::CALENDAR_MAC_1904) - ? 1 - : 0; // Flag for 1904 date system + $f1904 = ($this->spreadsheet->getExcelCalendar() === Date::CALENDAR_MAC_1904) + ? 1 // Flag for 1904 date system + : 0; // Flag for 1900 date system $header = pack('vv', $record, $length); $data = pack('v', $f1904); diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php b/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php index f9d7197d7a..176039d660 100644 --- a/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php +++ b/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php @@ -39,7 +39,7 @@ public function writeWorkbook(Spreadsheet $spreadsheet, $recalcRequired = false) $this->writeFileVersion($objWriter); // workbookPr - $this->writeWorkbookPr($objWriter); + $this->writeWorkbookPr($objWriter, $spreadsheet); // workbookProtection $this->writeWorkbookProtection($objWriter, $spreadsheet); @@ -80,11 +80,11 @@ private function writeFileVersion(XMLWriter $objWriter): void /** * Write WorkbookPr. */ - private function writeWorkbookPr(XMLWriter $objWriter): void + private function writeWorkbookPr(XMLWriter $objWriter, Spreadsheet $spreadsheet): void { $objWriter->startElement('workbookPr'); - if (Date::getExcelCalendar() === Date::CALENDAR_MAC_1904) { + if ($spreadsheet->getExcelCalendar() === Date::CALENDAR_MAC_1904) { $objWriter->writeAttribute('date1904', '1'); } From 1fda83de96f625b73d9145113a42dcbc57299b21 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 18 Jul 2022 16:28:53 +0200 Subject: [PATCH 82/94] Remember to re-baseline phpstan before final commit and push because of method name changes --- phpstan-baseline.neon | 5 - .../Calculation/Calculation.php | 102 +++++++++--------- .../Calculation/Engineering/BitWise.php | 10 +- .../Calculation/Engineering/Compare.php | 4 +- .../Calculation/Financial/Dollar.php | 2 +- .../Calculation/Logical/Conditional.php | 16 +-- .../Calculation/Logical/Operations.php | 8 +- .../Calculation/LookupRef/ExcelMatch.php | 2 +- .../Calculation/LookupRef/Indirect.php | 2 +- .../LookupRef/RowColumnInformation.php | 8 +- .../Calculation/Statistical/Conditional.php | 22 ++-- .../Calculation/Statistical/Counts.php | 2 +- .../Calculation/Statistical/Trends.php | 14 +-- .../Calculation/TextData/Concatenate.php | 6 +- .../Calculation/TextData/Format.php | 10 +- .../Functions/Engineering/DeltaTest.php | 2 +- .../Functions/Engineering/GeStepTest.php | 2 +- .../Calculation/Functions/Logical/AndTest.php | 2 +- .../Functions/Logical/IfErrorTest.php | 2 +- .../Functions/Logical/IfNaTest.php | 2 +- .../Calculation/Functions/Logical/IfTest.php | 8 +- .../Calculation/Functions/Logical/IfsTest.php | 2 +- .../Calculation/Functions/Logical/NotTest.php | 4 +- .../Calculation/Functions/Logical/OrTest.php | 2 +- .../Functions/Logical/SwitchTest.php | 2 +- .../Calculation/Functions/Logical/XorTest.php | 2 +- .../Functions/LookupRef/ColumnTest.php | 2 +- .../Functions/LookupRef/ColumnsTest.php | 2 +- .../Functions/LookupRef/MatchTest.php | 2 +- .../Functions/LookupRef/RowTest.php | 2 +- .../Functions/LookupRef/RowsTest.php | 2 +- .../Functions/MathTrig/SumIfsTest.php | 2 +- .../Functions/Statistical/AverageIfTest.php | 2 +- .../Functions/Statistical/AverageIfsTest.php | 2 +- .../Functions/Statistical/CorrelTest.php | 2 +- .../Functions/Statistical/CountBlankTest.php | 2 +- .../Functions/Statistical/CountIfTest.php | 2 +- .../Functions/Statistical/CountIfsTest.php | 2 +- .../Functions/Statistical/CovarTest.php | 2 +- .../Functions/Statistical/ForecastTest.php | 2 +- .../Functions/Statistical/GrowthTest.php | 6 +- .../Functions/Statistical/InterceptTest.php | 2 +- .../Functions/Statistical/MaxIfsTest.php | 2 +- .../Functions/Statistical/MinIfsTest.php | 2 +- .../Functions/Statistical/SlopeTest.php | 2 +- .../Functions/Statistical/TrendTest.php | 6 +- .../DocumentGeneratorTest.php | 8 +- 47 files changed, 147 insertions(+), 152 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 65789e1ebe..bd6b21ddb7 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2580,11 +2580,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/OLERead.php - - - message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_calculateFormulaValue\\(\\)\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/StringHelper.php - - message: "#^Static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\TimeZone\\:\\:validateTimeZone\\(\\) is unused\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 78c8e2a414..9144122618 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -291,7 +291,7 @@ class Calculation ], 'AND' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Operations::class, 'logicalAnd'], + 'functionCall' => [Logical\Operations::class, 'and'], 'argumentCount' => '1+', ], 'ARABIC' => [ @@ -356,12 +356,12 @@ class Calculation ], 'AVERAGEIF' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'AVERAGEIF'], + 'functionCall' => [Statistical\Conditional::class, 'averageIf'], 'argumentCount' => '2,3', ], 'AVERAGEIFS' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'AVERAGEIFS'], + 'functionCall' => [Statistical\Conditional::class, 'averageIfSeries'], 'argumentCount' => '3+', ], 'BAHTTEXT' => [ @@ -451,27 +451,27 @@ class Calculation ], 'BITAND' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITAND'], + 'functionCall' => [Engineering\BitWise::class, 'and'], 'argumentCount' => '2', ], 'BITOR' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITOR'], + 'functionCall' => [Engineering\BitWise::class, 'or'], 'argumentCount' => '2', ], 'BITXOR' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITXOR'], + 'functionCall' => [Engineering\BitWise::class, 'xor'], 'argumentCount' => '2', ], 'BITLSHIFT' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITLSHIFT'], + 'functionCall' => [Engineering\BitWise::class, 'leftShift'], 'argumentCount' => '2', ], 'BITRSHIFT' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BitWise::class, 'BITRSHIFT'], + 'functionCall' => [Engineering\BitWise::class, 'rightShift'], 'argumentCount' => '2', ], 'CEILING' => [ @@ -541,7 +541,7 @@ class Calculation ], 'CHOOSE' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Selection::class, 'CHOOSE'], + 'functionCall' => [LookupRef\Selection::class, 'choose'], 'argumentCount' => '2+', ], 'CHOOSECOLS' => [ @@ -566,14 +566,14 @@ class Calculation ], 'COLUMN' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\RowColumnInformation::class, 'COLUMN'], + 'functionCall' => [LookupRef\RowColumnInformation::class, 'column'], 'argumentCount' => '-1', 'passCellReference' => true, 'passByReference' => [true], ], 'COLUMNS' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\RowColumnInformation::class, 'COLUMNS'], + 'functionCall' => [LookupRef\RowColumnInformation::class, 'columns'], 'argumentCount' => '1', ], 'COMBIN' => [ @@ -593,12 +593,12 @@ class Calculation ], 'CONCAT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Concatenate::class, 'CONCATENATE'], + 'functionCall' => [TextData\Concatenate::class, 'concatenate'], 'argumentCount' => '1+', ], 'CONCATENATE' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Concatenate::class, 'CONCATENATE'], + 'functionCall' => [TextData\Concatenate::class, 'concatenate'], 'argumentCount' => '1+', ], 'CONFIDENCE' => [ @@ -623,7 +623,7 @@ class Calculation ], 'CORREL' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'CORREL'], + 'functionCall' => [Statistical\Trends::class, 'correl'], 'argumentCount' => '2', ], 'COS' => [ @@ -658,17 +658,17 @@ class Calculation ], 'COUNTBLANK' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Counts::class, 'COUNTBLANK'], + 'functionCall' => [Statistical\Counts::class, 'blank'], 'argumentCount' => '1', ], 'COUNTIF' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'COUNTIF'], + 'functionCall' => [Statistical\Conditional::class, 'countIf'], 'argumentCount' => '2', ], 'COUNTIFS' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'COUNTIFS'], + 'functionCall' => [Statistical\Conditional::class, 'countIfSeries'], 'argumentCount' => '2+', ], 'COUPDAYBS' => [ @@ -703,12 +703,12 @@ class Calculation ], 'COVAR' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'COVAR'], + 'functionCall' => [Statistical\Trends::class, 'covariance'], 'argumentCount' => '2', ], 'COVARIANCE.P' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'COVAR'], + 'functionCall' => [Statistical\Trends::class, 'covariance'], 'argumentCount' => '2', ], 'COVARIANCE.S' => [ @@ -868,7 +868,7 @@ class Calculation ], 'DELTA' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Compare::class, 'DELTA'], + 'functionCall' => [Engineering\Compare::class, 'delta'], 'argumentCount' => '1,2', ], 'DEVSQ' => [ @@ -898,7 +898,7 @@ class Calculation ], 'DOLLAR' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'DOLLAR'], + 'functionCall' => [TextData\Format::class, 'dollar'], 'argumentCount' => '1,2', ], 'DOLLARDE' => [ @@ -1109,7 +1109,7 @@ class Calculation ], 'FIXED' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'FIXEDFORMAT'], + 'functionCall' => [TextData\Format::class, 'fixedFormat'], 'argumentCount' => '1-3', ], 'FLOOR' => [ @@ -1129,7 +1129,7 @@ class Calculation ], 'FORECAST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'FORECAST'], + 'functionCall' => [Statistical\Trends::class, 'forecast'], 'argumentCount' => '3', ], 'FORECAST.ETS' => [ @@ -1154,7 +1154,7 @@ class Calculation ], 'FORECAST.LINEAR' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'FORECAST'], + 'functionCall' => [Statistical\Trends::class, 'forecast'], 'argumentCount' => '3', ], 'FORMULATEXT' => [ @@ -1241,7 +1241,7 @@ class Calculation ], 'GESTEP' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Compare::class, 'GESTEP'], + 'functionCall' => [Engineering\Compare::class, 'geStep'], 'argumentCount' => '1,2', ], 'GETPIVOTDATA' => [ @@ -1251,7 +1251,7 @@ class Calculation ], 'GROWTH' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'GROWTH'], + 'functionCall' => [Statistical\Trends::class, 'growth'], 'argumentCount' => '1-4', ], 'HARMEAN' => [ @@ -1307,22 +1307,22 @@ class Calculation ], 'IF' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'statementIf'], + 'functionCall' => [Logical\Conditional::class, 'if'], 'argumentCount' => '1-3', ], 'IFERROR' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'IFERROR'], + 'functionCall' => [Logical\Conditional::class, 'ifError'], 'argumentCount' => '2', ], 'IFNA' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'IFNA'], + 'functionCall' => [Logical\Conditional::class, 'ifNa'], 'argumentCount' => '2', ], 'IFS' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'IFS'], + 'functionCall' => [Logical\Conditional::class, 'ifSeries'], 'argumentCount' => '2+', ], 'IMABS' => [ @@ -1457,7 +1457,7 @@ class Calculation ], 'INDIRECT' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Indirect::class, 'INDIRECT'], + 'functionCall' => [LookupRef\Indirect::class, 'indirect'], 'argumentCount' => '1,2', 'passCellReference' => true, ], @@ -1473,7 +1473,7 @@ class Calculation ], 'INTERCEPT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'INTERCEPT'], + 'functionCall' => [Statistical\Trends::class, 'intercept'], 'argumentCount' => '2', ], 'INTRATE' => [ @@ -1672,7 +1672,7 @@ class Calculation ], 'MATCH' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\ExcelMatch::class, 'MATCH'], + 'functionCall' => [LookupRef\ExcelMatch::class, 'match'], 'argumentCount' => '2,3', ], 'MAX' => [ @@ -1687,7 +1687,7 @@ class Calculation ], 'MAXIFS' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'MAXIFS'], + 'functionCall' => [Statistical\Conditional::class, 'maxIfSeries'], 'argumentCount' => '3+', ], 'MDETERM' => [ @@ -1732,7 +1732,7 @@ class Calculation ], 'MINIFS' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Conditional::class, 'MINIFS'], + 'functionCall' => [Statistical\Conditional::class, 'minIfSeries'], 'argumentCount' => '3+', ], 'MINUTE' => [ @@ -1872,7 +1872,7 @@ class Calculation ], 'NOT' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Operations::class, 'NOT'], + 'functionCall' => [Logical\Operations::class, 'not'], 'argumentCount' => '1', ], 'NOW' => [ @@ -1897,7 +1897,7 @@ class Calculation ], 'NUMBERVALUE' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'NUMBERVALUE'], + 'functionCall' => [TextData\Format::class, 'numberValue'], 'argumentCount' => '1+', ], 'OCT2BIN' => [ @@ -1949,7 +1949,7 @@ class Calculation ], 'OR' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Operations::class, 'logicalOr'], + 'functionCall' => [Logical\Operations::class, 'or'], 'argumentCount' => '1+', ], 'PDURATION' => [ @@ -1959,7 +1959,7 @@ class Calculation ], 'PEARSON' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'CORREL'], + 'functionCall' => [Statistical\Trends::class, 'correl'], 'argumentCount' => '2', ], 'PERCENTILE' => [ @@ -2155,7 +2155,7 @@ class Calculation ], 'REPT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Concatenate::class, 'builtinREPT'], + 'functionCall' => [TextData\Concatenate::class, 'repeat'], 'argumentCount' => '2', ], 'RIGHT' => [ @@ -2200,14 +2200,14 @@ class Calculation ], 'ROW' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\RowColumnInformation::class, 'ROW'], + 'functionCall' => [LookupRef\RowColumnInformation::class, 'row'], 'argumentCount' => '-1', 'passCellReference' => true, 'passByReference' => [true], ], 'ROWS' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\RowColumnInformation::class, 'ROWS'], + 'functionCall' => [LookupRef\RowColumnInformation::class, 'rows'], 'argumentCount' => '1', ], 'RRI' => [ @@ -2303,7 +2303,7 @@ class Calculation ], 'SLOPE' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'SLOPE'], + 'functionCall' => [Statistical\Trends::class, 'slope'], 'argumentCount' => '2', ], 'SMALL' => [ @@ -2391,12 +2391,12 @@ class Calculation ], 'SUMIF' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Statistical\Conditional::class, 'SUMIF'], + 'functionCall' => [Statistical\Conditional::class, 'sumIf'], 'argumentCount' => '2,3', ], 'SUMIFS' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Statistical\Conditional::class, 'SUMIFS'], + 'functionCall' => [Statistical\Conditional::class, 'sumIfSeries'], 'argumentCount' => '3+', ], 'SUMPRODUCT' => [ @@ -2426,7 +2426,7 @@ class Calculation ], 'SWITCH' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Conditional::class, 'statementSwitch'], + 'functionCall' => [Logical\Conditional::class, 'switch'], 'argumentCount' => '3+', ], 'SYD' => [ @@ -2491,7 +2491,7 @@ class Calculation ], 'TEXT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'TEXTFORMAT'], + 'functionCall' => [TextData\Format::class, 'textFormat'], 'argumentCount' => '2', ], 'TEXTAFTER' => [ @@ -2506,7 +2506,7 @@ class Calculation ], 'TEXTJOIN' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Concatenate::class, 'TEXTJOIN'], + 'functionCall' => [TextData\Concatenate::class, 'join'], 'argumentCount' => '3+', ], 'TEXTSPLIT' => [ @@ -2596,7 +2596,7 @@ class Calculation ], 'TREND' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'TREND'], + 'functionCall' => [Statistical\Trends::class, 'trend'], 'argumentCount' => '1-4', ], 'TRIM' => [ @@ -2662,7 +2662,7 @@ class Calculation ], 'VALUE' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [TextData\Format::class, 'VALUE'], + 'functionCall' => [TextData\Format::class, 'value'], 'argumentCount' => '1', ], 'VALUETOTEXT' => [ @@ -2782,7 +2782,7 @@ class Calculation ], 'XOR' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Operations::class, 'logicalXor'], + 'functionCall' => [Logical\Operations::class, 'xor'], 'argumentCount' => '1+', ], 'YEAR' => [ diff --git a/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php b/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php index adeb1b5535..27346bfbb6 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/BitWise.php @@ -40,7 +40,7 @@ private static function splitNumber($number): array * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BITAND($number1, $number2) + public static function and($number1, $number2) { if (is_array($number1) || is_array($number2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2); @@ -75,7 +75,7 @@ public static function BITAND($number1, $number2) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BITOR($number1, $number2) + public static function or($number1, $number2) { if (is_array($number1) || is_array($number2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2); @@ -111,7 +111,7 @@ public static function BITOR($number1, $number2) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BITXOR($number1, $number2) + public static function xor($number1, $number2) { if (is_array($number1) || is_array($number2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number1, $number2); @@ -147,7 +147,7 @@ public static function BITXOR($number1, $number2) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BITLSHIFT($number, $shiftAmount) + public static function leftShift($number, $shiftAmount) { if (is_array($number) || is_array($shiftAmount)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $shiftAmount); @@ -185,7 +185,7 @@ public static function BITLSHIFT($number, $shiftAmount) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BITRSHIFT($number, $shiftAmount) + public static function rightShift($number, $shiftAmount) { if (is_array($number) || is_array($shiftAmount)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $shiftAmount); diff --git a/src/PhpSpreadsheet/Calculation/Engineering/Compare.php b/src/PhpSpreadsheet/Calculation/Engineering/Compare.php index 4d4bc07e37..25a3098f93 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/Compare.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/Compare.php @@ -29,7 +29,7 @@ class Compare * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function DELTA($a, $b = 0.0) + public static function delta($a, $b = 0.0) { if (is_array($a) || is_array($b)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $a, $b); @@ -64,7 +64,7 @@ public static function DELTA($a, $b = 0.0) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function GESTEP($number, $step = 0.0) + public static function geStep($number, $step = 0.0) { if (is_array($number) || is_array($step)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $number, $step); diff --git a/src/PhpSpreadsheet/Calculation/Financial/Dollar.php b/src/PhpSpreadsheet/Calculation/Financial/Dollar.php index b1f0d25c7b..ca40f168e3 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/Dollar.php +++ b/src/PhpSpreadsheet/Calculation/Financial/Dollar.php @@ -31,7 +31,7 @@ class Dollar */ public static function format($number, $precision = 2) { - return Format::DOLLAR($number, $precision); + return Format::dollar($number, $precision); } /** diff --git a/src/PhpSpreadsheet/Calculation/Logical/Conditional.php b/src/PhpSpreadsheet/Calculation/Logical/Conditional.php index 6a7757ce23..0eb6914775 100644 --- a/src/PhpSpreadsheet/Calculation/Logical/Conditional.php +++ b/src/PhpSpreadsheet/Calculation/Logical/Conditional.php @@ -46,7 +46,7 @@ class Conditional * * @return mixed The value of returnIfTrue or returnIfFalse determined by condition */ - public static function statementIf($condition = true, $returnIfTrue = 0, $returnIfFalse = false) + public static function if($condition = true, $returnIfTrue = 0, $returnIfFalse = false) { $condition = ($condition === null) ? true : Functions::flattenSingleValue($condition); @@ -86,7 +86,7 @@ public static function statementIf($condition = true, $returnIfTrue = 0, $return * * @return mixed The value of matched expression */ - public static function statementSwitch(...$arguments) + public static function switch(...$arguments) { $result = ExcelError::VALUE(); @@ -132,7 +132,7 @@ public static function statementSwitch(...$arguments) * If an array of values is passed as the $testValue argument, then the returned result will also be * an array with the same dimensions */ - public static function IFERROR($testValue = '', $errorpart = '') + public static function ifError($testValue = '', $errorpart = '') { if (is_array($testValue)) { return self::evaluateArrayArgumentsSubset([self::class, __FUNCTION__], 1, $testValue, $errorpart); @@ -140,7 +140,7 @@ public static function IFERROR($testValue = '', $errorpart = '') $errorpart = $errorpart ?? ''; - return self::statementIf(ErrorValue::isError($testValue), $errorpart, $testValue); + return self::if(ErrorValue::isError($testValue), $errorpart, $testValue); } /** @@ -158,7 +158,7 @@ public static function IFERROR($testValue = '', $errorpart = '') * If an array of values is passed as the $testValue argument, then the returned result will also be * an array with the same dimensions */ - public static function IFNA($testValue = '', $napart = '') + public static function ifNa($testValue = '', $napart = '') { if (is_array($testValue)) { return self::evaluateArrayArgumentsSubset([self::class, __FUNCTION__], 1, $testValue, $napart); @@ -166,7 +166,7 @@ public static function IFNA($testValue = '', $napart = '') $napart = $napart ?? ''; - return self::statementIf(ErrorValue::isNa($testValue), $napart, $testValue); + return self::if(ErrorValue::isNa($testValue), $napart, $testValue); } /** @@ -185,7 +185,7 @@ public static function IFNA($testValue = '', $napart = '') * * @return mixed|string The value of returnIfTrue_n, if testValue_n was true. #N/A if none of testValues was true */ - public static function IFS(...$arguments) + public static function ifSeries(...$arguments) { $argumentCount = count($arguments); @@ -197,7 +197,7 @@ public static function IFS(...$arguments) for ($i = 0; $i < $argumentCount; $i += 2) { $testValue = ($arguments[$i] === null) ? '' : Functions::flattenSingleValue($arguments[$i]); $returnIfTrue = ($arguments[$i + 1] === null) ? '' : $arguments[$i + 1]; - $result = self::statementIf($testValue, $returnIfTrue, $falseValueException); + $result = self::if($testValue, $returnIfTrue, $falseValueException); if ($result !== $falseValueException) { return $result; diff --git a/src/PhpSpreadsheet/Calculation/Logical/Operations.php b/src/PhpSpreadsheet/Calculation/Logical/Operations.php index 2e2faa136c..9f27585219 100644 --- a/src/PhpSpreadsheet/Calculation/Logical/Operations.php +++ b/src/PhpSpreadsheet/Calculation/Logical/Operations.php @@ -31,7 +31,7 @@ class Operations * * @return bool|string the logical AND of the arguments */ - public static function logicalAnd(...$args) + public static function and(...$args) { $args = Functions::flattenArray($args); @@ -72,7 +72,7 @@ public static function logicalAnd(...$args) * * @return bool|string the logical OR of the arguments */ - public static function logicalOr(...$args) + public static function or(...$args) { $args = Functions::flattenArray($args); @@ -114,7 +114,7 @@ public static function logicalOr(...$args) * * @return bool|string the logical XOR of the arguments */ - public static function logicalXor(...$args) + public static function xor(...$args) { $args = Functions::flattenArray($args); @@ -156,7 +156,7 @@ public static function logicalXor(...$args) * If an array of values is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function NOT($logical = false) + public static function not($logical = false) { if (is_array($logical)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $logical); diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php b/src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php index 2f691beeff..8806ce632c 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php @@ -32,7 +32,7 @@ class ExcelMatch * * @return array|int|string The relative position of the found item */ - public static function MATCH($lookupValue, $lookupArray, $matchType = self::MATCHTYPE_LARGEST_VALUE) + public static function match($lookupValue, $lookupArray, $matchType = self::MATCHTYPE_LARGEST_VALUE) { if (is_array($lookupValue)) { return self::evaluateArrayArgumentsIgnore([self::class, __FUNCTION__], 1, $lookupValue, $lookupArray, $matchType); diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php b/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php index 417a1f7987..b76b8635d9 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php @@ -61,7 +61,7 @@ private static function validateAddress($cellAddress): string * * @return array|string An array containing a cell or range of cells, or a string on error */ - public static function INDIRECT($cellAddress, $a1fmt, Cell $cell) + public static function indirect($cellAddress, $a1fmt, Cell $cell) { try { $a1 = self::a1Format($a1fmt); diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php b/src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php index 8bce07e908..97a696487b 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php @@ -42,7 +42,7 @@ private static function cellColumn(?Cell $cell): int * * @return int|int[] */ - public static function COLUMN($cellAddress = null, ?Cell $cell = null) + public static function column($cellAddress = null, ?Cell $cell = null) { if (self::cellAddressNullOrWhitespace($cellAddress)) { return self::cellColumn($cell); @@ -93,7 +93,7 @@ public static function COLUMN($cellAddress = null, ?Cell $cell = null) * * @return int|string The number of columns in cellAddress, or a string if arguments are invalid */ - public static function COLUMNS($cellAddress = null) + public static function columns($cellAddress = null) { if (self::cellAddressNullOrWhitespace($cellAddress)) { return 1; @@ -135,7 +135,7 @@ private static function cellRow(?Cell $cell): int * * @return int|mixed[]|string */ - public static function ROW($cellAddress = null, ?Cell $cell = null) + public static function row($cellAddress = null, ?Cell $cell = null) { if (self::cellAddressNullOrWhitespace($cellAddress)) { return self::cellRow($cell); @@ -187,7 +187,7 @@ function ($value) { * * @return int|string The number of rows in cellAddress, or a string if arguments are invalid */ - public static function ROWS($cellAddress = null) + public static function rows($cellAddress = null) { if (self::cellAddressNullOrWhitespace($cellAddress)) { return 1; diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php b/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php index 51e6b00430..ae447f0f52 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php @@ -29,7 +29,7 @@ class Conditional * * @return null|float|string */ - public static function AVERAGEIF($range, $condition, $averageRange = []) + public static function averageIf($range, $condition, $averageRange = []) { $database = self::databaseFromRangeAndValue($range, $averageRange); $condition = [[self::CONDITION_COLUMN_NAME, self::VALUE_COLUMN_NAME], [$condition, null]]; @@ -49,12 +49,12 @@ public static function AVERAGEIF($range, $condition, $averageRange = []) * * @return null|float|string */ - public static function AVERAGEIFS(...$args) + public static function averageIfSeries(...$args) { if (empty($args)) { return 0.0; } elseif (count($args) === 3) { - return self::AVERAGEIF($args[1], $args[2], $args[0]); + return self::averageIf($args[1], $args[2], $args[0]); } $conditions = self::buildConditionSetForValueRange(...$args); @@ -76,7 +76,7 @@ public static function AVERAGEIFS(...$args) * * @return int */ - public static function COUNTIF($range, $condition) + public static function countIf($range, $condition) { // Filter out any empty values that shouldn't be included in a COUNT $range = array_filter( @@ -104,12 +104,12 @@ function ($value) { * * @return int */ - public static function COUNTIFS(...$args) + public static function countIfSeries(...$args) { if (empty($args)) { return 0; } elseif (count($args) === 2) { - return self::COUNTIF(...$args); + return self::countIf(...$args); } $database = self::buildDatabase(...$args); @@ -130,7 +130,7 @@ public static function COUNTIFS(...$args) * * @return null|float|string */ - public static function MAXIFS(...$args) + public static function maxIfSeries(...$args) { if (empty($args)) { return 0.0; @@ -154,7 +154,7 @@ public static function MAXIFS(...$args) * * @return null|float|string */ - public static function MINIFS(...$args) + public static function minIfSeries(...$args) { if (empty($args)) { return 0.0; @@ -180,7 +180,7 @@ public static function MINIFS(...$args) * * @return float|string */ - public static function SUMIF($range, $condition, $sumRange = []) + public static function sumIf($range, $condition, $sumRange = []) { $database = self::databaseFromRangeAndValue($range, $sumRange); $condition = [[self::CONDITION_COLUMN_NAME, self::VALUE_COLUMN_NAME], [$condition, null]]; @@ -200,12 +200,12 @@ public static function SUMIF($range, $condition, $sumRange = []) * * @return null|float|string */ - public static function SUMIFS(...$args) + public static function sumIfSeries(...$args) { if (empty($args)) { return 0.0; } elseif (count($args) === 3) { - return self::SUMIF($args[1], $args[2], $args[0]); + return self::sumIf($args[1], $args[2], $args[0]); } $conditions = self::buildConditionSetForValueRange(...$args); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Counts.php b/src/PhpSpreadsheet/Calculation/Statistical/Counts.php index 13e7af7991..9ebc9a2c99 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Counts.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Counts.php @@ -77,7 +77,7 @@ public static function COUNTA(...$args) * * @return int */ - public static function COUNTBLANK(...$args) + public static function blank(...$args) { $returnValue = 0; diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Trends.php b/src/PhpSpreadsheet/Calculation/Statistical/Trends.php index af73519ef1..c1579730c0 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Trends.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Trends.php @@ -63,7 +63,7 @@ protected static function validateTrendArrays(array $yValues, array $xValues): v * * @return float|string */ - public static function CORREL($yValues, $xValues = null) + public static function correl($yValues, $xValues = null) { if (($xValues === null) || (!is_array($yValues)) || (!is_array($xValues))) { return ExcelError::VALUE(); @@ -91,7 +91,7 @@ public static function CORREL($yValues, $xValues = null) * * @return float|string */ - public static function COVAR($yValues, $xValues) + public static function covariance($yValues, $xValues) { try { self::checkTrendArrays($yValues, $xValues); @@ -120,7 +120,7 @@ public static function COVAR($yValues, $xValues) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function FORECAST($xValue, $yValues, $xValues) + public static function forecast($xValue, $yValues, $xValues) { if (is_array($xValue)) { return self::evaluateArrayArgumentsSubset([self::class, __FUNCTION__], 1, $xValue, $yValues, $xValues); @@ -151,7 +151,7 @@ public static function FORECAST($xValue, $yValues, $xValues) * * @return float[] */ - public static function GROWTH($yValues, $xValues = [], $newValues = [], $const = true) + public static function growth($yValues, $xValues = [], $newValues = [], $const = true) { $yValues = Functions::flattenArray($yValues); $xValues = Functions::flattenArray($xValues); @@ -181,7 +181,7 @@ public static function GROWTH($yValues, $xValues = [], $newValues = [], $const = * * @return float|string */ - public static function INTERCEPT($yValues, $xValues) + public static function intercept($yValues, $xValues) { try { self::checkTrendArrays($yValues, $xValues); @@ -358,7 +358,7 @@ public static function RSQ($yValues, $xValues) * * @return float|string The result, or a string containing an error */ - public static function SLOPE($yValues, $xValues) + public static function slope($yValues, $xValues) { try { self::checkTrendArrays($yValues, $xValues); @@ -408,7 +408,7 @@ public static function STEYX($yValues, $xValues) * * @return float[] */ - public static function TREND($yValues, $xValues = [], $newValues = [], $const = true) + public static function trend($yValues, $xValues = [], $newValues = [], $const = true) { $yValues = Functions::flattenArray($yValues); $xValues = Functions::flattenArray($xValues); diff --git a/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php b/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php index 7bd60e90f2..6d734c3ad3 100644 --- a/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php +++ b/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php @@ -18,7 +18,7 @@ class Concatenate * * @param array $args */ - public static function CONCATENATE(...$args): string + public static function concatenate(...$args): string { $returnValue = ''; @@ -56,7 +56,7 @@ public static function CONCATENATE(...$args): string * If an array of values is passed for the $delimiter or $ignoreEmpty arguments, then the returned result * will also be an array with matching dimensions */ - public static function TEXTJOIN($delimiter, $ignoreEmpty, ...$args) + public static function join($delimiter, $ignoreEmpty, ...$args) { if (is_array($delimiter) || is_array($ignoreEmpty)) { return self::evaluateArrayArgumentsSubset( @@ -107,7 +107,7 @@ public static function TEXTJOIN($delimiter, $ignoreEmpty, ...$args) * If an array of values is passed for the $stringValue or $repeatCount arguments, then the returned result * will also be an array with matching dimensions */ - public static function builtinREPT($stringValue, $repeatCount) + public static function repeat($stringValue, $repeatCount) { if (is_array($stringValue) || is_array($repeatCount)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $stringValue, $repeatCount); diff --git a/src/PhpSpreadsheet/Calculation/TextData/Format.php b/src/PhpSpreadsheet/Calculation/TextData/Format.php index bec114968e..470fdd1fee 100644 --- a/src/PhpSpreadsheet/Calculation/TextData/Format.php +++ b/src/PhpSpreadsheet/Calculation/TextData/Format.php @@ -34,7 +34,7 @@ class Format * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ - public static function DOLLAR($value = 0, $decimals = 2) + public static function dollar($value = 0, $decimals = 2) { if (is_array($value) || is_array($decimals)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $decimals); @@ -76,7 +76,7 @@ public static function DOLLAR($value = 0, $decimals = 2) * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ - public static function FIXEDFORMAT($value, $decimals = 2, $noCommas = false) + public static function fixedFormat($value, $decimals = 2, $noCommas = false) { if (is_array($value) || is_array($decimals) || is_array($noCommas)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $decimals, $noCommas); @@ -117,7 +117,7 @@ public static function FIXEDFORMAT($value, $decimals = 2, $noCommas = false) * If an array of values is passed for either of the arguments, then the returned result * will also be an array with matching dimensions */ - public static function TEXTFORMAT($value, $format) + public static function textFormat($value, $format) { if (is_array($value) || is_array($format)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $format); @@ -162,7 +162,7 @@ private static function convertValue($value) * If an array of values is passed for the argument, then the returned result * will also be an array with matching dimensions */ - public static function VALUE($value = '') + public static function value($value = '') { if (is_array($value)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); @@ -236,7 +236,7 @@ private static function getGroupSeparator($groupSeparator): string * * @return array|float|string */ - public static function NUMBERVALUE($value = '', $decimalSeparator = null, $groupSeparator = null) + public static function numberValue($value = '', $decimalSeparator = null, $groupSeparator = null) { if (is_array($value) || is_array($decimalSeparator) || is_array($groupSeparator)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $decimalSeparator, $groupSeparator); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php index 4ad4fcc8f5..6b5135d4d4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testDELTA($expectedResult, $a, $b): void { - $result = Compare::DELTA($a, $b); + $result = Compare::delta($a, $b); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php index 4cd612b14a..22a9a3b7e1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testGESTEP($expectedResult, $a, $b): void { - $result = Compare::GESTEP($a, $b); + $result = Compare::geStep($a, $b); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AndTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AndTest.php index 11f0376797..10058042b9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AndTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/AndTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAND($expectedResult, ...$args): void { - $result = Operations::logicalAnd(...$args); + $result = Operations::and(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfErrorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfErrorTest.php index c110fdcf7a..72b0154293 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfErrorTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfErrorTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testIFERROR($expectedResult, $value, $return): void { - $result = Conditional::IFERROR($value, $return); + $result = Conditional::ifError($value, $return); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfNaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfNaTest.php index 3daabc6233..74590dc4bc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfNaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfNaTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testIFNA($expectedResult, $value, $return): void { - $result = Conditional::IFNA($value, $return); + $result = Conditional::ifNa($value, $return); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfTest.php index 4bbe66104b..2f9832085d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfTest.php @@ -15,13 +15,13 @@ class IfTest extends TestCase public function testIF($expectedResult, ...$args): void { if (count($args) === 0) { - $result = Conditional::statementIf(); + $result = Conditional::if(); } elseif (count($args) === 1) { - $result = Conditional::statementIf($args[0]); + $result = Conditional::if($args[0]); } elseif (count($args) === 2) { - $result = Conditional::statementIf($args[0], $args[1]); + $result = Conditional::if($args[0], $args[1]); } else { - $result = Conditional::statementIf($args[0], $args[1], $args[2]); + $result = Conditional::if($args[0], $args[1], $args[2]); } self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfsTest.php index 9e75b6ac2b..14b4bdd355 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/IfsTest.php @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testIFS($expectedResult, ...$args): void { - $result = Conditional::IFS(...$args); + $result = Conditional::ifSeries(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/NotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/NotTest.php index 92445b88ae..af5a4c49a7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/NotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/NotTest.php @@ -16,9 +16,9 @@ class NotTest extends TestCase public function testNOT($expectedResult, ...$args): void { if (count($args) === 0) { - $result = Operations::NOT(); + $result = Operations::not(); } else { - $result = Operations::NOT($args[0]); + $result = Operations::not($args[0]); } self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/OrTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/OrTest.php index f96cfa321f..918ac48f0d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/OrTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/OrTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testOR($expectedResult, ...$args): void { - $result = Operations::logicalOr(...$args); + $result = Operations::or(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/SwitchTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/SwitchTest.php index f6e53b84a7..2eec58a26f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/SwitchTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/SwitchTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testSWITCH($expectedResult, ...$args): void { - $result = Conditional::statementSwitch(...$args); + $result = Conditional::switch(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/XorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/XorTest.php index bb3eb903be..c67968ea24 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/XorTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Logical/XorTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testXOR($expectedResult, ...$args): void { - $result = Operations::logicalXor(...$args); + $result = Operations::xor(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnTest.php index 9a0f38369e..1b98e37804 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnTest.php @@ -14,7 +14,7 @@ class ColumnTest extends AllSetupTeardown */ public function testCOLUMN($expectedResult, $cellReference = null): void { - $result = RowColumnInformation::COLUMN($cellReference); + $result = RowColumnInformation::column($cellReference); self::assertSame($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php index fdfe1db5f1..cfcda3e362 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testCOLUMNS($expectedResult, ...$args): void { - $result = RowColumnInformation::COLUMNS(...$args); + $result = RowColumnInformation::columns(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php index 02cee62a23..cb30567e3d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testMATCH($expectedResult, ...$args): void { - $result = ExcelMatch::MATCH(...$args); + $result = ExcelMatch::match(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowTest.php index 901d116620..d93f8d72f6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowTest.php @@ -14,7 +14,7 @@ class RowTest extends AllSetupTeardown */ public function testROW($expectedResult, $cellReference = null): void { - $result = RowColumnInformation::ROW($cellReference); + $result = RowColumnInformation::row($cellReference); self::assertSame($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php index 3c0c7e6ae8..748aded897 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testROWS($expectedResult, ...$args): void { - $result = RowColumnInformation::ROWS(...$args); + $result = RowColumnInformation::rows(...$args); self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfsTest.php index 1ae6e2314a..9e18bd6f16 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfsTest.php @@ -13,7 +13,7 @@ class SumIfsTest extends AllSetupTeardown */ public function testSUMIFS($expectedResult, ...$args): void { - $result = Statistical\Conditional::SUMIFS(...$args); + $result = Statistical\Conditional::sumIfSeries(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php index e36037890e..fe696dad0c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAVERAGEIF($expectedResult, ...$args): void { - $result = Conditional::AVERAGEIF(...$args); + $result = Conditional::averageIf(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfsTest.php index de59376490..55fc6749ad 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfsTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAVERAGEIFS($expectedResult, ...$args): void { - $result = Statistical\Conditional::AVERAGEIFS(...$args); + $result = Statistical\Conditional::averageIfSeries(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php index 9b7baf4bcc..52eaf94593 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php @@ -22,7 +22,7 @@ protected function setUp(): void */ public function testCORREL($expectedResult, $xargs, $yargs): void { - $result = Trends::CORREL($xargs, $yargs); + $result = Trends::correl($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php index e6aff66424..cb65158975 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountBlankTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUNTBLANK($expectedResult, ...$args): void { - $result = Counts::COUNTBLANK(...$args); + $result = Counts::blank(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfTest.php index 359ba7dbe4..66d3054d0d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUNTIF($expectedResult, ...$args): void { - $result = Conditional::COUNTIF(...$args); + $result = Conditional::countIf(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfsTest.php index 7bfeb21bcd..27d7807737 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountIfsTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUNTIFS($expectedResult, ...$args): void { - $result = Conditional::COUNTIFS(...$args); + $result = Conditional::countIfSeries(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CovarTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CovarTest.php index 9cf6bd000e..e631f986f6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CovarTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CovarTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOVAR($expectedResult, ...$args): void { - $result = Trends::COVAR(...$args); + $result = Trends::covariance(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php index 9d17fb06ed..6b6ad79a6e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ForecastTest.php @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testFORECAST($expectedResult, ...$args): void { - $result = Trends::FORECAST(...$args); + $result = Trends::forecast(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GrowthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GrowthTest.php index 9b0f0a72aa..e988c20d01 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GrowthTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/GrowthTest.php @@ -21,11 +21,11 @@ protected function setUp(): void public function testGROWTH($expectedResult, array $yValues, array $xValues, ?array $newValues = null, ?bool $const = null): void { if ($newValues === null) { - $result = Trends::GROWTH($yValues, $xValues); + $result = Trends::growth($yValues, $xValues); } elseif ($const === null) { - $result = Trends::GROWTH($yValues, $xValues, $newValues); + $result = Trends::growth($yValues, $xValues, $newValues); } else { - $result = Trends::GROWTH($yValues, $xValues, $newValues, $const); + $result = Trends::growth($yValues, $xValues, $newValues, $const); } self::assertEqualsWithDelta($expectedResult, $result[0], 1E-12); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/InterceptTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/InterceptTest.php index 9643dcccfd..971063396a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/InterceptTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/InterceptTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testINTERCEPT($expectedResult, array $xargs, array $yargs): void { - $result = Trends::INTERCEPT($xargs, $yargs); + $result = Trends::intercept($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxIfsTest.php index d1d6a19a98..b2b6415271 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxIfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MaxIfsTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testMAXIFS($expectedResult, ...$args): void { - $result = Conditional::MAXIFS(...$args); + $result = Conditional::maxIfSeries(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinIfsTest.php index cac400c336..76f049ae8d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinIfsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/MinIfsTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testMINIFS($expectedResult, ...$args): void { - $result = Conditional::MINIFS(...$args); + $result = Conditional::minIfSeries(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SlopeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SlopeTest.php index 0be7a17462..b2b20bb239 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SlopeTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SlopeTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testSLOPE($expectedResult, array $xargs, array $yargs): void { - $result = Trends::SLOPE($xargs, $yargs); + $result = Trends::slope($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrendTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrendTest.php index 9a8724b8ce..37e1f85980 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrendTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/TrendTest.php @@ -21,11 +21,11 @@ protected function setUp(): void public function testTREND($expectedResult, array $yValues, array $xValues, ?array $newValues = null, ?bool $const = null): void { if ($newValues === null) { - $result = Trends::TREND($yValues, $xValues); + $result = Trends::trend($yValues, $xValues); } elseif ($const === null) { - $result = Trends::TREND($yValues, $xValues, $newValues); + $result = Trends::trend($yValues, $xValues, $newValues); } else { - $result = Trends::TREND($yValues, $xValues, $newValues, $const); + $result = Trends::trend($yValues, $xValues, $newValues, $const); } self::assertEqualsWithDelta($expectedResult, $result[0], 1E-12); diff --git a/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php b/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php index 2edf0d7400..ce61ff4ac9 100644 --- a/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php +++ b/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php @@ -33,7 +33,7 @@ public function providerGenerateFunctionListByName(): array [ [ 'ABS' => ['category' => Cat::CATEGORY_MATH_AND_TRIG, 'functionCall' => 'abs'], - 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical\Operations::class, 'logicalAnd']], + 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical\Operations::class, 'and']], 'IFS' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Functions::class, 'DUMMY']], ], <<<'EXPECTED' @@ -44,7 +44,7 @@ public function providerGenerateFunctionListByName(): array Excel Function | Category | PhpSpreadsheet Function -------------------------|--------------------------------|-------------------------------------- ABS | CATEGORY_MATH_AND_TRIG | abs -AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical\Operations::logicalAnd +AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical\Operations::and ## I @@ -64,7 +64,7 @@ public function providerGenerateFunctionListByCategory(): array [ [ 'ABS' => ['category' => Cat::CATEGORY_MATH_AND_TRIG, 'functionCall' => 'abs'], - 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical\Operations::class, 'logicalAnd']], + 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical\Operations::class, 'and']], 'IFS' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Functions::class, 'DUMMY']], ], <<<'EXPECTED' @@ -104,7 +104,7 @@ public function providerGenerateFunctionListByCategory(): array Excel Function | PhpSpreadsheet Function -------------------------|-------------------------------------- -AND | \PhpOffice\PhpSpreadsheet\Calculation\Logical\Operations::logicalAnd +AND | \PhpOffice\PhpSpreadsheet\Calculation\Logical\Operations::and IFS | **Not yet Implemented** ## CATEGORY_LOOKUP_AND_REFERENCE From 76314ddbc8790e010400ac3ec4c16e4041bbaeff Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 3 Aug 2022 14:28:19 +0200 Subject: [PATCH 83/94] merge from master and re-baseline phpstan --- phpstan-baseline.neon | 5 ----- 1 file changed, 5 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index f94258f0b7..316663bb11 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -2535,11 +2535,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/OLERead.php - - - message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_calculateFormulaValue\\(\\)\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/StringHelper.php - - message: "#^Static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\TimeZone\\:\\:validateTimeZone\\(\\) is unused\\.$#" count: 1 From b30f364a1c0c18ee7598b2b3ba4b14e316f20bb9 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 5 Aug 2022 12:30:06 +0200 Subject: [PATCH 84/94] Renaming methods for Excel functions to provide more consistent case, and meaningful names --- .../Calculation/Calculation.php | 76 +++++++++---------- .../Calculation/Database/DCount.php | 2 +- .../Calculation/Database/DCountA.php | 2 +- .../Calculation/Engineering/BesselI.php | 2 +- .../Calculation/Engineering/BesselJ.php | 2 +- .../Calculation/Engineering/BesselK.php | 4 +- .../Calculation/Engineering/BesselY.php | 4 +- .../Calculation/Engineering/Complex.php | 6 +- .../Engineering/ComplexFunctions.php | 40 +++++----- .../Engineering/ComplexOperations.php | 8 +- .../Calculation/Financial/Coupons.php | 12 +-- .../Financial/Securities/Price.php | 8 +- .../Calculation/MathTrig/Subtotal.php | 4 +- .../Calculation/Statistical/Averages/Mean.php | 4 +- .../Calculation/Statistical/Counts.php | 4 +- .../Calculation/Statistical/Percentiles.php | 2 +- .../Calculation/Statistical/Size.php | 4 +- .../Functions/Engineering/BesselITest.php | 2 +- .../Functions/Engineering/BesselJTest.php | 2 +- .../Functions/Engineering/BesselKTest.php | 2 +- .../Functions/Engineering/BesselYTest.php | 2 +- .../Functions/Engineering/ComplexTest.php | 8 +- .../Functions/Engineering/ImAbsTest.php | 2 +- .../Functions/Engineering/ImArgumentTest.php | 2 +- .../Functions/Engineering/ImConjugateTest.php | 2 +- .../Functions/Engineering/ImCosTest.php | 2 +- .../Functions/Engineering/ImCoshTest.php | 2 +- .../Functions/Engineering/ImCotTest.php | 2 +- .../Functions/Engineering/ImCscTest.php | 2 +- .../Functions/Engineering/ImCschTest.php | 2 +- .../Functions/Engineering/ImDivTest.php | 2 +- .../Functions/Engineering/ImExpTest.php | 2 +- .../Functions/Engineering/ImLnTest.php | 2 +- .../Functions/Engineering/ImLog10Test.php | 2 +- .../Functions/Engineering/ImLog2Test.php | 2 +- .../Functions/Engineering/ImPowerTest.php | 2 +- .../Functions/Engineering/ImProductTest.php | 2 +- .../Functions/Engineering/ImRealTest.php | 2 +- .../Functions/Engineering/ImSecTest.php | 2 +- .../Functions/Engineering/ImSechTest.php | 2 +- .../Functions/Engineering/ImSinTest.php | 2 +- .../Functions/Engineering/ImSinhTest.php | 2 +- .../Functions/Engineering/ImSqrtTest.php | 2 +- .../Functions/Engineering/ImSubTest.php | 2 +- .../Functions/Engineering/ImSumTest.php | 2 +- .../Functions/Engineering/ImTanTest.php | 2 +- .../Functions/Engineering/ImaginaryTest.php | 2 +- .../Functions/Financial/CoupDayBsTest.php | 2 +- .../Functions/Financial/CoupDaysNcTest.php | 2 +- .../Functions/Financial/CoupDaysTest.php | 2 +- .../Functions/Financial/CoupNcdTest.php | 2 +- .../Functions/Financial/CoupNumTest.php | 2 +- .../Functions/Financial/CoupPcdTest.php | 2 +- .../Functions/Statistical/CountATest.php | 2 +- .../Functions/Statistical/CountTest.php | 8 +- 55 files changed, 136 insertions(+), 136 deletions(-) diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 9144122618..ecf8220a67 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -376,22 +376,22 @@ class Calculation ], 'BESSELI' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BesselI::class, 'BESSELI'], + 'functionCall' => [Engineering\BesselI::class, 'besselI'], 'argumentCount' => '2', ], 'BESSELJ' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BesselJ::class, 'BESSELJ'], + 'functionCall' => [Engineering\BesselJ::class, 'besselJ'], 'argumentCount' => '2', ], 'BESSELK' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BesselK::class, 'BESSELK'], + 'functionCall' => [Engineering\BesselK::class, 'besselK'], 'argumentCount' => '2', ], 'BESSELY' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\BesselY::class, 'BESSELY'], + 'functionCall' => [Engineering\BesselY::class, 'besselY'], 'argumentCount' => '2', ], 'BETADIST' => [ @@ -588,7 +588,7 @@ class Calculation ], 'COMPLEX' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Complex::class, 'COMPLEX'], + 'functionCall' => [Engineering\Complex::class, 'complex'], 'argumentCount' => '2,3', ], 'CONCAT' => [ @@ -648,12 +648,12 @@ class Calculation ], 'COUNT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Counts::class, 'COUNT'], + 'functionCall' => [Statistical\Counts::class, 'count'], 'argumentCount' => '1+', ], 'COUNTA' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Counts::class, 'COUNTA'], + 'functionCall' => [Statistical\Counts::class, 'countA'], 'argumentCount' => '1+', ], 'COUNTBLANK' => [ @@ -673,32 +673,32 @@ class Calculation ], 'COUPDAYBS' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPDAYBS'], + 'functionCall' => [Financial\Coupons::class, 'daysBeforeSettlement'], 'argumentCount' => '3,4', ], 'COUPDAYS' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPDAYS'], + 'functionCall' => [Financial\Coupons::class, 'days'], 'argumentCount' => '3,4', ], 'COUPDAYSNC' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPDAYSNC'], + 'functionCall' => [Financial\Coupons::class, 'daysToNextCoupon'], 'argumentCount' => '3,4', ], 'COUPNCD' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPNCD'], + 'functionCall' => [Financial\Coupons::class, 'nextCouponDate'], 'argumentCount' => '3,4', ], 'COUPNUM' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPNUM'], + 'functionCall' => [Financial\Coupons::class, 'numberPayable'], 'argumentCount' => '3,4', ], 'COUPPCD' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Coupons::class, 'COUPPCD'], + 'functionCall' => [Financial\Coupons::class, 'previousCouponDate'], 'argumentCount' => '3,4', ], 'COVAR' => [ @@ -1327,127 +1327,127 @@ class Calculation ], 'IMABS' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMABS'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'absolute'], 'argumentCount' => '1', ], 'IMAGINARY' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Complex::class, 'IMAGINARY'], + 'functionCall' => [Engineering\Complex::class, 'imaginary'], 'argumentCount' => '1', ], 'IMARGUMENT' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMARGUMENT'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'argument'], 'argumentCount' => '1', ], 'IMCONJUGATE' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCONJUGATE'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'conjugate'], 'argumentCount' => '1', ], 'IMCOS' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCOS'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'cos'], 'argumentCount' => '1', ], 'IMCOSH' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCOSH'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'cosh'], 'argumentCount' => '1', ], 'IMCOT' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCOT'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'cot'], 'argumentCount' => '1', ], 'IMCSC' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCSC'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'csc'], 'argumentCount' => '1', ], 'IMCSCH' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMCSCH'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'csch'], 'argumentCount' => '1', ], 'IMDIV' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexOperations::class, 'IMDIV'], + 'functionCall' => [Engineering\ComplexOperations::class, 'div'], 'argumentCount' => '2', ], 'IMEXP' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMEXP'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'exp'], 'argumentCount' => '1', ], 'IMLN' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMLN'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'ln'], 'argumentCount' => '1', ], 'IMLOG10' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMLOG10'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'log10'], 'argumentCount' => '1', ], 'IMLOG2' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMLOG2'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'log2'], 'argumentCount' => '1', ], 'IMPOWER' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMPOWER'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'power'], 'argumentCount' => '2', ], 'IMPRODUCT' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexOperations::class, 'IMPRODUCT'], + 'functionCall' => [Engineering\ComplexOperations::class, 'product'], 'argumentCount' => '1+', ], 'IMREAL' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Complex::class, 'IMREAL'], + 'functionCall' => [Engineering\Complex::class, 'real'], 'argumentCount' => '1', ], 'IMSEC' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSEC'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'sec'], 'argumentCount' => '1', ], 'IMSECH' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSECH'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'sech'], 'argumentCount' => '1', ], 'IMSIN' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSIN'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'sin'], 'argumentCount' => '1', ], 'IMSINH' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSINH'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'sinh'], 'argumentCount' => '1', ], 'IMSQRT' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMSQRT'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'sqrt'], 'argumentCount' => '1', ], 'IMSUB' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexOperations::class, 'IMSUB'], + 'functionCall' => [Engineering\ComplexOperations::class, 'sub'], 'argumentCount' => '2', ], 'IMSUM' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexOperations::class, 'IMSUM'], + 'functionCall' => [Engineering\ComplexOperations::class, 'sum'], 'argumentCount' => '1+', ], 'IMTAN' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ComplexFunctions::class, 'IMTAN'], + 'functionCall' => [Engineering\ComplexFunctions::class, 'tan'], 'argumentCount' => '1', ], 'INDEX' => [ diff --git a/src/PhpSpreadsheet/Calculation/Database/DCount.php b/src/PhpSpreadsheet/Calculation/Database/DCount.php index bf41d6b5e9..242116e824 100644 --- a/src/PhpSpreadsheet/Calculation/Database/DCount.php +++ b/src/PhpSpreadsheet/Calculation/Database/DCount.php @@ -36,7 +36,7 @@ public static function evaluate($database, $field, $criteria) { $field = self::fieldExtract($database, $field); - return Counts::COUNT( + return Counts::count( self::getFilteredColumn($database, $field, $criteria) ); } diff --git a/src/PhpSpreadsheet/Calculation/Database/DCountA.php b/src/PhpSpreadsheet/Calculation/Database/DCountA.php index c48e53c58a..75ca4babd8 100644 --- a/src/PhpSpreadsheet/Calculation/Database/DCountA.php +++ b/src/PhpSpreadsheet/Calculation/Database/DCountA.php @@ -35,7 +35,7 @@ public static function evaluate($database, $field, $criteria) { $field = self::fieldExtract($database, $field); - return Counts::COUNTA( + return Counts::countA( self::getFilteredColumn($database, $field ?? 0, $criteria) ); } diff --git a/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php b/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php index 2afb52bdb9..9b55957e06 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/BesselI.php @@ -35,7 +35,7 @@ class BesselI * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BESSELI($x, $ord) + public static function besselI($x, $ord) { if (is_array($x) || is_array($ord)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); diff --git a/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php b/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php index e23b0157d1..28d012a4fe 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php @@ -34,7 +34,7 @@ class BesselJ * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BESSELJ($x, $ord) + public static function besselJ($x, $ord) { if (is_array($x) || is_array($ord)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); diff --git a/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php b/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php index 2d21e7529a..6a0add4595 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/BesselK.php @@ -33,7 +33,7 @@ class BesselK * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BESSELK($x, $ord) + public static function besselK($x, $ord) { if (is_array($x) || is_array($ord)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); @@ -75,7 +75,7 @@ private static function calculate(float $x, int $ord): float */ private static function callBesselI(float $x, int $ord): float { - $rslt = BesselI::BESSELI($x, $ord); + $rslt = BesselI::besselI($x, $ord); if (!is_float($rslt)) { throw new Exception('Unexpected array or string'); } diff --git a/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php b/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php index 31d9694a70..263a06e1ac 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/BesselY.php @@ -31,7 +31,7 @@ class BesselY * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function BESSELY($x, $ord) + public static function besselY($x, $ord) { if (is_array($x) || is_array($ord)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $x, $ord); @@ -73,7 +73,7 @@ private static function calculate(float $x, int $ord): float */ private static function callBesselJ(float $x, int $ord): float { - $rslt = BesselJ::BESSELJ($x, $ord); + $rslt = BesselJ::besselJ($x, $ord); if (!is_float($rslt)) { throw new Exception('Unexpected array or string'); } diff --git a/src/PhpSpreadsheet/Calculation/Engineering/Complex.php b/src/PhpSpreadsheet/Calculation/Engineering/Complex.php index 691de8b704..d823d79334 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/Complex.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/Complex.php @@ -32,7 +32,7 @@ class Complex * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function COMPLEX($realNumber = 0.0, $imaginary = 0.0, $suffix = 'i') + public static function complex($realNumber = 0.0, $imaginary = 0.0, $suffix = 'i') { if (is_array($realNumber) || is_array($imaginary) || is_array($suffix)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $realNumber, $imaginary, $suffix); @@ -74,7 +74,7 @@ public static function COMPLEX($realNumber = 0.0, $imaginary = 0.0, $suffix = 'i * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMAGINARY($complexNumber) + public static function imaginary($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -104,7 +104,7 @@ public static function IMAGINARY($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMREAL($complexNumber) + public static function real($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); diff --git a/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php b/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php index 28a27a0317..2d5c610155 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php @@ -26,7 +26,7 @@ class ComplexFunctions * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMABS($complexNumber) + public static function absolute($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -57,7 +57,7 @@ public static function IMABS($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMARGUMENT($complexNumber) + public static function argument($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -91,7 +91,7 @@ public static function IMARGUMENT($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMCONJUGATE($complexNumber) + public static function conjugate($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -121,7 +121,7 @@ public static function IMCONJUGATE($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMCOS($complexNumber) + public static function cos($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -151,7 +151,7 @@ public static function IMCOS($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMCOSH($complexNumber) + public static function cosh($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -181,7 +181,7 @@ public static function IMCOSH($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMCOT($complexNumber) + public static function cot($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -211,7 +211,7 @@ public static function IMCOT($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMCSC($complexNumber) + public static function csc($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -241,7 +241,7 @@ public static function IMCSC($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMCSCH($complexNumber) + public static function csch($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -271,7 +271,7 @@ public static function IMCSCH($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMSIN($complexNumber) + public static function sin($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -301,7 +301,7 @@ public static function IMSIN($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMSINH($complexNumber) + public static function sinh($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -331,7 +331,7 @@ public static function IMSINH($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMSEC($complexNumber) + public static function sec($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -361,7 +361,7 @@ public static function IMSEC($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMSECH($complexNumber) + public static function sech($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -391,7 +391,7 @@ public static function IMSECH($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMTAN($complexNumber) + public static function tan($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -421,7 +421,7 @@ public static function IMTAN($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMSQRT($complexNumber) + public static function sqrt($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -433,7 +433,7 @@ public static function IMSQRT($complexNumber) return ExcelError::NAN(); } - $theta = self::IMARGUMENT($complexNumber); + $theta = self::argument($complexNumber); if ($theta === ExcelError::DIV0()) { return '0'; } @@ -456,7 +456,7 @@ public static function IMSQRT($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMLN($complexNumber) + public static function ln($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -490,7 +490,7 @@ public static function IMLN($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMLOG10($complexNumber) + public static function log10($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -524,7 +524,7 @@ public static function IMLOG10($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMLOG2($complexNumber) + public static function log2($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -558,7 +558,7 @@ public static function IMLOG2($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMEXP($complexNumber) + public static function exp($complexNumber) { if (is_array($complexNumber)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $complexNumber); @@ -590,7 +590,7 @@ public static function IMEXP($complexNumber) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMPOWER($complexNumber, $realNumber) + public static function power($complexNumber, $realNumber) { if (is_array($complexNumber) || is_array($realNumber)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $complexNumber, $realNumber); diff --git a/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php b/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php index e525b4b9aa..2edcc7ffd9 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/ComplexOperations.php @@ -29,7 +29,7 @@ class ComplexOperations * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMDIV($complexDividend, $complexDivisor) + public static function div($complexDividend, $complexDivisor) { if (is_array($complexDividend) || is_array($complexDivisor)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $complexDividend, $complexDivisor); @@ -59,7 +59,7 @@ public static function IMDIV($complexDividend, $complexDivisor) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function IMSUB($complexNumber1, $complexNumber2) + public static function sub($complexNumber1, $complexNumber2) { if (is_array($complexNumber1) || is_array($complexNumber2)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $complexNumber1, $complexNumber2); @@ -84,7 +84,7 @@ public static function IMSUB($complexNumber1, $complexNumber2) * * @return string */ - public static function IMSUM(...$complexNumbers) + public static function sum(...$complexNumbers) { // Return value $returnValue = new ComplexObject(0.0); @@ -114,7 +114,7 @@ public static function IMSUM(...$complexNumbers) * * @return string */ - public static function IMPRODUCT(...$complexNumbers) + public static function product(...$complexNumbers) { // Return value $returnValue = new ComplexObject(1.0); diff --git a/src/PhpSpreadsheet/Calculation/Financial/Coupons.php b/src/PhpSpreadsheet/Calculation/Financial/Coupons.php index 6138075c57..3b2cacf002 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/Coupons.php +++ b/src/PhpSpreadsheet/Calculation/Financial/Coupons.php @@ -42,7 +42,7 @@ class Coupons * * @return float|string */ - public static function COUPDAYBS( + public static function daysBeforeSettlement( $settlement, $maturity, $frequency, @@ -105,7 +105,7 @@ public static function COUPDAYBS( * * @return float|string */ - public static function COUPDAYS( + public static function days( $settlement, $maturity, $frequency, @@ -176,7 +176,7 @@ public static function COUPDAYS( * * @return float|string */ - public static function COUPDAYSNC( + public static function daysToNextCoupon( $settlement, $maturity, $frequency, @@ -242,7 +242,7 @@ public static function COUPDAYSNC( * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function COUPNCD( + public static function nextCouponDate( $settlement, $maturity, $frequency, @@ -296,7 +296,7 @@ public static function COUPNCD( * * @return int|string */ - public static function COUPNUM( + public static function numberPayable( $settlement, $maturity, $frequency, @@ -356,7 +356,7 @@ public static function COUPNUM( * @return mixed Excel date/time serial value, PHP date/time serial value or PHP date/time object, * depending on the value of the ReturnDateType flag */ - public static function COUPPCD( + public static function previousCouponDate( $settlement, $maturity, $frequency, diff --git a/src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php b/src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php index de1748a19d..cc450b1f30 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php +++ b/src/PhpSpreadsheet/Calculation/Financial/Securities/Price.php @@ -70,10 +70,10 @@ public static function price( return $e->getMessage(); } - $dsc = Coupons::COUPDAYSNC($settlement, $maturity, $frequency, $basis); - $e = Coupons::COUPDAYS($settlement, $maturity, $frequency, $basis); - $n = Coupons::COUPNUM($settlement, $maturity, $frequency, $basis); - $a = Coupons::COUPDAYBS($settlement, $maturity, $frequency, $basis); + $dsc = Coupons::daysToNextCoupon($settlement, $maturity, $frequency, $basis); + $e = Coupons::days($settlement, $maturity, $frequency, $basis); + $n = Coupons::numberPayable($settlement, $maturity, $frequency, $basis); + $a = Coupons::daysBeforeSettlement($settlement, $maturity, $frequency, $basis); $baseYF = 1.0 + ($yield / $frequency); $rfp = 100 * ($rate / $frequency); diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php b/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php index 6d8f4723c1..7d23e290d8 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php @@ -62,8 +62,8 @@ function ($index) use ($cellReference) { private const CALL_FUNCTIONS = [ 1 => [Statistical\Averages::class, 'average'], // 1 and 101 - [Statistical\Counts::class, 'COUNT'], // 2 and 102 - [Statistical\Counts::class, 'COUNTA'], // 3 and 103 + [Statistical\Counts::class, 'count'], // 2 and 102 + [Statistical\Counts::class, 'countA'], // 3 and 103 [Statistical\Maximum::class, 'max'], // 4 and 104 [Statistical\Minimum::class, 'min'], // 5 and 105 [Operations::class, 'product'], // 6 and 106 diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Averages/Mean.php b/src/PhpSpreadsheet/Calculation/Statistical/Averages/Mean.php index 001c91eb32..1994b27db5 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Averages/Mean.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Averages/Mean.php @@ -31,7 +31,7 @@ public static function geometric(...$args) $aMean = MathTrig\Operations::product($aArgs); if (is_numeric($aMean) && ($aMean > 0)) { - $aCount = Counts::COUNT($aArgs); + $aCount = Counts::count($aArgs); if (Minimum::min($aArgs) > 0) { return $aMean ** (1 / $aCount); } @@ -116,7 +116,7 @@ public static function trim(...$args) } } - $discard = floor(Counts::COUNT($mArgs) * $percent / 2); + $discard = floor(Counts::count($mArgs) * $percent / 2); sort($mArgs); for ($i = 0; $i < $discard; ++$i) { diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Counts.php b/src/PhpSpreadsheet/Calculation/Statistical/Counts.php index 9ebc9a2c99..5c06a76b96 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Counts.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Counts.php @@ -18,7 +18,7 @@ class Counts extends AggregateBase * * @return int */ - public static function COUNT(...$args) + public static function count(...$args) { $returnValue = 0; @@ -49,7 +49,7 @@ public static function COUNT(...$args) * * @return int */ - public static function COUNTA(...$args) + public static function countA(...$args) { $returnValue = 0; diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php b/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php index 99738232e1..d6a65cb1bf 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php @@ -45,7 +45,7 @@ public static function PERCENTILE(...$args) $mValueCount = count($mArgs); if ($mValueCount > 0) { sort($mArgs); - $count = Counts::COUNT($mArgs); + $count = Counts::count($mArgs); $index = $entry * ($count - 1); $iBase = floor($index); if ($index == $iBase) { diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Size.php b/src/PhpSpreadsheet/Calculation/Statistical/Size.php index 2eef5fc7fb..82675e1a61 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Size.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Size.php @@ -29,7 +29,7 @@ public static function large(...$args) $entry = (int) floor($entry); $mArgs = self::filter($aArgs); - $count = Counts::COUNT($mArgs); + $count = Counts::count($mArgs); --$entry; if ($count === 0 || $entry < 0 || $entry >= $count) { return ExcelError::NAN(); @@ -65,7 +65,7 @@ public static function small(...$args) $entry = (int) floor($entry); $mArgs = self::filter($aArgs); - $count = Counts::COUNT($mArgs); + $count = Counts::count($mArgs); --$entry; if ($count === 0 || $entry < 0 || $entry >= $count) { return ExcelError::NAN(); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php index 9f16832811..b51ff36142 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testBESSELI($expectedResult, ...$args): void { - $result = BesselI::BESSELI(...$args); + $result = BesselI::besselI(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php index 0eff38f47c..466a6e8fc4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testBESSELJ($expectedResult, ...$args): void { - $result = BesselJ::BESSELJ(...$args); + $result = BesselJ::besselJ(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php index 28c4bffa62..40582b2804 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testBESSELK($expectedResult, ...$args): void { - $result = BesselK::BESSELK(...$args); + $result = BesselK::besselK(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php index 414ea306c5..7b1636c679 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testBESSELY($expectedResult, ...$args): void { - $result = BesselY::BESSELY(...$args); + $result = BesselY::besselY(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php index cc7e0fc000..8fcbd02623 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php @@ -16,13 +16,13 @@ class ComplexTest extends TestCase public function testCOMPLEX($expectedResult, ...$args): void { if (count($args) === 0) { - $result = Complex::COMPLEX(); + $result = Complex::complex(); } elseif (count($args) === 1) { - $result = Complex::COMPLEX($args[0]); + $result = Complex::complex($args[0]); } elseif (count($args) === 2) { - $result = Complex::COMPLEX($args[0], $args[1]); + $result = Complex::complex($args[0], $args[1]); } else { - $result = Complex::COMPLEX($args[0], $args[1], $args[2]); + $result = Complex::complex($args[0], $args[1], $args[2]); } self::assertEquals($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php index 1ffd3a290f..58d73ffc64 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testIMABS($expectedResult, $value): void { - $result = ComplexFunctions::IMABS($value); + $result = ComplexFunctions::absolute($value); self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php index f6800875ad..60d0b9c00e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testIMARGUMENT($expectedResult, $value): void { - $result = ComplexFunctions::IMARGUMENT($value); + $result = ComplexFunctions::argument($value); self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php index 58288c66c6..ab1bf4853b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCONJUGATE($expectedResult, $value): void { - $result = ComplexFunctions::IMCONJUGATE($value); + $result = ComplexFunctions::conjugate($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php index f55d9ea622..7be6b25cfc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCOS($expectedResult, $value): void { - $result = ComplexFunctions::IMCOS($value); + $result = ComplexFunctions::cos($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php index 00a2ce6738..cd62b37bb4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCOSH($expectedResult, $value): void { - $result = ComplexFunctions::IMCOSH($value); + $result = ComplexFunctions::cosh($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php index 6cb2dbfa1b..890ae40f28 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCOT($expectedResult, $value): void { - $result = ComplexFunctions::IMCOT($value); + $result = ComplexFunctions::cot($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php index 51ca29204c..4fc9634e21 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCSC($expectedResult, $value): void { - $result = ComplexFunctions::IMCSC($value); + $result = ComplexFunctions::csc($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php index d4328b5f12..5da774946f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMCSCH($expectedResult, $value): void { - $result = ComplexFunctions::IMCSCH($value); + $result = ComplexFunctions::csch($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php index 0cf46c6330..6cf5b7e1ae 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php @@ -30,7 +30,7 @@ protected function setUp(): void */ public function testIMDIV($expectedResult, ...$args): void { - $result = ComplexOperations::IMDIV(...$args); + $result = ComplexOperations::div(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php index 5eb92b8cab..7f5f8eb1a8 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMEXP($expectedResult, $value): void { - $result = ComplexFunctions::IMEXP($value); + $result = ComplexFunctions::exp($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php index 806432cd77..03aaf470da 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMLN($expectedResult, $value): void { - $result = ComplexFunctions::IMLN($value); + $result = ComplexFunctions::ln($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php index f22a025335..6965430d16 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMLOG10($expectedResult, $value): void { - $result = ComplexFunctions::IMLOG10($value); + $result = ComplexFunctions::log10($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php index 69c398ff02..aa0d54d7bc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMLOG2($expectedResult, $value): void { - $result = ComplexFunctions::IMLOG2($value); + $result = ComplexFunctions::log2($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php index fa5f7aff9a..4278bc06b0 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php @@ -30,7 +30,7 @@ protected function setUp(): void */ public function testIMPOWER($expectedResult, ...$args): void { - $result = ComplexFunctions::IMPOWER(...$args); + $result = ComplexFunctions::power(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php index 8f798bf2a1..3f79f6be5b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php @@ -29,7 +29,7 @@ protected function setUp(): void */ public function testIMPRODUCT($expectedResult, ...$args): void { - $result = ComplexOperations::IMPRODUCT(...$args); + $result = ComplexOperations::product(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php index 121dd61dee..73258dd2bc 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testIMREAL($expectedResult, $value): void { - $result = Complex::IMREAL($value); + $result = Complex::real($value); self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php index 6da1bbec1c..666e6bff4f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSEC($expectedResult, $value): void { - $result = ComplexFunctions::IMSEC($value); + $result = ComplexFunctions::sec($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php index 30eeacee0d..9503913801 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSECH($expectedResult, $value): void { - $result = ComplexFunctions::IMSECH($value); + $result = ComplexFunctions::sech($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php index 78335c95fa..76d9a8f9c2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSIN($expectedResult, $value): void { - $result = ComplexFunctions::IMSIN($value); + $result = ComplexFunctions::sin($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php index da5ff29c00..370ea3f331 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSINH($expectedResult, $value): void { - $result = ComplexFunctions::IMSINH($value); + $result = ComplexFunctions::sinh($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php index 2fea7106f5..6a21f43673 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMSQRT($expectedResult, $value): void { - $result = ComplexFunctions::IMSQRT($value); + $result = ComplexFunctions::sqrt($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php index d2e9224368..b2a84f058d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php @@ -30,7 +30,7 @@ protected function setUp(): void */ public function testIMSUB($expectedResult, ...$args): void { - $result = ComplexOperations::IMSUB(...$args); + $result = ComplexOperations::sub(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php index e4cd1ec706..56b3709cf1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php @@ -29,7 +29,7 @@ protected function setUp(): void */ public function testIMSUM($expectedResult, ...$args): void { - $result = ComplexOperations::IMSUM(...$args); + $result = ComplexOperations::sum(...$args); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php index 65bc54ae72..fd25a2c7de 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php @@ -31,7 +31,7 @@ protected function setUp(): void */ public function testIMTAN($expectedResult, $value): void { - $result = ComplexFunctions::IMTAN($value); + $result = ComplexFunctions::tan($value); self::assertTrue( $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), $this->complexAssert->getErrorMessage() diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php index 2d3e5d3a42..06fa0d5ca3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php @@ -24,7 +24,7 @@ protected function setUp(): void */ public function testIMAGINARY($expectedResult, $value): void { - $result = Complex::IMAGINARY($value); + $result = Complex::imaginary($value); self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDayBsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDayBsTest.php index 26064b28d6..4392f8bd34 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDayBsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDayBsTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUPDAYBS($expectedResult, ...$args): void { - $result = Coupons::COUPDAYBS(...$args); + $result = Coupons::daysBeforeSettlement(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDaysNcTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDaysNcTest.php index fc9fad1d83..e0c3b357af 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDaysNcTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDaysNcTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUPDAYSNC($expectedResult, ...$args): void { - $result = Coupons::COUPDAYSNC(...$args); + $result = Coupons::daysToNextCoupon(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDaysTest.php index 45cd5c46c0..d52ef6f718 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDaysTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupDaysTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUPDAYS($expectedResult, ...$args): void { - $result = Coupons::COUPDAYS(...$args); + $result = Coupons::days(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupNcdTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupNcdTest.php index 8a54b236a0..432e695c35 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupNcdTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupNcdTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUPNCD($expectedResult, ...$args): void { - $result = Coupons::COUPNCD(...$args); + $result = Coupons::nextCouponDate(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupNumTest.php index 10f6c6d4d6..b6e558e327 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupNumTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUPNUM($expectedResult, ...$args): void { - $result = Coupons::COUPNUM(...$args); + $result = Coupons::numberPayable(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupPcdTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupPcdTest.php index 2e3693b80a..370282e7b7 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupPcdTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/CoupPcdTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUPPCD($expectedResult, ...$args): void { - $result = Coupons::COUPPCD(...$args); + $result = Coupons::previousCouponDate(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountATest.php index 091045858d..db7ad9e10f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountATest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testCOUNTA($expectedResult, ...$args): void { - $result = Counts::COUNTA(...$args); + $result = Counts::countA(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountTest.php index 85cce083fe..56840f680e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CountTest.php @@ -31,7 +31,7 @@ protected function tearDown(): void */ public function testBasicCOUNT($expectedResult, ...$args): void { - $result = Counts::COUNT(...$args); + $result = Counts::count(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -47,7 +47,7 @@ public function providerBasicCOUNT(): array */ public function testExcelCOUNT($expectedResult, ...$args): void { - $result = Counts::COUNT(...$args); + $result = Counts::count(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -65,7 +65,7 @@ public function testOpenOfficeCOUNT($expectedResult, ...$args): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Counts::COUNT(...$args); + $result = Counts::count(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -83,7 +83,7 @@ public function testGnumericCOUNT($expectedResult, ...$args): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC); - $result = Counts::COUNT(...$args); + $result = Counts::count(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } From 39640877799f3d41cda66f89def6253d9db3548e Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 13 Jul 2022 17:42:40 +0200 Subject: [PATCH 85/94] Test for calendar when reading Excel Files. Set Excel calendar to be used for calculations and formatting for the calendar stored against the spreadsheet. --- phpstan-baseline.neon | 10 -- src/PhpSpreadsheet/Cell/Cell.php | 21 +++- src/PhpSpreadsheet/Shared/Date.php | 5 +- .../Reader/Xls/DateReaderTest.php | 45 ++++++++ .../Reader/Xlsx/DateReaderTest.php | 103 ++++++++++++++++++ tests/data/Reader/XLS/1900_Calendar.xls | Bin 0 -> 28160 bytes tests/data/Reader/XLS/1904_Calendar.xls | Bin 0 -> 28160 bytes tests/data/Reader/XLSX/1900_Calendar.xlsx | Bin 0 -> 10134 bytes tests/data/Reader/XLSX/1904_Calendar.xlsx | Bin 0 -> 10119 bytes 9 files changed, 166 insertions(+), 18 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Reader/Xls/DateReaderTest.php create mode 100644 tests/PhpSpreadsheetTests/Reader/Xlsx/DateReaderTest.php create mode 100644 tests/data/Reader/XLS/1900_Calendar.xls create mode 100644 tests/data/Reader/XLS/1904_Calendar.xls create mode 100644 tests/data/Reader/XLSX/1900_Calendar.xlsx create mode 100644 tests/data/Reader/XLSX/1904_Calendar.xlsx diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 65789e1ebe..ffff21e48c 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -990,11 +990,6 @@ parameters: count: 6 path: src/PhpSpreadsheet/Cell/Cell.php - - - message: "#^Unreachable statement \\- code above always terminates\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Cell.php - - message: "#^Call to an undefined method object\\:\\:getHashCode\\(\\)\\.$#" count: 1 @@ -2580,11 +2575,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Shared/OLERead.php - - - message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_calculateFormulaValue\\(\\)\\.$#" - count: 1 - path: src/PhpSpreadsheet/Shared/StringHelper.php - - message: "#^Static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\TimeZone\\:\\:validateTimeZone\\(\\) is unused\\.$#" count: 1 diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 56b5f5f8ca..28c2ef2cd5 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -15,6 +15,7 @@ use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use Throwable; +use function _PHPStan_59fb0a3b2\RingCentral\Psr7\str; class Cell { @@ -176,16 +177,22 @@ public function getValue() /** * Get cell value with formatting. - * - * @return string */ - public function getFormattedValue() + public function getFormattedValue(): string { - return (string) NumberFormat::toFormattedString( + $currentCalendar = SharedDate::getExcelCalendar(); + SharedDate::setExcelCalendar($this->getWorksheet()->getParent()->getExcelCalendar()); + + $formattedValue = (string) NumberFormat::toFormattedString( $this->getCalculatedValue(), $this->getStyle() ->getNumberFormat()->getFormatCode() ); + + SharedDate::setExcelCalendar($currentCalendar); + + return $formattedValue; + } /** @@ -342,8 +349,6 @@ public function setValueExplicit($value, $dataType, bool $isArrayFormula = false break; default: throw new Exception('Invalid datatype: ' . $dataType); - - break; } // set the datatype @@ -403,6 +408,8 @@ public function getCalculatedValue(bool $asArray = false, bool $resetLog = true) { if ($this->dataType === DataType::TYPE_FORMULA) { try { +// $currentCalendar = SharedDate::getExcelCalendar(); +// SharedDate::setExcelCalendar($this->getWorksheet()->getParent()->getExcelCalendar()); $coordinate = $this->getCoordinate(); $worksheet = $this->getWorksheet(); $value = $this->value; @@ -430,6 +437,7 @@ public function getCalculatedValue(bool $asArray = false, bool $resetLog = true) $this->getWorksheet()->setSelectedCells($selected); $this->getWorksheet()->getParent()->setActiveSheetIndex($index); } catch (Exception $ex) { +// SharedDate::setExcelCalendar($currentCalendar); if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) { return $this->calculatedValue; // Fallback for calculations referencing external files. } elseif (preg_match('/[Uu]ndefined (name|offset: 2|array key 2)/', $ex->getMessage()) === 1) { @@ -441,6 +449,7 @@ public function getCalculatedValue(bool $asArray = false, bool $resetLog = true) ); } +// SharedDate::setExcelCalendar($currentCalendar); if ($result === '#Not Yet Implemented') { return $this->calculatedValue; // Fallback if calculation engine does not support the formula. } diff --git a/src/PhpSpreadsheet/Shared/Date.php b/src/PhpSpreadsheet/Shared/Date.php index 6c43bca4a3..547e875ca7 100644 --- a/src/PhpSpreadsheet/Shared/Date.php +++ b/src/PhpSpreadsheet/Shared/Date.php @@ -67,7 +67,7 @@ class Date protected static $defaultTimeZone; /** - * Set the Excel Default Calendar (Windows 1900 or Mac 1904). + * Set the Excel Date Calendar (Windows 1900 or Mac 1904) used for calculations and formatting. * * @param int $baseYear Excel base date (1900 or 1904) * @@ -85,7 +85,8 @@ public static function setExcelCalendar($baseYear) } /** - * Return the Excel Default Calendar (Windows 1900 or Mac 1904). + * Return the Excel Date Calendar (Windows 1900 or Mac 1904) + * to be used for current calculations and formatting. * * @return int Excel base date (1900 or 1904) */ diff --git a/tests/PhpSpreadsheetTests/Reader/Xls/DateReaderTest.php b/tests/PhpSpreadsheetTests/Reader/Xls/DateReaderTest.php new file mode 100644 index 0000000000..30bbb660bc --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xls/DateReaderTest.php @@ -0,0 +1,45 @@ +load($filename); + + self::assertSame(Date::CALENDAR_WINDOWS_1900, $spreadsheet->getExcelCalendar()); + + $worksheet = $spreadsheet->getActiveSheet(); + self::assertSame(44562, $worksheet->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue()); + self::assertSame(44926, $worksheet->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue()); + } + + public function testReadExcel1904Spreadsheet(): void + { + $filename = 'tests/data/Reader/XLS/1904_Calendar.xls'; + $reader = new Xls(); + $spreadsheet = $reader->load($filename); + + self::assertSame(Date::CALENDAR_MAC_1904, $spreadsheet->getExcelCalendar()); + + $worksheet = $spreadsheet->getActiveSheet(); + self::assertSame(43100, $worksheet->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue()); + self::assertSame(43464, $worksheet->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue()); + } +} diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/DateReaderTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/DateReaderTest.php new file mode 100644 index 0000000000..51e59d3bbb --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/DateReaderTest.php @@ -0,0 +1,103 @@ +load($filename); + + self::assertSame(Date::CALENDAR_WINDOWS_1900, $spreadsheet->getExcelCalendar()); + + $worksheet = $spreadsheet->getActiveSheet(); + self::assertSame(44562, $worksheet->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue()); + self::assertSame(44926, $worksheet->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue()); + self::assertSame(44561, $worksheet->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet->getCell('B1')->getFormattedValue()); + self::assertSame(44927, $worksheet->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet->getCell('B2')->getFormattedValue()); + } + + public function testReadExcel1904Spreadsheet(): void + { + $filename = 'tests/data/Reader/XLSX/1904_Calendar.xlsx'; + $reader = new Xlsx(); + $spreadsheet = $reader->load($filename); + + self::assertSame(Date::CALENDAR_MAC_1904, $spreadsheet->getExcelCalendar()); + + $worksheet = $spreadsheet->getActiveSheet(); + self::assertSame(43100, $worksheet->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet->getCell('A1')->getFormattedValue()); + self::assertSame(43464, $worksheet->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue()); + self::assertSame(43099, $worksheet->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet->getCell('B1')->getFormattedValue()); + self::assertSame(43465, $worksheet->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet->getCell('B2')->getFormattedValue()); + } + + public function testSwitchCalendars(): void + { + $filename1900 = 'tests/data/Reader/XLSX/1900_Calendar.xlsx'; + $reader1900 = new Xlsx(); + $spreadsheet1900 = $reader1900->load($filename1900); + $worksheet1900 = $spreadsheet1900->getActiveSheet(); + + $filename1904 = 'tests/data/Reader/XLSX/1904_Calendar.xlsx'; + $reader1904 = new Xlsx(); + $spreadsheet1904 = $reader1904->load($filename1904); + $worksheet1904 = $spreadsheet1904->getActiveSheet(); + + self::assertSame(44562, $worksheet1900->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet1900->getCell('A1')->getFormattedValue()); + self::assertSame(44926, $worksheet1900->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet1900->getCell('A2')->getFormattedValue()); + self::assertSame(44561, $worksheet1900->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet1900->getCell('B1')->getFormattedValue()); + self::assertSame(44927, $worksheet1900->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet1900->getCell('B2')->getFormattedValue()); + + self::assertSame(43100, $worksheet1904->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet1904->getCell('A1')->getFormattedValue()); + self::assertSame(43464, $worksheet1904->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet1904->getCell('A2')->getFormattedValue()); + self::assertSame(43099, $worksheet1904->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet1904->getCell('B1')->getFormattedValue()); + self::assertSame(43465, $worksheet1904->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet1904->getCell('B2')->getFormattedValue()); + + // Check that accessing date values from one spreadsheet doesn't break accessing correct values from another + self::assertSame(44561, $worksheet1900->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet1900->getCell('B1')->getFormattedValue()); + self::assertSame(44927, $worksheet1900->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet1900->getCell('B2')->getFormattedValue()); + self::assertSame(44562, $worksheet1900->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet1900->getCell('A1')->getFormattedValue()); + self::assertSame(44926, $worksheet1900->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet1900->getCell('A2')->getFormattedValue()); + + self::assertSame(43099, $worksheet1904->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet1904->getCell('B1')->getFormattedValue()); + self::assertSame(43465, $worksheet1904->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet1904->getCell('B2')->getFormattedValue()); + self::assertSame(43100, $worksheet1904->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet1904->getCell('A1')->getFormattedValue()); + self::assertSame(43464, $worksheet1904->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet1904->getCell('A2')->getFormattedValue()); + } +} diff --git a/tests/data/Reader/XLS/1900_Calendar.xls b/tests/data/Reader/XLS/1900_Calendar.xls new file mode 100644 index 0000000000000000000000000000000000000000..69027c5b181674e7c79ffb46aa62743da445aae2 GIT binary patch literal 28160 zcmeHQ2V9d^*S`q?f`SYYMO4C2LD|!VOhu3-;Hm==!Vn}HK(R`pidEd=R$3>DdoSEd zQ4|#wv}zr=s&!kH`nERTInP7FlZPb2+qd8E8@c@MGfwXPpL5SW_uQFKdD-y(+TCqy z2rKj^8ssmD4$)%JIq>W*eK#QRxkQ4m(z_cx14$kJ7imC;4;87UNxllds9jFDM2k;I z4cvF}PQjIs2M~voafC-mXskFz@ZS~uC>dfoD8orGJTG|SkV2pu5>rYtBkJ0cy6&XX z9i^^b#E3|8Bst`(yw2SqH-UUZxIR?6xzyE?y0(BTha9Bx+@dJXqyzaG((}mzG<7cF zYIFQaEJ-EFWHb@O^?y!^E+h$L^pHua$C6Y)LO|X`l0-5nsqHu%NPQI5sia)IFQ)hz z^radDwPz@kNtyPHznG%e7gO~9LJAJ?R#{psi`y4c5J;ig5;#QXix|zmfWalLzmS3h z7OAS{Q0qEMF*@+t5KYpO5X<$JR(4iaPCbX)OCLM%+JlF0!}x4iq%eL2GeHNU4Gm6~ z*};jKAKp6ftU$aD@+nv-R5Ewcg*XusgUq`KC`n@MX<6!D>pr!#w}j7P?0sVFJMip? zE$NII>yr&-bBvQf!&|+L8^V z6(Pf{?YlX39}yovTrd{GaKR)99e9SMi0Bf6FT?GDY#$$gpBO{c5%NJIpzieLqyXuf zQu=%8M{4@t(GTY35CIK=S1wDR`|3X8t(MonjJ{I|JzoiZr4sroCG;&y=-ZUgmC3VI zN&2ly=*sYwrQfXt=bx76FvS-d7~NiE^>SPZeZLa=K_&FPO6YWX8}g;)Y2HAd?G%o_ zl)l)|a9Q(Z%?XdL7eg66A>oAi33I}u<S9GY$-rR&tw1%%{6pF*dX(OG=;r0He)q3s8T zqf-1)@Yq(01Fn;%%j9I)XQ82?Nplm>Gu`f5NYev8t!HVw(4lcydd7(krGJ*3#!`9} zj08z;MAW;Hs2nij9B-;C3@ihHQ)_L zp;Wg7T}=z<5x5OAV3He_)0t1%#|Ysai{AgXJpU1LC8TvgXj`^JH&t{s>i zepx3juBvMXdfvu>sIDDB<3Lo`jz!}@RM(EB90C`w7)wR>PaUiN|$3_N%?cG2qCQT|7(r9Qxq(U)i4M(wEA-T$N0ehTm*VGL5P0irY)C{mdKnR-x{4d#B9&v#+{f>>J+IQSEiG-}TYy%7giytR44gqt<* zB%1h)dIkA9;$jA}F=VrGX~@P>1smFPQEW7Y34cDiu9%Gxn~iHjHl0+kp?w?0MoXCR z^5sj#Y+AC}xHV+cMFku5esxOI7A8pERVZd-%x2@>kd1>1Hs~|!*zko3cb?ZOX48tz z#-kw{7Zq%1FGwj(N0{*7^)1D0OpuM6YD+T*Hg1iuw2F{@Wxpt9)0)jjfu&igV8gVu zijdzgY*);t4V#SuOY5wH4b##pLT=x_t(c7|n~efX>#Bkc)6yzJBu`c-X496(OA*1`t0Wq~p+1d4o;C>(~Fn&z?wK*gH;67BR=C&LtTv< zz_|xl^!JZVjmu1p%}5rd74W~62jrSaniKknQXI*IgG#Y5^hzco7=qyt8~a`a#gVj> z0WL#O473PrDZz(04dOsz<{Mw`O-Jr+5mz5ha=`Y5f08gRMc^+?O)cQ(u;gkjX$Ep7 z!C)|sq`=V7AD&X-k13Tx^N~u0gLN&LRP>uvD*8<-75%n|%OhQLH6#UmfxIZ18c=k9 zP{~;MivUHTI1o zlVmv@ad0wrEBaFaFpR94Iv1zdxBJm_av@k29fFCFi#dVh$kUk^} z4(MUsr&0AU0zoE$&Z9w`EU*Wh*GOw0E4$9Tbf9c7qYo5`z)*Y2<8snc zgDWChpg3LP3G$OLVP=Ln7TgQVF>~61V-5pgEU6f53LOhQqoMpMEQv_Vi|ZzJ1`j5c zOQ1Qr%FD_jz%mRhT}(L$gsRg%2OhyY%i2pfY%gJ=3}FF(v^)m48MGI~$N-@Tluzn; zabZR3(r{6v-qF%;QkO=*NnINKwusxDbSJRv9-f&&)%Zjf(^dc-PU)awoiklNdPuoC zM?$?M^qW)?`b{bc{e}*+N3JI5&RSjsO--nX2q?2yHt|Q5p{e#nQ;kl}NCj;<%jeS2 zhw6z2>&SqLLwz;0b`C=Hq98;WXaTIX2MtpS0u@fzK94dgx%CCqyVQ@+rIo&+i5U_v za6DvitT+u_7VTcW@Q1Afu?G%G04#CAe4xmJyXC6lOTDDmxUXHwVm^17{>parhA7NdK=b$e(bAQyL^tAAAzWH-RXn5n@vJ z$R$hpgLRiOKGB=QB@z8Kc*Y{62CN~)L{AzgOdsKp zH8yqI!V6(%oDBNZ_WN_%WBcI3JwE)7&!(Q8cXr*Bljl}go0R{wXVbtxYD2C@`xOgJ zQtfWK*8b4*q4=1&_Wm==3pWMteCOBI`ng%)h@yL*;WxJr%Kx@)n_jU+`pe&!96xH~ zIU_eHe`RFRzx^XYKPw15UIk&~d%mF{Qd7i(p+rx7I8;>;( z>}o&6>(%2=%dHh1+Kjgo-eSK)^(L3|@%$wpdvLfu1#CX&P z@24%VRpboI0gXst5Gb#&qU)P}ISG35fZD)g9x-BJYPzEXUi0Q(9&^S?cgE}K$EID$ z9&q(cn~oD4ix&7huFoblHaSU_X1C3r-wr>k)$9mAZ^P@_&0c@)nEk0{@h<|Cm0PsV zJn;9vkW@3l>qO4f^648kb>t7r8u#7$$+!2%9F4fLzSl)(v!Z?noR%2r&%7CaG;)Vu z{FQQptHFJ4yN$Na*|czc%nkG9KbYS42)XvbB=Uyms2%f*%O!iyI92=*eky0D-QzyI zG|$B$$&W^_Ep~hub!=q$#O>*fB;i=0BjXwh z!<|H-7%fD%BDC2Vfq_p=_S%UHZhFQYvFS5<&xIXFJ`(@Jw!UZATwQ(p#^Z<6JTKid zu3pt&Z>U|Nw%#n^MTeOO-%PRFWLA8uU%MaeQftn(dh#r*P5HjLE$;=LOCOMJRlQ*P z_WgGR*Y|g=ws>uKXXIh)Fi=q8RW}XJeTR+Vi^5WR;_~(YE3pJj%>byJEDl+m>zo04y`&VM$$O#!;3!)q~ zn{DXhsQLBtwKi?naN54VY91%>UG>+@7Kg7o*baEB(RZQA0pj03+x5?Gu036QPX6W9 z-kD!_Uf%rlgOZq|1K)VH)4w^h)b~!#&#$LUxLunU@RmQoU72%O7hOmwzn#uFYu|qk}`H#{E9FA}h~&_`6YYrB`g9&V5>zur}i6OoRMv z$G(QeUhU?W8%)kFx_WP@jVS8SoT7;4{^utLyC1N2o8V^KC2x6tr^k17)@7Q1G~Ioz z_cxug=UZCT%qWSe%=xSA()W7%yjrgl&)sHm<4R8Y;ln4B_H3?wbV_i0Uv!scU5>2y zMsJO{)r}noy1oqF7_Lz{j^8=-@J~IquDW=&T}tlNoh|NcACs~*sYdVfu&#v@FZ>!; z<8D(O^VO+|JwkV_n|@=Bam>h5%gpxoy>NY}ukGPICKobyo2-p1>q#PfW?AQZb?^VCjh@A< zRWl1Xo$vP6@#7!m{TOmm9J{yDHuY4_2is?&TkDg|to*-v%k4B;81(jS>4HT8*FS5o zsrD3z?j7wu`LBPy_#{en99ifk5gtD{NLc=IZ8xXKcO}1nxOXq7=JSW=`mbZYS(J8c zPU}v8-MJid{EyG`^*7IG`OC(vKVEK~xHIP1=T}?3bH097dHlkalX{_lKMlg#q3Hr3F3~PbU=d&^Y2W1C7-1P|PTR_ku_IY0elKi)Sh4)dpOwZEOQ zI!mwbh)roVEzNWeYOZVXE<42D^{#(ZzU8v>y=N6Czsa`tZ(V+Oj(+IyVg24@4 zd*^3UC$7kzQJnHdW7dt5KXgtlJ#smmH{as$%Ej-%|7fA5w{(cd@Bac55Ue9dj zd2EipS6Qf|>*{U8!yOkLbgaBtoE+HW@fFwANiWYOhS?(fr z{!q(AtCQAwJGWGv(lT+l-|s?JVfp2J-N_cgquiq3FDdY;7^r=^|MJ}Yg(D~YIw-5h z+>+GAVLfK|ajy>Py4A-e#&Pl9%;k~g#v?XAxppMvSc2J8+vihr3y$gP#JR32T{gV zAVt))wj(@j~^H_?Pqb?n%ygGlU{s({qy-jrhW-C3rf7d z%XgkK*Jx(@wLg>?=-uCcA>!Tp?@k0K1RYvnZ+*JzevfAxZVD`o(&rZxzuNjR5dbb( ztQ9?3mz*#?JgQcFe!IQ+PUPwZ19hCT61)SekNNmI6+d1z zw95Elwc9rF$0^l2+RxVb!T+UYpVR05wPgCOjz@&ndDAKbp`3+BMHtfIkt}Ix606sB;-W|`` zFuOo{&_Yody?EUqCbZdUC*!=@sT27k(X|qTg`MuqtlVCuk@v`5&%@h#z>Al9JM8!l zGh&agNItUc`|_4?E_a=iwzTE{d351X>eMzxTP z5fqGZBl^n&u!ni|xt&0tj6okeBYW6XpV1V?lgvtBtDlX;9>dflT~~xejcC{yY$K@0 zxCzTNOlee@L_~j0JWvL+Hcc`DN?(QNp~)(kuB>8AE#Lz(2WWE`G)#wy>2IzY$bECQ zIoB9JrUI0QeBGCjClK{uN`q5!E=;)esb@pD;uMKb{@ncbYUt<)?-+{Sg`#(*u2U&W zE@Nuc5hlWf2sq!uC#PV-L-6}vWEzz^kGgh()Cp90;@z3?Y$HQ?>TSz-4ka6*F#TZq zCxE$p0{kUYQ|Vxs9A*G50_L6~xOamU5!`FXbwXbf0ISH(@a|T(I?3T_X#Gsi>1doF zTn?1<*JdJqJlyq(9ZVWwvd6*Ikq`BSSQn1Z0j&6=spJ@UT84QkX7E&7_h9LqSOe5*w^XNZ#l?D7(dj_m@_kev8 zM@SP#Z8hQkPC9Xb(#fB4VJ?F3efa-;N(l{*3C zjRj2z>ts)%gsYbsw@u{3e^zE^N@nc4{*KHjk`B+u`Ohp53H^OED zS1MfdmfqnPT3~;?kTqJTAnGo?aO;!`0|A2%{VdI6UNe2%>VlypjsfWrB|R48b8#aB zp9OUH!O&kGF^z#{Mo1#RHAI?*R~TI5m{$Y9Y3}tO{qK1C3-)Q6QR8=cd9lFv zr>}nZDLlzw>q0*1+IjCyC!no?2s^WsLVVzk^PzqaQ71zn8bM5gh_#vv5l-B}h7-LF zv>fg@Q+NcK@GD`M2Y*xuZVKPA-b0h)#G-UjLWZDER-7=E_y8@p#poV`7yrbeo}YE^ zcy#GcFuzd;wFcB0P-{S~0ksCy8c=IMtpT+L)EZE0K&=6_2Gkl*rU6y+e{S`~>Ou!I zgGI|={%`kb2hRUXA>s->t`9^&#B%~T@5f*9iHC^C7gHhP+&u##9{-#I5s#1NL6ois z;QGL7h|Ki>SQelHJ(oA2u#kY57})m?zy#&M^$7YXEYSrLLgMlQCLb&kr=;U4*>q|p z2UDwqS_5hgs5PM0fLa4;4X8Ds)___AY7MA0pw@s|1ONXtfHPv8FyovX=ihh`4-ZG+ zoErD%ajuUi8*nm>b9S7+;|UF%_v0Mj5F+mR<2>IOBA$oFxjwE3w1J4fsf#~}i@#`# z-}q|}5hv&75Csq|AX-ASf{6b|sw3PxLBwwt*g&*}*ac!&i1@iZ+#Mj|uPr)3#4}2G z-UpAB;OCzq;$0mYr-4W~?}Xo?7QoL);HgLa>4>HT6QW6-fI)6(M*==x2{}n!;jpcO zfb}CK52nsrrNEb?QH~TTxzTs{FHkc6C_`g2h6U0oHAxip1#CP!ie(Q1EhJDfA*KGu wRFvV`0Do*l*nS$z-x|TN@j%dob4emNd4*pBr++!GY4UXYH_C5^jO+OS7x`BoNB{r; literal 0 HcmV?d00001 diff --git a/tests/data/Reader/XLS/1904_Calendar.xls b/tests/data/Reader/XLS/1904_Calendar.xls new file mode 100644 index 0000000000000000000000000000000000000000..8f52d97cb6fa199e46c5ddafe34891932cb6e6fc GIT binary patch literal 28160 zcmeHQ2V7Iv_rD1Nf`SYYMO4C2LD?XLKuQX11MH0RI!R%+)C?2QQTYH zN>LOQ6|`y{xTM1qgfs~g+{Nge(dX+Vb$6{)33z6!gjT~4?} zi%&=mTzBzK!6zXPAdVp836GGF7;&=Tzbp7sGQ@CDhLd1;o^Zz@1wb_rJJbM}1ntCx^74J`YlPZc%h+(t-R8>G@9Zo z4u`m_ig!O1c^I5G3XQwN?Eh}S_r1q+2r){S%_PJ~1w^DY8Pl4yHcmiouKx0d#n@Gjck zJKDYj&yLuV&X}=2*$Box(&f^75<3D7pUDUWVDX|U_3XU7>KVF`uEdeSP@21rzceew zmYJ_D*+^OuGThp}yHk&mad9IA;~Ooq^bXGjW(E+P0Z!XC)>adG#FF&G>n?QVZ zO$l9@Jj;}%FIGZVhOaFBZY4PXv^<9?zBnMI+Ka4Sjw_+>S3*CiguYh^oi1-fzO+2r z4dmHQ;lMbGmUD@r;qvCon-d;gFFG=MeEbRX6Xt|R%cBWShbq?}kbnwO`?OU;w^Ksz zqLAJUFe!YNKWQ$d%k)XxA-F0!eH96ZTXPtOQRUK;r<+LWE$Zn4LUN!_q0`IgEWY~E z^fLX>_5;IFDc{j>+g6HWD5cBfWZ7qdp`l506VNl=?u?}A0iV{hv|Z>Z)DLu!3iV?w zrB}g7ko1x10UW);^aR{I)h$6+(*k+~Zo>?iq)8d*v0f86pdd}+fCX<-2JGsZlmXjflQLigz;!{I9L=w z$l|j>&~-Ed1kF%62>O#ofS_qA2SF#(2oN+^7HY27#w)wKiNO=BccT{|$%X$*+!+JO$MF(9gI$E}_&X!4G&HVD(VAk?8jfPSLUNVk0`@rBuBjR9o0`F)sTp9!sIClH z+gO2eifuS7fyJ;ohlUwob|IfZYGY-;F>Q=JwsDq$V0B`YNrL7El_9Ush8guow8m#tKu@o%8u2BpxhdP$i|S(#-$+}OBHNr&qcA(6vqGc=(=JyMr<~&4cT;3!G`v2 z6dNsJ{L7aw6|-r{X5-e7O&1kx(EHUXOK6c}kVm4-MHVQ1wRRtTSrBwu%-QTB}O*>@cuG-QBz{b51mgeF* ze~Xg3Y0qY(z|yQ$uwh!7i|e~xxr$5Efz3vNrP-)p!?ZLP*Yfgm#ca&kY!q0UoeDNg zOLK9R+>BSuM!;sHz|x#luwh!7i|gvsPZYDUV6#zRX>KamFfGl+bxY-ZMQn75C5&%~ ztl#uu^_%S_+DiLMLj1+0G$?kI5bF9$U1C)a3Kqo%wP1lVt%#79ST=WlF70h4msM8!-17UTcX<_hdi%V#1Tf|q;KZoYzQeA1k}gymX*!FryC;iNH{M$>Va`N_Zpy zlqO=CDlSGyv4EKrs|B1?f(5ny!kDD@Jo1%Efre75UQN%0W@UR zDDy>9?}IBMTA(;x;sNrLP+>;8I0oDc%Q17>fnyE@U@WN^YziFe6sgq~6iePg0jgKS^C0{j`|dob({D>>iepPSyA%7SmP$9Y*P(VVyHw zK6*&GI!8jiB=nP168cFh3H^i)vuBPb=+0VR1Wiq-h;S&gST^xTm7%HjLQ{=ON>2f8 zIm_qL(1+@Y0_#YJibH)hv~~_c^rj$0>1YA0wFeDT3IY{Q*FKLjD!KIq)VtJ=(500= zp@|t1PjEbBNQ^iYT^8+Lz2pVuHV02V1UQJnkfmNrkz2)1oYL@o{!lWXu}HEIN@oav zQ2;WADs3c)Jej%+fwH4B%mBM{0WBtxiIfG^r(hlgbtj{#qslX&R3*4r1(p$+C={kU zuj02Ms~9|KvnAMpkPUFWdjsPg=9>#<%z-nKr#O6waHRj&7UVBD!zm3Cs1H7g<(oj1 z(g-oByXBH){2{u_7;p6Ea!L3A4W2Pbgk%fy?5_R^Pzh-V>rpM?I^0i`nhtA7(NUAf z3)4nAWR6SOw&+6W87G6jwf+B^{@6aKV2?MyiO#N#}(EO7VazYau3}We2mH)kaCz(*C*7I9 z%{VswO4h)uXWDd}=vcVW&v8Q*sjPA__-T@tKH)HdB>cOHA{XG zn5^2Wb>@Me*M-EIiJm92rtKj5^~NPpJN zu%i(>eB-W^8(a z2^|@qAu!xY5Q@=4bSpxdoe>y#*JQ1mwD6`!>=B#3WAD`@L;cJ0+Qw{JXt zINjsYJ>%-t1N4U36=>_t7G89ib@266yUk`rxB9pH(JrOtY^x{FGTW5zo7eJQ;JLJc zSyt5xXKdepM{s?A*J_L3?Cy*@Y(3Us zbZcOUO&7r##eOktfXK|l;CSn&*+X9(+a34Z&~%Z;^H!aAr&vWqJnA1<=Q9D zy=#7?qh_;>eH}Hwe!kA8?OIOTcUR401wN}k&uVe_s)OyoHyZsGnH(T~1F~HI>h9Xh zwbztiUhSRrb>|h$Pd_M$K04^NXFL6yvr2vLWdHoz)QPuibN%1&2bw%A@j7$*#F5{h zb)HmtKzBl}=fVX)x^Mk+-IDSTW#6?q?P7Fr=(N~B##LnIT90@;I=1wR?bCTr%i`CC z-<)NTm*v>cu*kFBf^vf?S%p{c4YLtN9-3Pi-rVo}l%Q@0tlcKM*>=fYk=N<*U7htA z<{wOVU+eQtr>q5*7Bw?VqARmMmtFc^Z=YxD_2PNkEN)!MPCI<~Wa6GJwU15-Ztsig zvb@WYmEY*C6}P&v<3QJ!L7T!fD#!CXhaCQ?XYuNbSKB4$T;18?&i1j%#fdd~pN4lW zm~`RS*qUxO)zM#_n$$C7*ZLVZ)*45TIXYcly{K-!pBe$;9D>TMMJ7`vyHI zZ&nh%Bc)sG%@+l+{b~zde|5NOOX{Vizu3(B&aR}&B-Z3Y#%_~!v1PqTxc6-9JkK5j zUboS+n7w*dKBx2DK03bqqr4x3Pl{vqR@$bV%6@PAOmu5QqM4Q7S8uqT#s~x7yeVC{ z*#G(`?X}e&0@1yrJ*IsA*Ncy$1jkVYo)Y2lgM)?TFV}TGPe-(Z~P%v_OB$%$C1w%KY^EyS5D^E2IkI~ zloNI=z;2pG&p#e=P89fi`IqKfw3d& zOG|hEe#U7}&d9RF=@T|{I&3|r+q`!3g!^|3!a{zw$_*Vc#baPfk3*gzf@4O@&&SWQ zUlm~dqmgF!va69NcI%YQzvkJobWief-5xDd?2c_NO%^rK>IBrhJDvQ}htq%k|s4TtP zx+Q<$qxR0vrcGLzHM1!BwZ`llC4cIiT6W}e7;k~a;Z;lCl7T0J51(0H>$La5L5~fw zxg&?gFAo?z@y_E?)AsX{M$h=rr_A{K^@e44AO6`wOK;gw_sfA^e2d~2F+)asdQaT8 z^?94-iHoD6_pY+6&D-UBV5Y`_@4_Y>SdtlUGv6S3^G9+t_100nL6=qr=|3AkhO5ut zmu=t}x}jaO${1elSK9+D_KaO#V)82U`w17aTOU4q|9I~Mi6ibG=b27TGVT9jQ-$`p zYXMca1o|ubOw&5EG}Wh6ob9mw*R3Y2dp<7v5VHCRr>#}-y}bTYQ-9xE^dOnXhe>YbX~J;M402^gN~Iqi;@C*KEC3*Ch_IDgkYPO<)%OW=^K{C>wRTz z&s{~2-W_V0V0F?ucjwlMQ(7ht_xoSSEGWO6r#rvB(&$8zTK*WyB2%9L_03oo3SFI+<4@cC)bVyAB#78YWsXzPW~}nomkh^ zrOT%KXY4MTyD_0;w41h0)}G{;foZ!AZLe}1vHvu;NI2@-fK>esRnNaU%(E2m&U8<_ z9B@8tOL6PF)t8QjhV69S)QVF%#?ewxn;tS@@`(V%6{oEsahG4A`NS^f=Z^JM`f9bI->1Ub5--yjH?z?~GiguIgHFV(gpZ=}WCw zPdhTD=4q8#rEPYup!9t8dYAjN_?Z*JgSYpveBH@zK-}cN>|1S`e5+e@-)C)tZWxC6 zy6v=ycL}TMxilgD-Jp1lhhx8qcPfg>pKQ^NxAo+ze*3p34el1vBDwh0N8j_}epf4! zH!U3$Rh^#ToIJCy>Cioot7jiQH8y6McKUF8yHQ)-g2Jj!U(LKS zWbAE{6anZlHc*9X2bql@5;h82jGnv z^zL}hhS>$ugBFUy=*8;>F(J)PI~nKJPMgFRiLR9xEb4S;R^|38joe4w^xVCy2flcz zx5JL_Ff-=(%A_O9zb|hY>vGpQacf(C&u2>~tU5LB(2M!r5hkH|H+#kH8a-{k$m3vzjyYN9$u_ z45m~Q(`DhSBzr$~Z=09kXl^p{^FW`pn=>?R)|XY>w_3e5n0J17NlEEFSIWDNS)8QH_8`i!P9o@7=6Tm5V#_86uf>AE5$YDB}v zU>iX_#!XnJVM?RIB*F)1;(;=lwP})(Q2Hu74^39XbY(STY5_0ET%gTm&@de)roXvr zAotDH=3HZZO$8_q`MMt=Pax{Slm@5dT$pg_Q}>4OiBlv#`D@FYt07~;y`m|47mD7M z`kY2lau`#ijxZ4>M8NqL-kgF755ezyk?BiV;6R*yUdm9WAh~Qp3t`qtYe^^C!hG)0B)kzLdL+fX9 zPDkSe;c}p)zcv%`|oLelRXZujs#PfxI`fassC=^)B)fXb%|HpuLuZ?#1$-A z@DB_fWJ!uRJYK1$&s}pote`aDfpQv8imo)N`o;fI4K$_Ziy(1iNK_E2!ho#cOo4Xc z0WHHF{+vlaXdm{_THK($_`#hUto8Z>)gDs$QK{^K(gSF&@aF+nXINqN0ZKQL1&Gu_ zt8Y>&eDfVXBKk)92M3cusYzmC8s3G+j2DU{lfD)bA2)bN5c-P5aYAv5Ff9#M2~&k6 zL>QM8gG(MHGRh~^-zUPqZYd8j`^Cfx{Y8^fNswp^W)8!=Br-iFH7-URN5aHOuwX*% z`jGIjh^Ppkz$l6dy%;z!BPJy&eKPP7kBdnmexelEArg|XP=pH|G(H?;l;-ybfn#y| zh(shMB&Pd{($hubh=0cT6k#R_4GZl{B7|w8lng3~e|Vs)lT#){1Qm%xL~%m;?(dje zDXaw!cJmLB*6rZ%@W6AGwS#N`bQ`=o1QA0nT%ixag*kEvVk$`kpGW_}qb%Teqtjuf zyC>|EI6|6OYO4wNchZOhET^FlMZcK_F&lpCdQ ztlaS+ZwzQcSSNcjC0xDCxNRaI{<`ODR)6cJ<}!lCuRP3^vt#o+Ma27 zox$Sd!#|;8C-7p8*D+h(i6A2_CALGU+-&RkC**FLZ77nPmNF6K&IC)x4IOrnmwOVl zg-PHeCV_1_P%RqU{ZJADBPK`CLJ#=EHip})*mBZ9A2HM@4RJ?9%mi8-KCnV#_@DN`DKD1>-VQg9@$4q;dl4IbFh&e`T?eOHI8aI)Uvgl? zXUDPQxKiPom-Gt1&;tA81+39J1yT3W8@EoWFbFXC(9hC5<~P&Ftu7c!;uw$~QPN{U zJ{LDK@LoW79~^yxG<;yvzJVPh41GvW^T*!!gel;tYmdj?H-M8rJQ>60Ngp_NdVpf( z4HRjZ1G9`da&mJ?dl)}!)bWILc$dI$4N;m2#pK|aR|CLl?)9(!cier3eVS&}_+4IJ zEbRRmYuciH(YT()E^@1WGF-;WO5INK&j=lqQN#7xc}H6{Zkxpyjj}({sp@pE%UL z%VD>p%YK6SjXJ0`pw@s|18NPZHK5jjS_5hgs5PM0fLa4;4X8Ds)_^h%sG9$Ct1ng; zIG7nMUJmnryN^3?{$C0aSLktlARHo|6To>t{)$f=L_EHj0ukr#=@9Yw=TwMzd^8uL zbUgsq2i8Djt_Q%f02S!Dya9!U1jNL^zIFg6C> z9v+UsIW_Lj<6Iw4HsE9$=j=Ft#}gVj@5ed5Aw=Bs$9cXnL_80TbA4P7Xaf;{Qx|^{ z7k|+fzwy@|B2LcDAqpT`K(vHt1rh&`R7bdWf{5QPuz_d`u?xhm5b?b|Tpb|duPr)3 z#4}2G-UpAB;QLPy@v07u(?A5AcfxN`3*cuY@YEyzbVO5v3DKlZz#uoYBLN>j2{}o9 z!eLtl0qaLf9zvbBN`@~-qa4Xna-*;CU!Y|CQHI853=N=DYLZCm3)pye6w4k6T8O7) zLQ4IQsVKv>0sh#Au>CZazcqqk*WfO}-QC??L+}vXU4n!V+^uo90KuKFlRNX}UMBA^ zm^r<=&N{2lepXfWezul^G{g%G02BZQ0058xmY4Zptib?)`xgKJIsgV-OT^a3$;8G< zPsQEN#8HRQ&Dx4M?*%w@4gehV{{OE3;vFbUlC|k(MhU)3_6Y3<(y}-yzQy#1v`%GE z+5?MXBf*NXc87v%Jnp@xr-c))l1!RA>$tLth0b@jti=>%Urx@`I~RqLyBlb7r|I~3 zd{f&WmsFZ`fh1K8hLOMau%zDt>-SQPmtIT+L$^S5>2+z<2^fCtlt4qoHQR`Zf=BK) zF_C9G)u(ncyCmh0Bq4!n#nTf?mkrx1T2yQsq8!U32MUD>BXsrOn^)f{1*Reii}N^|d|mW$MGVK)ztP<`2WKrtY!XY8i>9^mW|sRL&xp}-_HY4WSIeM5#6zw8(h&%FA##Y& zZ7!F7BvG4-Qgjj5R22mRgFz=(L|+gWpPnE93jbhf{aa?TbCBxEfJg`rVyT{kiIpQ0 zsF^A%qGRwNfUxNnusxXr5!vmJOy-Sv#EKA(wZ zcA`IcG00{0E0MCJU9*l#e5J^_@YSqi|1tR9y_XZVr?mg%TROFua?Z0EF2yz z05JPV){ZXNg+!u7qyBwcU$DTRY#yES)nZjb7q12+UfC*S)asKs8F9HP9SQmId$Y%o z%*dEntTuhl_f8C&v#E9L$+U5A6$<6qDm1WiMbslGfD3W51e|Sv(gWx;;vF}#olkYF z4LP#8l|uded`{vhQQ9kR0nBo6!^UE-@FJxGk!I~5Dz`Nc?HOOM&0yY*+kMNaeyxW> z7sZaa*PfyDUMrfOlpSeDnWm#wrS#_f>|7d%duFaXs*7t~LE`Xgw7BSuZdZVEXJy26 zWxKLh+Ld>UXj57_5gj^V0`>T4g%aj^uqt&|MH>ESlyXO*=%sf+o8X^7H12?+9p{ubD1GSuVvZ_}{!S zMDB+H+T$Zw`6jqMlB7q;KlDz0^&;y|7Se93y$F@NW6y8#Z(t@EuMlCQJXjju&I784 zc2Mk`SQrXx2tIIredz@O-|*4Vq4wj(_38Spq5R6(B%b+2ggsB+}4Y*%gT_ zvuUWHfJp&^K-s`}4!4|I+X)_tVLJThJfe)UBPwUh*zDo!whRd~vpS`XYtXrh|N z9acV9#^~9XrBH4POs>upf5~v1EY926!Ms(wfK`%cl*21@^1%r%>4_($x!ql&Uuy7c zh#C`u`C?O(Bo*e2+OB6Ee~cw9@BMHrc( zXjX}opgGVfNHsHoe5T$34jPZ!CIF06i4dI;hC&K4!a zcHk-lyhrf;m(Gic2wk8>{@_T_xiTX7ku}anf3d{L%*5J+>DTy+Acq>mk$9XKo!Ga6 z2#&7zuQp;SmRCou5|_x0-zVYMHykRevau$#;h}?5a9=1<7Zj!n+wvz(yoNw*KaYha zuiGOUry8CkE8il|w35> zp^WnLjz~wY7xFoBw$g?bRh+FvgY9yB`}CO(3hu?HjA`FchMrc>tn_zXg~oGB z1yMSs3TSZfFHOLx#aq{ zF9`BuFf~n))ZDARK#EBiG}{m~O8q7k8bqnL*OdbPk40n=4a}?s$vXPs>Uc_*ZicskA5ZqqLOc0=&v$Qn^lF;xX{BwTDU_9urepP<9v-ll^*SF<_J45h zO;P>m?(Mw48BFbb`oVKiwZ4eS)Zu-4x|fK(;(f6rA4{+R#3x8QAqlTOsaP{Qri?W3 zN4om~CiuRWS-3ahHR`TQ@zG#ExULrQez$Yg_iiA*dLLvPU#I1K3(=2e@|g5W@oLCL zqbL^~SDw|9jKPx=yKI@I#Ixq`*6^`-%OggqGQiaiTaMbg(tLE4$u?pHT6hsx*MxFs zwMY~}X{$)s)+|5kx=dC0`4LKGVAv#uh=V?b5@Vf+Vc1}|331TE>F~03Wlyo?G{2WI znE_}X%syeCw)zIm7!?ndxJ6lB5p+ZvZ?Zc0c1ciHFp-OTM9`ew8qo(yZ}Ws+;0krZ zA#5Ps5$g1EBuG2#PBcg2u*LJc%tb5kIWEW~^!NHuB9Vy2y9P>Pd&SQ4it>x#E7Y(o zHo`V^KfEJtg50#oNTLe6H5nnOZi`B9C&G3LsERaM;A@zx9}Z{Z=f09 z`_99Ck%p{@2a)!ns6^72_>PM1wm8q?LfEyNd zIO1|&A1C+<7yV>$>)mv;NNk@Z_Us{D-y@d+L>;l_cD4L#Z@B}ih6z$$3W&Co}x33 zq8^ekhOTLl?tHrXxRd(0!hUM5rnvnU9J4hhrrXx#s#yD0sL+B?$UFR`9V5(-b?I$U z6>uZz;vR`?pVGk;44K%7W1W=eTkPE}oXtzx#R?e6qMT}@nJ1V7u-E8$hg0q}`dZRM zri4V&>C*!H85Q7y$tsha#LDV4{1d2Md$EnpgH$=EG#(06fqX5FBg$)>ch^OT!h zUP@-$T)P^iyu_{v6;0yNPLvyfVu?@lOzLIOWAIHzWFN=Rv!+w?LlMy2$aqahlxdIR z#M|%2+C^p_vV^0UEl1?Prd(n7Sn_3spp1MTzq_3%I<_5xXNMEDKwX`Q4mu{>FEY?! zf0)HTvkEhQ>&A6mf52?EEnaxqaO8fK-9n~LGdhsFweNotNE3D=+#MI}%v z7qy`@*ab&*@S#e3-3Qq>SDWcKzDz zdWZJBm;Es+@%y{_fgBBM7mMI`_59Q?+U4@c4rh3Rb<4Gm5j~cw#_{=1+Q|@+7N%_! z4mjcJ9U8S@EGSHT@->Q~lcjiz8}S};9*F6T^tWidjXMBW7Of3We@tt9>*)KoKtbvi z6aawum-}^ea55hhro@%twQ4DxO>h`2cE}-N zy?v#~x8Pi1;M1QF!wR;|_1v3NFzdZ~AR9xm;K|aNY#OBST2Not!&0(K$TGhou^3`` zW9f}5ak{vxnR*Fs7tSc1U7PB(V=QOpBMiRTNCJuaqo;Ne?@YV^mgO*=_r?ylw0)?c zT(RP6ARsFc)|rYE66Yg&6wh1L7Q2M*o$|%(eJ^Dz8)xCLxk~$?2*FQ-{bTp7oZ7**h}J0y97er9#S;7- zGd|^Y-D59YN9vm00h{kkL-3mubMJ$5UnxDzpylcE8uBfyEBr;=sfH$u_ zhr9{p9%2<&J?9IF+!ATtyVvfSY?>&dRD4X_a!wK>I~vC`O_vYI$&85cs;kmw?V46B z%@;PJ3wr?+Bo~U2iklQvy@mf%(#C7eD%}O*fiQ?IWPkDDXM+E)r0uVa|99&4E8h=_ z?TYAT#t^%LcocE-Oq>Zu5K-nNZF;){VR*X$1x$^*!g%nk#W(r9wPiQD#gTc(_X+PE zQat@s3wZFR5w=;?iRS`Cr%*N5{vrk}17DoMBx6Sggq)mI_}4gfO!(?xMe+xn9-rR% z>KNEhaRS@(lHu;m-)z@8tWWiz>zL%~kLfqP)dG3=l{6j?W4wv@Z1Out-kgpG zNpi>O3*^1w?ic%h>Sri);Ch*D>5cTF$a-k->=O1*JFtTU8G8w`2nBEe0M%bRVCP^C z>Wn!kn>aa{+n72sJ$q(hG&Hw4R2{aNe2qeQ1+5t5#|f}sALEd;q!wF`n__6PutKN8 zL=*0w%IqsSs6RwB7g}_KA0sYy_uPsXn_0?)?TbJM8 z@TK3Z-))Y)s`(U6IED+W8A5%?ofH?;A?wI4VlqUin2b=O2xU>dR;RBAh zJQ=R}`Aq=dv4~!gr1c9ACA=?93G*sAiH9>kpvs#@Jc3wWcjPUx>3EOT7-*Is)a6G< ze~(rZ)M>wCt4xLCjk@u@<0Lzw>byrnYQ5NImDq=CpV7@>+*WwmI7U|&bekqzzgwIN zIpmb_#R|3-cgD*Cj`wUXQ|v=v#h7f?hp*RYSi{suC7LLTOFd)iPSMGj7GgrAO4;1H z^k|%JjKw8J)r=ObKg7@?*eRsN1NOU-+qPZk`>j<|Tp*yIfe2Gp>-a$hsAVoivb2NSyJbg^aBAE-c?_? zs&oGGleHSb*TtukLT3o^mDPF1ARyf?>~3V7&Kpr0E~ewaN8VL&F_xuVG!MAGL%(T` zZ#`bP8Qe+kY{7N*4!D-#4`>%B^rS?kgxM*qa^-$H(kFRFQTDO&#a7yaRcyPa5RVN8 zBI|7*G+6C9q556paCpCyfxFZ+4fbpH4e$D5yW+X=iwa}Rak3@}GLPa5drwrq8@gX{ z#vh70wMN~!M?~rtxZ^_Jk;op+!p3vE8&F7+C+jn*np@d9t39S}M!IVXt=%|uG~ybG z;+2>OJ7O^QxE|y=%*FCp4I|t)=P5O-xC>SJijBUr&&M;XuA(9r;pR54hMVb=a3k3T z9t!Nb#{VALxj%3+akYz7^-?Pe{;rE=?!$mOBP7t>jrZ|rs5w=K1-kZpX9Yxz|E%~d z$&FTIf_`ZMeNq0Rj*)?tk%*arxy?_1$`{l1vnn8Z9Pos4X`}3k5?>Sy=i~45IiW(9 zcs|Jr<-s#QC)M8_f^9N(6lW^1=DHW^QWid9u4w+uaMh*#FeayfcoYXM(H|Q&s>fwg z3*qu`thNM^9!i_$K+>{0hEyt1bvS3L62bhj|&O(-uW&9vVa;OJAeu*b{g9nDLB~LIWig9I+*-i38?k< zzZxfK>w*&Wq2Ko4mEh&9B6|)yGhNPzA`27oI#PAULoFxOg20s8A=~m>rmBd)-0E0KTgO1KL0}uZYi5OVroc5~_gTr1z3|C3JU1A%p(k5j2)}D|^h!rq7*yb;Ae5s3$ix5VR zlzFf;UtXFESg`>LK9BiD^5?Rlbj$MTI<3P-2r zOV%|awWHUMmjg_H)I8Kx53od#=Fxzs`CCJ(WfA%~fE{PD9 z@VJ*05d6#X-f*5*8Gx-fn7%DC%B>*}D~ms$m9H7^)$rVpCSuYRAf>3dYG;57GixiI zb5N`S&$^7ZZ;e=*?PT<+0+(zS*Er5GgnsS9(CLGkxeFo6>L*rXr(PXHUB)G`Bvfe^ zzrg6MN#rR;6U}=BoH1*1fa{&Ye zP<5%`_cXf@W*$3m!ztM@4nd*6vB)Bu387zIamgq3e%+RZ9*cl}98^2(H95q+a=ppE zCwN?c9Ow`_#US>)ivj?QposAQZhJk)dEWl`jiit8|0nSu z&5-9P&&$KVQ9?lFZP09<7mJ?*JWp_c13+T`0{EToJ{NtS3;Y(v#C^VkKV}Bc0iTD~ zzX7rFegQrUtp6BjKL>ptbo>TYBK!sVj}YX!^gliQZ&?5U57f^155NCh{GaCf@8ZcM ce-rc!}()PjKHMqM&a0wh7f(LgA?(XjH!68U+*I+>c1lQmi2pZh=JIUPnGQ-UK z3-0Z+PWS57UA6Y!T~Ad#Ra-#@0umDd4S)pz0HlDG6@FN2FaY2l5&*yez=CT5ZEc)P zY@GB|-0e&pb(q|&tw`QOg45&zz(Mc-@AxlXf%2r+Hr*_!!B@#1p#zI_tWJt=u>7H{ zQyG=q2Zg3dhZ$N;68V@|`W~utYgllHco{i$crY4K};e zc6>OxsT+t(DoeURmaYNA%wK<4*8d3S_d<=2K@5ngTOhjps;v4Lj39PeurcDAebhw3 zBkwy2v1dDVNjte+lJW=AkU+KKnMtL~#_y|I)a>6xIafya6$%wd)$_4x6k8l-h$RpA z7tD&=bQ>9T^uu!LtN_IgVqqcSCkSEOxbW^tFS<5N#&t>q=o4A3WIw^gJfh^`-w4fA z9ws)Cr^DBVN1W$rjxx=vK3+G!bMK^)i`4$eVICf#`l9K|J0OQDU$*KoI@;+b;rIn{ zuPLIjhpsK@mrO7+YlgLoRDtkpQcIJI=Jkpe*85z~h_MQea6uAR%b+2o1FihBQ3wQK z3W(6}+%5yiqBa+07(mxl6$L_rAtzTPUl10bo*)1Ue?w`*8y50&km<>SK!^ZBsh)$0 zl_N9L&-4G#`Ckmlzf8S6;kA4Z3u4HTE#ATc_ca}A9D+NH1>i-YA>#m{%KSJMfaZ>ls^p zIup(4#CY&xl*=4YBI7{6W*d{}r_8H+MocbsIo2&r1ILKr2Sa)x+`o4KQyphmERyf`M z3dtCM`eH8&I&w5IC{z^w?Y%;%&&87WXZ=c&w{d}s_#5w|gK}Ve4TX)asJo`S6rtn` zia$$d0qW=D1&?#osYpFZ=Lq`NxGDOR4$}4s4%MZOqRZO|Q?B5}%b&!_Nh(z71tE{3 z%?@KSqQ~Ua_)VL#oX{#t={0v`w{W-WRqK-IQ=r{ofi-VEq32Z$dK}+1=!}ug@h^UH zXHt~LA~zcHclbnOLcg%N2d%Q41LZP?zgW2fO_#PA@df=-R;=Vzk{0!onjhmO2L_3& z(@4ilZMI@IRD5n^#@AlA3S%XM3gl-1`G+m-h$;rf3x`Mh$C8S~E&ej>sy9t4s39J3 zj}u!jlgJW>m~kSRhxC$UQHH(~*UMrMVqgSJq8+XHqM#n9`c%!fB*3nWDh7Yz#-4a}eSo+xLk}hFQ;@7_+30EUg>kJ^)M$wy6U+ z=@uh^K$tl&N&;D($=5Er4|L=Lq8WU;MTUg> zf$DbA9S110KQ;;F-$3&c_@T4zSrNbR9rj~=5!Lq*y09V*$}LuLnl)mb)v2z3;67N% za~-^)QNl!v0>K+D@S~O%zHwAR)mYrNxfaUXPR2ZUaIw5rm-Tn*m+GD)oO|z8tx?c7 zUoksL?20;hy z$K0%STf<>g*=V)1xBTd%bAitM;p1XAlozU_%jU-Q@A#MxDCGPzAWcib)t-VdRttKH2Y>|wVeOBY^jF0F8K1yF z*&_(C|J_G8TkosJ*=P3;llZR1|YFvucZK=jmtY z8e9njO#Yba-%k{!*|1?=ixIGHO5sf9@(fK6DP{y7D%uR5>K1hpDdf0Cc$bmP1Ov=@(czeC0zz)#$%!Jd7lVJDSSm}%)8o~N0( z&RzteA*#zA!GogK|gOq?8|TCG_oX)(d- z38Y_M2N*tiCuQ~f5nxZpl~4;MkTrPCmBqCAJ5TN;P$|m7nHgA=a8Y`DYm6Pz*k|vj zyNUy)P}X*O_RcFU6pf2%CM3+@w3Po;ncU7dk<<+Jp?MkkK^Aw0{Cz^!c_^B6 zIQr))ar~h&*iO>&{e`zsg4hrW;~Gk_K)|<3$}3OpYBba_NDzt3b+j9py_7ubq38 zx;tctDUYB{#Tc8=Hk^xfw9HQdK!qfzBo@L238^GR6qx5C@L+^P6NUmG*WxX$YMbgf`!65(1l*{t0pVwxt}4-7Y_P6u!{&Jvs$u z;8*9_tDV3z#{=OU3se^#LWd0IAho;&vyo=_{JS5iweoE5@(nUON^BMxKSSDjpg(d|9W>pwQ@>809d1go zYibc5%=M`qrHWZ_a^7;2zehBm$BN4na_ik5C#_H`usI@)pN{g>->DGU0J8>uWV~t_ zVZP3fMw!!=Vcr1k<%Jcj`3bQ`%&z*J!E7Tev(mT4&It&ZP!D)5?e`;E=YrH^_#MAS z@;smK!a?njg8=~gNPe>JUtn-DGqE;d{&oI^g9D9`NPI5LPMljIL`T>Am)~M3SJuX? z5|=5AvyuoJ8V?jz+1V1>@G-zCc`lS_3JOz2Yz2}gUqK+XpU1*c)bA2cP>;-!S8P#a zSV?QTAVo?%wtx6=mF?qk=5#XI{?0?<9YS|Pie87psX%7b+&hY?6kkhj8V)ac$)qSW z6F8e21crN=#T*|8H0v+0{c{jEqE>k+#8Nzqbl9I^L*ko1z2){_rHbm8>?Y5_?k6A& zTzQ90U#L`pOP+A88(^s5>CHw;et?uL?dw_6Ccn-aFM-N)>P@?jgNi5YuBl}dCAS_5d4`^45FtM8>g;dr{+Wid$t z8>s17s0UH3-G8zFpxN0t`2oy~BOtk`agKLC*(S~aN#S-TuT|~n%@Fp=xSmd33t?$& z@NBM%Z*>SU;>R^HgeqZLLG7NSGs#9*u-1`4+)(2gm_A(b5{Da)#pacyZv9kK}m{J@ncq&B{MMwB0it!<8^;aTfl zq@039w+%t3(r;FwMUsAVT_x!MSVSJt$ih~TtfL>Uj<0m-X4v~hw(*`mcZQ3EIa|Q< z@p$(vv{S(MeCMV|uePOuPR0g?Qd#+MCRXq1;Q?nwuk-PE?}Tf2n);->xAXpHD7EwH zg!iI)V+o77!~67fHxXym`(j%@mT+N_fbiWhX?V?X<+{-kRiuGG^4$rTP*yLCNN>U` zv>lh?!=V9iT`iKmZs+PB-HQb3eNb)uotE<-iBDQ6V$!O_YoL~lqFiuYdDlwQhmMc! zvSpVO&sxG;!^h(-51FLP0ax4XxoR6q^U>8N-;pBF!;84PCY3vDfKh~Ht-!FYSpl{U z+3N7~L)5CkuqjHQgFdAaQ$5fyY^d9WBxvDuWW~Cwr`U2vz{{B205lF3pRkgxz9BOv z#RDZCQP!7)9g)VHY!1F%5>%DU6rvsxv}dGX0Y$T;jw zwnXBx#|ya3MJw<-F32Vf^!iXClZwT=21?<0#m@7I3IGWdYFU?>;2OIh-jX##ZCa!! zQHR}{j1tzgMWwY9<2VIWN180~H_kPTgtPPUo|PmowBjl|MfKr&HVHbaj~lQLZMRIQ zk?AKB9!Qtd4~)LK$kYcjNhr1aO6!mcOK);@l4Mi))2cjo%(uJrAcu3(kPsAbxj zX5Yo-g|J0ho0tC})zRrrwtQR77CULu;Skj4RuNZk$hL_n7?$Ei#gEi27GR@f*Xb|c zF)SsKGk&wD5~5~Xh#g1N1ez>=%8Zb`P;q0Y$~7tob*9J48LzmLJ9CSTo{}?dDgT&W zf&i6p<3_6;4NR3T+R+p^TB(@c_t{Z#)kuY=nV-TnkbR4<=!~nVhb)4rYZ|0GpQb+H zq&}grmzt+3ZodW3VvU96wspBC*1i=gydWI%mLO@{2Sk7=RPZ1OFJE%*-Xd(kLp zmSSYo&HhwW%HzF!Ha86xuuXL29F{j2JGecwZqO~{(^@$1m785&NM+kxyBegtz^M%t zP2$x~lpBO*jeqBv)XS*H=$nkhF+uR&nqJKhRZ#O=`YU?k40}{3z5zG3E^_mbWn9H< zIb#2Hgvq&FfrkNk%10-Bdq=z)mZUcH?AA{ zgJ!dB5tBSgG330F3NG*88E1FD46huXkf$fcm7h=V%G+n+e^&}|*)G4#MLaX;2yOn| zwCFS4-n3KVZYbX-QrRhRx|Xic=0T3pq0*A61sQ$DUAk?3+B*`Wi-j>~7({B@J%62*%@FF<)=BXt)0cW1x_ldg$A;QHJx8E>`P}|-wrOd&Af$i_2>7n^X2}aw4)$m zn@Ub|JBdG##Hk;-l&BF6yV}M>&G_U)YX!3`J;#`YXV8hN5~!4i)>szof~z|8P_4b^ zOoy_jAFrs5Jhgudrfo1T=3-veKg)FZZHsXv7%ehVR&N-mVf}WaLwnxK{s@gE>#kui zSHs%HBKU2C01afjT>kjMSKeUV3auj~kLBtK0{-K6awO!185@OtF8BtACM{SCN)w-a zjbfN&X};nn{D<5J5_%*3En08m4#1T~Yva?uRtkLU8Tz(Bx#$%%0D$yI_;qx0w=!}3 zqfW5;XPuzyl<(zu93`3pqf|Vd^Gt!uB+>1LpH%rR44a$;=MUf27qFyz^)@<0=ywNq zhpl&`sn@0P-~#N*juq$x+Sj9i)&ZUT#w&>V3rcSk@~~u%{b#P}yq}mVe+XCK z5gK8G1(jm7)ir9ODsA&onS1Ba7p)aciz^{$)loW|;4)flQ$WFa`$|)6!MnmDq&*>p z6?`|>b8kt(YVhiTY6`_hAWvhqX_UtQi1w-hj*3I#HOosToaV>vS)5%A3>QYf^Op1LLcGw}jA)`K*@8#}zR_ThpG#mcL}fXqNRXKF4e z+z%L0yl+%L+9h;vPb8jB(8J44zB{Ke*S2^G9jGZHh9fWStDMHSN7k%muI(!^rs79w zhuea^K!T730Mm?opWw`;s&X8?eyAx$i4!_XzzbaDe-QX0JeZ<@<6rOeDI9^d09Pbp zG_G$PDdk0S7xcw`C=hBLi^B$HYQ=Nw^6NMdRh%4V5?c0KG$#~)lD$2jG9H4eroQd9 z%eGHN<(g-HMetkcZvj&ksw&M3L;|;BNQH(XORfFq4g5VegYjm^3_6!`LQO%UwY|VxtD%yg`|}eB6!=@m-}xQeCWQFQ``Rz)H)@F$86B2Tt>KKA)vahf9!?tNL{zv zXZQWu7%X{g?!AAGQp5ypd0>q+2JSPlat!&@tn2fxs;X{0<7Oz0tHn5;D>lWFIlVk( z-8cJ(?k)q@EntVWRMnsHPeYG}Q*NkFWzK9Wh804Z5g>Z~? z+?0^&EyBNXGd^oJnJy3xL_laE{{s&{dHjF4*&oFIH$(eH>w{vuBDz^H#jYS8fo`6O zUxN{W%3Ng4Z?+)}Zx^5!Q{%2MA3W;_Og?RG*^O;+X58_Y;J-zVXPEv79=vIUV^)3a zxxm;dT*JM$gbByUA7?Pd)R7J$Cnp`=AE%CmP!p_3@qpXo(>q@i16L9!_? zhQj-LjvPRfVIsw3#8O2l%Pb-cE^DjvC5eR`TyJ@DJoEFL0RAJOUXheF zq=ypz=jMcY72L#wuP4wI&7&SctgkxWFSF}-kJlP#R_xd3M@RpNRuj@`zhkdTh3AX9 z@x9|BKc?=yM@DYF_|7J=2jBixH<#(V!i%PH`ud>TcOnft#i>xkPU)Ym;Og+cdRf5p zoy}#4qcq&?!qu&t;(3cz%p=H+WkGDi3)K((o92eYlw4|Qq4X7h*EG~iiB*d z&`!wuVzEY~> zgbZV+ZwglNCR&lxs3nN4^JqP+rbAndu=vSRI=5swgw*&~ec`Ik`72M>YJ~kuPsfGM z5aO$A^GrdD^gD1nk#RbbqO{!1M}d!gYvN+8%X#P?@O=k+K!z zEW;nrFOC_=h|7qwQ`qDx{B&fF-y22Q$I2I5X$w`e@0db7HW~mo+Hy45?75%^T;p*0 zevpH^)HV+dX!ecl_~N+Yy9tPjV9s%|B?+;N5r}wC*1R3QUv(xJjyknQ+rCFa?iRe` zM%k9g9?QhRce@)@NRlV-GpU|i-9D>3qG>_CYYwgZcHn5lJsQO)F%NdgXzX!4#Cwp3 z?Xea{v}ev+W>$F@s?v{xvAxI7JFBjuA{XK2Hm`=4;gfJ9)de29*mX_tBeZjG@ObiS z2f6x%RusZr7wufmpgI%OqPrX4@3TTRc3&md<6Yb|A3B> zft3-^%)s2{XFTPP>H1j}5IqWbLcO$6_C$>@3WoRb_xY4i`I=-t$qMzsGe0-g-yMQ| zDs~KaItdg(}H%1eyVjWB7%kCuypF%5u_l~ODHy;nE4U@F(ekL&Oq&EOAu zge(6#5$wEjD^ZXK)ByPbG*C^`*w#qF!Pd@^*~r$xRuywq#GxtqrMcAm<&O5MztfU$8$`=4y z7M0vre39m&C$Y2sikD*{x@kObcIBd1&7=5CWmv-!@63k2%r#n1Gu`3}3VlAx_>k%| zQ$4+00h!C68~_KgG()v&=O}qnK2BJ*@zwf1tBG>pZfd8c+*6L&)6XB#3zf51klr>j zwBIoL^j)vLWC|%IRP>A2b3ab=@$bqy5jZiYx$pH1(Gv=CgFYvH=3?J?5%=MGgMIVg zF@(0}0hS0dJz7xv3iYq1XJBXdKg$D|+<%VDgx5cd!y!M5!-&iHJj)7*{^jo_xz4K% zz&099-xL|;)l!6&$Dhy2*G}|mcE zGWk@4OSOn=9OW9qymDde^g+wmfe>Z$6RWjTuZf{4=ayI&uCj|?U~<+Z_7tOy<~v;c zYSw&lTL>d@U&~O%eE_EoF(Sr|SNp~O<+$l<{3>>0!RgRAzrtbxTCEHsW7=z4G_IdJ z5(;OBgv2FcI|?_pbpx@yRxrao5N;{)c#UJ-=^8aP)Ia#wzQGngRu*3J9~@eu!BC9w zSA{S;t$B5p{?+|U1a)v6D?MkiSyFybhKVv;A18^}&CWM=7eG(|b(ac3Pm2pt#*qUL zypkQ$Ff@jwMJD;z5Qeo?mwYnsS8bUXv4|K)L3JZuQ^P!~*P9%>LPrfpfexY5+~S?l zo_%);cUoe{jiYDp=UnJS5}E9@uWCpRC#mvBsP^Sr2sv!iucE!~LwC1_wr1Yns}{A6 zS_I@gHs6EFmwyBUFmOh||Fxm$&ky(K^uhihV!sog5Z-p@UzZ5>ptp7FB zey;R+*6~}Z2+=R4f6GChOaDF8|CR;qt|0~h{t@_}i~rqS|5ZGM^e^K7ao!3tP$2sQ Q01!bxGLQ+&Q~bR9fAqm=g8%>k literal 0 HcmV?d00001 From 765037e31d62979acbaa1cfa13db46510200dc45 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 17 Aug 2022 16:41:14 +0200 Subject: [PATCH 86/94] Ensure that correct calendar (read from the spreadsheet when loaded) is used for all date-related calculations and formatting --- src/PhpSpreadsheet/Cell/Cell.php | 11 ++- .../Functions/DateTime/AllSetupTeardown.php | 8 +- .../Functions/DateTime/IsoWeekNumTest.php | 2 +- .../Functions/DateTime/WeekNumTest.php | 2 +- .../Reader/Xls/DateReaderTest.php | 72 ++++++++++++++++++ .../Reader/Xlsx/DateReaderTest.php | 22 ++++++ tests/data/Reader/XLS/1900_Calendar.xls | Bin 28160 -> 28160 bytes tests/data/Reader/XLS/1904_Calendar.xls | Bin 28160 -> 28160 bytes 8 files changed, 107 insertions(+), 10 deletions(-) diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php index 28c2ef2cd5..e8594506f6 100644 --- a/src/PhpSpreadsheet/Cell/Cell.php +++ b/src/PhpSpreadsheet/Cell/Cell.php @@ -15,7 +15,6 @@ use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; use Throwable; -use function _PHPStan_59fb0a3b2\RingCentral\Psr7\str; class Cell { @@ -192,7 +191,6 @@ public function getFormattedValue(): string SharedDate::setExcelCalendar($currentCalendar); return $formattedValue; - } /** @@ -407,9 +405,10 @@ private function processArrayResult( public function getCalculatedValue(bool $asArray = false, bool $resetLog = true) { if ($this->dataType === DataType::TYPE_FORMULA) { + $currentCalendar = SharedDate::getExcelCalendar(); + SharedDate::setExcelCalendar($this->getWorksheet()->getParent()->getExcelCalendar()); + try { -// $currentCalendar = SharedDate::getExcelCalendar(); -// SharedDate::setExcelCalendar($this->getWorksheet()->getParent()->getExcelCalendar()); $coordinate = $this->getCoordinate(); $worksheet = $this->getWorksheet(); $value = $this->value; @@ -437,7 +436,7 @@ public function getCalculatedValue(bool $asArray = false, bool $resetLog = true) $this->getWorksheet()->setSelectedCells($selected); $this->getWorksheet()->getParent()->setActiveSheetIndex($index); } catch (Exception $ex) { -// SharedDate::setExcelCalendar($currentCalendar); + SharedDate::setExcelCalendar($currentCalendar); if (($ex->getMessage() === 'Unable to access External Workbook') && ($this->calculatedValue !== null)) { return $this->calculatedValue; // Fallback for calculations referencing external files. } elseif (preg_match('/[Uu]ndefined (name|offset: 2|array key 2)/', $ex->getMessage()) === 1) { @@ -449,7 +448,7 @@ public function getCalculatedValue(bool $asArray = false, bool $resetLog = true) ); } -// SharedDate::setExcelCalendar($currentCalendar); + SharedDate::setExcelCalendar($currentCalendar); if ($result === '#Not Yet Implemented') { return $this->calculatedValue; // Fallback if calculation engine does not support the formula. } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php index 9fb5dfa58b..0cb3b62bd2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php @@ -55,9 +55,13 @@ protected function tearDown(): void } } - protected static function setMac1904(): void + protected static function setMac1904(?Worksheet $worksheet = null): void { - Date::setExcelCalendar(Date::CALENDAR_MAC_1904); + if ($worksheet === null) { + Date::setExcelCalendar(Date::CALENDAR_MAC_1904); + } else { + $worksheet->getParent()->setExcelCalendar(Date::CALENDAR_MAC_1904); + } } protected static function setUnixReturn(): void diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php index a6615ff623..86b1389ba4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php @@ -35,8 +35,8 @@ public function providerISOWEEKNUM(): array public function testISOWEEKNUM1904($expectedResult, $dateValue): void { $this->mightHaveException($expectedResult); - self::setMac1904(); $sheet = $this->getSheet(); + self::setMac1904($sheet); $sheet->getCell('A1')->setValue("=ISOWEEKNUM($dateValue)"); $sheet->getCell('B1')->setValue('1954-11-23'); self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php index 65b00516e0..c1c2fe774e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php @@ -33,8 +33,8 @@ public function providerWEEKNUM(): array public function testWEEKNUM1904($expectedResult, string $formula): void { $this->mightHaveException($expectedResult); - self::setMac1904(); $sheet = $this->getSheet(); + self::setMac1904($sheet); $sheet->getCell('B1')->setValue('1954-11-23'); $sheet->getCell('A1')->setValue("=WEEKNUM($formula)"); self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue()); diff --git a/tests/PhpSpreadsheetTests/Reader/Xls/DateReaderTest.php b/tests/PhpSpreadsheetTests/Reader/Xls/DateReaderTest.php index 30bbb660bc..5ba83166bc 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xls/DateReaderTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Xls/DateReaderTest.php @@ -42,4 +42,76 @@ public function testReadExcel1904Spreadsheet(): void self::assertSame(43464, $worksheet->getCell('A2')->getValue()); self::assertSame('2022-12-31', $worksheet->getCell('A2')->getFormattedValue()); } + + public function testNewDateInLoadedExcel1900Spreadsheet(): void + { + $filename = 'tests/data/Reader/XLS/1900_Calendar.xls'; + $reader = new Xls(); + $spreadsheet = $reader->load($filename); + + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->getCell('A4')->setValue('=DATE(2023,1,1)'); + self::assertEquals(44927, $worksheet->getCell('A4')->getCalculatedValue()); + } + + public function testNewDateInLoadedExcel1904Spreadsheet(): void + { + $filename = 'tests/data/Reader/XLS/1904_Calendar.xls'; + $reader = new Xls(); + $spreadsheet = $reader->load($filename); + + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->getCell('A4')->setValue('=DATE(2023,1,1)'); + self::assertEquals(43465, $worksheet->getCell('A4')->getCalculatedValue()); + } + + public function testSwitchCalendars(): void + { + $filename1900 = 'tests/data/Reader/XLS/1900_Calendar.xls'; + $reader1900 = new Xls(); + $spreadsheet1900 = $reader1900->load($filename1900); + $worksheet1900 = $spreadsheet1900->getActiveSheet(); + + $filename1904 = 'tests/data/Reader/XLS/1904_Calendar.xls'; + $reader1904 = new Xls(); + $spreadsheet1904 = $reader1904->load($filename1904); + $worksheet1904 = $spreadsheet1904->getActiveSheet(); + + self::assertSame(44562, $worksheet1900->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet1900->getCell('A1')->getFormattedValue()); + self::assertSame(44926, $worksheet1900->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet1900->getCell('A2')->getFormattedValue()); + self::assertSame(44561, $worksheet1900->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet1900->getCell('B1')->getFormattedValue()); + self::assertSame(44927, $worksheet1900->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet1900->getCell('B2')->getFormattedValue()); + + self::assertSame(43100, $worksheet1904->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet1904->getCell('A1')->getFormattedValue()); + self::assertSame(43464, $worksheet1904->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet1904->getCell('A2')->getFormattedValue()); + self::assertSame(43099, $worksheet1904->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet1904->getCell('B1')->getFormattedValue()); + self::assertSame(43465, $worksheet1904->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet1904->getCell('B2')->getFormattedValue()); + + // Check that accessing date values from one spreadsheet doesn't break accessing correct values from another + self::assertSame(44561, $worksheet1900->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet1900->getCell('B1')->getFormattedValue()); + self::assertSame(44927, $worksheet1900->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet1900->getCell('B2')->getFormattedValue()); + self::assertSame(44562, $worksheet1900->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet1900->getCell('A1')->getFormattedValue()); + self::assertSame(44926, $worksheet1900->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet1900->getCell('A2')->getFormattedValue()); + + self::assertSame(43099, $worksheet1904->getCell('B1')->getCalculatedValue()); + self::assertSame('2021-12-31', $worksheet1904->getCell('B1')->getFormattedValue()); + self::assertSame(43465, $worksheet1904->getCell('B2')->getCalculatedValue()); + self::assertSame('2023-01-01', $worksheet1904->getCell('B2')->getFormattedValue()); + self::assertSame(43100, $worksheet1904->getCell('A1')->getValue()); + self::assertSame('2022-01-01', $worksheet1904->getCell('A1')->getFormattedValue()); + self::assertSame(43464, $worksheet1904->getCell('A2')->getValue()); + self::assertSame('2022-12-31', $worksheet1904->getCell('A2')->getFormattedValue()); + } } diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/DateReaderTest.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/DateReaderTest.php index 51e59d3bbb..042683f9c3 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xlsx/DateReaderTest.php +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/DateReaderTest.php @@ -51,6 +51,28 @@ public function testReadExcel1904Spreadsheet(): void self::assertSame('2023-01-01', $worksheet->getCell('B2')->getFormattedValue()); } + public function testNewDateInLoadedExcel1900Spreadsheet(): void + { + $filename = 'tests/data/Reader/XLSX/1900_Calendar.xlsx'; + $reader = new Xlsx(); + $spreadsheet = $reader->load($filename); + + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->getCell('A4')->setValue('=DATE(2023,1,1)'); + self::assertEquals(44927, $worksheet->getCell('A4')->getCalculatedValue()); + } + + public function testNewDateInLoadedExcel1904Spreadsheet(): void + { + $filename = 'tests/data/Reader/XLSX/1904_Calendar.xlsx'; + $reader = new Xlsx(); + $spreadsheet = $reader->load($filename); + + $worksheet = $spreadsheet->getActiveSheet(); + $worksheet->getCell('A4')->setValue('=DATE(2023,1,1)'); + self::assertEquals(43465, $worksheet->getCell('A4')->getCalculatedValue()); + } + public function testSwitchCalendars(): void { $filename1900 = 'tests/data/Reader/XLSX/1900_Calendar.xlsx'; diff --git a/tests/data/Reader/XLS/1900_Calendar.xls b/tests/data/Reader/XLS/1900_Calendar.xls index 69027c5b181674e7c79ffb46aa62743da445aae2..714670a7dc10c2236f73d4e9fc33e28372a894f2 100644 GIT binary patch delta 727 zcmZ{gL1+^}6o&uVolUpd#7$xv)1q-LrI(g&do3jmA{cwhr57)P;LVc=LZvo%tT$h2 zZasvaS_^GfX}oCkBwj=iETxA~+JmPcC|E)3o2gryNZ#^h|M}kg=gn?;Pn7q>X5FN5 zGeYmI0V;oDt!(1mZEPe?p1nW#FVg-p(^2KlhJ&KsnpNQ$WXHm*!%= zNYWawDcX(s^u@{2m3UV4(PVsDu2eJY!F>FVZ%kbe4yK+t)ANWy@G~2A_1}k~h62Xv zY8#2a+7ns`7mBHkL9dJbw<79Gc%Rp0@9kj$XbxTY)r)IP8aV;^$cSn~9*x#vK^fH0 z6GM}Ua*E$<;8T^s{0tk54AYpPuf_8t%@**)PH?K$F!o!Q;KEeH!xV!28xNn(ys_UO b7bj~w!VEsn_%0>#cJ1bmlvoXp?)Hd3wPl-x delta 639 zcmZ{f!7BuD6vyB1H^12(J3BkG8$zsUdr0he=Of)!)adsiMVp8(qAorVc2cAkT?!A1;QVjs`{$&E}bK?~| zHH%OW|M@`;p0B~(8hp2!4^(}8EFM(8!{3Fr1=q`bBOK1ESru4D@G#D+3s|Q$r2^%S z$|*U~;V<)RNOIc_a3;9&mp7Jq-7hx*oTh*LjW>w;nWJ&fH%2GeMS_?MS|o&bTzweO zEE2(9t)JyrZoysBrY-t3(FOAY!OP+1$z>Vo7xxMNSOkDe>fJ)I|+ XTOzqvqn3__t?W&GM97%?Ip-(e9*BrD diff --git a/tests/data/Reader/XLS/1904_Calendar.xls b/tests/data/Reader/XLS/1904_Calendar.xls index 8f52d97cb6fa199e46c5ddafe34891932cb6e6fc..cde7fc1931da9196e01661b390f0469aef06cc6a 100644 GIT binary patch delta 265 zcmZp;!`N_#al<1UCL8z7Pi)q3+t)JiFfamPC>K8i8v_t9@qtJNCOFB#BmiYAFoGG3 z{0ty55Qk~ Date: Wed, 17 Aug 2022 17:57:06 +0200 Subject: [PATCH 87/94] Fix merge from 2.0 for the Spreadsheet Copy (I really don't like this approach, it shouldn't be necessary to save to a temporary file and then restore, a deep clone should be the correct approach) --- src/PhpSpreadsheet/Spreadsheet.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/PhpSpreadsheet/Spreadsheet.php b/src/PhpSpreadsheet/Spreadsheet.php index 79d4141baf..ab2196e8b1 100644 --- a/src/PhpSpreadsheet/Spreadsheet.php +++ b/src/PhpSpreadsheet/Spreadsheet.php @@ -3,11 +3,14 @@ namespace PhpOffice\PhpSpreadsheet; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; +use PhpOffice\PhpSpreadsheet\Reader\Xlsx as XlsxReader; use PhpOffice\PhpSpreadsheet\Shared\Date; +use PhpOffice\PhpSpreadsheet\Shared\File; use PhpOffice\PhpSpreadsheet\Shared\StringHelper; use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\Iterator; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; +use PhpOffice\PhpSpreadsheet\Writer\Xlsx as XlsxWriter; class Spreadsheet { From a7ac633134ab7cbf647542ef213fb0c774027173 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Wed, 17 Aug 2022 21:28:58 +0200 Subject: [PATCH 88/94] Adjustment to error check in TEXTFROMARRAY() function --- src/PhpSpreadsheet/Calculation/TextData/Text.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/PhpSpreadsheet/Calculation/TextData/Text.php b/src/PhpSpreadsheet/Calculation/TextData/Text.php index 83810422cc..12ebbef620 100644 --- a/src/PhpSpreadsheet/Calculation/TextData/Text.php +++ b/src/PhpSpreadsheet/Calculation/TextData/Text.php @@ -5,6 +5,7 @@ use PhpOffice\PhpSpreadsheet\Calculation\ArrayEnabled; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Functions; +use PhpOffice\PhpSpreadsheet\Calculation\Information\ErrorValue; class Text { @@ -243,7 +244,7 @@ private static function formatValueMode0($cellValue): string */ private static function formatValueMode1($cellValue): string { - if (is_string($cellValue) && Functions::isError($cellValue) === false) { + if (is_string($cellValue) && ErrorValue::isError($cellValue) === false) { return Calculation::FORMULA_STRING_QUOTE . $cellValue . Calculation::FORMULA_STRING_QUOTE; } elseif (is_bool($cellValue)) { return ($cellValue) ? Calculation::$localeBoolean['TRUE'] : Calculation::$localeBoolean['FALSE']; From 0665a87f202ffc09b2b3f0d79efbc29fe8f067d9 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 18 Aug 2022 06:46:49 +0200 Subject: [PATCH 89/94] Re-baseline phpstan --- phpstan-baseline.neon | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index bd6b21ddb7..9998cdd96e 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -705,11 +705,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Averages.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Conditional\\:\\:SUMIF\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Conditional\\:\\:buildConditionSet\\(\\) has parameter \\$args with no type specified\\.$#" count: 1 @@ -740,6 +735,11 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php + - + message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Conditional\\:\\:sumIf\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#" + count: 1 + path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php + - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\Beta\\:\\:\\$logBetaCacheP has no type specified\\.$#" count: 1 @@ -926,22 +926,22 @@ parameters: path: src/PhpSpreadsheet/Calculation/Statistical/Permutations.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:GROWTH\\(\\) should return array\\ but returns array\\\\>\\>\\.$#" + message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:checkTrendArrays\\(\\) has parameter \\$array1 with no type specified\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:TREND\\(\\) should return array\\ but returns array\\\\>\\>\\.$#" + message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:checkTrendArrays\\(\\) has parameter \\$array2 with no type specified\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:checkTrendArrays\\(\\) has parameter \\$array1 with no type specified\\.$#" + message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:growth\\(\\) should return array\\ but returns array\\\\>\\>\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:checkTrendArrays\\(\\) has parameter \\$array2 with no type specified\\.$#" + message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:trend\\(\\) should return array\\ but returns array\\\\>\\>\\.$#" count: 1 path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php From 42cf5ce6a4d3142dbcf0910328467c29add2b3cb Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 18 Aug 2022 12:31:08 +0200 Subject: [PATCH 90/94] Re-baseline phpstan --- phpstan-baseline.neon | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 8c4d686771..00a27f7980 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -970,11 +970,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Calculation/TextData/Text.php - - - message: "#^Elseif branch is unreachable because previous condition is always true\\.$#" - count: 1 - path: src/PhpSpreadsheet/Cell/Cell.php - - message: "#^Parameter \\#2 \\$format of static method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\:\\:toFormattedString\\(\\) expects string, string\\|null given\\.$#" count: 1 @@ -992,7 +987,7 @@ parameters: - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" - count: 2 + count: 3 path: src/PhpSpreadsheet/Cell/Coordinate.php - From ff655bd47d087fa6e81df42b27b4716d04a09b8f Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 25 Sep 2022 17:31:58 +0200 Subject: [PATCH 91/94] Resolve merge conflicts for master -> 2.0-dev --- phpstan-baseline.neon | 720 ------------------ src/PhpSpreadsheet/Helper/Sample.php | 2 +- src/PhpSpreadsheet/Reader/Xlsx.php | 5 +- .../Calculation/ArrayFormulaTest.php | 12 +- .../Functions/Engineering/ConvertUoMTest.php | 2 - .../Functions/Engineering/ErfCTest.php | 2 - .../Functions/Engineering/ErfPreciseTest.php | 2 - .../Functions/Engineering/ErfTest.php | 2 - .../Engineering/ParseComplexTest.php | 22 - .../Functions/Financial/IrrTest.php | 5 - .../Functions/LookupRef/AddressTest.php | 2 - .../Functions/LookupRef/ColumnsTest.php | 2 - .../Functions/LookupRef/IndexTest.php | 4 +- .../Functions/LookupRef/IndirectTest.php | 10 - .../Functions/LookupRef/RowsTest.php | 4 +- 15 files changed, 12 insertions(+), 784 deletions(-) delete mode 100644 tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ParseComplexTest.php diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index b66dc687a8..f01a6ad4b3 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1005,11 +1005,6 @@ parameters: count: 1 path: src/PhpSpreadsheet/Chart/DataSeriesValues.php - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Memory\\:\\:\\$cache has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Collection/Memory.php - - message: "#^Parameter \\#1 \\$namedRange of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:addNamedRange\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\NamedRange, \\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\) given\\.$#" count: 1 @@ -1580,441 +1575,11 @@ parameters: count: 2 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Cannot call method addChart\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Cannot call method setUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Comparison operation \"\\>\" between SimpleXMLElement\\|null and 0 results in an error\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:boolean\\(\\) has parameter \\$value with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToBoolean\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToBoolean\\(\\) has parameter \\$c with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToError\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToError\\(\\) has parameter \\$c with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$c with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$calculatedValue with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$castBaseType with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$cellDataType with no type specified\\.$#" count: 1 path: src/PhpSpreadsheet/Reader/Xlsx.php - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$r with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$sharedFormulas with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$value with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToString\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToString\\(\\) has parameter \\$c with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:dirAdd\\(\\) has parameter \\$add with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:dirAdd\\(\\) has parameter \\$base with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has parameter \\$array with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has parameter \\$key with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getFromZipArchive\\(\\) should return string but returns string\\|false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$dir with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$docSheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$fileWorksheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$dir with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$docSheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$fileWorksheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:stripWhiteSpaceFromStyleString\\(\\) has parameter \\$string with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:toCSSArray\\(\\) has parameter \\$style with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Negated boolean expression is always true\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$fontSizeInPoints of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:fontSizeToPixels\\(\\) expects int, string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$haystack of function strpos expects string, int\\|string given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$sizeInCm of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:centimeterSizeToPixels\\(\\) expects int, string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#1 \\$sizeInInch of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:inchSizeToPixels\\(\\) expects int, string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, int\\|string given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:readAutoFilter\\(\\) has parameter \\$autoFilterRange with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:readAutoFilter\\(\\) has parameter \\$xmlSheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Parameter \\#1 \\$operator of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:setRule\\(\\) expects string, null given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\BaseParserClass\\:\\:boolean\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\BaseParserClass\\:\\:boolean\\(\\) has parameter \\$value with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredColumn\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredColumn\\(\\) has parameter \\$columnCoordinate with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredRow\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredRow\\(\\) has parameter \\$rowCoordinate with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnAttributes\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnAttributes\\(\\) has parameter \\$readDataOnly with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnRangeAttributes\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnRangeAttributes\\(\\) has parameter \\$readDataOnly with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readRowAttributes\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readRowAttributes\\(\\) has parameter \\$readDataOnly with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readConditionalStyles\\(\\) has parameter \\$xmlSheet with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarExtLstOfConditionalRule\\(\\) has parameter \\$cfRule with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarExtLstOfConditionalRule\\(\\) has parameter \\$conditionalFormattingRuleExtensions with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarOfConditionalRule\\(\\) has parameter \\$cfRule with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarOfConditionalRule\\(\\) has parameter \\$conditionalFormattingRuleExtensions with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has parameter \\$cfRules with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has parameter \\$extLst with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:setConditionalStyles\\(\\) has parameter \\$xmlExtLst with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$dxfs has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\DataValidations\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\DataValidations\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Hyperlinks\\:\\:\\$hyperlinks has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Hyperlinks\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:load\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:pageSetup\\(\\) has no return type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\SheetViewOptions\\:\\:\\$worksheet has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\SheetViewOptions\\:\\:\\$worksheetXml has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php - - message: "#^Parameter \\#1 \\$haystack of function strpos expects string, string\\|false given\\.$#" count: 1 @@ -3390,298 +2955,13 @@ parameters: count: 1 path: src/PhpSpreadsheet/Writer/Xls/Xf.php - - - message: "#^Argument of an invalid type array\\|null supplied for foreach, only iterables are supported\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Parameter \\#1 \\$path of function basename expects string, array\\|string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Parameter \\#1 \\$path of function dirname expects string, array\\|string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Possibly invalid array key type array\\|string\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\:\\:\\$pathNames has no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx.php - - - - message: "#^Parameter \\#1 \\$string of function substr expects string, int given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Comments.php - - - - message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/Comments.php - - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php - - - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php - - - - message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/DocProps.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/DocProps.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeUnparsedRelationship\\(\\) has parameter \\$relationship with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeUnparsedRelationship\\(\\) has parameter \\$type with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php - - - - message: "#^Parameter \\#2 \\$id of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeRelationship\\(\\) expects int, string given\\.$#" - count: 5 - path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php - - - - message: "#^Parameter \\#4 \\$target of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeRelationship\\(\\) expects string, array\\|string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php - - - - message: "#^Cannot call method getBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Instanceof between \\*NEVER\\* and PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\RichText will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Instanceof between string and PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\RichText will always evaluate to false\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#1 \\$text of method PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\RichText\\:\\:createTextRun\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, float\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#" - count: 4 - path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php - - - - message: "#^Cannot call method getStyle\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Conditional\\|null\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Comparison operation \"\\<\" between int\\ and 0 is always true\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$borders of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Style\\:\\:writeBorder\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Borders, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Borders\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$fill of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Style\\:\\:writeFill\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Fill, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Fill\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$font of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Style\\:\\:writeFont\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$numberFormat of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Style\\:\\:writeNumFmt\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, float given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 22 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<1, max\\> given\\.$#" - count: 2 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#" - count: 7 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Result of \\|\\| is always true\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Style.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 7 - path: src/PhpSpreadsheet/Writer/Xlsx/Workbook.php - - message: "#^Cannot use array destructuring on array\\\\|string\\.$#" count: 1 path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - message: "#^Expression on left side of \\?\\? is not nullable\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^If condition is always true\\.$#" - count: 6 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeAttributeIf\\(\\) has parameter \\$condition with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeDataBarElements\\(\\) has parameter \\$dataBar with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeElementIf\\(\\) has parameter \\$condition with no type specified\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int\\|string given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#" - count: 15 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#" - count: 3 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<1, max\\> given\\.$#" - count: 9 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#3 \\$stringTable of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeSheetData\\(\\) expects array\\, array\\\\|null given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - - - - message: "#^Parameter \\#4 \\$val of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeAttributeIf\\(\\) expects string, int given\\.$#" - count: 1 - path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php - diff --git a/src/PhpSpreadsheet/Helper/Sample.php b/src/PhpSpreadsheet/Helper/Sample.php index 9f7563d64b..0ac0c79691 100644 --- a/src/PhpSpreadsheet/Helper/Sample.php +++ b/src/PhpSpreadsheet/Helper/Sample.php @@ -85,7 +85,7 @@ public function getSamples() foreach ($regex as $file) { $file = str_replace(str_replace('\\', '/', $baseDir) . '/', '', str_replace('\\', '/', $file[0])); $info = pathinfo($file); - $category = str_replace('_', ' ', $info['dirname']); + $category = str_replace('_', ' ', $info['dirname'] ?? ''); $name = str_replace('_', ' ', (string) preg_replace('/(|\.php)/', '', $info['filename'])); if (!in_array($category, ['.', 'boostrap', 'templates'])) { if (!isset($files[$category])) { diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php index 7c98c230a4..36310578bd 100644 --- a/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/src/PhpSpreadsheet/Reader/Xlsx.php @@ -320,11 +320,12 @@ private static function castToString(?SimpleXMLElement $c): ?string * @param mixed $value * @param mixed $calculatedValue */ - private function castToFormula(?SimpleXMLElement $c, string $r, string &$cellDataType, &$value, &$calculatedValue, array &$sharedFormulas, string $castBaseType): void + private function castToFormula(Worksheet $docSheet, ?SimpleXMLElement $c, string $r, string &$cellDataType, &$value, &$calculatedValue, array &$sharedFormulas, string $castBaseType): void { if ($c === null) { return; } + $formulaAttributes = $c->f->attributes(); $cellDataType = 'f'; $value = "={$c->f}"; @@ -1615,7 +1616,7 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet if (strpos((string) $definedName, '!') !== false) { $range[0] = str_replace("''", "'", $range[0]); $range[0] = str_replace("'", '', $range[0]); - if ($worksheet = $excel->getSheetByName($range[0])) { // @phpstan-ignore-line + if ($worksheet = $excel->getSheetByName($range[0])) { $excel->addDefinedName(DefinedName::createInstance((string) $definedName['name'], $worksheet, $extractedRange, true, $scope)); } else { $excel->addDefinedName(DefinedName::createInstance((string) $definedName['name'], $scope, $extractedRange, true, $scope)); diff --git a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php index 8bccde185a..f962aa7926 100644 --- a/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/ArrayFormulaTest.php @@ -260,19 +260,19 @@ public function providerArrayArithmetic(): array ], 'Division: row vector / column vector' => [ '={1,2,3} / {4;5;6}', - [[0.25, 0.5, 0.75], [0.2, 0.4, 0.6], [0.16666666666667, 0.33333333333333, 0.5]], + [[0.25, 0.5, 0.75], [0.2, 0.4, 0.6], [0.16666666666666667, 0.3333333333333333, 0.5]], ], 'Division: column vector / row vector' => [ '={1;2;3} / {4,5,6}', - [[0.25, 0.2, 0.16666666666667], [0.5, 0.4, 0.33333333333333], [0.75, 0.6, 0.5]], + [[0.25, 0.2, 0.16666666666666667], [0.5, 0.4, 0.3333333333333333], [0.75, 0.6, 0.5]], ], 'Division: matrix 3x2 / 3x2' => [ '={1,2,3;4,5,6} / {7,8,9;10,11,12}', - [[0.142857142857143, 0.25, 0.33333333333333], [0.4, 0.45454545454545, 0.5]], + [[0.14285714285714285, 0.25, 0.3333333333333333], [0.4, 0.45454545454545453, 0.5]], ], 'Division: matrix 2x3 / 2x3' => [ '={1,4;2,5;3,6} / {7,10;8,11;9,12}', - [[0.142857142857143, 0.4], [0.25, 0.45454545454545], [0.33333333333333, 0.5]], + [[0.14285714285714285, 0.4], [0.25, 0.45454545454545453], [0.3333333333333333, 0.5]], ], 'Division: row vector 2 / column vector 2' => [ '={2,3} / {4;5}', @@ -280,7 +280,7 @@ public function providerArrayArithmetic(): array ], 'Division: matrix 3x2 / 2x3' => [ '={1,2,3;4,5,6} / {7,10;8,11;9,12}', - [[0.14285714285714, 0.2], [0.5, 0.45454545454545]], + [[0.14285714285714285, 0.2], [0.5, 0.45454545454545453]], ], 'Division: matrix 2x3 / 3x2' => [ '={7,10;8,11;9,12} / {1,2,3;4,5,6}', @@ -289,7 +289,7 @@ public function providerArrayArithmetic(): array // Power 'Power: square matrix 2x2 ^ 2x2' => [ '={1,2;3,4} ^ {-2,4;-6,8}', - [[1, 16], [0.00137174211248, 65536]], + [[1, 16], [0.0013717421124828531, 65536]], ], 'Power: square matrix 2x2 ^ scalar' => [ '={1,2;3,4} ^ 2', diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php index 034d269eac..9675b20994 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php @@ -4,8 +4,6 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ConvertUOM; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PHPUnit\Framework\TestCase; class ConvertUoMTest extends TestCase diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php index b505f560e4..ee38626672 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php @@ -4,8 +4,6 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Engineering\ErfC; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PHPUnit\Framework\TestCase; class ErfCTest extends TestCase diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php index 42b031241d..a4fc9dfda1 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php @@ -4,8 +4,6 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Erf; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PHPUnit\Framework\TestCase; class ErfPreciseTest extends TestCase diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php index 6e1d0a0a5a..26d0290ad9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php @@ -4,8 +4,6 @@ use PhpOffice\PhpSpreadsheet\Calculation\Calculation; use PhpOffice\PhpSpreadsheet\Calculation\Engineering\Erf; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; -use PhpOffice\PhpSpreadsheet\Calculation\Engineering; use PHPUnit\Framework\TestCase; class ErfTest extends TestCase diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ParseComplexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ParseComplexTest.php deleted file mode 100644 index a32d946f59..0000000000 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ParseComplexTest.php +++ /dev/null @@ -1,22 +0,0 @@ -getSheet(); - $sheet->getCell('A1')->setValue('A2'); - $sheet->getCell('A2')->setValue('This is it'); - $result = \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDIRECT('A2', $sheet->getCell('A1')); - $result = \PhpOffice\PhpSpreadsheet\Calculation\Functions::flattenSingleValue($result); - self::assertSame('This is it', $result); - } - /** * @param null|int|string $expectedResult * diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php index 8fd1ef37b0..31b941013d 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php @@ -3,9 +3,7 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\LookupRef; use PhpOffice\PhpSpreadsheet\Calculation\Calculation; -use PhpOffice\PhpSpreadsheet\Calculation\Functions; use PhpOffice\PhpSpreadsheet\Calculation\LookupRef\RowColumnInformation; -use PhpOffice\PhpSpreadsheet\Calculation\LookupRef; use PHPUnit\Framework\TestCase; class RowsTest extends TestCase @@ -17,7 +15,7 @@ class RowsTest extends TestCase */ public function testROWS($expectedResult, ...$args): void { - $result = LookupRef::ROWS(/** @scrutinizer ignore-type */ ...$args); + $result = RowColumnInformation::rows(/** @scrutinizer ignore-type */ ...$args); self::assertEquals($expectedResult, $result); } From 40b6fc7c69570886ad8059f94d1c86ac61932437 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Mon, 26 Sep 2022 16:20:11 +0200 Subject: [PATCH 92/94] Excel Functions implementation method renaming --- infra/DocumentGenerator.php | 2 +- .../Calculation/Calculation.php | 272 +++++++++--------- .../Calculation/Database/DStDev.php | 2 +- .../Calculation/Database/DStDevP.php | 2 +- .../Calculation/Database/DVar.php | 2 +- .../Calculation/Database/DVarP.php | 2 +- .../Calculation/Engineering/ConvertUOM.php | 2 +- .../Calculation/Engineering/Erf.php | 8 +- .../Calculation/Engineering/ErfC.php | 2 +- .../Calculation/Financial/Amortization.php | 4 +- .../Calculation/Financial/Depreciation.php | 8 +- src/PhpSpreadsheet/Calculation/Functions.php | 2 +- .../Calculation/LookupRef/Offset.php | 2 +- .../Calculation/MathTrig/Subtotal.php | 8 +- .../Calculation/Statistical/Confidence.php | 2 +- .../Calculation/Statistical/Deviations.php | 4 +- .../Distributions/StandardNormal.php | 2 +- .../Calculation/Statistical/Percentiles.php | 10 +- .../Calculation/Statistical/Permutations.php | 4 +- .../Statistical/StandardDeviations.php | 16 +- .../Calculation/Statistical/Trends.php | 10 +- .../Calculation/Statistical/Variances.php | 8 +- .../CalculationFunctionListTest.php | 8 +- .../Functions/Engineering/ConvertUoMTest.php | 2 +- .../Functions/Engineering/ErfCTest.php | 2 +- .../Functions/Engineering/ErfPreciseTest.php | 2 +- .../Functions/Engineering/ErfTest.php | 2 +- .../Functions/Financial/AmorDegRcTest.php | 2 +- .../Functions/Financial/AmorLincTest.php | 2 +- .../Functions/Financial/DbTest.php | 2 +- .../Functions/Financial/DdbTest.php | 2 +- .../Functions/Financial/SlnTest.php | 2 +- .../Functions/Financial/SydTest.php | 2 +- .../Functions/LookupRef/OffsetTest.php | 2 +- .../Functions/Statistical/ConfidenceTest.php | 2 +- .../Functions/Statistical/CorrelTest.php | 2 +- .../Functions/Statistical/LinEstTest.php | 2 +- .../Functions/Statistical/LogEstTest.php | 2 +- .../Functions/Statistical/PercentRankTest.php | 2 +- .../Functions/Statistical/PercentileTest.php | 2 +- .../Functions/Statistical/PermutTest.php | 2 +- .../Statistical/PermutationATest.php | 2 +- .../Functions/Statistical/QuartileTest.php | 2 +- .../Functions/Statistical/RankTest.php | 2 +- .../Functions/Statistical/RsqTest.php | 2 +- .../Functions/Statistical/StDevATest.php | 4 +- .../Functions/Statistical/StDevPATest.php | 4 +- .../Functions/Statistical/StDevPTest.php | 4 +- .../Functions/Statistical/StDevTest.php | 4 +- .../Functions/Statistical/SteyxTest.php | 2 +- .../Functions/Statistical/VarATest.php | 4 +- .../Functions/Statistical/VarPATest.php | 4 +- .../Functions/Statistical/VarPTest.php | 4 +- .../Functions/Statistical/VarTest.php | 4 +- .../Calculation/FunctionsTest.php | 2 +- .../DocumentGeneratorTest.php | 4 +- 56 files changed, 233 insertions(+), 233 deletions(-) diff --git a/infra/DocumentGenerator.php b/infra/DocumentGenerator.php index 8551746006..6704a687d9 100644 --- a/infra/DocumentGenerator.php +++ b/infra/DocumentGenerator.php @@ -60,7 +60,7 @@ private static function getPhpSpreadsheetFunctionText($functionCall): string if (is_string($functionCall)) { return $functionCall; } - if ($functionCall === [Functions::class, 'DUMMY']) { + if ($functionCall === [Functions::class, 'dummy']) { return '**Not yet Implemented**'; } if (is_array($functionCall)) { diff --git a/src/PhpSpreadsheet/Calculation/Calculation.php b/src/PhpSpreadsheet/Calculation/Calculation.php index 5ee26836cf..6f923a1df7 100644 --- a/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/src/PhpSpreadsheet/Calculation/Calculation.php @@ -275,17 +275,17 @@ class Calculation ], 'AGGREGATE' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3+', ], 'AMORDEGRC' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Amortization::class, 'AMORDEGRC'], + 'functionCall' => [Financial\Amortization::class, 'withCoefficient'], 'argumentCount' => '6,7', ], 'AMORLINC' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Amortization::class, 'AMORLINC'], + 'functionCall' => [Financial\Amortization::class, 'depreciation'], 'argumentCount' => '6,7', ], 'AND' => [ @@ -300,7 +300,7 @@ class Calculation ], 'AREAS' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1', ], 'ARRAYTOTEXT' => [ @@ -310,7 +310,7 @@ class Calculation ], 'ASC' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1', ], 'ASIN' => [ @@ -365,7 +365,7 @@ class Calculation ], 'BAHTTEXT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1', ], 'BASE' => [ @@ -400,7 +400,7 @@ class Calculation ], 'BETA.DIST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '4-6', ], 'BETAINV' => [ @@ -490,7 +490,7 @@ class Calculation ], 'CELL' => [ 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1,2', ], 'CHAR' => [ @@ -545,12 +545,12 @@ class Calculation ], 'CHOOSECOLS' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2+', ], 'CHOOSEROWS' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2+', ], 'CLEAN' => [ @@ -602,27 +602,27 @@ class Calculation ], 'CONFIDENCE' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Confidence::class, 'CONFIDENCE'], + 'functionCall' => [Statistical\Confidence::class, 'confidence'], 'argumentCount' => '3', ], 'CONFIDENCE.NORM' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Confidence::class, 'CONFIDENCE'], + 'functionCall' => [Statistical\Confidence::class, 'confidence'], 'argumentCount' => '3', ], 'CONFIDENCE.T' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3', ], 'CONVERT' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ConvertUOM::class, 'CONVERT'], + 'functionCall' => [Engineering\ConvertUOM::class, 'convert'], 'argumentCount' => '3', ], 'CORREL' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'correl'], + 'functionCall' => [Statistical\Trends::class, 'correlation'], 'argumentCount' => '2', ], 'COS' => [ @@ -712,7 +712,7 @@ class Calculation ], 'COVARIANCE.S' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'CRITBINOM' => [ @@ -732,37 +732,37 @@ class Calculation ], 'CUBEKPIMEMBER' => [ 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'CUBEMEMBER' => [ 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'CUBEMEMBERPROPERTY' => [ 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'CUBERANKEDMEMBER' => [ 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'CUBESET' => [ 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'CUBESETCOUNT' => [ 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'CUBEVALUE' => [ 'category' => Category::CATEGORY_CUBE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'CUMIPMT' => [ @@ -787,7 +787,7 @@ class Calculation ], 'DATESTRING' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'DATEVALUE' => [ @@ -817,12 +817,12 @@ class Calculation ], 'DB' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Depreciation::class, 'DB'], + 'functionCall' => [Financial\Depreciation::class, 'decliningBalance'], 'argumentCount' => '4,5', ], 'DBCS' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1', ], 'DCOUNT' => [ @@ -837,7 +837,7 @@ class Calculation ], 'DDB' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Depreciation::class, 'DDB'], + 'functionCall' => [Financial\Depreciation::class, 'doubleDecliningBalance'], 'argumentCount' => '4,5', ], 'DEC2BIN' => [ @@ -857,7 +857,7 @@ class Calculation ], 'DECIMAL' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'DEGREES' => [ @@ -917,7 +917,7 @@ class Calculation ], 'DROP' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2-3', ], 'DSTDEV' => [ @@ -937,7 +937,7 @@ class Calculation ], 'DURATION' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '5,6', ], 'DVAR' => [ @@ -952,7 +952,7 @@ class Calculation ], 'ECMA.CEILING' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1,2', ], 'EDATE' => [ @@ -977,22 +977,22 @@ class Calculation ], 'ERF' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Erf::class, 'ERF'], + 'functionCall' => [Engineering\Erf::class, 'erf'], 'argumentCount' => '1,2', ], 'ERF.PRECISE' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\Erf::class, 'ERFPRECISE'], + 'functionCall' => [Engineering\Erf::class, 'precise'], 'argumentCount' => '1', ], 'ERFC' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ErfC::class, 'ERFC'], + 'functionCall' => [Engineering\ErfC::class, 'complementary'], 'argumentCount' => '1', ], 'ERFC.PRECISE' => [ 'category' => Category::CATEGORY_ENGINEERING, - 'functionCall' => [Engineering\ErfC::class, 'ERFC'], + 'functionCall' => [Engineering\ErfC::class, 'complementary'], 'argumentCount' => '1', ], 'ERROR.TYPE' => [ @@ -1017,7 +1017,7 @@ class Calculation ], 'EXPAND' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2-4', ], 'EXPONDIST' => [ @@ -1042,12 +1042,12 @@ class Calculation ], 'FALSE' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Boolean::class, 'FALSE'], + 'functionCall' => [Logical\Boolean::class, 'false'], 'argumentCount' => '0', ], 'FDIST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3', ], 'F.DIST' => [ @@ -1057,7 +1057,7 @@ class Calculation ], 'F.DIST.RT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3', ], 'FILTER' => [ @@ -1068,7 +1068,7 @@ class Calculation ], 'FILTERXML' => [ 'category' => Category::CATEGORY_WEB, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'FIND' => [ @@ -1083,17 +1083,17 @@ class Calculation ], 'FINV' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3', ], 'F.INV' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3', ], 'F.INV.RT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3', ], 'FISHER' => [ @@ -1133,22 +1133,22 @@ class Calculation ], 'FORECAST.ETS' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3-6', ], 'FORECAST.ETS.CONFINT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3-6', ], 'FORECAST.ETS.SEASONALITY' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2-4', ], 'FORECAST.ETS.STAT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3-6', ], 'FORECAST.LINEAR' => [ @@ -1165,17 +1165,17 @@ class Calculation ], 'FREQUENCY' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'FTEST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'F.TEST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'FV' => [ @@ -1245,7 +1245,7 @@ class Calculation ], 'GETPIVOTDATA' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2+', ], 'GROWTH' => [ @@ -1285,7 +1285,7 @@ class Calculation ], 'HSTACK' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1+', ], 'HYPERLINK' => [ @@ -1301,7 +1301,7 @@ class Calculation ], 'HYPGEOM.DIST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '5', ], 'IF' => [ @@ -1462,7 +1462,7 @@ class Calculation ], 'INFO' => [ 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1', ], 'INT' => [ @@ -1539,7 +1539,7 @@ class Calculation ], 'ISO.CEILING' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1,2', ], 'ISODD' => [ @@ -1571,12 +1571,12 @@ class Calculation ], 'ISTHAIDIGIT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'JIS' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1', ], 'KURT' => [ @@ -1616,7 +1616,7 @@ class Calculation ], 'LINEST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'LINEST'], + 'functionCall' => [Statistical\Trends::class, 'lineEstimate'], 'argumentCount' => '1-4', ], 'LN' => [ @@ -1636,7 +1636,7 @@ class Calculation ], 'LOGEST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'LOGEST'], + 'functionCall' => [Statistical\Trends::class, 'logEstimate'], 'argumentCount' => '1-4', ], 'LOGINV' => [ @@ -1696,7 +1696,7 @@ class Calculation ], 'MDURATION' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '5,6', ], 'MEDIAN' => [ @@ -1706,7 +1706,7 @@ class Calculation ], 'MEDIANIF' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2+', ], 'MID' => [ @@ -1766,7 +1766,7 @@ class Calculation ], 'MODE.MULT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1+', ], 'MODE.SNGL' => [ @@ -1811,7 +1811,7 @@ class Calculation ], 'NEGBINOM.DIST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '4', ], 'NETWORKDAYS' => [ @@ -1821,7 +1821,7 @@ class Calculation ], 'NETWORKDAYS.INTL' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2-4', ], 'NOMINAL' => [ @@ -1891,7 +1891,7 @@ class Calculation ], 'NUMBERSTRING' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'NUMBERVALUE' => [ @@ -1921,27 +1921,27 @@ class Calculation ], 'ODDFPRICE' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '8,9', ], 'ODDFYIELD' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '8,9', ], 'ODDLPRICE' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '7,8', ], 'ODDLYIELD' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '7,8', ], 'OFFSET' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [LookupRef\Offset::class, 'OFFSET'], + 'functionCall' => [LookupRef\Offset::class, 'offset'], 'argumentCount' => '3-5', 'passCellReference' => true, 'passByReference' => [true], @@ -1958,57 +1958,57 @@ class Calculation ], 'PEARSON' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'correl'], + 'functionCall' => [Statistical\Trends::class, 'correlation'], 'argumentCount' => '2', ], 'PERCENTILE' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'PERCENTILE'], + 'functionCall' => [Statistical\Percentiles::class, 'percentile'], 'argumentCount' => '2', ], 'PERCENTILE.EXC' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'PERCENTILE.INC' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'PERCENTILE'], + 'functionCall' => [Statistical\Percentiles::class, 'percentile'], 'argumentCount' => '2', ], 'PERCENTRANK' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'PERCENTRANK'], + 'functionCall' => [Statistical\Percentiles::class, 'percentRank'], 'argumentCount' => '2,3', ], 'PERCENTRANK.EXC' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2,3', ], 'PERCENTRANK.INC' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'PERCENTRANK'], + 'functionCall' => [Statistical\Percentiles::class, 'percentRank'], 'argumentCount' => '2,3', ], 'PERMUT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Permutations::class, 'PERMUT'], + 'functionCall' => [Statistical\Permutations::class, 'permut'], 'argumentCount' => '2', ], 'PERMUTATIONA' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Permutations::class, 'PERMUTATIONA'], + 'functionCall' => [Statistical\Permutations::class, 'permutationA'], 'argumentCount' => '2', ], 'PHONETIC' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1', ], 'PHI' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1', ], 'PI' => [ @@ -2058,7 +2058,7 @@ class Calculation ], 'PROB' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3,4', ], 'PRODUCT' => [ @@ -2078,17 +2078,17 @@ class Calculation ], 'QUARTILE' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'QUARTILE'], + 'functionCall' => [Statistical\Percentiles::class, 'quartile'], 'argumentCount' => '2', ], 'QUARTILE.EXC' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'QUARTILE.INC' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'QUARTILE'], + 'functionCall' => [Statistical\Percentiles::class, 'quartile'], 'argumentCount' => '2', ], 'QUOTIENT' => [ @@ -2119,17 +2119,17 @@ class Calculation ], 'RANK' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'RANK'], + 'functionCall' => [Statistical\Percentiles::class, 'rank'], 'argumentCount' => '2,3', ], 'RANK.AVG' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2,3', ], 'RANK.EQ' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Percentiles::class, 'RANK'], + 'functionCall' => [Statistical\Percentiles::class, 'rank'], 'argumentCount' => '2,3', ], 'RATE' => [ @@ -2179,12 +2179,12 @@ class Calculation ], 'ROUNDBAHTDOWN' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'ROUNDBAHTUP' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'ROUNDDOWN' => [ @@ -2216,12 +2216,12 @@ class Calculation ], 'RSQ' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'RSQ'], + 'functionCall' => [Statistical\Trends::class, 'pearsonSquares'], 'argumentCount' => '2', ], 'RTD' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1+', ], 'SEARCH' => [ @@ -2262,12 +2262,12 @@ class Calculation ], 'SHEET' => [ 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '0,1', ], 'SHEETS' => [ 'category' => Category::CATEGORY_INFORMATION, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '0,1', ], 'SIGN' => [ @@ -2292,12 +2292,12 @@ class Calculation ], 'SKEW.P' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1+', ], 'SLN' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Depreciation::class, 'SLN'], + 'functionCall' => [Financial\Depreciation::class, 'straightLine'], 'argumentCount' => '3', ], 'SLOPE' => [ @@ -2339,37 +2339,37 @@ class Calculation ], 'STDEV' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'], + 'functionCall' => [Statistical\StandardDeviations::class, 'stdev'], 'argumentCount' => '1+', ], 'STDEV.S' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEV'], + 'functionCall' => [Statistical\StandardDeviations::class, 'stdev'], 'argumentCount' => '1+', ], 'STDEV.P' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVP'], + 'functionCall' => [Statistical\StandardDeviations::class, 'stdevP'], 'argumentCount' => '1+', ], 'STDEVA' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVA'], + 'functionCall' => [Statistical\StandardDeviations::class, 'stdevA'], 'argumentCount' => '1+', ], 'STDEVP' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVP'], + 'functionCall' => [Statistical\StandardDeviations::class, 'stdevP'], 'argumentCount' => '1+', ], 'STDEVPA' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\StandardDeviations::class, 'STDEVPA'], + 'functionCall' => [Statistical\StandardDeviations::class, 'stdevPA'], 'argumentCount' => '1+', ], 'STEYX' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Trends::class, 'STEYX'], + 'functionCall' => [Statistical\Trends::class, 'standardError'], 'argumentCount' => '2', ], 'SUBSTITUTE' => [ @@ -2430,7 +2430,7 @@ class Calculation ], 'SYD' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Financial\Depreciation::class, 'SYD'], + 'functionCall' => [Financial\Depreciation::class, 'sumOfYears'], 'argumentCount' => '4', ], 'T' => [ @@ -2440,7 +2440,7 @@ class Calculation ], 'TAKE' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2-3', ], 'TAN' => [ @@ -2475,17 +2475,17 @@ class Calculation ], 'T.DIST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3', ], 'T.DIST.2T' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'T.DIST.RT' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'TEXT' => [ @@ -2515,37 +2515,37 @@ class Calculation ], 'THAIDAYOFWEEK' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'THAIDIGIT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'THAIMONTHOFYEAR' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'THAINUMSOUND' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'THAINUMSTRING' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'THAISTRINGLENGTH' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'THAIYEAR' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '?', ], 'TIME' => [ @@ -2570,7 +2570,7 @@ class Calculation ], 'T.INV.2T' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2', ], 'TODAY' => [ @@ -2580,12 +2580,12 @@ class Calculation ], 'TOCOL' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1-3', ], 'TOROW' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1-3', ], 'TRANSPOSE' => [ @@ -2610,7 +2610,7 @@ class Calculation ], 'TRUE' => [ 'category' => Category::CATEGORY_LOGICAL, - 'functionCall' => [Logical\Boolean::class, 'TRUE'], + 'functionCall' => [Logical\Boolean::class, 'true'], 'argumentCount' => '0', ], 'TRUNC' => [ @@ -2620,12 +2620,12 @@ class Calculation ], 'TTEST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '4', ], 'T.TEST' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '4', ], 'TYPE' => [ @@ -2671,37 +2671,37 @@ class Calculation ], 'VAR' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VAR'], + 'functionCall' => [Statistical\Variances::class, 'variance'], 'argumentCount' => '1+', ], 'VAR.P' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VARP'], + 'functionCall' => [Statistical\Variances::class, 'varianceP'], 'argumentCount' => '1+', ], 'VAR.S' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VAR'], + 'functionCall' => [Statistical\Variances::class, 'variance'], 'argumentCount' => '1+', ], 'VARA' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VARA'], + 'functionCall' => [Statistical\Variances::class, 'varianceA'], 'argumentCount' => '1+', ], 'VARP' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VARP'], + 'functionCall' => [Statistical\Variances::class, 'varianceP'], 'argumentCount' => '1+', ], 'VARPA' => [ 'category' => Category::CATEGORY_STATISTICAL, - 'functionCall' => [Statistical\Variances::class, 'VARPA'], + 'functionCall' => [Statistical\Variances::class, 'variancePA'], 'argumentCount' => '1+', ], 'VDB' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '5-7', ], 'VLOOKUP' => [ @@ -2711,7 +2711,7 @@ class Calculation ], 'VSTACK' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '1+', ], 'WEBSERVICE' => [ @@ -2746,17 +2746,17 @@ class Calculation ], 'WORKDAY.INTL' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2-4', ], 'WRAPCOLS' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2-3', ], 'WRAPROWS' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2-3', ], 'XIRR' => [ @@ -2766,7 +2766,7 @@ class Calculation ], 'XLOOKUP' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '3-6', ], 'XNPV' => [ @@ -2776,7 +2776,7 @@ class Calculation ], 'XMATCH' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '2,3', ], 'XOR' => [ @@ -2796,7 +2796,7 @@ class Calculation ], 'YIELD' => [ 'category' => Category::CATEGORY_FINANCIAL, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [Functions::class, 'dummy'], 'argumentCount' => '6,7', ], 'YIELDDISC' => [ @@ -5371,7 +5371,7 @@ public function extractNamedRange(string &$range = 'A1', ?Worksheet $worksheet = public function isImplemented($function) { $function = strtoupper($function); - $notImplemented = !isset(self::$phpSpreadsheetFunctions[$function]) || (is_array(self::$phpSpreadsheetFunctions[$function]['functionCall']) && self::$phpSpreadsheetFunctions[$function]['functionCall'][1] === 'DUMMY'); + $notImplemented = !isset(self::$phpSpreadsheetFunctions[$function]) || (is_array(self::$phpSpreadsheetFunctions[$function]['functionCall']) && self::$phpSpreadsheetFunctions[$function]['functionCall'][1] === 'dummy'); return !$notImplemented; } diff --git a/src/PhpSpreadsheet/Calculation/Database/DStDev.php b/src/PhpSpreadsheet/Calculation/Database/DStDev.php index 7ec42bc469..79ba9cd40c 100644 --- a/src/PhpSpreadsheet/Calculation/Database/DStDev.php +++ b/src/PhpSpreadsheet/Calculation/Database/DStDev.php @@ -39,7 +39,7 @@ public static function evaluate($database, $field, $criteria) return null; } - return StandardDeviations::STDEV( + return StandardDeviations::stdev( self::getFilteredColumn($database, $field, $criteria) ); } diff --git a/src/PhpSpreadsheet/Calculation/Database/DStDevP.php b/src/PhpSpreadsheet/Calculation/Database/DStDevP.php index cbe241f024..f6c8f5d342 100644 --- a/src/PhpSpreadsheet/Calculation/Database/DStDevP.php +++ b/src/PhpSpreadsheet/Calculation/Database/DStDevP.php @@ -39,7 +39,7 @@ public static function evaluate($database, $field, $criteria) return null; } - return StandardDeviations::STDEVP( + return StandardDeviations::stdevP( self::getFilteredColumn($database, $field, $criteria) ); } diff --git a/src/PhpSpreadsheet/Calculation/Database/DVar.php b/src/PhpSpreadsheet/Calculation/Database/DVar.php index 0a998c0312..f4b0c37a5d 100644 --- a/src/PhpSpreadsheet/Calculation/Database/DVar.php +++ b/src/PhpSpreadsheet/Calculation/Database/DVar.php @@ -39,7 +39,7 @@ public static function evaluate($database, $field, $criteria) return null; } - return Variances::VAR( + return Variances::variance( self::getFilteredColumn($database, $field, $criteria) ); } diff --git a/src/PhpSpreadsheet/Calculation/Database/DVarP.php b/src/PhpSpreadsheet/Calculation/Database/DVarP.php index 77acbdfcbd..faeffda6f0 100644 --- a/src/PhpSpreadsheet/Calculation/Database/DVarP.php +++ b/src/PhpSpreadsheet/Calculation/Database/DVarP.php @@ -39,7 +39,7 @@ public static function evaluate($database, $field, $criteria) return null; } - return Variances::VARP( + return Variances::varianceP( self::getFilteredColumn($database, $field, $criteria) ); } diff --git a/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php b/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php index b7c298dbc3..af23a46b69 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php @@ -533,7 +533,7 @@ public static function getBinaryConversionMultipliers() * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function CONVERT($value, $fromUOM, $toUOM) + public static function convert($value, $fromUOM, $toUOM) { if (is_array($value) || is_array($fromUOM) || is_array($toUOM)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $value, $fromUOM, $toUOM); diff --git a/src/PhpSpreadsheet/Calculation/Engineering/Erf.php b/src/PhpSpreadsheet/Calculation/Engineering/Erf.php index 6254d4776c..2b92c3b967 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/Erf.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/Erf.php @@ -35,7 +35,7 @@ class Erf * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function ERF($lower, $upper = null) + public static function erf($lower, $upper = null) { if (is_array($lower) || is_array($upper)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $lower, $upper); @@ -68,13 +68,13 @@ public static function ERF($lower, $upper = null) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function ERFPRECISE($limit) + public static function precise($limit) { if (is_array($limit)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $limit); } - return self::ERF($limit); + return self::erf($limit); } // @@ -83,7 +83,7 @@ public static function ERFPRECISE($limit) public static function erfValue($value) { if (abs($value) > 2.2) { - return 1 - ErfC::ERFC($value); + return 1 - ErfC::complementary($value); } $sum = $term = $value; $xsqr = ($value * $value); diff --git a/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php b/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php index 7b023bee59..d326249d29 100644 --- a/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php +++ b/src/PhpSpreadsheet/Calculation/Engineering/ErfC.php @@ -30,7 +30,7 @@ class ErfC * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function ERFC($value) + public static function complementary($value) { if (is_array($value)) { return self::evaluateSingleArgumentArray([self::class, __FUNCTION__], $value); diff --git a/src/PhpSpreadsheet/Calculation/Financial/Amortization.php b/src/PhpSpreadsheet/Calculation/Financial/Amortization.php index 691ba40ce1..df3529f286 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/Amortization.php +++ b/src/PhpSpreadsheet/Calculation/Financial/Amortization.php @@ -39,7 +39,7 @@ class Amortization * * @return float|string (string containing the error type if there is an error) */ - public static function AMORDEGRC( + public static function withCoefficient( $cost, $purchased, $firstPeriod, @@ -128,7 +128,7 @@ public static function AMORDEGRC( * * @return float|string (string containing the error type if there is an error) */ - public static function AMORLINC( + public static function depreciation( $cost, $purchased, $firstPeriod, diff --git a/src/PhpSpreadsheet/Calculation/Financial/Depreciation.php b/src/PhpSpreadsheet/Calculation/Financial/Depreciation.php index 3d72757a82..6fdb5f70b6 100644 --- a/src/PhpSpreadsheet/Calculation/Financial/Depreciation.php +++ b/src/PhpSpreadsheet/Calculation/Financial/Depreciation.php @@ -33,7 +33,7 @@ class Depreciation * * @return float|string */ - public static function DB($cost, $salvage, $life, $period, $month = 12) + public static function decliningBalance($cost, $salvage, $life, $period, $month = 12) { $cost = Functions::flattenSingleValue($cost); $salvage = Functions::flattenSingleValue($salvage); @@ -99,7 +99,7 @@ public static function DB($cost, $salvage, $life, $period, $month = 12) * * @return float|string */ - public static function DDB($cost, $salvage, $life, $period, $factor = 2.0) + public static function doubleDecliningBalance($cost, $salvage, $life, $period, $factor = 2.0) { $cost = Functions::flattenSingleValue($cost); $salvage = Functions::flattenSingleValue($salvage); @@ -147,7 +147,7 @@ public static function DDB($cost, $salvage, $life, $period, $factor = 2.0) * * @return float|string Result, or a string containing an error */ - public static function SLN($cost, $salvage, $life) + public static function straightLine($cost, $salvage, $life) { $cost = Functions::flattenSingleValue($cost); $salvage = Functions::flattenSingleValue($salvage); @@ -180,7 +180,7 @@ public static function SLN($cost, $salvage, $life) * * @return float|string Result, or a string containing an error */ - public static function SYD($cost, $salvage, $life, $period) + public static function sumOfYears($cost, $salvage, $life, $period) { $cost = Functions::flattenSingleValue($cost); $salvage = Functions::flattenSingleValue($salvage); diff --git a/src/PhpSpreadsheet/Calculation/Functions.php b/src/PhpSpreadsheet/Calculation/Functions.php index ec6010d9d4..482ffba556 100644 --- a/src/PhpSpreadsheet/Calculation/Functions.php +++ b/src/PhpSpreadsheet/Calculation/Functions.php @@ -125,7 +125,7 @@ public static function getReturnDateType() * * @return string #Not Yet Implemented */ - public static function DUMMY() + public static function dummy() { return '#Not Yet Implemented'; } diff --git a/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php b/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php index 02a255812f..41d9e2f6d3 100644 --- a/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php +++ b/src/PhpSpreadsheet/Calculation/LookupRef/Offset.php @@ -41,7 +41,7 @@ class Offset * * @return array|int|string An array containing a cell or range of cells, or a string on error */ - public static function OFFSET($cellAddress = null, $rows = 0, $columns = 0, $height = null, $width = null, ?Cell $cell = null) + public static function offset($cellAddress = null, $rows = 0, $columns = 0, $height = null, $width = null, ?Cell $cell = null) { $rows = Functions::flattenSingleValue($rows); $columns = Functions::flattenSingleValue($columns); diff --git a/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php b/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php index 7d23e290d8..df69c6c2c5 100644 --- a/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php +++ b/src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php @@ -67,11 +67,11 @@ function ($index) use ($cellReference) { [Statistical\Maximum::class, 'max'], // 4 and 104 [Statistical\Minimum::class, 'min'], // 5 and 105 [Operations::class, 'product'], // 6 and 106 - [Statistical\StandardDeviations::class, 'STDEV'], // 7 and 107 - [Statistical\StandardDeviations::class, 'STDEVP'], // 8 and 108 + [Statistical\StandardDeviations::class, 'stdev'], // 7 and 107 + [Statistical\StandardDeviations::class, 'stdevP'], // 8 and 108 [Sum::class, 'sumIgnoringStrings'], // 9 and 109 - [Statistical\Variances::class, 'VAR'], // 10 and 110 - [Statistical\Variances::class, 'VARP'], // 111 and 111 + [Statistical\Variances::class, 'variance'], // 10 and 110 + [Statistical\Variances::class, 'varianceP'], // 111 and 111 ]; /** diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php b/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php index ec2ce34ee1..d051fdebfe 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Confidence.php @@ -27,7 +27,7 @@ class Confidence * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function CONFIDENCE($alpha, $stdDev, $size) + public static function confidence($alpha, $stdDev, $size) { if (is_array($alpha) || is_array($stdDev) || is_array($size)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $alpha, $stdDev, $size); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Deviations.php b/src/PhpSpreadsheet/Calculation/Statistical/Deviations.php index 6b1db3a43b..99c6ec3fa3 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Deviations.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Deviations.php @@ -68,7 +68,7 @@ public static function kurtosis(...$args) if (!is_numeric($mean)) { return ExcelError::DIV0(); } - $stdDev = StandardDeviations::STDEV($aArgs); + $stdDev = StandardDeviations::stdev($aArgs); if ($stdDev > 0) { $count = $summer = 0; @@ -113,7 +113,7 @@ public static function skew(...$args) if (!is_numeric($mean)) { return ExcelError::DIV0(); } - $stdDev = StandardDeviations::STDEV($aArgs); + $stdDev = StandardDeviations::stdev($aArgs); if ($stdDev === 0.0 || is_string($stdDev)) { return ExcelError::DIV0(); } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php index a655fa745f..dfd376935b 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php @@ -142,7 +142,7 @@ public static function zTest($dataSet, $m0, $sigma = null) if ($sigma === null) { /** @var float */ - $sigma = StandardDeviations::STDEV($dataSet); + $sigma = StandardDeviations::stdev($dataSet); } $n = count($dataSet); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php b/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php index d6a65cb1bf..670585a624 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php @@ -24,7 +24,7 @@ class Percentiles * * @return float|string The result, or a string containing an error */ - public static function PERCENTILE(...$args) + public static function percentile(...$args) { $aArgs = Functions::flattenArray($args); @@ -74,7 +74,7 @@ public static function PERCENTILE(...$args) * * @return float|string (string if result is an error) */ - public static function PERCENTRANK($valueSet, $value, $significance = 3) + public static function percentRank($valueSet, $value, $significance = 3) { $valueSet = Functions::flattenArray($valueSet); $value = Functions::flattenSingleValue($value); @@ -125,7 +125,7 @@ public static function PERCENTRANK($valueSet, $value, $significance = 3) * * @return float|string The result, or a string containing an error */ - public static function QUARTILE(...$args) + public static function quartile(...$args) { $aArgs = Functions::flattenArray($args); $entry = array_pop($aArgs); @@ -142,7 +142,7 @@ public static function QUARTILE(...$args) return ExcelError::NAN(); } - return self::PERCENTILE($aArgs, $entry); + return self::percentile($aArgs, $entry); } /** @@ -156,7 +156,7 @@ public static function QUARTILE(...$args) * * @return float|string The result, or a string containing an error (0 = Descending, 1 = Ascending) */ - public static function RANK($value, $valueSet, $order = self::RANK_SORT_DESCENDING) + public static function rank($value, $valueSet, $order = self::RANK_SORT_DESCENDING) { $value = Functions::flattenSingleValue($value); $valueSet = Functions::flattenArray($valueSet); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php b/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php index 5d9d304837..280220b9eb 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php @@ -30,7 +30,7 @@ class Permutations * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function PERMUT($numObjs, $numInSet) + public static function permut($numObjs, $numInSet) { if (is_array($numObjs) || is_array($numInSet)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $numObjs, $numInSet); @@ -66,7 +66,7 @@ public static function PERMUT($numObjs, $numInSet) * If an array of numbers is passed as an argument, then the returned result will also be an array * with the same dimensions */ - public static function PERMUTATIONA($numObjs, $numInSet) + public static function permutationA($numObjs, $numInSet) { if (is_array($numObjs) || is_array($numInSet)) { return self::evaluateArrayArguments([self::class, __FUNCTION__], $numObjs, $numInSet); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php b/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php index af2712053f..d7cac87f24 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php @@ -17,9 +17,9 @@ class StandardDeviations * * @return float|string The result, or a string containing an error */ - public static function STDEV(...$args) + public static function stdev(...$args) { - $result = Variances::VAR(...$args); + $result = Variances::variance(...$args); if (!is_numeric($result)) { return $result; } @@ -39,9 +39,9 @@ public static function STDEV(...$args) * * @return float|string */ - public static function STDEVA(...$args) + public static function stdevA(...$args) { - $result = Variances::VARA(...$args); + $result = Variances::varianceA(...$args); if (!is_numeric($result)) { return $result; } @@ -61,9 +61,9 @@ public static function STDEVA(...$args) * * @return float|string */ - public static function STDEVP(...$args) + public static function stdevP(...$args) { - $result = Variances::VARP(...$args); + $result = Variances::varianceP(...$args); if (!is_numeric($result)) { return $result; } @@ -83,9 +83,9 @@ public static function STDEVP(...$args) * * @return float|string */ - public static function STDEVPA(...$args) + public static function stdevPA(...$args) { - $result = Variances::VARPA(...$args); + $result = Variances::variancePA(...$args); if (!is_numeric($result)) { return $result; } diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Trends.php b/src/PhpSpreadsheet/Calculation/Statistical/Trends.php index c1579730c0..07ce487b08 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Trends.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Trends.php @@ -63,7 +63,7 @@ protected static function validateTrendArrays(array $yValues, array $xValues): v * * @return float|string */ - public static function correl($yValues, $xValues = null) + public static function correlation($yValues, $xValues = null) { if (($xValues === null) || (!is_array($yValues)) || (!is_array($xValues))) { return ExcelError::VALUE(); @@ -208,7 +208,7 @@ public static function intercept($yValues, $xValues) * * @return array|int|string The result, or a string containing an error */ - public static function LINEST($yValues, $xValues = null, $const = true, $stats = false) + public static function lineEstimate($yValues, $xValues = null, $const = true, $stats = false) { $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const); $stats = ($stats === null) ? false : (bool) Functions::flattenSingleValue($stats); @@ -269,7 +269,7 @@ public static function LINEST($yValues, $xValues = null, $const = true, $stats = * * @return array|int|string The result, or a string containing an error */ - public static function LOGEST($yValues, $xValues = null, $const = true, $stats = false) + public static function logEstimate($yValues, $xValues = null, $const = true, $stats = false) { $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const); $stats = ($stats === null) ? false : (bool) Functions::flattenSingleValue($stats); @@ -334,7 +334,7 @@ public static function LOGEST($yValues, $xValues = null, $const = true, $stats = * * @return float|string The result, or a string containing an error */ - public static function RSQ($yValues, $xValues) + public static function pearsonSquares($yValues, $xValues) { try { self::checkTrendArrays($yValues, $xValues); @@ -382,7 +382,7 @@ public static function slope($yValues, $xValues) * * @return float|string */ - public static function STEYX($yValues, $xValues) + public static function standardError($yValues, $xValues) { try { self::checkTrendArrays($yValues, $xValues); diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Variances.php b/src/PhpSpreadsheet/Calculation/Statistical/Variances.php index 35d01d1c57..55685c1df2 100644 --- a/src/PhpSpreadsheet/Calculation/Statistical/Variances.php +++ b/src/PhpSpreadsheet/Calculation/Statistical/Variances.php @@ -19,7 +19,7 @@ class Variances extends VarianceBase * * @return float|string (string if result is an error) */ - public static function VAR(...$args) + public static function variance(...$args) { $returnValue = ExcelError::DIV0(); @@ -61,7 +61,7 @@ public static function VAR(...$args) * * @return float|string (string if result is an error) */ - public static function VARA(...$args) + public static function varianceA(...$args) { $returnValue = ExcelError::DIV0(); @@ -107,7 +107,7 @@ public static function VARA(...$args) * * @return float|string (string if result is an error) */ - public static function VARP(...$args) + public static function varianceP(...$args) { // Return value $returnValue = ExcelError::DIV0(); @@ -150,7 +150,7 @@ public static function VARP(...$args) * * @return float|string (string if result is an error) */ - public static function VARPA(...$args) + public static function variancePA(...$args) { $returnValue = ExcelError::DIV0(); diff --git a/tests/PhpSpreadsheetTests/Calculation/CalculationFunctionListTest.php b/tests/PhpSpreadsheetTests/Calculation/CalculationFunctionListTest.php index e95c32677d..23f591aeaf 100644 --- a/tests/PhpSpreadsheetTests/Calculation/CalculationFunctionListTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/CalculationFunctionListTest.php @@ -54,10 +54,10 @@ public function providerGetFunctions(): array public function testIsImplemented(): void { $calculation = Calculation::getInstance(); - self::assertFalse($calculation->isImplemented('non-existing-function')); - self::assertFalse($calculation->isImplemented('AREAS')); - self::assertTrue($calculation->isImplemented('coUNt')); - self::assertTrue($calculation->isImplemented('abs')); + self::assertFalse($calculation->isImplemented('non-existing-function'), 'Non-existent Function'); + self::assertFalse($calculation->isImplemented('AREAS'), 'AREAS()'); + self::assertTrue($calculation->isImplemented('coUNt'), 'COUNT()'); + self::assertTrue($calculation->isImplemented('abs'), 'ABS()'); } public function testUnknownFunction(): void diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php index 9675b20994..bc6a4a9c89 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php @@ -47,7 +47,7 @@ public function testGetBinaryConversionMultipliers(): void */ public function testCONVERTUOM($expectedResult, ...$args): void { - $result = ConvertUOM::CONVERT(...$args); + $result = ConvertUOM::convert(...$args); self::assertEqualsWithDelta($expectedResult, $result, self::UOM_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php index ee38626672..030ef96c0c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php @@ -18,7 +18,7 @@ class ErfCTest extends TestCase */ public function testERFC($expectedResult, $lower): void { - $result = ErfC::ERFC($lower); + $result = ErfC::complementary($lower); self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php index a4fc9dfda1..bb3f2c13a9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php @@ -18,7 +18,7 @@ class ErfPreciseTest extends TestCase */ public function testERFPRECISE($expectedResult, $limit): void { - $result = Erf::ERFPRECISE($limit); + $result = Erf::precise($limit); self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php index 26d0290ad9..04204d12af 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php @@ -19,7 +19,7 @@ class ErfTest extends TestCase */ public function testERF($expectedResult, $lower, $upper = null): void { - $result = Erf::ERF($lower, $upper); + $result = Erf::erf($lower, $upper); self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorDegRcTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorDegRcTest.php index f0fb0a4573..db309c27f9 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorDegRcTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorDegRcTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAMORDEGRC($expectedResult, ...$args): void { - $result = Amortization::AMORDEGRC(...$args); + $result = Amortization::withCoefficient(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorLincTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorLincTest.php index b7661e0244..319848f3f4 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorLincTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorLincTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testAMORLINC($expectedResult, ...$args): void { - $result = Amortization::AMORLINC(...$args); + $result = Amortization::depreciation(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DbTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DbTest.php index f92e639eed..2365f08eaf 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DbTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DbTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testDB($expectedResult, ...$args): void { - $result = Depreciation::DB(...$args); + $result = Depreciation::decliningBalance(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DdbTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DdbTest.php index cebb5ecd2f..0369ebf2d6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DdbTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/DdbTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testDDB($expectedResult, ...$args): void { - $result = Depreciation::DDB(...$args); + $result = Depreciation::doubleDecliningBalance(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/SlnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/SlnTest.php index 77c2735d44..05842799ab 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/SlnTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/SlnTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testSLN($expectedResult, array $args): void { - $result = Depreciation::SLN(...$args); + $result = Depreciation::straightLine(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/SydTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/SydTest.php index 2e6589c700..8eee51e0df 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/SydTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/SydTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testSYD($expectedResult, array $args): void { - $result = Depreciation::SYD(...$args); + $result = Depreciation::sumOfYears(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-8); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/OffsetTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/OffsetTest.php index 22787e25f3..f5b67d965e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/OffsetTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/OffsetTest.php @@ -15,7 +15,7 @@ class OffsetTest extends AllSetupTeardown */ public function testOFFSET($expectedResult, $cellReference = null): void { - $result = LookupRef\Offset::OFFSET($cellReference); + $result = LookupRef\Offset::offset($cellReference); self::assertSame($expectedResult, $result); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php index 6c20910261..9f387fb0fb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/ConfidenceTest.php @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testCONFIDENCE($expectedResult, ...$args): void { - $result = Confidence::CONFIDENCE(...$args); + $result = Confidence::confidence(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php index 52eaf94593..2b5f9038c3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/CorrelTest.php @@ -22,7 +22,7 @@ protected function setUp(): void */ public function testCORREL($expectedResult, $xargs, $yargs): void { - $result = Trends::correl($xargs, $yargs); + $result = Trends::correlation($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LinEstTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LinEstTest.php index 131ee7a052..5fc70bb157 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LinEstTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LinEstTest.php @@ -17,7 +17,7 @@ class LinEstTest extends TestCase */ public function testLINEST(array $expectedResult, $yValues, $xValues, $const, $stats): void { - $result = Trends::LINEST($yValues, $xValues, $const, $stats); + $result = Trends::lineEstimate($yValues, $xValues, $const, $stats); self::assertIsArray($result); $elements = count($expectedResult); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogEstTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogEstTest.php index 916eedefb3..f96737a04e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogEstTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/LogEstTest.php @@ -17,7 +17,7 @@ class LogEstTest extends TestCase */ public function testLOGEST(array $expectedResult, $yValues, $xValues, $const, $stats): void { - $result = Trends::LOGEST($yValues, $xValues, $const, $stats); + $result = Trends::logEstimate($yValues, $xValues, $const, $stats); self::assertIsArray($result); $elements = count($expectedResult); diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentRankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentRankTest.php index 6c5a20f392..d8311342eb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentRankTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentRankTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testPERCENTRANK($expectedResult, $valueSet, $value, $digits = 3): void { - $result = Percentiles::PERCENTRANK($valueSet, $value, $digits); + $result = Percentiles::percentRank($valueSet, $value, $digits); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentileTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentileTest.php index 938c3c9ea8..8dcf11f549 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentileTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PercentileTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testPERCENTILE($expectedResult, ...$args): void { - $result = Percentiles::PERCENTILE(...$args); + $result = Percentiles::percentile(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php index eda12cbcfc..92ee67a65f 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutTest.php @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testPERMUT($expectedResult, ...$args): void { - $result = Permutations::PERMUT(...$args); + $result = Permutations::permut(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php index acbcf1a85a..7d67ff286c 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/PermutationATest.php @@ -21,7 +21,7 @@ protected function setUp(): void */ public function testPERMUT($expectedResult, ...$args): void { - $result = Permutations::PERMUTATIONA(...$args); + $result = Permutations::permutationA(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/QuartileTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/QuartileTest.php index 5c6225738f..1a4f82d608 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/QuartileTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/QuartileTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testQUARTILE($expectedResult, ...$args): void { - $result = Percentiles::QUARTILE(...$args); + $result = Percentiles::quartile(...$args); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RankTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RankTest.php index 4acae2620f..37e4f326c6 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RankTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RankTest.php @@ -23,7 +23,7 @@ protected function setUp(): void */ public function testRANK($expectedResult, $value, $valueSet, $order = 0): void { - $result = Percentiles::RANK($value, $valueSet, $order); + $result = Percentiles::rank($value, $valueSet, $order); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RsqTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RsqTest.php index cc89d7ce14..5231815e43 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RsqTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/RsqTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testRSQ($expectedResult, array $xargs, array $yargs): void { - $result = Trends::RSQ($xargs, $yargs); + $result = Trends::pearsonSquares($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php index dbb8bb1ab6..00d1e47f32 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevATest.php @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testSTDEVA($expectedResult, $values): void { - $result = StandardDeviations::STDEVA($values); + $result = StandardDeviations::stdevA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsSTDEVA($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = StandardDeviations::STDEVA($values); + $result = StandardDeviations::stdevA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php index 84aa21b545..6718fbb0fb 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPATest.php @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testSTDEVPA($expectedResult, $values): void { - $result = StandardDeviations::STDEVPA($values); + $result = StandardDeviations::stdevPA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsSTDEVPA($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = StandardDeviations::STDEVPA($values); + $result = StandardDeviations::stdevPA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php index 0bed3f055f..011a60e1a2 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevPTest.php @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testSTDEVP($expectedResult, $values): void { - $result = StandardDeviations::STDEVP($values); + $result = StandardDeviations::stdevP($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsSTDEVP($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = StandardDeviations::STDEVP($values); + $result = StandardDeviations::stdevP($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php index 38ed4e240d..c433d0104b 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/StDevTest.php @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testSTDEV($expectedResult, $values): void { - $result = StandardDeviations::STDEV($values); + $result = StandardDeviations::stdev($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsSTDEV($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = StandardDeviations::STDEV($values); + $result = StandardDeviations::stdev($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SteyxTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SteyxTest.php index b8e23741c3..ef64cd139a 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SteyxTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/SteyxTest.php @@ -20,7 +20,7 @@ protected function setUp(): void */ public function testSTEYX($expectedResult, array $xargs, array $yargs): void { - $result = Trends::STEYX($xargs, $yargs); + $result = Trends::standardError($xargs, $yargs); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php index 45ccf7ba4c..dbc45d0816 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarATest.php @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testVARA($expectedResult, $values): void { - $result = Variances::VARA($values); + $result = Variances::varianceA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsVARA($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Variances::VARA($values); + $result = Variances::varianceA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php index 2adfd7c132..2f04d1e88e 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPATest.php @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testVARPA($expectedResult, $values): void { - $result = Variances::VARPA($values); + $result = Variances::variancePA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsVARPA($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Variances::VARPA($values); + $result = Variances::variancePA($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php index 69b7c8d64b..5ba80661a3 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarPTest.php @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testVARP($expectedResult, $values): void { - $result = Variances::VARP($values); + $result = Variances::varianceP($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsVARP($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Variances::VARP($values); + $result = Variances::varianceP($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php index 6a33c04a60..76dd3d5d98 100644 --- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/VarTest.php @@ -21,7 +21,7 @@ protected function tearDown(): void */ public function testVAR($expectedResult, $values): void { - $result = Variances::VAR($values); + $result = Variances::variance($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } @@ -40,7 +40,7 @@ public function testOdsVAR($expectedResult, $values): void { Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); - $result = Variances::VAR($values); + $result = Variances::variance($values); self::assertEqualsWithDelta($expectedResult, $result, 1E-12); } diff --git a/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php index dbb3667f1f..a79044e922 100644 --- a/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php +++ b/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php @@ -69,7 +69,7 @@ public function testInvalidReturnDateType(): void public function testDUMMY(): void { - $result = Functions::DUMMY(); + $result = Functions::dummy(); self::assertEquals('#Not Yet Implemented', $result); } diff --git a/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php b/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php index ce61ff4ac9..e36a9f2864 100644 --- a/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php +++ b/tests/PhpSpreadsheetTests/DocumentGeneratorTest.php @@ -34,7 +34,7 @@ public function providerGenerateFunctionListByName(): array [ 'ABS' => ['category' => Cat::CATEGORY_MATH_AND_TRIG, 'functionCall' => 'abs'], 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical\Operations::class, 'and']], - 'IFS' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Functions::class, 'DUMMY']], + 'IFS' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Functions::class, 'dummy']], ], <<<'EXPECTED' # Function list by name @@ -65,7 +65,7 @@ public function providerGenerateFunctionListByCategory(): array [ 'ABS' => ['category' => Cat::CATEGORY_MATH_AND_TRIG, 'functionCall' => 'abs'], 'AND' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Logical\Operations::class, 'and']], - 'IFS' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Functions::class, 'DUMMY']], + 'IFS' => ['category' => Cat::CATEGORY_LOGICAL, 'functionCall' => [Functions::class, 'dummy']], ], <<<'EXPECTED' # Function list by category From 43413002fd0da6048fff4defa148512efbe279b3 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Fri, 30 Sep 2022 15:34:23 +0200 Subject: [PATCH 93/94] Stricter type-hinting for IReader --- samples/Basic/24_Readfilter.php | 2 +- ...Simple_file_reader_using_a_read_filter.php | 2 +- ...eader_using_a_configurable_read_filter.php | 2 +- ...a_configurable_read_filter_(version_1).php | 2 +- ...a_configurable_read_filter_(version_2).php | 2 +- ...ks_to_split_across_multiple_worksheets.php | 2 +- src/PhpSpreadsheet/Reader/BaseReader.php | 28 ++++----- .../Reader/DefaultReadFilter.php | 4 +- src/PhpSpreadsheet/Reader/IReadFilter.php | 4 +- src/PhpSpreadsheet/Reader/IReader.php | 61 +++++-------------- .../Functional/ReadFilterFilter.php | 4 +- .../Reader/Csv/CsvContiguousFilter.php | 4 +- .../Reader/Gnumeric/GnumericFilter.php | 2 +- .../Reader/Xlsx/OddColumnReadFilter.php | 2 +- .../Reader/Xml/XmlFilter.php | 2 +- 15 files changed, 43 insertions(+), 80 deletions(-) diff --git a/samples/Basic/24_Readfilter.php b/samples/Basic/24_Readfilter.php index e5b613a67e..0f73818f9e 100644 --- a/samples/Basic/24_Readfilter.php +++ b/samples/Basic/24_Readfilter.php @@ -18,7 +18,7 @@ class MyReadFilter implements IReadFilter { - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { // Read title row and rows 20 - 30 if ($row == 1 || ($row >= 20 && $row <= 30)) { diff --git a/samples/Reader/09_Simple_file_reader_using_a_read_filter.php b/samples/Reader/09_Simple_file_reader_using_a_read_filter.php index 4603164c65..ed394c5926 100644 --- a/samples/Reader/09_Simple_file_reader_using_a_read_filter.php +++ b/samples/Reader/09_Simple_file_reader_using_a_read_filter.php @@ -13,7 +13,7 @@ class MyReadFilter implements IReadFilter { - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { // Read rows 1 to 7 and columns A to E only if ($row >= 1 && $row <= 7) { diff --git a/samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php b/samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php index 82ca22349e..dd039a9348 100644 --- a/samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php +++ b/samples/Reader/10_Simple_file_reader_using_a_configurable_read_filter.php @@ -26,7 +26,7 @@ public function __construct($startRow, $endRow, $columns) $this->columns = $columns; } - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { if ($row >= $this->startRow && $row <= $this->endRow) { if (in_array($columnAddress, $this->columns)) { diff --git a/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php b/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php index cf070054b7..321b228bc8 100644 --- a/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php +++ b/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php @@ -29,7 +29,7 @@ public function __construct($startRow, $chunkSize) $this->endRow = $startRow + $chunkSize; } - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { // Only read the heading row, and the rows that were configured in the constructor if (($row == 1) || ($row >= $this->startRow && $row < $this->endRow)) { diff --git a/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php b/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php index 13692e3aa5..54296fe9d9 100644 --- a/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php +++ b/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php @@ -29,7 +29,7 @@ public function setRows($startRow, $chunkSize): void $this->endRow = $startRow + $chunkSize; } - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { // Only read the heading row, and the rows that are configured in $this->_startRow and $this->_endRow if (($row == 1) || ($row >= $this->startRow && $row < $this->endRow)) { diff --git a/samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php b/samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php index eab7ec01d2..749f98d1fb 100644 --- a/samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php +++ b/samples/Reader/14_Reading_a_large_CSV_file_in_chunks_to_split_across_multiple_worksheets.php @@ -29,7 +29,7 @@ public function setRows($startRow, $chunkSize): void $this->endRow = $startRow + $chunkSize; } - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { // Only read the heading row, and the rows that are configured in $this->_startRow and $this->_endRow if (($row == 1) || ($row >= $this->startRow && $row < $this->endRow)) { diff --git a/src/PhpSpreadsheet/Reader/BaseReader.php b/src/PhpSpreadsheet/Reader/BaseReader.php index 3aec6eafab..c6cf8b9a15 100644 --- a/src/PhpSpreadsheet/Reader/BaseReader.php +++ b/src/PhpSpreadsheet/Reader/BaseReader.php @@ -41,7 +41,7 @@ abstract class BaseReader implements IReader * Restrict which sheets should be loaded? * This property holds an array of worksheet names to be loaded. If null, then all worksheets will be loaded. * - * @var null|string[] + * @var ?string[] */ protected $loadSheetsOnly; @@ -64,38 +64,38 @@ public function __construct() $this->readFilter = new DefaultReadFilter(); } - public function getReadDataOnly() + public function getReadDataOnly(): bool { return $this->readDataOnly; } - public function setReadDataOnly($readCellValuesOnly) + public function setReadDataOnly(bool $readDataOnly): IReader { - $this->readDataOnly = (bool) $readCellValuesOnly; + $this->readDataOnly = (bool) $readDataOnly; return $this; } - public function getReadEmptyCells() + public function getReadEmptyCells(): bool { return $this->readEmptyCells; } - public function setReadEmptyCells($readEmptyCells) + public function setReadEmptyCells(bool $readEmptyCells): IReader { - $this->readEmptyCells = (bool) $readEmptyCells; + $this->readEmptyCells = $readEmptyCells; return $this; } - public function getIncludeCharts() + public function getIncludeCharts(): bool { return $this->includeCharts; } - public function setIncludeCharts($includeCharts) + public function setIncludeCharts(bool $includeCharts): IReader { - $this->includeCharts = (bool) $includeCharts; + $this->includeCharts = $includeCharts; return $this; } @@ -105,7 +105,7 @@ public function getLoadSheetsOnly() return $this->loadSheetsOnly; } - public function setLoadSheetsOnly($sheetList) + public function setLoadSheetsOnly($sheetList): IReader { if ($sheetList === null) { return $this->setLoadAllSheets(); @@ -116,19 +116,19 @@ public function setLoadSheetsOnly($sheetList) return $this; } - public function setLoadAllSheets() + public function setLoadAllSheets(): IReader { $this->loadSheetsOnly = null; return $this; } - public function getReadFilter() + public function getReadFilter(): IReadFilter { return $this->readFilter; } - public function setReadFilter(IReadFilter $readFilter) + public function setReadFilter(IReadFilter $readFilter): IReader { $this->readFilter = $readFilter; diff --git a/src/PhpSpreadsheet/Reader/DefaultReadFilter.php b/src/PhpSpreadsheet/Reader/DefaultReadFilter.php index 8fdb162b4c..0c4b87b61a 100644 --- a/src/PhpSpreadsheet/Reader/DefaultReadFilter.php +++ b/src/PhpSpreadsheet/Reader/DefaultReadFilter.php @@ -10,10 +10,8 @@ class DefaultReadFilter implements IReadFilter * @param string $columnAddress Column address (as a string value like "A", or "IV") * @param int $row Row number * @param string $worksheetName Optional worksheet name - * - * @return bool */ - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { return true; } diff --git a/src/PhpSpreadsheet/Reader/IReadFilter.php b/src/PhpSpreadsheet/Reader/IReadFilter.php index 9f68a7f360..1fd12e56f7 100644 --- a/src/PhpSpreadsheet/Reader/IReadFilter.php +++ b/src/PhpSpreadsheet/Reader/IReadFilter.php @@ -10,8 +10,6 @@ interface IReadFilter * @param string $columnAddress Column address (as a string value like "A", or "IV") * @param int $row Row number * @param string $worksheetName Optional worksheet name - * - * @return bool */ - public function readCell($columnAddress, $row, $worksheetName = ''); + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool; } diff --git a/src/PhpSpreadsheet/Reader/IReader.php b/src/PhpSpreadsheet/Reader/IReader.php index d73662b426..de5df5e218 100644 --- a/src/PhpSpreadsheet/Reader/IReader.php +++ b/src/PhpSpreadsheet/Reader/IReader.php @@ -2,15 +2,12 @@ namespace PhpOffice\PhpSpreadsheet\Reader; +use PhpOffice\PhpSpreadsheet\Spreadsheet; + interface IReader { public const LOAD_WITH_CHARTS = 1; - /** - * IReader constructor. - */ - public function __construct(); - /** * Can the current IReader read the file? */ @@ -20,110 +17,82 @@ public function canRead(string $filename): bool; * Read data only? * If this is true, then the Reader will only read data values for cells, it will not read any formatting information. * If false (the default) it will read data and formatting. - * - * @return bool */ - public function getReadDataOnly(); + public function getReadDataOnly(): bool; /** * Set read data only * Set to true, to advise the Reader only to read data values for cells, and to ignore any formatting information. * Set to false (the default) to advise the Reader to read both data and formatting for cells. - * - * @param bool $readDataOnly - * - * @return IReader */ - public function setReadDataOnly($readDataOnly); + public function setReadDataOnly(bool $readDataOnly): self; /** * Read empty cells? * If this is true (the default), then the Reader will read data values for all cells, irrespective of value. * If false it will not read data for cells containing a null value or an empty string. - * - * @return bool */ - public function getReadEmptyCells(); + public function getReadEmptyCells(): bool; /** * Set read empty cells * Set to true (the default) to advise the Reader read data values for all cells, irrespective of value. * Set to false to advise the Reader to ignore cells containing a null value or an empty string. - * - * @param bool $readEmptyCells - * - * @return IReader */ - public function setReadEmptyCells($readEmptyCells); + public function setReadEmptyCells(bool $readEmptyCells): self; /** * Read charts in workbook? * If this is true, then the Reader will include any charts that exist in the workbook. * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. * If false (the default) it will ignore any charts defined in the workbook file. - * - * @return bool */ - public function getIncludeCharts(); + public function getIncludeCharts(): bool; /** * Set read charts in workbook * Set to true, to advise the Reader to include any charts that exist in the workbook. * Note that a ReadDataOnly value of false overrides, and charts won't be read regardless of the IncludeCharts value. * Set to false (the default) to discard charts. - * - * @param bool $includeCharts - * - * @return IReader */ - public function setIncludeCharts($includeCharts); + public function setIncludeCharts(bool $includeCharts): self; /** * Get which sheets to load * Returns either an array of worksheet names (the list of worksheets that should be loaded), or a null * indicating that all worksheets in the workbook should be loaded. * - * @return mixed + * @return ?string[] */ public function getLoadSheetsOnly(); /** * Set which sheets to load. * - * @param mixed $value + * @param null|string|string[] $sheetList * This should be either an array of worksheet names to be loaded, or a string containing a single worksheet name. * If NULL, then it tells the Reader to read all worksheets in the workbook - * - * @return IReader */ - public function setLoadSheetsOnly($value); + public function setLoadSheetsOnly($sheetList): self; /** * Set all sheets to load * Tells the Reader to load all worksheets from the workbook. - * - * @return IReader */ - public function setLoadAllSheets(); + public function setLoadAllSheets(): self; /** * Read filter. - * - * @return IReadFilter */ - public function getReadFilter(); + public function getReadFilter(): IReadFilter; /** * Set read filter. - * - * @return IReader */ - public function setReadFilter(IReadFilter $readFilter); + public function setReadFilter(IReadFilter $readFilter): self; /** * Loads PhpSpreadsheet from file. - * - * @return \PhpOffice\PhpSpreadsheet\Spreadsheet */ - public function load(string $filename, int $flags = 0); + public function load(string $filename, int $flags = 0): Spreadsheet; } diff --git a/tests/PhpSpreadsheetTests/Functional/ReadFilterFilter.php b/tests/PhpSpreadsheetTests/Functional/ReadFilterFilter.php index a9a26a5ee8..a96dfd1839 100644 --- a/tests/PhpSpreadsheetTests/Functional/ReadFilterFilter.php +++ b/tests/PhpSpreadsheetTests/Functional/ReadFilterFilter.php @@ -11,11 +11,9 @@ class ReadFilterFilter implements IReadFilter * @param int $row Row number * @param string $worksheetName Optional worksheet name * - * @return bool - * * @see \PhpOffice\PhpSpreadsheet\Reader\IReadFilter::readCell() */ - public function readCell($column, $row, $worksheetName = '') + public function readCell($column, $row, $worksheetName = ''): bool { // define filter range $rowMin = 2; diff --git a/tests/PhpSpreadsheetTests/Reader/Csv/CsvContiguousFilter.php b/tests/PhpSpreadsheetTests/Reader/Csv/CsvContiguousFilter.php index 31e60bdd40..11d26b6a0a 100644 --- a/tests/PhpSpreadsheetTests/Reader/Csv/CsvContiguousFilter.php +++ b/tests/PhpSpreadsheetTests/Reader/Csv/CsvContiguousFilter.php @@ -52,9 +52,9 @@ public function filter0(int $row): bool return false; } - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { - if ($this->filterType == 1) { + if ($this->filterType === 1) { return $this->filter1($row); } diff --git a/tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericFilter.php b/tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericFilter.php index 8d8fd62b40..27e68f5f84 100644 --- a/tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericFilter.php +++ b/tests/PhpSpreadsheetTests/Reader/Gnumeric/GnumericFilter.php @@ -7,7 +7,7 @@ /** Define a Read Filter class implementing IReadFilter */ class GnumericFilter implements IReadFilter { - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { return $row !== 4; } diff --git a/tests/PhpSpreadsheetTests/Reader/Xlsx/OddColumnReadFilter.php b/tests/PhpSpreadsheetTests/Reader/Xlsx/OddColumnReadFilter.php index 859e5b56b3..5814f21f79 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xlsx/OddColumnReadFilter.php +++ b/tests/PhpSpreadsheetTests/Reader/Xlsx/OddColumnReadFilter.php @@ -9,7 +9,7 @@ */ class OddColumnReadFilter implements IReadFilter { - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { return (\ord(\substr($columnAddress, -1, 1)) % 2) === 1; } diff --git a/tests/PhpSpreadsheetTests/Reader/Xml/XmlFilter.php b/tests/PhpSpreadsheetTests/Reader/Xml/XmlFilter.php index b53fffd590..864549cc97 100644 --- a/tests/PhpSpreadsheetTests/Reader/Xml/XmlFilter.php +++ b/tests/PhpSpreadsheetTests/Reader/Xml/XmlFilter.php @@ -7,7 +7,7 @@ /** Define a Read Filter class implementing IReadFilter */ class XmlFilter implements IReadFilter { - public function readCell($columnAddress, $row, $worksheetName = '') + public function readCell(string $columnAddress, int $row, string $worksheetName = ''): bool { return $row !== 4; } From ecc18d2220ca3315335aa826772454f3c9f06458 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Sun, 2 Oct 2022 20:50:35 +0200 Subject: [PATCH 94/94] Binary-value options for Reader using flag settings --- docs/topics/reading-files.md | 69 +++++++++++- src/PhpSpreadsheet/Reader/BaseReader.php | 18 ++- src/PhpSpreadsheet/Reader/IReader.php | 4 +- .../Reader/ReaderFlagsTest.php | 106 ++++++++++++++++++ 4 files changed, 191 insertions(+), 6 deletions(-) create mode 100644 tests/PhpSpreadsheetTests/Reader/ReaderFlagsTest.php diff --git a/docs/topics/reading-files.md b/docs/topics/reading-files.md index 767052812c..129ca43a3e 100644 --- a/docs/topics/reading-files.md +++ b/docs/topics/reading-files.md @@ -168,6 +168,68 @@ Once you have created a reader object for the workbook that you want to load, you have the opportunity to set additional options before executing the `load()` method. +All of these options can be set by calling the appropriate methods against the Reader (as described below), but some options (those with only two possible values) can also be set through flags, either by calling the Reader's `setFlags()` method, or passing the flags as an argument in the call to `load()`. +Those options that can be set through flags are: + +Option | Flag | Default +-------------------|------------------------------|--- +Ignore Empty Cells | IReader::IGNORE_EMPTY_CELLS | Load empty cells +Read Data Only | IReader::READ_DATA_ONLY | Read data, structure and style +Include Charts | IReader::LOAD_WITH_CHARTS | Don't read charts + +Several flags can be combined in a single call: +```php +$inputFileType = 'Xlsx'; +$inputFileName = './sampleData/example1.xlsx'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); +/** Set additional flags before the call to load() */ +$reader->setFlags(IReader::IGNORE_EMPTY_CELLS | IReader::LOAD_WITH_CHARTS); +$reader->load($inputFileName); +``` +or +```php +$inputFileType = 'Xlsx'; +$inputFileName = './sampleData/example1.xlsx'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); +/** Set additional flags in the call to load() */ +$reader->load($inputFileName, IReader::IGNORE_EMPTY_CELLS | IReader::LOAD_WITH_CHARTS); +``` + +### Ignoring Empty Cells + +Many Excel files have empty rows or columns at the end of a worksheet, which can't easily be seen when looking at the file in Excel (Try using Ctrl-End to see the last cell in a worksheet). +By default, PhpSpreadsheet will load these cells, because they are valid Excel values; but you may find that an apparently small spreadsheet requires a lot of memory for all those empty cells. +If you are running into memory issues with seemingly small files, you can tell PhpSpreadsheet not to load those empty cells using the `setReadEmptyCells()` method. + +```php +$inputFileType = 'Xls'; +$inputFileName = './sampleData/example1.xls'; + +/** Create a new Reader of the type defined in $inputFileType **/ +$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); +/** Advise the Reader that we only want to load cell's that contain actual content **/ +$reader->setReadEmptyCells(false); +/** Load $inputFileName to a Spreadsheet Object **/ +$spreadsheet = $reader->load($inputFileName); +``` + +Note that cells containing formulae will still be loaded, even if that formula evaluates to a NULL or an empty string. +Similarly, Conditional Styling might also hide the value of a cell; but cells that contain Conditional Styling or Data Validation will always be loaded regardless of their value. + +This option is available for the following formats: + +Reader | Y/N |Reader | Y/N |Reader | Y/N | +----------|:---:|--------|:---:|--------------|:---:| +Xlsx | YES | Xls | YES | Xml | NO | +Ods | NO | SYLK | NO | Gnumeric | NO | +CSV | NO | HTML | NO + +This option is also available through flags. + ### Reading Only Data from a Spreadsheet File If you're only interested in the cell values in a workbook, but don't @@ -210,6 +272,8 @@ Xlsx | YES | Xls | YES | Xml | YES | Ods | YES | SYLK | NO | Gnumeric | YES | CSV | NO | HTML | NO +This option is also available through flags. + ### Reading Only Named WorkSheets from a File If your workbook contains a number of worksheets, but you are only @@ -642,7 +706,7 @@ Xlsx | NO | Xls | NO | Xml | NO | Ods | NO | SYLK | NO | Gnumeric | NO | CSV | YES | HTML | NO -### A Brief Word about the Advanced Value Binder +## A Brief Word about the Advanced Value Binder When loading data from a file that contains no formatting information, such as a CSV file, then data is read either as strings or numbers @@ -694,6 +758,9 @@ Xlsx | NO | Xls | NO | Xml | NO Ods | NO | SYLK | NO | Gnumeric | NO CSV | YES | HTML | YES +Note that you can also use the Binder to determine how PhpSpreadsheet identified datatypes for values when you set a cell value without explicitly setting a datatype. +Value Binders can also be used to set formatting for a cell appropriate to the value. + ## Error Handling Of course, you should always apply some error handling to your scripts diff --git a/src/PhpSpreadsheet/Reader/BaseReader.php b/src/PhpSpreadsheet/Reader/BaseReader.php index c6cf8b9a15..552995fd31 100644 --- a/src/PhpSpreadsheet/Reader/BaseReader.php +++ b/src/PhpSpreadsheet/Reader/BaseReader.php @@ -140,8 +140,14 @@ public function getSecurityScanner() return $this->securityScanner; } - protected function processFlags(int $flags): void + public function setFlags(int $flags): void { + if (((bool) ($flags & self::IGNORE_EMPTY_CELLS)) === true) { + $this->setReadEmptyCells(false); + } + if (((bool) ($flags & self::READ_DATA_ONLY)) === true) { + $this->setReadDataOnly(true); + } if (((bool) ($flags & self::LOAD_WITH_CHARTS)) === true) { $this->setIncludeCharts(true); } @@ -155,13 +161,17 @@ protected function loadSpreadsheetFromFile(string $filename): Spreadsheet /** * Loads Spreadsheet from file. * - * @param int $flags the optional second parameter flags may be used to identify specific elements + * @param ?int $flags the optional second parameter flags may be used to identify specific elements * that should be loaded, but which won't be loaded by default, using these values: + * IReader::IGNORE_EMPTY_CELLS - Don't create empty cells (those containing a null or an empty string) + * IReader::READ_DATA_ONLY - Only read data from the file, not structure or styling * IReader::LOAD_WITH_CHARTS - Include any charts that are defined in the loaded file */ - public function load(string $filename, int $flags = 0): Spreadsheet + public function load(string $filename, ?int $flags = null): Spreadsheet { - $this->processFlags($flags); + if ($flags !== null) { + $this->setFlags($flags); + } IOFactory::setLoading(true); diff --git a/src/PhpSpreadsheet/Reader/IReader.php b/src/PhpSpreadsheet/Reader/IReader.php index de5df5e218..cf2de47bba 100644 --- a/src/PhpSpreadsheet/Reader/IReader.php +++ b/src/PhpSpreadsheet/Reader/IReader.php @@ -6,7 +6,9 @@ interface IReader { - public const LOAD_WITH_CHARTS = 1; + public const IGNORE_EMPTY_CELLS = 1; + public const READ_DATA_ONLY = 2; + public const LOAD_WITH_CHARTS = 4; /** * Can the current IReader read the file? diff --git a/tests/PhpSpreadsheetTests/Reader/ReaderFlagsTest.php b/tests/PhpSpreadsheetTests/Reader/ReaderFlagsTest.php new file mode 100644 index 0000000000..1a08d031c3 --- /dev/null +++ b/tests/PhpSpreadsheetTests/Reader/ReaderFlagsTest.php @@ -0,0 +1,106 @@ +reader = new Xlsx(); + } + + /** + * @dataProvider flagsProvider + */ + public function testFlags(int $flags, array $settings): void + { + $this->reader->setFlags($flags); + + self::assertSame($settings[self::EMPTY_CELLS], $this->reader->getReadEmptyCells()); + self::assertSame($settings[self::DATA_ONLY], $this->reader->getReadDataOnly()); + self::assertSame($settings[self::WITH_CHARTS], $this->reader->getIncludeCharts()); + } + + public function flagsProvider(): array + { + return [ + [ + 0, + [ + self::EMPTY_CELLS => true, + self::DATA_ONLY => false, + self::WITH_CHARTS => false, + ], + ], + [ + IReader::IGNORE_EMPTY_CELLS, + [ + self::EMPTY_CELLS => false, + self::DATA_ONLY => false, + self::WITH_CHARTS => false, + ], + ], + [ + IReader::READ_DATA_ONLY, + [ + self::EMPTY_CELLS => true, + self::DATA_ONLY => true, + self::WITH_CHARTS => false, + ], + ], + [ + IReader::IGNORE_EMPTY_CELLS | IReader::READ_DATA_ONLY, + [ + self::EMPTY_CELLS => false, + self::DATA_ONLY => true, + self::WITH_CHARTS => false, + ], + ], + [ + IReader::LOAD_WITH_CHARTS, + [ + self::EMPTY_CELLS => true, + self::DATA_ONLY => false, + self::WITH_CHARTS => true, + ], + ], + [ + IReader::IGNORE_EMPTY_CELLS | IReader::LOAD_WITH_CHARTS, + [ + self::EMPTY_CELLS => false, + self::DATA_ONLY => false, + self::WITH_CHARTS => true, + ], + ], + [ + IReader::READ_DATA_ONLY | IReader::LOAD_WITH_CHARTS, + [ + self::EMPTY_CELLS => true, + self::DATA_ONLY => true, + self::WITH_CHARTS => true, + ], + ], + [ + IReader::IGNORE_EMPTY_CELLS | IReader::READ_DATA_ONLY | IReader::LOAD_WITH_CHARTS, + [ + self::EMPTY_CELLS => false, + self::DATA_ONLY => true, + self::WITH_CHARTS => true, + ], + ], + ]; + } +}