diff --git a/.gitattributes b/.gitattributes
index 19c90f40..9f2b2f6e 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -3,7 +3,6 @@
/.github export-ignore
/.gitignore export-ignore
/.php_cs.dist export-ignore
-/.sami.php export-ignore
/.scrutinizer.yml export-ignore
/CHANGELOG.PHPExcel.md export-ignore
/bin export-ignore
diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml
index a01892ae..87d933e2 100644
--- a/.github/workflows/main.yml
+++ b/.github/workflows/main.yml
@@ -5,12 +5,17 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
+ experimental:
+ - false
php-version:
- '7.2'
- '7.3'
- '7.4'
- '8.0'
- - '8.1'
+
+ include:
+ - php-version: '8.1'
+ experimental: true
name: PHP ${{ matrix.php-version }}
@@ -38,13 +43,13 @@ jobs:
- name: Delete composer lock file
id: composer-lock
- if: ${{ matrix.php-version == '8.0' || matrix.php-version == '8.1' }}
+ if: ${{ matrix.php-version == '8.1' }}
run: |
rm composer.lock
echo "::set-output name=flags::--ignore-platform-reqs"
- name: Install dependencies
- run: composer install --no-progress --prefer-dist --optimize-autoloader ${{ steps.composer-lock.outputs.flags }}
+ run: composer update --no-progress --prefer-dist --optimize-autoloader ${{ steps.composer-lock.outputs.flags }}
- name: Setup problem matchers for PHP
run: echo "::add-matcher::${{ runner.tool_cache }}/php.json"
@@ -52,8 +57,10 @@ jobs:
- name: Setup problem matchers for PHPUnit
run: echo "::add-matcher::${{ runner.tool_cache }}/phpunit.json"
- - name: Test with PHPUnit
- run: ./vendor/bin/phpunit
+ - name: "Run PHPUnit tests (Experimental: ${{ matrix.experimental }})"
+ env:
+ FAILURE_ACTION: "${{ matrix.experimental == true }}"
+ run: vendor/bin/phpunit --verbose || $FAILURE_ACTION
php-cs-fixer:
runs-on: ubuntu-latest
@@ -117,6 +124,37 @@ jobs:
- name: Code style with PHP_CodeSniffer
run: ./vendor/bin/phpcs -q --report=checkstyle | cs2pr
+ phpstan:
+ runs-on: ubuntu-latest
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v2
+
+ - name: Setup PHP, with composer and extensions
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: 7.4
+ extensions: ctype, dom, gd, iconv, fileinfo, libxml, mbstring, simplexml, xml, xmlreader, xmlwriter, zip, zlib
+ coverage: none
+ tools: cs2pr
+
+ - name: Get composer cache directory
+ id: composer-cache
+ run: echo "::set-output name=dir::$(composer config cache-files-dir)"
+
+ - name: Cache composer dependencies
+ uses: actions/cache@v2
+ with:
+ path: ${{ steps.composer-cache.outputs.dir }}
+ key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
+ restore-keys: ${{ runner.os }}-composer-
+
+ - name: Install dependencies
+ run: composer install --no-progress --prefer-dist --optimize-autoloader
+
+ - name: Static analysis with PHPStan
+ run: ./vendor/bin/phpstan analyse
+
coverage:
runs-on: ubuntu-latest
steps:
diff --git a/.gitignore b/.gitignore
index 0723541d..eac08567 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,6 @@
*.project
/.settings
/.idea
+
+## mkdocs output
+/site
diff --git a/.php_cs.dist b/.php_cs.dist
index f8797e88..1a646420 100644
--- a/.php_cs.dist
+++ b/.php_cs.dist
@@ -160,7 +160,7 @@ return PhpCsFixer\Config::create()
'php_unit_test_annotation' => true,
'php_unit_test_case_static_method_calls' => ['call_type' => 'self'],
'php_unit_test_class_requires_covers' => false, // We don't care as much as we should about coverage
- 'phpdoc_add_missing_param_annotation' => true,
+ 'phpdoc_add_missing_param_annotation' => false, // Don't add things that bring no value
'phpdoc_align' => false, // Waste of time
'phpdoc_annotation_without_dot' => true,
'phpdoc_indent' => true,
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 64efac09..bb09f628 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,7 +9,8 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Added
-- CSV Reader - Best Guess for Encoding, and Handle Null-string Escape [#1647](https://github.com/PHPOffice/PhpSpreadsheet/issues/1647)
+- Implemented the CHITEST(), CHISQ.DIST() and CHISQ.INV() and equivalent Statistical functions, for both left- and right-tailed distributions.
+- Support for ActiveSheet and SelectedCells in the ODS Reader and Writer. [PR #1908](https://github.com/PHPOffice/PhpSpreadsheet/pull/1908)
### Changed
@@ -25,22 +26,106 @@ and this project adheres to [Semantic Versioning](https://semver.org).
### Fixed
+- Fixed issue where array key check for existince before accessing arrays in Xlsx.php. [PR #1970](https://github.com/PHPOffice/PhpSpreadsheet/pull/1970)
+- Fixed issue with quoted strings in number format mask rendered with toFormattedString() [Issue 1972#](https://github.com/PHPOffice/PhpSpreadsheet/issues/1972) [PR #1978](https://github.com/PHPOffice/PhpSpreadsheet/pull/1978)
+- Fixed issue with percentage formats in number format mask rendered with toFormattedString() [Issue 1929#](https://github.com/PHPOffice/PhpSpreadsheet/issues/1929) [PR #1928](https://github.com/PHPOffice/PhpSpreadsheet/pull/1928)
+- Fixed issue with _ spacing character in number format mask corrupting output from toFormattedString() [Issue 1924#](https://github.com/PHPOffice/PhpSpreadsheet/issues/1924) [PR #1927](https://github.com/PHPOffice/PhpSpreadsheet/pull/1927)
+- Fix for [Issue #1887](https://github.com/PHPOffice/PhpSpreadsheet/issues/1887) - Lose Track of Selected Cells After Save
+- Fixed issue with Xlsx@listWorksheetInfo not returning any data
+- Fixed invalid arguments triggering mb_substr() error in LEFT(), MID() and RIGHT() text functions. [Issue #640](https://github.com/PHPOffice/PhpSpreadsheet/issues/640)
+- Fix for [Issue #1916](https://github.com/PHPOffice/PhpSpreadsheet/issues/1916) - Invalid signature check for XML files
+
+## 1.17.1 - 2021-03-01
+
+### Added
+
+- Implementation of the Excel `AVERAGEIFS()` functions as part of a restructuring of Database functions and Conditional Statistical functions.
+- Support for date values and percentages in query parameters for Database functions, and the IF expressions in functions like COUNTIF() and AVERAGEIF(). [#1875](https://github.com/PHPOffice/PhpSpreadsheet/pull/1875)
+- Support for booleans, and for wildcard text search in query parameters for Database functions, and the IF expressions in functions like COUNTIF() and AVERAGEIF(). [#1876](https://github.com/PHPOffice/PhpSpreadsheet/pull/1876)
+- Implemented DataBar for conditional formatting in Xlsx, providing read/write and creation of (type, value, direction, fills, border, axis position, color settings) as DataBar options in Excel. [#1754](https://github.com/PHPOffice/PhpSpreadsheet/pull/1754)
+- Alignment for ODS Writer [#1796](https://github.com/PHPOffice/PhpSpreadsheet/issues/1796)
+- Basic implementation of the PERMUTATIONA() Statistical Function
+
+### Changed
+
+- Formula functions that previously called PHP functions directly are now processed through the Excel Functions classes; resolving issues with PHP8 stricter typing. [#1789](https://github.com/PHPOffice/PhpSpreadsheet/issues/1789)
+
+ The following MathTrig functions are affected:
+ `ABS()`, `ACOS()`, `ACOSH()`, `ASIN()`, `ASINH()`, `ATAN()`, `ATANH()`,
+ `COS()`, `COSH()`, `DEGREES()` (rad2deg), `EXP()`, `LN()` (log), `LOG10()`,
+ `RADIANS()` (deg2rad), `SIN()`, `SINH()`, `SQRT()`, `TAN()`, `TANH()`.
+
+ One TextData function is also affected: `REPT()` (str_repeat).
+- `formatAsDate` correctly matches language metadata, reverting c55272e
+- Formulae that previously crashed on sub function call returning excel error value now return said value.
+ The following functions are affected `CUMPRINC()`, `CUMIPMT()`, `AMORLINC()`,
+ `AMORDEGRC()`.
+- Adapt some function error return value to match excel's error.
+ The following functions are affected `PPMT()`, `IPMT()`.
+
+### Deprecated
+
+- Calling many of the Excel formula functions directly rather than through the Calculation Engine.
+
+ The logic for these Functions is now being moved out of the categorised `Database`, `DateTime`, `Engineering`, `Financial`, `Logical`, `LookupRef`, `MathTrig`, `Statistical`, `TextData` and `Web` classes into small, dedicated classes for individual functions or related groups of functions.
+
+ This makes the logic in these classes easier to maintain; and will reduce the memory footprint required to execute formulae when calling these functions.
+
+### Removed
+
+- Nothing.
+
+### Fixed
+
+- Avoid Duplicate Titles When Reading Multiple HTML Files.[Issue #1823](https://github.com/PHPOffice/PhpSpreadsheet/issues/1823) [PR #1829](https://github.com/PHPOffice/PhpSpreadsheet/pull/1829)
+- Fixed issue with Worksheet's `getCell()` method when trying to get a cell by defined name. [#1858](https://github.com/PHPOffice/PhpSpreadsheet/issues/1858)
+- Fix possible endless loop in NumberFormat Masks [#1792](https://github.com/PHPOffice/PhpSpreadsheet/issues/1792)
+- Fix problem resulting from literal dot inside quotes in number format masks. [PR #1830](https://github.com/PHPOffice/PhpSpreadsheet/pull/1830)
+- Resolve Google Sheets Xlsx charts issue. Google Sheets uses oneCellAnchor positioning and does not include *Cache values in the exported Xlsx. [PR #1761](https://github.com/PHPOffice/PhpSpreadsheet/pull/1761)
+- Fix for Xlsx Chart axis titles mapping to correct X or Y axis label when only one is present. [PR #1760](https://github.com/PHPOffice/PhpSpreadsheet/pull/1760)
+- Fix For Null Exception on ODS Read of Page Settings. [#1772](https://github.com/PHPOffice/PhpSpreadsheet/issues/1772)
+- Fix Xlsx reader overriding manually set number format with builtin number format. [PR #1805](https://github.com/PHPOffice/PhpSpreadsheet/pull/1805)
+- Fix Xlsx reader cell alignment. [PR #1710](https://github.com/PHPOffice/PhpSpreadsheet/pull/1710)
+- Fix for not yet implemented data-types in Open Document writer [Issue #1674](https://github.com/PHPOffice/PhpSpreadsheet/issues/1674)
+- Fix XLSX reader when having a corrupt numeric cell data type [PR #1664](https://github.com/phpoffice/phpspreadsheet/pull/1664)
+- Fix on `CUMPRINC()`, `CUMIPMT()`, `AMORLINC()`, `AMORDEGRC()` usage. When those functions called one of `YEARFRAC()`, `PPMT()`, `IPMT()` and they would get back an error value (represented as a string), trying to use numeral operands (`+`, `/`, `-`, `*`) on said return value and a number (`float or `int`) would fail.
+
+## 1.16.0 - 2020-12-31
+
+### Added
+
+- CSV Reader - Best Guess for Encoding, and Handle Null-string Escape [#1647](https://github.com/PHPOffice/PhpSpreadsheet/issues/1647)
+
+### Changed
+
+- Updated the CONVERT() function to support all current MS Excel categories and Units of Measure.
+
+### Deprecated
+
+- Nothing.
+
+### Removed
+
+- Nothing.
+
+### Fixed
+
- Fixed issue with absolute path in worksheets' Target. [PR #1769](https://github.com/PHPOffice/PhpSpreadsheet/pull/1769)
- Fix for Xls Reader when SST has a bad length [#1592](https://github.com/PHPOffice/PhpSpreadsheet/issues/1592)
-- Resolve Xlsx loader issue whe hyperlinks don't have a destination
+- Resolve Xlsx loader issue whe hyperlinks don't have a destination
- Resolve issues when printer settings resources IDs clash with drawing IDs
- Resolve issue with SLK long filenames [#1612](https://github.com/PHPOffice/PhpSpreadsheet/issues/1612)
- ROUNDUP and ROUNDDOWN return incorrect results for values of 0 [#1627](https://github.com/phpoffice/phpspreadsheet/pull/1627)
- Apply Column and Row Styles to Existing Cells [#1712](https://github.com/PHPOffice/PhpSpreadsheet/issues/1712) [PR #1721](https://github.com/PHPOffice/PhpSpreadsheet/pull/1721)
- Resolve issues with defined names where worksheet doesn't exist (#1686)[https://github.com/PHPOffice/PhpSpreadsheet/issues/1686] and [#1723](https://github.com/PHPOffice/PhpSpreadsheet/issues/1723) - [PR #1742](https://github.com/PHPOffice/PhpSpreadsheet/pull/1742)
-- Fix for issue [#1735](https://github.com/PHPOffice/PhpSpreadsheet/issues/1735) Incorrect activeSheetIndex after RemoveSheetByIndex - [PR #1743](https://github.com/PHPOffice/PhpSpreadsheet/pull/1743)
+- Fix for issue [#1735](https://github.com/PHPOffice/PhpSpreadsheet/issues/1735) Incorrect activeSheetIndex after RemoveSheetByIndex - [PR #1743](https://github.com/PHPOffice/PhpSpreadsheet/pull/1743)
- Ensure that the list of shared formulae is maintained when an xlsx file is chunked with readFilter[Issue #169](https://github.com/PHPOffice/PhpSpreadsheet/issues/1669).
- Fix for notice during accessing "cached magnification factor" offset [#1354](https://github.com/PHPOffice/PhpSpreadsheet/pull/1354)
- Fix compatibility with ext-gd on php 8
### Security Fix (CVE-2020-7776)
-- Prevent XSS through cell comments in the HTML Writer.
+- Prevent XSS through cell comments in the HTML Writer.
## 1.15.0 - 2020-10-11
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index aed13fe2..f5953533 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -9,3 +9,12 @@ If you would like to contribute, here are some notes and guidelines:
- All code changes must be validated by `composer check`
- [Helpful article about forking](https://help.github.com/articles/fork-a-repo/ "Forking a GitHub repository")
- [Helpful article about pull requests](https://help.github.com/articles/using-pull-requests/ "Pull Requests")
+
+## How to release
+
+1. Complete CHANGELOG.md and commit
+2. Create an annotated tag
+ 1. `git tag -a 1.2.3`
+ 2. Tag subject must be the version number, eg: `1.2.3`
+ 3. Tag body must be a copy-paste of the changelog entries
+3. Push tag with `git push --tags`, GitHub Actions will create a GitHub release automatically
diff --git a/composer.json b/composer.json
index c6f8e30e..6cd65021 100644
--- a/composer.json
+++ b/composer.json
@@ -1,7 +1,19 @@
{
"name": "phpoffice/phpspreadsheet",
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
- "keywords": ["PHP", "OpenXML", "Excel", "xlsx", "xls", "ods", "gnumeric", "spreadsheet"],
+ "keywords": [
+ "PHP",
+ "OpenXML",
+ "Excel",
+ "xlsx",
+ "xls",
+ "ods",
+ "gnumeric",
+ "spreadsheet"
+ ],
+ "config": {
+ "sort-packages": true
+ },
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
"type": "library",
"license": "MIT",
@@ -29,7 +41,8 @@
"check": [
"php-cs-fixer fix --ansi --dry-run --diff",
"phpcs",
- "phpunit --color=always"
+ "phpunit --color=always",
+ "phpstan analyse --ansi"
],
"fix": [
"php-cs-fixer fix --ansi"
@@ -39,35 +52,37 @@
]
},
"require": {
- "php": "^7.2||^8.0",
+ "php": "^7.2 || ^8.0",
+ "ext-simplexml": "*",
"ext-ctype": "*",
"ext-dom": "*",
+ "ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
- "ext-fileinfo": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
- "ext-SimpleXML": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
"ext-zip": "*",
"ext-zlib": "*",
+ "ezyang/htmlpurifier": "^4.13",
"maennchen/zipstream-php": "^2.1",
- "markbaker/complex": "^1.5||^2.0",
- "markbaker/matrix": "^1.2||^2.0",
- "psr/simple-cache": "^1.0",
+ "markbaker/complex": "^2.0",
+ "markbaker/matrix": "^2.0",
"psr/http-client": "^1.0",
"psr/http-factory": "^1.0",
- "ezyang/htmlpurifier": "^4.13"
+ "psr/simple-cache": "^1.0"
},
"require-dev": {
- "dompdf/dompdf": "^0.8.5",
- "friendsofphp/php-cs-fixer": "^2.16",
+ "dompdf/dompdf": "^1.0",
+ "friendsofphp/php-cs-fixer": "^2.18",
"jpgraph/jpgraph": "^4.0",
"mpdf/mpdf": "^8.0",
"phpcompatibility/php-compatibility": "^9.3",
- "phpunit/phpunit": "^8.5||^9.3",
+ "phpstan/phpstan": "^0.12.82",
+ "phpstan/phpstan-phpunit": "^0.12.18",
+ "phpunit/phpunit": "^8.5",
"squizlabs/php_codesniffer": "^3.5",
"tecnickcom/tcpdf": "^6.3"
},
diff --git a/composer.lock b/composer.lock
index a1fb99b7..3670f857 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "458fe4e974b469230da589a8781d1e0e",
+ "content-hash": "3be2673a6367d296c616bf9c34b77953",
"packages": [
{
"name": "ezyang/htmlpurifier",
@@ -119,6 +119,16 @@
"stream",
"zip"
],
+ "support": {
+ "issues": "https://github.com/maennchen/ZipStream-PHP/issues",
+ "source": "https://github.com/maennchen/ZipStream-PHP/tree/master"
+ },
+ "funding": [
+ {
+ "url": "https://opencollective.com/zipstream",
+ "type": "open_collective"
+ }
+ ],
"time": "2020-05-30T13:11:16+00:00"
},
{
@@ -214,24 +224,28 @@
"complex",
"mathematics"
],
+ "support": {
+ "issues": "https://github.com/MarkBaker/PHPComplex/issues",
+ "source": "https://github.com/MarkBaker/PHPComplex/tree/PHP8"
+ },
"time": "2020-08-26T10:42:07+00:00"
},
{
"name": "markbaker/matrix",
- "version": "2.0.0",
+ "version": "2.1.2",
"source": {
"type": "git",
"url": "https://github.com/MarkBaker/PHPMatrix.git",
- "reference": "9567d9c4c519fbe40de01dbd1e4469dbbb66f46a"
+ "reference": "361c0f545c3172ee26c3d596a0aa03f0cef65e6a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/9567d9c4c519fbe40de01dbd1e4469dbbb66f46a",
- "reference": "9567d9c4c519fbe40de01dbd1e4469dbbb66f46a",
+ "url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/361c0f545c3172ee26c3d596a0aa03f0cef65e6a",
+ "reference": "361c0f545c3172ee26c3d596a0aa03f0cef65e6a",
"shasum": ""
},
"require": {
- "php": "^7.2 || ^8.0"
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
"dealerdirect/phpcodesniffer-composer-installer": "^0.7.0",
@@ -249,22 +263,22 @@
"Matrix\\": "classes/src/"
},
"files": [
- "classes/src/functions/adjoint.php",
- "classes/src/functions/antidiagonal.php",
- "classes/src/functions/cofactors.php",
- "classes/src/functions/determinant.php",
- "classes/src/functions/diagonal.php",
- "classes/src/functions/identity.php",
- "classes/src/functions/inverse.php",
- "classes/src/functions/minors.php",
- "classes/src/functions/trace.php",
- "classes/src/functions/transpose.php",
- "classes/src/operations/add.php",
- "classes/src/operations/directsum.php",
- "classes/src/operations/subtract.php",
- "classes/src/operations/multiply.php",
- "classes/src/operations/divideby.php",
- "classes/src/operations/divideinto.php"
+ "classes/src/Functions/adjoint.php",
+ "classes/src/Functions/antidiagonal.php",
+ "classes/src/Functions/cofactors.php",
+ "classes/src/Functions/determinant.php",
+ "classes/src/Functions/diagonal.php",
+ "classes/src/Functions/identity.php",
+ "classes/src/Functions/inverse.php",
+ "classes/src/Functions/minors.php",
+ "classes/src/Functions/trace.php",
+ "classes/src/Functions/transpose.php",
+ "classes/src/Operations/add.php",
+ "classes/src/Operations/directsum.php",
+ "classes/src/Operations/subtract.php",
+ "classes/src/Operations/multiply.php",
+ "classes/src/Operations/divideby.php",
+ "classes/src/Operations/divideinto.php"
]
},
"notification-url": "https://packagist.org/downloads/",
@@ -284,20 +298,24 @@
"matrix",
"vector"
],
- "time": "2020-08-28T17:11:00+00:00"
+ "support": {
+ "issues": "https://github.com/MarkBaker/PHPMatrix/issues",
+ "source": "https://github.com/MarkBaker/PHPMatrix/tree/2.1.2"
+ },
+ "time": "2021-01-23T16:37:31+00:00"
},
{
"name": "myclabs/php-enum",
- "version": "1.7.6",
+ "version": "1.7.7",
"source": {
"type": "git",
"url": "https://github.com/myclabs/php-enum.git",
- "reference": "5f36467c7a87e20fbdc51e524fd8f9d1de80187c"
+ "reference": "d178027d1e679832db9f38248fcc7200647dc2b7"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/php-enum/zipball/5f36467c7a87e20fbdc51e524fd8f9d1de80187c",
- "reference": "5f36467c7a87e20fbdc51e524fd8f9d1de80187c",
+ "url": "https://api.github.com/repos/myclabs/php-enum/zipball/d178027d1e679832db9f38248fcc7200647dc2b7",
+ "reference": "d178027d1e679832db9f38248fcc7200647dc2b7",
"shasum": ""
},
"require": {
@@ -330,7 +348,21 @@
"keywords": [
"enum"
],
- "time": "2020-02-14T08:15:52+00:00"
+ "support": {
+ "issues": "https://github.com/myclabs/php-enum/issues",
+ "source": "https://github.com/myclabs/php-enum/tree/1.7.7"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/mnapoli",
+ "type": "github"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/myclabs/php-enum",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-11-14T18:14:52+00:00"
},
{
"name": "psr/http-client",
@@ -379,6 +411,9 @@
"psr",
"psr-18"
],
+ "support": {
+ "source": "https://github.com/php-fig/http-client/tree/master"
+ },
"time": "2020-06-29T06:28:15+00:00"
},
{
@@ -431,6 +466,9 @@
"request",
"response"
],
+ "support": {
+ "source": "https://github.com/php-fig/http-factory/tree/master"
+ },
"time": "2019-04-30T12:38:16+00:00"
},
{
@@ -481,6 +519,9 @@
"request",
"response"
],
+ "support": {
+ "source": "https://github.com/php-fig/http-message/tree/master"
+ },
"time": "2016-08-06T14:39:51+00:00"
},
{
@@ -529,24 +570,27 @@
"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.18.1",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-mbstring.git",
- "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a"
+ "reference": "5232de97ee3b75b0360528dae24e73db49566ab1"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/a6977d63bf9a0ad4c65cd352709e230876f9904a",
- "reference": "a6977d63bf9a0ad4c65cd352709e230876f9904a",
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1",
+ "reference": "5232de97ee3b75b0360528dae24e73db49566ab1",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
"suggest": {
"ext-mbstring": "For best performance"
@@ -554,7 +598,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.18-dev"
+ "dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -592,6 +636,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -606,34 +653,35 @@
"type": "tidelift"
}
],
- "time": "2020-07-14T12:35:20+00:00"
+ "time": "2021-01-22T09:19:47+00:00"
}
],
"packages-dev": [
{
"name": "composer/semver",
- "version": "1.7.1",
+ "version": "3.2.4",
"source": {
"type": "git",
"url": "https://github.com/composer/semver.git",
- "reference": "38276325bd896f90dfcfe30029aa5db40df387a7"
+ "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/semver/zipball/38276325bd896f90dfcfe30029aa5db40df387a7",
- "reference": "38276325bd896f90dfcfe30029aa5db40df387a7",
+ "url": "https://api.github.com/repos/composer/semver/zipball/a02fdf930a3c1c3ed3a49b5f63859c0c20e10464",
+ "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464",
"shasum": ""
},
"require": {
- "php": "^5.3.2 || ^7.0"
+ "php": "^5.3.2 || ^7.0 || ^8.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.5 || ^5.0.5"
+ "phpstan/phpstan": "^0.12.54",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.x-dev"
+ "dev-main": "3.x-dev"
}
},
"autoload": {
@@ -669,6 +717,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.2.4"
+ },
"funding": [
{
"url": "https://packagist.com",
@@ -683,20 +736,20 @@
"type": "tidelift"
}
],
- "time": "2020-09-27T13:13:07+00:00"
+ "time": "2020-11-13T08:59:24+00:00"
},
{
"name": "composer/xdebug-handler",
- "version": "1.4.3",
+ "version": "1.4.6",
"source": {
"type": "git",
"url": "https://github.com/composer/xdebug-handler.git",
- "reference": "ebd27a9866ae8254e873866f795491f02418c5a5"
+ "reference": "f27e06cd9675801df441b3656569b328e04aa37c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ebd27a9866ae8254e873866f795491f02418c5a5",
- "reference": "ebd27a9866ae8254e873866f795491f02418c5a5",
+ "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f27e06cd9675801df441b3656569b328e04aa37c",
+ "reference": "f27e06cd9675801df441b3656569b328e04aa37c",
"shasum": ""
},
"require": {
@@ -704,7 +757,8 @@
"psr/log": "^1.0"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8"
+ "phpstan/phpstan": "^0.12.55",
+ "symfony/phpunit-bridge": "^4.2 || ^5"
},
"type": "library",
"autoload": {
@@ -727,6 +781,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/1.4.6"
+ },
"funding": [
{
"url": "https://packagist.com",
@@ -741,20 +800,20 @@
"type": "tidelift"
}
],
- "time": "2020-08-19T10:27:58+00:00"
+ "time": "2021-03-25T17:01:18+00:00"
},
{
"name": "doctrine/annotations",
- "version": "1.10.4",
+ "version": "1.12.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
- "reference": "bfe91e31984e2ba76df1c1339681770401ec262f"
+ "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/annotations/zipball/bfe91e31984e2ba76df1c1339681770401ec262f",
- "reference": "bfe91e31984e2ba76df1c1339681770401ec262f",
+ "url": "https://api.github.com/repos/doctrine/annotations/zipball/b17c5014ef81d212ac539f07a1001832df1b6d3b",
+ "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b",
"shasum": ""
},
"require": {
@@ -764,15 +823,11 @@
},
"require-dev": {
"doctrine/cache": "1.*",
+ "doctrine/coding-standard": "^6.0 || ^8.1",
"phpstan/phpstan": "^0.12.20",
"phpunit/phpunit": "^7.5 || ^9.1.5"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.9.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
@@ -805,46 +860,45 @@
}
],
"description": "Docblock Annotations Parser",
- "homepage": "http://www.doctrine-project.org",
+ "homepage": "https://www.doctrine-project.org/projects/annotations.html",
"keywords": [
"annotations",
"docblock",
"parser"
],
- "time": "2020-08-10T19:35:50+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/annotations/issues",
+ "source": "https://github.com/doctrine/annotations/tree/1.12.1"
+ },
+ "time": "2021-02-21T21:00:45+00:00"
},
{
"name": "doctrine/instantiator",
- "version": "1.3.1",
+ "version": "1.4.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/instantiator.git",
- "reference": "f350df0268e904597e3bd9c4685c53e0e333feea"
+ "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea",
- "reference": "f350df0268e904597e3bd9c4685c53e0e333feea",
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b",
+ "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b",
"shasum": ""
},
"require": {
"php": "^7.1 || ^8.0"
},
"require-dev": {
- "doctrine/coding-standard": "^6.0",
+ "doctrine/coding-standard": "^8.0",
"ext-pdo": "*",
"ext-phar": "*",
- "phpbench/phpbench": "^0.13",
- "phpstan/phpstan-phpunit": "^0.11",
- "phpstan/phpstan-shim": "^0.11",
- "phpunit/phpunit": "^7.0"
+ "phpbench/phpbench": "^0.13 || 1.0.0-alpha2",
+ "phpstan/phpstan": "^0.12",
+ "phpstan/phpstan-phpunit": "^0.12",
+ "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.2.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
@@ -858,7 +912,7 @@
{
"name": "Marco Pivetta",
"email": "ocramius@gmail.com",
- "homepage": "http://ocramius.github.com/"
+ "homepage": "https://ocramius.github.io/"
}
],
"description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
@@ -867,7 +921,25 @@
"constructor",
"instantiate"
],
- "time": "2020-05-29T17:27:14+00:00"
+ "support": {
+ "issues": "https://github.com/doctrine/instantiator/issues",
+ "source": "https://github.com/doctrine/instantiator/tree/1.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2020-11-10T18:47:58+00:00"
},
{
"name": "doctrine/lexer",
@@ -929,20 +1001,38 @@
"parser",
"php"
],
+ "support": {
+ "issues": "https://github.com/doctrine/lexer/issues",
+ "source": "https://github.com/doctrine/lexer/tree/1.2.1"
+ },
+ "funding": [
+ {
+ "url": "https://www.doctrine-project.org/sponsorship.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://www.patreon.com/phpdoctrine",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer",
+ "type": "tidelift"
+ }
+ ],
"time": "2020-05-25T17:44:05+00:00"
},
{
"name": "dompdf/dompdf",
- "version": "v0.8.6",
+ "version": "v1.0.2",
"source": {
"type": "git",
"url": "https://github.com/dompdf/dompdf.git",
- "reference": "db91d81866c69a42dad1d2926f61515a1e3f42c5"
+ "reference": "8768448244967a46d6e67b891d30878e0e15d25c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/dompdf/dompdf/zipball/db91d81866c69a42dad1d2926f61515a1e3f42c5",
- "reference": "db91d81866c69a42dad1d2926f61515a1e3f42c5",
+ "url": "https://api.github.com/repos/dompdf/dompdf/zipball/8768448244967a46d6e67b891d30878e0e15d25c",
+ "reference": "8768448244967a46d6e67b891d30878e0e15d25c",
"shasum": ""
},
"require": {
@@ -950,11 +1040,11 @@
"ext-mbstring": "*",
"phenx/php-font-lib": "^0.5.2",
"phenx/php-svg-lib": "^0.3.3",
- "php": "^7.1"
+ "php": "^7.1 || ^8.0"
},
"require-dev": {
"mockery/mockery": "^1.3",
- "phpunit/phpunit": "^7.5",
+ "phpunit/phpunit": "^7.5 || ^8 || ^9",
"squizlabs/php_codesniffer": "^3.5"
},
"suggest": {
@@ -997,31 +1087,35 @@
],
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
"homepage": "https://github.com/dompdf/dompdf",
- "time": "2020-08-30T22:54:22+00:00"
+ "support": {
+ "issues": "https://github.com/dompdf/dompdf/issues",
+ "source": "https://github.com/dompdf/dompdf/tree/v1.0.2"
+ },
+ "time": "2021-01-08T14:18:52+00:00"
},
{
"name": "friendsofphp/php-cs-fixer",
- "version": "v2.16.4",
+ "version": "v2.18.4",
"source": {
"type": "git",
"url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
- "reference": "1023c3458137ab052f6ff1e09621a721bfdeca13"
+ "reference": "06f764e3cb6d60822d8f5135205f9d32b5508a31"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/1023c3458137ab052f6ff1e09621a721bfdeca13",
- "reference": "1023c3458137ab052f6ff1e09621a721bfdeca13",
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/06f764e3cb6d60822d8f5135205f9d32b5508a31",
+ "reference": "06f764e3cb6d60822d8f5135205f9d32b5508a31",
"shasum": ""
},
"require": {
- "composer/semver": "^1.4",
+ "composer/semver": "^1.4 || ^2.0 || ^3.0",
"composer/xdebug-handler": "^1.2",
"doctrine/annotations": "^1.2",
"ext-json": "*",
"ext-tokenizer": "*",
- "php": "^5.6 || ^7.0",
+ "php": "^5.6 || ^7.0 || ^8.0",
"php-cs-fixer/diff": "^1.3",
- "symfony/console": "^3.4.17 || ^4.1.6 || ^5.0",
+ "symfony/console": "^3.4.43 || ^4.1.6 || ^5.0",
"symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0",
"symfony/filesystem": "^3.0 || ^4.0 || ^5.0",
"symfony/finder": "^3.0 || ^4.0 || ^5.0",
@@ -1032,17 +1126,19 @@
"symfony/stopwatch": "^3.0 || ^4.0 || ^5.0"
},
"require-dev": {
- "johnkary/phpunit-speedtrap": "^1.1 || ^2.0 || ^3.0",
"justinrainbow/json-schema": "^5.0",
- "keradus/cli-executor": "^1.2",
+ "keradus/cli-executor": "^1.4",
"mikey179/vfsstream": "^1.6",
- "php-coveralls/php-coveralls": "^2.1",
+ "php-coveralls/php-coveralls": "^2.4.2",
"php-cs-fixer/accessible-object": "^1.0",
- "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.1",
- "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.1",
- "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.1",
- "phpunitgoodpractices/traits": "^1.8",
- "symfony/phpunit-bridge": "^5.1",
+ "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2",
+ "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1",
+ "phpspec/prophecy-phpunit": "^1.1 || ^2.0",
+ "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.13 || ^9.5",
+ "phpunitgoodpractices/polyfill": "^1.5",
+ "phpunitgoodpractices/traits": "^1.9.1",
+ "sanmai/phpunit-legacy-adapter": "^6.4 || ^8.2.1",
+ "symfony/phpunit-bridge": "^5.2.1",
"symfony/yaml": "^3.0 || ^4.0 || ^5.0"
},
"suggest": {
@@ -1070,6 +1166,7 @@
"tests/Test/IntegrationCaseFactoryInterface.php",
"tests/Test/InternalIntegrationCaseFactory.php",
"tests/Test/IsIdenticalConstraint.php",
+ "tests/Test/TokensWithObservedTransformers.php",
"tests/TestCase.php"
]
},
@@ -1088,7 +1185,17 @@
}
],
"description": "A tool to automatically fix PHP code style",
- "time": "2020-06-27T23:57:46+00:00"
+ "support": {
+ "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues",
+ "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v2.18.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/keradus",
+ "type": "github"
+ }
+ ],
+ "time": "2021-03-20T14:52:33+00:00"
},
{
"name": "jpgraph/jpgraph",
@@ -1128,36 +1235,40 @@
"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"
},
{
"name": "mpdf/mpdf",
- "version": "v8.0.7",
+ "version": "v8.0.10",
"source": {
"type": "git",
"url": "https://github.com/mpdf/mpdf.git",
- "reference": "7daf07f15334ed59a276bd52131dcca48794cdbd"
+ "reference": "1333a962cd2f7ae1a127b7534b7734b58179186f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/mpdf/mpdf/zipball/7daf07f15334ed59a276bd52131dcca48794cdbd",
- "reference": "7daf07f15334ed59a276bd52131dcca48794cdbd",
+ "url": "https://api.github.com/repos/mpdf/mpdf/zipball/1333a962cd2f7ae1a127b7534b7734b58179186f",
+ "reference": "1333a962cd2f7ae1a127b7534b7734b58179186f",
"shasum": ""
},
"require": {
"ext-gd": "*",
"ext-mbstring": "*",
"myclabs/deep-copy": "^1.7",
- "paragonie/random_compat": "^1.4|^2.0|9.99.99",
- "php": "^5.6 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0",
+ "paragonie/random_compat": "^1.4|^2.0|^9.99.99",
+ "php": "^5.6 || ^7.0 || ~8.0.0",
"psr/log": "^1.0",
"setasign/fpdi": "^2.1"
},
"require-dev": {
- "mockery/mockery": "^0.9.5",
- "mpdf/qrcode": "^1.0.0",
- "phpunit/phpunit": "^5.0",
+ "mockery/mockery": "^1.3.0",
+ "mpdf/qrcode": "^1.1.0",
+ "phpunit/phpunit": "^5.7",
"squizlabs/php_codesniffer": "^3.5.0",
"tracy/tracy": "^2.4"
},
@@ -1167,11 +1278,6 @@
"ext-zlib": "Needed for compression of embedded resources, such as fonts"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-development": "7.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Mpdf\\": "src/"
@@ -1198,26 +1304,31 @@
"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",
"type": "custom"
}
],
- "time": "2020-07-15T09:48:00+00:00"
+ "time": "2021-01-08T14:59:28+00:00"
},
{
"name": "myclabs/deep-copy",
- "version": "1.10.1",
+ "version": "1.10.2",
"source": {
"type": "git",
"url": "https://github.com/myclabs/DeepCopy.git",
- "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5"
+ "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5",
- "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5",
+ "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220",
+ "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220",
"shasum": ""
},
"require": {
@@ -1252,30 +1363,34 @@
"object",
"object graph"
],
+ "support": {
+ "issues": "https://github.com/myclabs/DeepCopy/issues",
+ "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2"
+ },
"funding": [
{
"url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy",
"type": "tidelift"
}
],
- "time": "2020-06-29T13:22:24+00:00"
+ "time": "2020-11-13T09:40:50+00:00"
},
{
"name": "paragonie/random_compat",
- "version": "v9.99.99",
+ "version": "v9.99.100",
"source": {
"type": "git",
"url": "https://github.com/paragonie/random_compat.git",
- "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95"
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/paragonie/random_compat/zipball/84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
- "reference": "84b4dfb120c6f9b4ff7b3685f9b8f1aa365a0c95",
+ "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a",
+ "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a",
"shasum": ""
},
"require": {
- "php": "^7"
+ "php": ">= 7"
},
"require-dev": {
"phpunit/phpunit": "4.*|5.*",
@@ -1303,32 +1418,38 @@
"pseudorandom",
"random"
],
- "time": "2018-07-02T15:55:56+00:00"
+ "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"
},
{
"name": "phar-io/manifest",
- "version": "1.0.3",
+ "version": "2.0.1",
"source": {
"type": "git",
"url": "https://github.com/phar-io/manifest.git",
- "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4"
+ "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
- "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4",
+ "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
+ "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-phar": "*",
- "phar-io/version": "^2.0",
- "php": "^5.6 || ^7.0"
+ "ext-xmlwriter": "*",
+ "phar-io/version": "^3.0.1",
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.0.x-dev"
+ "dev-master": "2.0.x-dev"
}
},
"autoload": {
@@ -1358,24 +1479,28 @@
}
],
"description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)",
- "time": "2018-07-08T19:23:20+00:00"
+ "support": {
+ "issues": "https://github.com/phar-io/manifest/issues",
+ "source": "https://github.com/phar-io/manifest/tree/master"
+ },
+ "time": "2020-06-27T14:33:11+00:00"
},
{
"name": "phar-io/version",
- "version": "2.0.1",
+ "version": "3.1.0",
"source": {
"type": "git",
"url": "https://github.com/phar-io/version.git",
- "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6"
+ "reference": "bae7c545bef187884426f042434e561ab1ddb182"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6",
- "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6",
+ "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182",
+ "reference": "bae7c545bef187884426f042434e561ab1ddb182",
"shasum": ""
},
"require": {
- "php": "^5.6 || ^7.0"
+ "php": "^7.2 || ^8.0"
},
"type": "library",
"autoload": {
@@ -1405,7 +1530,11 @@
}
],
"description": "Library for handling version information and constraints",
- "time": "2018-07-08T19:19:57+00:00"
+ "support": {
+ "issues": "https://github.com/phar-io/version/issues",
+ "source": "https://github.com/phar-io/version/tree/3.1.0"
+ },
+ "time": "2021-02-23T14:00:09+00:00"
},
{
"name": "phenx/php-font-lib",
@@ -1442,6 +1571,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/PhenX/php-font-lib/issues",
+ "source": "https://github.com/PhenX/php-font-lib/tree/0.5.2"
+ },
"time": "2020-03-08T15:31:32+00:00"
},
{
@@ -1482,6 +1615,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/PhenX/php-svg-lib/issues",
+ "source": "https://github.com/PhenX/php-svg-lib/tree/master"
+ },
"time": "2019-09-11T20:02:13+00:00"
},
{
@@ -1533,6 +1670,10 @@
"keywords": [
"diff"
],
+ "support": {
+ "issues": "https://github.com/PHP-CS-Fixer/diff/issues",
+ "source": "https://github.com/PHP-CS-Fixer/diff/tree/v1.3.1"
+ },
"time": "2020-10-14T08:39:05+00:00"
},
{
@@ -1591,6 +1732,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"
},
{
@@ -1640,6 +1785,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"
},
{
@@ -1692,6 +1841,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/master"
+ },
"time": "2020-09-03T19:13:55+00:00"
},
{
@@ -1737,20 +1890,24 @@
}
],
"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.4.0"
+ },
"time": "2020-09-17T18:55:26+00:00"
},
{
"name": "phpspec/prophecy",
- "version": "1.12.1",
+ "version": "1.13.0",
"source": {
"type": "git",
"url": "https://github.com/phpspec/prophecy.git",
- "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d"
+ "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d",
- "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d",
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea",
+ "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea",
"shasum": ""
},
"require": {
@@ -1762,7 +1919,7 @@
},
"require-dev": {
"phpspec/phpspec": "^6.0",
- "phpunit/phpunit": "^8.0 || ^9.0 <9.3"
+ "phpunit/phpunit": "^8.0 || ^9.0"
},
"type": "library",
"extra": {
@@ -1800,29 +1957,148 @@
"spy",
"stub"
],
- "time": "2020-09-29T09:10:42+00:00"
+ "support": {
+ "issues": "https://github.com/phpspec/prophecy/issues",
+ "source": "https://github.com/phpspec/prophecy/tree/1.13.0"
+ },
+ "time": "2021-03-17T13:42:18+00:00"
},
{
- "name": "phpunit/php-code-coverage",
- "version": "7.0.10",
+ "name": "phpstan/phpstan",
+ "version": "0.12.82",
"source": {
"type": "git",
- "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
- "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf"
+ "url": "https://github.com/phpstan/phpstan.git",
+ "reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f1884187926fbb755a9aaf0b3836ad3165b478bf",
- "reference": "f1884187926fbb755a9aaf0b3836ad3165b478bf",
+ "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3920f0fb0aff39263d3a4cb0bca120a67a1a6a11",
+ "reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1|^8.0"
+ },
+ "conflict": {
+ "phpstan/phpstan-shim": "*"
+ },
+ "bin": [
+ "phpstan",
+ "phpstan.phar"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.12-dev"
+ }
+ },
+ "autoload": {
+ "files": [
+ "bootstrap.php"
+ ]
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "PHPStan - PHP Static Analysis Tool",
+ "support": {
+ "issues": "https://github.com/phpstan/phpstan/issues",
+ "source": "https://github.com/phpstan/phpstan/tree/0.12.82"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/ondrejmirtes",
+ "type": "github"
+ },
+ {
+ "url": "https://www.patreon.com/phpstan",
+ "type": "patreon"
+ },
+ {
+ "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan",
+ "type": "tidelift"
+ }
+ ],
+ "time": "2021-03-19T06:08:17+00:00"
+ },
+ {
+ "name": "phpstan/phpstan-phpunit",
+ "version": "0.12.18",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/phpstan/phpstan-phpunit.git",
+ "reference": "ab44aec7cfb5cb267b8bc30a8caea86dd50d1f72"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/ab44aec7cfb5cb267b8bc30a8caea86dd50d1f72",
+ "reference": "ab44aec7cfb5cb267b8bc30a8caea86dd50d1f72",
+ "shasum": ""
+ },
+ "require": {
+ "php": "^7.1 || ^8.0",
+ "phpstan/phpstan": "^0.12.60"
+ },
+ "conflict": {
+ "phpunit/phpunit": "<7.0"
+ },
+ "require-dev": {
+ "phing/phing": "^2.16.3",
+ "php-parallel-lint/php-parallel-lint": "^1.2",
+ "phpstan/phpstan-strict-rules": "^0.12.6",
+ "phpunit/phpunit": "^7.5.20"
+ },
+ "type": "phpstan-extension",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "0.12-dev"
+ },
+ "phpstan": {
+ "includes": [
+ "extension.neon",
+ "rules.neon"
+ ]
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PHPStan\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "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/0.12.18"
+ },
+ "time": "2021-03-06T11:51:27+00:00"
+ },
+ {
+ "name": "phpunit/php-code-coverage",
+ "version": "7.0.14",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
+ "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/bb7c9a210c72e4709cdde67f8b7362f672f2225c",
+ "reference": "bb7c9a210c72e4709cdde67f8b7362f672f2225c",
"shasum": ""
},
"require": {
"ext-dom": "*",
"ext-xmlwriter": "*",
- "php": "^7.2",
+ "php": ">=7.2",
"phpunit/php-file-iterator": "^2.0.2",
"phpunit/php-text-template": "^1.2.1",
- "phpunit/php-token-stream": "^3.1.1",
+ "phpunit/php-token-stream": "^3.1.1 || ^4.0",
"sebastian/code-unit-reverse-lookup": "^1.0.1",
"sebastian/environment": "^4.2.2",
"sebastian/version": "^2.0.1",
@@ -1863,27 +2139,37 @@
"testing",
"xunit"
],
- "time": "2019-11-20T13:55:58+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
+ "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.14"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-12-02T13:39:03+00:00"
},
{
"name": "phpunit/php-file-iterator",
- "version": "2.0.2",
+ "version": "2.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-file-iterator.git",
- "reference": "050bedf145a257b1ff02746c31894800e5122946"
+ "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/050bedf145a257b1ff02746c31894800e5122946",
- "reference": "050bedf145a257b1ff02746c31894800e5122946",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357",
+ "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "^7.1"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -1913,7 +2199,17 @@
"filesystem",
"iterator"
],
- "time": "2018-09-13T20:33:42+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues",
+ "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:25:21+00:00"
},
{
"name": "phpunit/php-text-template",
@@ -1954,27 +2250,31 @@
"keywords": [
"template"
],
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-text-template/issues",
+ "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1"
+ },
"time": "2015-06-21T13:50:34+00:00"
},
{
"name": "phpunit/php-timer",
- "version": "2.1.2",
+ "version": "2.1.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-timer.git",
- "reference": "1038454804406b0b5f5f520358e78c1c2f71501e"
+ "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/1038454804406b0b5f5f520358e78c1c2f71501e",
- "reference": "1038454804406b0b5f5f520358e78c1c2f71501e",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662",
+ "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
- "phpunit/phpunit": "^7.0"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -2003,25 +2303,35 @@
"keywords": [
"timer"
],
- "time": "2019-06-07T04:22:29+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-timer/issues",
+ "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:20:02+00:00"
},
{
"name": "phpunit/php-token-stream",
- "version": "3.1.1",
+ "version": "3.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/php-token-stream.git",
- "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff"
+ "reference": "472b687829041c24b25f475e14c2f38a09edf1c2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/995192df77f63a59e47f025390d2d1fdf8f425ff",
- "reference": "995192df77f63a59e47f025390d2d1fdf8f425ff",
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2",
+ "reference": "472b687829041c24b25f475e14c2f38a09edf1c2",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^7.0"
@@ -2052,43 +2362,54 @@
"keywords": [
"tokenizer"
],
- "time": "2019-09-17T06:23:10+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/php-token-stream/issues",
+ "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "abandoned": true,
+ "time": "2020-11-30T08:38:46+00:00"
},
{
"name": "phpunit/phpunit",
- "version": "8.5.8",
+ "version": "8.5.15",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/phpunit.git",
- "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997"
+ "reference": "038d4196d8e8cb405cd5e82cedfe413ad6eef9ef"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34c18baa6a44f1d1fbf0338907139e9dce95b997",
- "reference": "34c18baa6a44f1d1fbf0338907139e9dce95b997",
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/038d4196d8e8cb405cd5e82cedfe413ad6eef9ef",
+ "reference": "038d4196d8e8cb405cd5e82cedfe413ad6eef9ef",
"shasum": ""
},
"require": {
- "doctrine/instantiator": "^1.2.0",
+ "doctrine/instantiator": "^1.3.1",
"ext-dom": "*",
"ext-json": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
"ext-xml": "*",
"ext-xmlwriter": "*",
- "myclabs/deep-copy": "^1.9.1",
- "phar-io/manifest": "^1.0.3",
- "phar-io/version": "^2.0.1",
- "php": "^7.2",
- "phpspec/prophecy": "^1.8.1",
- "phpunit/php-code-coverage": "^7.0.7",
+ "myclabs/deep-copy": "^1.10.0",
+ "phar-io/manifest": "^2.0.1",
+ "phar-io/version": "^3.0.2",
+ "php": ">=7.2",
+ "phpspec/prophecy": "^1.10.3",
+ "phpunit/php-code-coverage": "^7.0.12",
"phpunit/php-file-iterator": "^2.0.2",
"phpunit/php-text-template": "^1.2.1",
"phpunit/php-timer": "^2.1.2",
"sebastian/comparator": "^3.0.2",
"sebastian/diff": "^3.0.2",
- "sebastian/environment": "^4.2.2",
- "sebastian/exporter": "^3.1.1",
+ "sebastian/environment": "^4.2.3",
+ "sebastian/exporter": "^3.1.2",
"sebastian/global-state": "^3.0.0",
"sebastian/object-enumerator": "^3.0.3",
"sebastian/resource-operations": "^2.0.1",
@@ -2135,31 +2456,40 @@
"testing",
"xunit"
],
- "time": "2020-06-22T07:06:58+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/phpunit/issues",
+ "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.15"
+ },
+ "funding": [
+ {
+ "url": "https://phpunit.de/donate.html",
+ "type": "custom"
+ },
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2021-03-17T07:27:54+00:00"
},
{
"name": "psr/container",
- "version": "1.0.0",
+ "version": "1.1.1",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
- "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf",
+ "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf",
"shasum": ""
},
"require": {
- "php": ">=5.3.0"
+ "php": ">=7.2.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "1.0.x-dev"
- }
- },
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
@@ -2172,7 +2502,7 @@
"authors": [
{
"name": "PHP-FIG",
- "homepage": "http://www.php-fig.org/"
+ "homepage": "https://www.php-fig.org/"
}
],
"description": "Common Container Interface (PHP FIG PSR-11)",
@@ -2184,7 +2514,11 @@
"container-interop",
"psr"
],
- "time": "2017-02-14T16:28:37+00:00"
+ "support": {
+ "issues": "https://github.com/php-fig/container/issues",
+ "source": "https://github.com/php-fig/container/tree/1.1.1"
+ },
+ "time": "2021-03-05T17:36:06+00:00"
},
{
"name": "psr/event-dispatcher",
@@ -2230,6 +2564,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"
},
{
@@ -2277,6 +2615,9 @@
"psr",
"psr-3"
],
+ "support": {
+ "source": "https://github.com/php-fig/log/tree/1.1.3"
+ },
"time": "2020-03-23T09:12:05+00:00"
},
{
@@ -2322,27 +2663,31 @@
"parser",
"stylesheet"
],
+ "support": {
+ "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues",
+ "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.3.1"
+ },
"time": "2020-06-01T09:10:00+00:00"
},
{
"name": "sebastian/code-unit-reverse-lookup",
- "version": "1.0.1",
+ "version": "1.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git",
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18"
+ "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
- "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18",
+ "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619",
+ "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619",
"shasum": ""
},
"require": {
- "php": "^5.6 || ^7.0"
+ "php": ">=5.6"
},
"require-dev": {
- "phpunit/phpunit": "^5.7 || ^6.0"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -2367,29 +2712,39 @@
],
"description": "Looks up which function or method a line of code belongs to",
"homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/",
- "time": "2017-03-04T06:30:41+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues",
+ "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:15:22+00:00"
},
{
"name": "sebastian/comparator",
- "version": "3.0.2",
+ "version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/comparator.git",
- "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da"
+ "reference": "1071dfcef776a57013124ff35e1fc41ccd294758"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
- "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da",
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758",
+ "reference": "1071dfcef776a57013124ff35e1fc41ccd294758",
"shasum": ""
},
"require": {
- "php": "^7.1",
+ "php": ">=7.1",
"sebastian/diff": "^3.0",
"sebastian/exporter": "^3.1"
},
"require-dev": {
- "phpunit/phpunit": "^7.1"
+ "phpunit/phpunit": "^8.5"
},
"type": "library",
"extra": {
@@ -2407,6 +2762,10 @@
"BSD-3-Clause"
],
"authors": [
+ {
+ "name": "Sebastian Bergmann",
+ "email": "sebastian@phpunit.de"
+ },
{
"name": "Jeff Welch",
"email": "whatthejeff@gmail.com"
@@ -2418,10 +2777,6 @@
{
"name": "Bernhard Schussek",
"email": "bschussek@2bepublished.at"
- },
- {
- "name": "Sebastian Bergmann",
- "email": "sebastian@phpunit.de"
}
],
"description": "Provides the functionality to compare PHP values for equality",
@@ -2431,24 +2786,34 @@
"compare",
"equality"
],
- "time": "2018-07-12T15:12:46+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/comparator/issues",
+ "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T08:04:30+00:00"
},
{
"name": "sebastian/diff",
- "version": "3.0.2",
+ "version": "3.0.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/diff.git",
- "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29"
+ "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
- "reference": "720fcc7e9b5cf384ea68d9d930d480907a0c1a29",
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
+ "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^7.5 || ^8.0",
@@ -2470,13 +2835,13 @@
"BSD-3-Clause"
],
"authors": [
- {
- "name": "Kore Nordmann",
- "email": "mail@kore-nordmann.de"
- },
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
+ },
+ {
+ "name": "Kore Nordmann",
+ "email": "mail@kore-nordmann.de"
}
],
"description": "Diff implementation",
@@ -2487,24 +2852,34 @@
"unidiff",
"unified diff"
],
- "time": "2019-02-04T06:01:07+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/diff/issues",
+ "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:59:04+00:00"
},
{
"name": "sebastian/environment",
- "version": "4.2.3",
+ "version": "4.2.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/environment.git",
- "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368"
+ "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
- "reference": "464c90d7bdf5ad4e8a6aea15c091fec0603d4368",
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
+ "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"require-dev": {
"phpunit/phpunit": "^7.5"
@@ -2540,24 +2915,34 @@
"environment",
"hhvm"
],
- "time": "2019-11-20T08:46:58+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/environment/issues",
+ "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:53:42+00:00"
},
{
"name": "sebastian/exporter",
- "version": "3.1.2",
+ "version": "3.1.3",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/exporter.git",
- "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e"
+ "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/68609e1261d215ea5b21b7987539cbfbe156ec3e",
- "reference": "68609e1261d215ea5b21b7987539cbfbe156ec3e",
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e",
+ "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e",
"shasum": ""
},
"require": {
- "php": "^7.0",
+ "php": ">=7.0",
"sebastian/recursion-context": "^3.0"
},
"require-dev": {
@@ -2607,24 +2992,34 @@
"export",
"exporter"
],
- "time": "2019-09-14T09:02:43+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/exporter/issues",
+ "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:47:53+00:00"
},
{
"name": "sebastian/global-state",
- "version": "3.0.0",
+ "version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/global-state.git",
- "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4"
+ "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4",
- "reference": "edf8a461cf1d4005f19fb0b6b8b95a9f7fa0adc4",
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/474fb9edb7ab891665d3bfc6317f42a0a150454b",
+ "reference": "474fb9edb7ab891665d3bfc6317f42a0a150454b",
"shasum": ""
},
"require": {
- "php": "^7.2",
+ "php": ">=7.2",
"sebastian/object-reflector": "^1.1.1",
"sebastian/recursion-context": "^3.0"
},
@@ -2661,24 +3056,34 @@
"keywords": [
"global state"
],
- "time": "2019-02-01T05:30:01+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/global-state/issues",
+ "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:43:24+00:00"
},
{
"name": "sebastian/object-enumerator",
- "version": "3.0.3",
+ "version": "3.0.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-enumerator.git",
- "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5"
+ "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5",
- "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
+ "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2",
"shasum": ""
},
"require": {
- "php": "^7.0",
+ "php": ">=7.0",
"sebastian/object-reflector": "^1.1.1",
"sebastian/recursion-context": "^3.0"
},
@@ -2708,24 +3113,34 @@
],
"description": "Traverses array structures and object graphs to enumerate all referenced objects",
"homepage": "https://github.com/sebastianbergmann/object-enumerator/",
- "time": "2017-08-03T12:35:26+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-enumerator/issues",
+ "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:40:27+00:00"
},
{
"name": "sebastian/object-reflector",
- "version": "1.1.1",
+ "version": "1.1.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/object-reflector.git",
- "reference": "773f97c67f28de00d397be301821b06708fca0be"
+ "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be",
- "reference": "773f97c67f28de00d397be301821b06708fca0be",
+ "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
+ "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
@@ -2753,24 +3168,34 @@
],
"description": "Allows reflection of object attributes, including inherited and non-public ones",
"homepage": "https://github.com/sebastianbergmann/object-reflector/",
- "time": "2017-03-29T09:07:27+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/object-reflector/issues",
+ "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:37:18+00:00"
},
{
"name": "sebastian/recursion-context",
- "version": "3.0.0",
+ "version": "3.0.1",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/recursion-context.git",
- "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8"
+ "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
- "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8",
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb",
+ "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb",
"shasum": ""
},
"require": {
- "php": "^7.0"
+ "php": ">=7.0"
},
"require-dev": {
"phpunit/phpunit": "^6.0"
@@ -2791,14 +3216,14 @@
"BSD-3-Clause"
],
"authors": [
- {
- "name": "Jeff Welch",
- "email": "whatthejeff@gmail.com"
- },
{
"name": "Sebastian Bergmann",
"email": "sebastian@phpunit.de"
},
+ {
+ "name": "Jeff Welch",
+ "email": "whatthejeff@gmail.com"
+ },
{
"name": "Adam Harvey",
"email": "aharvey@php.net"
@@ -2806,24 +3231,34 @@
],
"description": "Provides functionality to recursively process PHP variables",
"homepage": "http://www.github.com/sebastianbergmann/recursion-context",
- "time": "2017-03-03T06:23:57+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/recursion-context/issues",
+ "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:34:24+00:00"
},
{
"name": "sebastian/resource-operations",
- "version": "2.0.1",
+ "version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/resource-operations.git",
- "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9"
+ "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
- "reference": "4d7a795d35b889bf80a0cc04e08d77cedfa917a9",
+ "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3",
+ "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3",
"shasum": ""
},
"require": {
- "php": "^7.1"
+ "php": ">=7.1"
},
"type": "library",
"extra": {
@@ -2848,24 +3283,34 @@
],
"description": "Provides a list of PHP built-in functions that operate on resources",
"homepage": "https://www.github.com/sebastianbergmann/resource-operations",
- "time": "2018-10-04T04:07:39+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/resource-operations/issues",
+ "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:30:19+00:00"
},
{
"name": "sebastian/type",
- "version": "1.1.3",
+ "version": "1.1.4",
"source": {
"type": "git",
"url": "https://github.com/sebastianbergmann/type.git",
- "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3"
+ "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/3aaaa15fa71d27650d62a948be022fe3b48541a3",
- "reference": "3aaaa15fa71d27650d62a948be022fe3b48541a3",
+ "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/0150cfbc4495ed2df3872fb31b26781e4e077eb4",
+ "reference": "0150cfbc4495ed2df3872fb31b26781e4e077eb4",
"shasum": ""
},
"require": {
- "php": "^7.2"
+ "php": ">=7.2"
},
"require-dev": {
"phpunit/phpunit": "^8.2"
@@ -2894,7 +3339,17 @@
],
"description": "Collection of value objects that represent the types of the PHP type system",
"homepage": "https://github.com/sebastianbergmann/type",
- "time": "2019-07-02T08:10:15+00:00"
+ "support": {
+ "issues": "https://github.com/sebastianbergmann/type/issues",
+ "source": "https://github.com/sebastianbergmann/type/tree/1.1.4"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/sebastianbergmann",
+ "type": "github"
+ }
+ ],
+ "time": "2020-11-30T07:25:11+00:00"
},
{
"name": "sebastian/version",
@@ -2937,25 +3392,29 @@
],
"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/master"
+ },
"time": "2016-10-03T07:35:21+00:00"
},
{
"name": "setasign/fpdi",
- "version": "v2.3.4",
+ "version": "v2.3.6",
"source": {
"type": "git",
"url": "https://github.com/Setasign/FPDI.git",
- "reference": "2b5fb811c04f937ef257ef3f798cebeded33c136"
+ "reference": "6231e315f73e4f62d72b73f3d6d78ff0eed93c31"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/Setasign/FPDI/zipball/2b5fb811c04f937ef257ef3f798cebeded33c136",
- "reference": "2b5fb811c04f937ef257ef3f798cebeded33c136",
+ "url": "https://api.github.com/repos/Setasign/FPDI/zipball/6231e315f73e4f62d72b73f3d6d78ff0eed93c31",
+ "reference": "6231e315f73e4f62d72b73f3d6d78ff0eed93c31",
"shasum": ""
},
"require": {
"ext-zlib": "*",
- "php": "^5.6 || ^7.0"
+ "php": "^5.6 || ^7.0 || ^8.0"
},
"conflict": {
"setasign/tfpdf": "<1.31"
@@ -2999,26 +3458,30 @@
"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",
"type": "tidelift"
}
],
- "time": "2020-08-27T06:55:47+00:00"
+ "time": "2021-02-11T11:37:01+00:00"
},
{
"name": "squizlabs/php_codesniffer",
- "version": "3.5.6",
+ "version": "3.5.8",
"source": {
"type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
- "reference": "e97627871a7eab2f70e59166072a6b767d5834e0"
+ "reference": "9d583721a7157ee997f235f327de038e7ea6dac4"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/e97627871a7eab2f70e59166072a6b767d5834e0",
- "reference": "e97627871a7eab2f70e59166072a6b767d5834e0",
+ "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/9d583721a7157ee997f235f327de038e7ea6dac4",
+ "reference": "9d583721a7157ee997f235f327de038e7ea6dac4",
"shasum": ""
},
"require": {
@@ -3056,20 +3519,25 @@
"phpcs",
"standards"
],
- "time": "2020-08-10T04:50:15+00:00"
+ "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": "2020-10-23T02:01:07+00:00"
},
{
"name": "symfony/console",
- "version": "v5.1.7",
+ "version": "v5.2.5",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "ae789a8a2ad189ce7e8216942cdb9b77319f5eb8"
+ "reference": "938ebbadae1b0a9c9d1ec313f87f9708609f1b79"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/ae789a8a2ad189ce7e8216942cdb9b77319f5eb8",
- "reference": "ae789a8a2ad189ce7e8216942cdb9b77319f5eb8",
+ "url": "https://api.github.com/repos/symfony/console/zipball/938ebbadae1b0a9c9d1ec313f87f9708609f1b79",
+ "reference": "938ebbadae1b0a9c9d1ec313f87f9708609f1b79",
"shasum": ""
},
"require": {
@@ -3106,11 +3574,6 @@
"symfony/process": ""
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.1-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\Console\\": ""
@@ -3133,8 +3596,17 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Console Component",
+ "description": "Eases the creation of beautiful and testable command line interfaces",
"homepage": "https://symfony.com",
+ "keywords": [
+ "cli",
+ "command line",
+ "console",
+ "terminal"
+ ],
+ "support": {
+ "source": "https://github.com/symfony/console/tree/v5.2.5"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3149,7 +3621,7 @@
"type": "tidelift"
}
],
- "time": "2020-10-07T15:23:00+00:00"
+ "time": "2021-03-06T13:42:15+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -3199,6 +3671,9 @@
],
"description": "A generic function and convention to trigger deprecation notices",
"homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/deprecation-contracts/tree/master"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3217,16 +3692,16 @@
},
{
"name": "symfony/event-dispatcher",
- "version": "v5.1.7",
+ "version": "v5.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/event-dispatcher.git",
- "reference": "d5de97d6af175a9e8131c546db054ca32842dd0f"
+ "reference": "d08d6ec121a425897951900ab692b612a61d6240"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d5de97d6af175a9e8131c546db054ca32842dd0f",
- "reference": "d5de97d6af175a9e8131c546db054ca32842dd0f",
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d08d6ec121a425897951900ab692b612a61d6240",
+ "reference": "d08d6ec121a425897951900ab692b612a61d6240",
"shasum": ""
},
"require": {
@@ -3257,11 +3732,6 @@
"symfony/http-kernel": ""
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.1-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\EventDispatcher\\": ""
@@ -3284,8 +3754,11 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony EventDispatcher Component",
+ "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.2.4"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3300,7 +3773,7 @@
"type": "tidelift"
}
],
- "time": "2020-09-18T14:27:32+00:00"
+ "time": "2021-02-18T17:12:37+00:00"
},
{
"name": "symfony/event-dispatcher-contracts",
@@ -3362,6 +3835,9 @@
"interoperability",
"standards"
],
+ "support": {
+ "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.2.0"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3380,16 +3856,16 @@
},
{
"name": "symfony/filesystem",
- "version": "v5.1.7",
+ "version": "v5.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "1a8697545a8d87b9f2f6b1d32414199cc5e20aae"
+ "reference": "710d364200997a5afde34d9fe57bd52f3cc1e108"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/1a8697545a8d87b9f2f6b1d32414199cc5e20aae",
- "reference": "1a8697545a8d87b9f2f6b1d32414199cc5e20aae",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/710d364200997a5afde34d9fe57bd52f3cc1e108",
+ "reference": "710d364200997a5afde34d9fe57bd52f3cc1e108",
"shasum": ""
},
"require": {
@@ -3397,11 +3873,6 @@
"symfony/polyfill-ctype": "~1.8"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.1-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\Filesystem\\": ""
@@ -3424,8 +3895,11 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Filesystem Component",
+ "description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/filesystem/tree/v5.2.4"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3440,31 +3914,26 @@
"type": "tidelift"
}
],
- "time": "2020-09-27T14:02:37+00:00"
+ "time": "2021-02-12T10:38:38+00:00"
},
{
"name": "symfony/finder",
- "version": "v5.1.7",
+ "version": "v5.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/finder.git",
- "reference": "2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8"
+ "reference": "0d639a0943822626290d169965804f79400e6a04"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/finder/zipball/2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8",
- "reference": "2c3ba7ad6884e6c4451ce2340e2dc23f6fa3e0d8",
+ "url": "https://api.github.com/repos/symfony/finder/zipball/0d639a0943822626290d169965804f79400e6a04",
+ "reference": "0d639a0943822626290d169965804f79400e6a04",
"shasum": ""
},
"require": {
"php": ">=7.2.5"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.1-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\Finder\\": ""
@@ -3487,8 +3956,11 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Finder Component",
+ "description": "Finds files and directories via an intuitive fluent interface",
"homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/finder/tree/v5.2.4"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3503,33 +3975,29 @@
"type": "tidelift"
}
],
- "time": "2020-09-02T16:23:27+00:00"
+ "time": "2021-02-15T18:55:04+00:00"
},
{
"name": "symfony/options-resolver",
- "version": "v5.1.7",
+ "version": "v5.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/options-resolver.git",
- "reference": "4c7e155bf7d93ea4ba3824d5a14476694a5278dd"
+ "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4c7e155bf7d93ea4ba3824d5a14476694a5278dd",
- "reference": "4c7e155bf7d93ea4ba3824d5a14476694a5278dd",
+ "url": "https://api.github.com/repos/symfony/options-resolver/zipball/5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce",
+ "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce",
"shasum": ""
},
"require": {
"php": ">=7.2.5",
"symfony/deprecation-contracts": "^2.1",
+ "symfony/polyfill-php73": "~1.0",
"symfony/polyfill-php80": "^1.15"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.1-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\OptionsResolver\\": ""
@@ -3552,13 +4020,16 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony OptionsResolver Component",
+ "description": "Provides an improved replacement for the array_replace PHP function",
"homepage": "https://symfony.com",
"keywords": [
"config",
"configuration",
"options"
],
+ "support": {
+ "source": "https://github.com/symfony/options-resolver/tree/v5.2.4"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3573,24 +4044,24 @@
"type": "tidelift"
}
],
- "time": "2020-09-27T03:44:28+00:00"
+ "time": "2021-01-27T12:56:27+00:00"
},
{
"name": "symfony/polyfill-ctype",
- "version": "v1.18.1",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-ctype.git",
- "reference": "1c302646f6efc070cd46856e600e5e0684d6b454"
+ "reference": "c6c942b1ac76c82448322025e084cadc56048b4e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454",
- "reference": "1c302646f6efc070cd46856e600e5e0684d6b454",
+ "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e",
+ "reference": "c6c942b1ac76c82448322025e084cadc56048b4e",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
"suggest": {
"ext-ctype": "For best performance"
@@ -3598,7 +4069,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.18-dev"
+ "dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -3635,6 +4106,9 @@
"polyfill",
"portable"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3649,24 +4123,24 @@
"type": "tidelift"
}
],
- "time": "2020-07-14T12:35:20+00:00"
+ "time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-intl-grapheme",
- "version": "v1.18.1",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-grapheme.git",
- "reference": "b740103edbdcc39602239ee8860f0f45a8eb9aa5"
+ "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b740103edbdcc39602239ee8860f0f45a8eb9aa5",
- "reference": "b740103edbdcc39602239ee8860f0f45a8eb9aa5",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170",
+ "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
"suggest": {
"ext-intl": "For best performance"
@@ -3674,7 +4148,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.18-dev"
+ "dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -3713,6 +4187,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3727,24 +4204,24 @@
"type": "tidelift"
}
],
- "time": "2020-07-14T12:35:20+00:00"
+ "time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-intl-normalizer",
- "version": "v1.18.1",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-intl-normalizer.git",
- "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e"
+ "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e",
- "reference": "37078a8dd4a2a1e9ab0231af7c6cb671b2ed5a7e",
+ "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248",
+ "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
"suggest": {
"ext-intl": "For best performance"
@@ -3752,7 +4229,7 @@
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.18-dev"
+ "dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -3794,6 +4271,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3808,47 +4288,35 @@
"type": "tidelift"
}
],
- "time": "2020-07-14T12:35:20+00:00"
+ "time": "2021-01-22T09:19:47+00:00"
},
{
"name": "symfony/polyfill-php70",
- "version": "v1.18.1",
+ "version": "v1.20.0",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php70.git",
- "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3"
+ "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/0dd93f2c578bdc9c72697eaa5f1dd25644e618d3",
- "reference": "0dd93f2c578bdc9c72697eaa5f1dd25644e618d3",
+ "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644",
+ "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644",
"shasum": ""
},
"require": {
- "paragonie/random_compat": "~1.0|~2.0|~9.99",
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
- "type": "library",
+ "type": "metapackage",
"extra": {
"branch-alias": {
- "dev-master": "1.18-dev"
+ "dev-main": "1.20-dev"
},
"thanks": {
"name": "symfony/polyfill",
"url": "https://github.com/symfony/polyfill"
}
},
- "autoload": {
- "psr-4": {
- "Symfony\\Polyfill\\Php70\\": ""
- },
- "files": [
- "bootstrap.php"
- ],
- "classmap": [
- "Resources/stubs"
- ]
- },
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
@@ -3871,6 +4339,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php70/tree/v1.20.0"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3885,29 +4356,29 @@
"type": "tidelift"
}
],
- "time": "2020-07-14T12:35:20+00:00"
+ "time": "2020-10-23T14:02:19+00:00"
},
{
"name": "symfony/polyfill-php72",
- "version": "v1.18.1",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php72.git",
- "reference": "639447d008615574653fb3bc60d1986d7172eaae"
+ "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/639447d008615574653fb3bc60d1986d7172eaae",
- "reference": "639447d008615574653fb3bc60d1986d7172eaae",
+ "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
+ "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.18-dev"
+ "dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -3944,6 +4415,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php72/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -3958,29 +4432,29 @@
"type": "tidelift"
}
],
- "time": "2020-07-14T12:35:20+00:00"
+ "time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-php73",
- "version": "v1.18.1",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php73.git",
- "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca"
+ "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fffa1a52a023e782cdcc221d781fe1ec8f87fcca",
- "reference": "fffa1a52a023e782cdcc221d781fe1ec8f87fcca",
+ "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
+ "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2",
"shasum": ""
},
"require": {
- "php": ">=5.3.3"
+ "php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.18-dev"
+ "dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -4020,6 +4494,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php73/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -4034,29 +4511,29 @@
"type": "tidelift"
}
],
- "time": "2020-07-14T12:35:20+00:00"
+ "time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/polyfill-php80",
- "version": "v1.18.1",
+ "version": "v1.22.1",
"source": {
"type": "git",
"url": "https://github.com/symfony/polyfill-php80.git",
- "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981"
+ "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/d87d5766cbf48d72388a9f6b85f280c8ad51f981",
- "reference": "d87d5766cbf48d72388a9f6b85f280c8ad51f981",
+ "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91",
+ "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91",
"shasum": ""
},
"require": {
- "php": ">=7.0.8"
+ "php": ">=7.1"
},
"type": "library",
"extra": {
"branch-alias": {
- "dev-master": "1.18-dev"
+ "dev-main": "1.22-dev"
},
"thanks": {
"name": "symfony/polyfill",
@@ -4100,6 +4577,9 @@
"portable",
"shim"
],
+ "support": {
+ "source": "https://github.com/symfony/polyfill-php80/tree/v1.22.1"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -4114,20 +4594,20 @@
"type": "tidelift"
}
],
- "time": "2020-07-14T12:35:20+00:00"
+ "time": "2021-01-07T16:49:33+00:00"
},
{
"name": "symfony/process",
- "version": "v5.1.7",
+ "version": "v5.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/process.git",
- "reference": "d3a2e64866169586502f0cd9cab69135ad12cee9"
+ "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/process/zipball/d3a2e64866169586502f0cd9cab69135ad12cee9",
- "reference": "d3a2e64866169586502f0cd9cab69135ad12cee9",
+ "url": "https://api.github.com/repos/symfony/process/zipball/313a38f09c77fbcdc1d223e57d368cea76a2fd2f",
+ "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f",
"shasum": ""
},
"require": {
@@ -4135,11 +4615,6 @@
"symfony/polyfill-php80": "^1.15"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.1-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\Process\\": ""
@@ -4162,8 +4637,11 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Process Component",
+ "description": "Executes commands in sub-processes",
"homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/process/tree/v5.2.4"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -4178,7 +4656,7 @@
"type": "tidelift"
}
],
- "time": "2020-09-02T16:23:27+00:00"
+ "time": "2021-01-27T10:15:41+00:00"
},
{
"name": "symfony/service-contracts",
@@ -4240,6 +4718,9 @@
"interoperability",
"standards"
],
+ "support": {
+ "source": "https://github.com/symfony/service-contracts/tree/master"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -4258,16 +4739,16 @@
},
{
"name": "symfony/stopwatch",
- "version": "v5.1.7",
+ "version": "v5.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/stopwatch.git",
- "reference": "0f7c58cf81dbb5dd67d423a89d577524a2ec0323"
+ "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/stopwatch/zipball/0f7c58cf81dbb5dd67d423a89d577524a2ec0323",
- "reference": "0f7c58cf81dbb5dd67d423a89d577524a2ec0323",
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b12274acfab9d9850c52583d136a24398cdf1a0c",
+ "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c",
"shasum": ""
},
"require": {
@@ -4275,11 +4756,6 @@
"symfony/service-contracts": "^1.0|^2"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.1-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\Stopwatch\\": ""
@@ -4302,8 +4778,11 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony Stopwatch Component",
+ "description": "Provides a way to profile code",
"homepage": "https://symfony.com",
+ "support": {
+ "source": "https://github.com/symfony/stopwatch/tree/v5.2.4"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -4318,20 +4797,20 @@
"type": "tidelift"
}
],
- "time": "2020-05-20T17:43:50+00:00"
+ "time": "2021-01-27T10:15:41+00:00"
},
{
"name": "symfony/string",
- "version": "v5.1.7",
+ "version": "v5.2.4",
"source": {
"type": "git",
"url": "https://github.com/symfony/string.git",
- "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e"
+ "reference": "4e78d7d47061fa183639927ec40d607973699609"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/string/zipball/4a9afe9d07bac506f75bcee8ed3ce76da5a9343e",
- "reference": "4a9afe9d07bac506f75bcee8ed3ce76da5a9343e",
+ "url": "https://api.github.com/repos/symfony/string/zipball/4e78d7d47061fa183639927ec40d607973699609",
+ "reference": "4e78d7d47061fa183639927ec40d607973699609",
"shasum": ""
},
"require": {
@@ -4349,11 +4828,6 @@
"symfony/var-exporter": "^4.4|^5.0"
},
"type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "5.1-dev"
- }
- },
"autoload": {
"psr-4": {
"Symfony\\Component\\String\\": ""
@@ -4379,7 +4853,7 @@
"homepage": "https://symfony.com/contributors"
}
],
- "description": "Symfony String component",
+ "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way",
"homepage": "https://symfony.com",
"keywords": [
"grapheme",
@@ -4389,6 +4863,9 @@
"utf-8",
"utf8"
],
+ "support": {
+ "source": "https://github.com/symfony/string/tree/v5.2.4"
+ },
"funding": [
{
"url": "https://symfony.com/sponsor",
@@ -4403,20 +4880,20 @@
"type": "tidelift"
}
],
- "time": "2020-09-15T12:23:47+00:00"
+ "time": "2021-02-16T10:20:28+00:00"
},
{
"name": "tecnickcom/tcpdf",
- "version": "6.3.5",
+ "version": "6.4.1",
"source": {
"type": "git",
"url": "https://github.com/tecnickcom/TCPDF.git",
- "reference": "19a535eaa7fb1c1cac499109deeb1a7a201b4549"
+ "reference": "5ba838befdb37ef06a16d9f716f35eb03cb1b329"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/19a535eaa7fb1c1cac499109deeb1a7a201b4549",
- "reference": "19a535eaa7fb1c1cac499109deeb1a7a201b4549",
+ "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/5ba838befdb37ef06a16d9f716f35eb03cb1b329",
+ "reference": "5ba838befdb37ef06a16d9f716f35eb03cb1b329",
"shasum": ""
},
"require": {
@@ -4465,7 +4942,17 @@
"pdf417",
"qrcode"
],
- "time": "2020-02-14T14:20:12+00:00"
+ "support": {
+ "issues": "https://github.com/tecnickcom/TCPDF/issues",
+ "source": "https://github.com/tecnickcom/TCPDF/tree/6.4.1"
+ },
+ "funding": [
+ {
+ "url": "https://www.paypal.com/cgi-bin/webscr?cmd=_donations¤cy_code=GBP&business=paypal@tecnick.com&item_name=donation%20for%20tcpdf%20project",
+ "type": "custom"
+ }
+ ],
+ "time": "2021-03-27T16:00:33+00:00"
},
{
"name": "theseer/tokenizer",
@@ -4505,6 +4992,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/master"
+ },
"funding": [
{
"url": "https://github.com/theseer",
@@ -4515,30 +5006,35 @@
},
{
"name": "webmozart/assert",
- "version": "1.9.1",
+ "version": "1.10.0",
"source": {
"type": "git",
- "url": "https://github.com/webmozart/assert.git",
- "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389"
+ "url": "https://github.com/webmozarts/assert.git",
+ "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389",
- "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389",
+ "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25",
+ "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25",
"shasum": ""
},
"require": {
- "php": "^5.3.3 || ^7.0 || ^8.0",
+ "php": "^7.2 || ^8.0",
"symfony/polyfill-ctype": "^1.8"
},
"conflict": {
"phpstan/phpstan": "<0.12.20",
- "vimeo/psalm": "<3.9.1"
+ "vimeo/psalm": "<4.6.1 || 4.6.2"
},
"require-dev": {
- "phpunit/phpunit": "^4.8.36 || ^7.5.13"
+ "phpunit/phpunit": "^8.5.13"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "1.10-dev"
+ }
+ },
"autoload": {
"psr-4": {
"Webmozart\\Assert\\": "src/"
@@ -4560,7 +5056,11 @@
"check",
"validate"
],
- "time": "2020-07-08T17:02:28+00:00"
+ "support": {
+ "issues": "https://github.com/webmozarts/assert/issues",
+ "source": "https://github.com/webmozarts/assert/tree/1.10.0"
+ },
+ "time": "2021-03-09T10:59:23+00:00"
}
],
"aliases": [],
@@ -4569,15 +5069,15 @@
"prefer-stable": false,
"prefer-lowest": false,
"platform": {
- "php": "^7.2||^8.0",
+ "php": "^7.2 || ^8.0",
+ "ext-simplexml": "*",
"ext-ctype": "*",
"ext-dom": "*",
+ "ext-fileinfo": "*",
"ext-gd": "*",
"ext-iconv": "*",
- "ext-fileinfo": "*",
"ext-libxml": "*",
"ext-mbstring": "*",
- "ext-simplexml": "*",
"ext-xml": "*",
"ext-xmlreader": "*",
"ext-xmlwriter": "*",
diff --git a/docs/extra/extrajs.js b/docs/extra/extrajs.js
new file mode 100644
index 00000000..9ad135e8
--- /dev/null
+++ b/docs/extra/extrajs.js
@@ -0,0 +1,5 @@
+document.addEventListener("DOMContentLoaded", function() {
+ document.querySelectorAll("table").forEach(function(table) {
+ table.classList.add("docutils");
+ });
+});
\ No newline at end of file
diff --git a/docs/index.md b/docs/index.md
index b1207d53..42acedf9 100644
--- a/docs/index.md
+++ b/docs/index.md
@@ -89,7 +89,7 @@ php vendor/phpoffice/phpspreadsheet/samples/Basic/01_Simple.php
## Learn by documentation
-For more in-depth documentation, you may read about an [overview of the
+For more documentation in depth, you may read about an [overview of the
architecture](./topics/architecture.md),
[creating a spreadsheet](./topics/creating-spreadsheet.md),
[worksheets](./topics/worksheets.md),
diff --git a/docs/topics/images/10-databar-of-conditional-formatting.png b/docs/topics/images/10-databar-of-conditional-formatting.png
new file mode 100644
index 00000000..10c88f9f
Binary files /dev/null and b/docs/topics/images/10-databar-of-conditional-formatting.png differ
diff --git a/docs/topics/reading-and-writing-to-file.md b/docs/topics/reading-and-writing-to-file.md
index e1b7e3a2..a9f767aa 100644
--- a/docs/topics/reading-and-writing-to-file.md
+++ b/docs/topics/reading-and-writing-to-file.md
@@ -580,6 +580,18 @@ $writer->setUseBOM(true);
$writer->save("05featuredemo.csv");
```
+#### Writing CSV files with desired encoding
+
+It can be set to output with the encoding that can be specified by PHP's mb_convert_encoding.
+This looks like the following code:
+
+```php
+$writer = new \PhpOffice\PhpSpreadsheet\Writer\Csv($spreadsheet);
+$writer->setUseBOM(false);
+$writer->setOutputEncoding('SJIS-WIN');
+$writer->save("05featuredemo.csv");
+```
+
#### Decimal and thousands separators
If the worksheet you are exporting contains numbers with decimal or
diff --git a/docs/topics/recipes.md b/docs/topics/recipes.md
index db09642d..bbdc29a8 100644
--- a/docs/topics/recipes.md
+++ b/docs/topics/recipes.md
@@ -884,6 +884,44 @@ $spreadsheet->getActiveSheet()
);
```
+### DataBar of Conditional formatting
+The basics are the same as conditional formatting.
+Additional DataBar object to conditional formatting.
+
+For example, the following code will result in the conditional formatting shown in the image.
+```php
+$conditional = new Conditional();
+$conditional->setConditionType(Conditional::CONDITION_DATABAR);
+$conditional->setDataBar(new ConditionalDataBar());
+$conditional->getDataBar()
+ ->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject('num', '2'))
+ ->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject('max'))
+ ->setColor('FFFF555A');
+$ext = $conditional
+ ->getDataBar()
+ ->setConditionalFormattingRuleExt(new ConditionalFormattingRuleExtension())
+ ->getConditionalFormattingRuleExt();
+
+$ext->setCfRule('dataBar');
+$ext->setSqref('A1:A5'); // target CellCoordinates
+$ext->setDataBarExt(new ConditionalDataBarExtension());
+$ext->getDataBarExt()
+ ->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject('num', '2'))
+ ->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject('autoMax'))
+ ->setMinLength(0)
+ ->setMaxLength(100)
+ ->setBorder(true)
+ ->setDirection('rightToLeft')
+ ->setNegativeBarBorderColorSameAsPositive(false)
+ ->setBorderColor('FFFF555A')
+ ->setNegativeFillColor('FFFF0000')
+ ->setNegativeBorderColor('FFFF0000')
+ ->setAxisColor('FF000000');
+
+```
+
+
+
## Add a comment to a cell
To add a comment to a cell, use the following code. The example below
diff --git a/mkdocs.yml b/mkdocs.yml
index cf87a142..f79acb69 100644
--- a/mkdocs.yml
+++ b/mkdocs.yml
@@ -5,3 +5,5 @@ edit_uri: edit/master/docs/
theme: readthedocs
extra_css:
- extra/extra.css
+extra_javascript:
+ - extra/extrajs.js
diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon
new file mode 100644
index 00000000..ced31605
--- /dev/null
+++ b/phpstan-baseline.neon
@@ -0,0 +1,8827 @@
+parameters:
+ ignoreErrors:
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$returnArrayAsType has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$branchPruningEnabled has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$cellStack has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$cyclicFormulaCell has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$localeFunctions has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$phpSpreadsheetFunctions has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$controlFunctions has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Binary operation \"\\-\" between 0 and string\\|false results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$spreadsheet \\(PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Argument of an invalid type array\\\\|false supplied for foreach, only iterables are supported\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#3 \\$formula of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:translateSeparator\\(\\) expects string, string\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$functionReplaceFromExcel has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$functionReplaceToLocale has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToLocale\\(\\) has parameter \\$formula with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function preg_quote expects string, int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$functionReplaceFromLocale has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$functionReplaceToExcel has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:_translateFormulaToEnglish\\(\\) has parameter \\$formula with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function trim expects string, int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:localeFunc\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:localeFunc\\(\\) has parameter \\$function with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 6
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$operatorAssociativity has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$comparisonOperators has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:\\$operatorPrecedence has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between mixed and null will always evaluate to false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#1 \\$haystack of function stripos expects string, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#1 \\$haystack of function strpos expects string, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:dataTestReference\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:dataTestReference\\(\\) has parameter \\$operandData with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method getTitle\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method getColumn\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function trim expects string, null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method getCoordinate\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method getRow\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method has\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#1 \\$parent of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:attach\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells, PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method attach\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has parameter \\$operand with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:validateBinaryOperand\\(\\) has parameter \\$stack with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:strCaseReverse\\(\\) expects string, string\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:raiseFormulaError\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:raiseFormulaError\\(\\) has parameter \\$errorMessage with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method cellExists\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Parameter \\#2 \\$pSheet of static method PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\:\\:resolveName\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet, PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method getHighestRow\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Cannot call method getHighestColumn\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:getUnusedBranchStoreKey\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:getTokensAsString\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:getTokensAsString\\(\\) has parameter \\$tokens with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Calculation.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\\:\\: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: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\\\DatabaseAbstract\\:\\:evaluate\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\\\DatabaseAbstract\\:\\:evaluate\\(\\) has parameter \\$criteria with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\\\DatabaseAbstract\\:\\:evaluate\\(\\) has parameter \\$database with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\\\DatabaseAbstract\\:\\:evaluate\\(\\) has parameter \\$field with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\\\DatabaseAbstract\\:\\:buildCondition\\(\\) has parameter \\$criterion with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Database\\\\DatabaseAbstract\\:\\:processCondition\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Database/DatabaseAbstract.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTime\\:\\:NETWORKDAYS\\(\\) has parameter \\$dateArgs with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTime.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTime\\:\\:WORKDAY\\(\\) has parameter \\$dateArgs with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTime.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
+
+ -
+ message: "#^Parameter \\#1 \\$haystack of function strpos expects string, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
+
+ -
+ message: "#^Parameter \\#1 \\$PHPDateArray of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\DateValue\\:\\:finalResults\\(\\) expects array\\|false, array\\|bool given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
+
+ -
+ message: "#^Parameter \\#1 \\$testVal1 of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustYear\\(\\) expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
+
+ -
+ message: "#^Parameter \\#2 \\$testVal2 of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustYear\\(\\) expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/DateValue.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:testStringAsNumeric\\(\\) expects string, float\\|int\\|string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Datefunc.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Day\\:\\:weirdCondition\\(\\) has parameter \\$dateValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Day.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustDateByMonths\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustDateByMonths\\(\\) has parameter \\$adjustmentMonths with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:adjustDateByMonths\\(\\) has parameter \\$dateValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
+
+ -
+ message: "#^Parameter \\#1 \\$excelTimestamp of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Date\\:\\:excelToTimestamp\\(\\) expects float\\|int, bool\\|float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Helpers\\:\\:validateNumericNull\\(\\) should return float\\|int but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Helpers.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\IsoWeekNum\\:\\:apparentBug\\(\\) has parameter \\$dateValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/IsoWeekNum.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\NetworkDays\\:\\:funcNetworkDays\\(\\) has parameter \\$dateArgs with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\NetworkDays\\:\\:applySign\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/NetworkDays.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\Time\\:\\:toIntWithNullBool\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/Time.php
+
+ -
+ message: "#^Cannot access offset 0 on array\\\\|false\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php
+
+ -
+ message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\\\|false given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/TimeValue.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\WeekDay\\:\\:validateStyle\\(\\) has parameter \\$style with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WeekDay.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\DateTimeExcel\\\\WorkDay\\:\\:funcWorkDay\\(\\) has parameter \\$dateArgs with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php
+
+ -
+ message: "#^Binary operation \"\\-\" between 7 and int\\|string results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php
+
+ -
+ message: "#^Binary operation \"\\-\" between 7 and int\\<5, max\\>\\|string results in an error\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php
+
+ -
+ message: "#^Binary operation \"\\-\" between 4 and int\\<5, max\\>\\|string results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/WorkDay.php
+
+ -
+ message: "#^Binary operation \"\\-\" between int\\|string and int\\|string results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php
+
+ -
+ message: "#^Binary operation \"\\*\" between 100 and int\\|string results in an error\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/DateTimeExcel/YearFrac.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engine\\\\Logger\\:\\:writeDebugLog\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engine/Logger.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\:\\:BITLSHIFT\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\:\\:BITRSHIFT\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\BesselJ\\:\\:besselj2a\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\BesselJ\\:\\:besselj2b\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/BesselJ.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\BesselK\\:\\:besselK2\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/BesselK.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\BitWise\\:\\:validateBitwiseArgument\\(\\) never returns int so it can be removed from the return typehint\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/BitWise.php
+
+ -
+ message: "#^Parameter \\#1 \\$number of function floor expects float, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/BitWise.php
+
+ -
+ message: "#^Parameter \\#1 \\$number of function floor expects float, float\\|int\\<0, 281474976710655\\>\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/BitWise.php
+
+ -
+ message: "#^Parameter \\#1 \\$power of method Complex\\\\Complex\\:\\:pow\\(\\) expects float\\|int, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ComplexFunctions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\ConvertBase\\:\\:validateValue\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ConvertBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\ConvertBase\\:\\:validatePlaces\\(\\) has parameter \\$places with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ConvertBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\ConvertUOM\\:\\:getUOMDetails\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\ConvertUOM\\:\\:resolveTemperatureSynonyms\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ConvertUOM.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\Erf\\:\\:\\$twoSqrtPi has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/Erf.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\Erf\\:\\:erfValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/Erf.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\Erf\\:\\:erfValue\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/Erf.php
+
+ -
+ message: "#^Binary operation \"\\-\" between 1 and float\\|string results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/Erf.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\ErfC\\:\\:\\$oneSqrtPi has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ErfC.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\ErfC\\:\\:erfcValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ErfC.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Engineering\\\\ErfC\\:\\:erfcValue\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ErfC.php
+
+ -
+ message: "#^Binary operation \"\\-\" between 2 and float\\|string results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Engineering/ErfC.php
+
+ -
+ message: "#^Parameter \\#1 \\$callback of function set_error_handler expects \\(callable\\(int, string, string, int, array\\)\\: bool\\)\\|null, array\\('PhpOffice\\\\\\\\PhpSpreadsheet\\\\\\\\Calculation\\\\\\\\Exception', 'errorHandlerCallback'\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/ExceptionHandler.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:ISPMT\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:ISPMT\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\:\\:NPV\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:schedulePayment\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:rateNextGuess\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:rateNextGuess\\(\\) has parameter \\$futureValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:rateNextGuess\\(\\) has parameter \\$numberOfPeriods with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:rateNextGuess\\(\\) has parameter \\$payment with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:rateNextGuess\\(\\) has parameter \\$presentValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:rateNextGuess\\(\\) has parameter \\$rate with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\Interest\\:\\:rateNextGuess\\(\\) has parameter \\$type with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/Interest.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\InterestAndPrincipal\\:\\:\\$interest has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/InterestAndPrincipal.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Constant\\\\Periodic\\\\InterestAndPrincipal\\:\\:\\$principal has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/InterestAndPrincipal.php
+
+ -
+ message: "#^Binary operation \"\\-\" between float\\|string and 0\\|float results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Constant/Periodic/InterestAndPrincipal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:bothNegAndPos\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:bothNegAndPos\\(\\) has parameter \\$neg with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:bothNegAndPos\\(\\) has parameter \\$pos with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart1\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart1\\(\\) has parameter \\$dates with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart1\\(\\) has parameter \\$values with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart2\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart2\\(\\) has parameter \\$values with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart3\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart3\\(\\) has parameter \\$dates with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart3\\(\\) has parameter \\$values with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart3\\(\\) has parameter \\$x1 with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xirrPart3\\(\\) has parameter \\$x2 with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xnpvOrdered\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xnpvOrdered\\(\\) has parameter \\$dates with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xnpvOrdered\\(\\) has parameter \\$ordered with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xnpvOrdered\\(\\) has parameter \\$rate with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:xnpvOrdered\\(\\) has parameter \\$values with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:validateXnpv\\(\\) has parameter \\$dates with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:validateXnpv\\(\\) has parameter \\$rate with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\NonPeriodic\\:\\:validateXnpv\\(\\) has parameter \\$values with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/NonPeriodic.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\CashFlow\\\\Variable\\\\Periodic\\:\\:presentValue\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/CashFlow/Variable/Periodic.php
+
+ -
+ message: "#^Binary operation \"\\*\" between float\\|string and int results in an error\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
+
+ -
+ message: "#^Binary operation \"\\*\" between float\\|string and int\\|string results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Coupons\\:\\:couponFirstPeriodDate\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Coupons\\:\\:couponFirstPeriodDate\\(\\) has parameter \\$maturity with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Coupons\\:\\:couponFirstPeriodDate\\(\\) has parameter \\$next with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Coupons\\:\\:couponFirstPeriodDate\\(\\) has parameter \\$settlement with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Coupons\\:\\:validateCouponPeriod\\(\\) has parameter \\$maturity with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Coupons\\:\\:validateCouponPeriod\\(\\) has parameter \\$settlement with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Coupons.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Depreciation\\:\\:validateCost\\(\\) has parameter \\$cost with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Depreciation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Depreciation\\:\\:validateSalvage\\(\\) has parameter \\$salvage with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Depreciation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Depreciation\\:\\:validateLife\\(\\) has parameter \\$life with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Depreciation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Depreciation\\:\\:validatePeriod\\(\\) has parameter \\$period with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Depreciation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Depreciation\\:\\:validateMonth\\(\\) has parameter \\$month with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Depreciation.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Financial\\\\Depreciation\\:\\:validateFactor\\(\\) has parameter \\$factor with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Financial/Depreciation.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/FormulaParser.php
+
+ -
+ message: "#^Cannot call method setValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\FormulaToken\\|null\\.$#"
+ count: 5
+ path: src/PhpSpreadsheet/Calculation/FormulaParser.php
+
+ -
+ message: "#^Cannot call method setTokenSubType\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\FormulaToken\\|null\\.$#"
+ count: 5
+ path: src/PhpSpreadsheet/Calculation/FormulaParser.php
+
+ -
+ message: "#^Cannot call method getTokenType\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\FormulaToken\\|null\\.$#"
+ count: 9
+ path: src/PhpSpreadsheet/Calculation/FormulaParser.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\FormulaToken and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/FormulaParser.php
+
+ -
+ message: "#^Cannot call method getTokenSubType\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\FormulaToken\\|null\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Calculation/FormulaParser.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:isMatrixValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:isMatrixValue\\(\\) has parameter \\$idx with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:isValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:isValue\\(\\) has parameter \\$idx with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:isCellValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:isCellValue\\(\\) has parameter \\$idx with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:ifCondition\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:ifCondition\\(\\) has parameter \\$condition with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:operandSpecialHandling\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Functions\\:\\:operandSpecialHandling\\(\\) has parameter \\$operand with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Functions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Internal\\\\MakeMatrix\\:\\:make\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Internal/MakeMatrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Internal\\\\WildcardMatch\\:\\:wildcard\\(\\) should return string but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Internal/WildcardMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Internal\\\\WildcardMatch\\:\\:compare\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Internal/WildcardMatch.php
+
+ -
+ message: "#^Call to function is_string\\(\\) with null will always evaluate to false\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Calculation/Logical/Operations.php
+
+ -
+ message: "#^Result of && is always false\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Calculation/Logical/Operations.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\\:\\:CHOOSE\\(\\) has parameter \\$chooseArgs with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef.php
+
+ -
+ message: "#^Call to function is_bool\\(\\) with float\\|int\\|\\(string&numeric\\) will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef.php
+
+ -
+ message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/LookupRef.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Address\\:\\:sheetName\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Address.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:MATCH\\(\\) should return int\\|string but returns float\\|int\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchFirstValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchFirstValue\\(\\) has parameter \\$lookupArray with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchFirstValue\\(\\) has parameter \\$lookupValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchLargestValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchLargestValue\\(\\) has parameter \\$keySet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchLargestValue\\(\\) has parameter \\$lookupArray with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchLargestValue\\(\\) has parameter \\$lookupValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchSmallestValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchSmallestValue\\(\\) has parameter \\$lookupArray with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:matchSmallestValue\\(\\) has parameter \\$lookupValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:validateLookupValue\\(\\) has parameter \\$lookupValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:validateMatchType\\(\\) has parameter \\$matchType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:validateLookupArray\\(\\) has parameter \\$lookupArray with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:prepareLookupArray\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:prepareLookupArray\\(\\) has parameter \\$lookupArray with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\ExcelMatch\\:\\:prepareLookupArray\\(\\) has parameter \\$matchType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/ExcelMatch.php
+
+ -
+ message: "#^Binary operation \"\\-\" between int\\|string and 1 results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\HLookup\\:\\:hLookupSearch\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\HLookup\\:\\:hLookupSearch\\(\\) has parameter \\$column with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\HLookup\\:\\:hLookupSearch\\(\\) has parameter \\$lookupArray with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\HLookup\\:\\:hLookupSearch\\(\\) has parameter \\$lookupValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\HLookup\\:\\:hLookupSearch\\(\\) has parameter \\$notExactMatch with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/HLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Indirect\\:\\:extractRequiredCells\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Indirect\\:\\:extractWorksheet\\(\\) has parameter \\$cellAddress with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Indirect.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Lookup\\:\\:verifyResultVector\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Lookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Lookup\\:\\:verifyResultVector\\(\\) has parameter \\$resultVector with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Lookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\LookupBase\\:\\:validateIndexLookup\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\LookupBase\\:\\:validateIndexLookup\\(\\) has parameter \\$index_number with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\LookupBase\\:\\:validateIndexLookup\\(\\) has parameter \\$lookup_array with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\LookupBase\\:\\:checkMatch\\(\\) has parameter \\$notExactMatch with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/LookupBase.php
+
+ -
+ message: "#^Parameter \\#3 \\$rowNum of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Matrix\\:\\:extractRowValue\\(\\) expects int, float\\|int\\<0, max\\>\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Matrix\\:\\:extractRowValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:extractRequiredCells\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:extractWorksheet\\(\\) has parameter \\$cellAddress with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:adjustEndCellColumnForWidth\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:adjustEndCellColumnForWidth\\(\\) has parameter \\$columns with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:adjustEndCellColumnForWidth\\(\\) has parameter \\$width with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:adustEndCellRowForHeight\\(\\) has parameter \\$endCellRow with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:adustEndCellRowForHeight\\(\\) has parameter \\$height with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\Offset\\:\\:adustEndCellRowForHeight\\(\\) has parameter \\$rows with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/Offset.php
+
+ -
+ message: "#^Parameter \\#1 \\$pString of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:columnIndexFromString\\(\\) expects string, string\\|null given\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php
+
+ -
+ message: "#^Cannot cast array\\|string to string\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php
+
+ -
+ message: "#^Parameter \\#1 \\$low of function range expects float\\|int\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php
+
+ -
+ message: "#^Parameter \\#2 \\$high of function range expects float\\|int\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/RowColumnInformation.php
+
+ -
+ message: "#^Parameter \\#2 \\$cmp_function of function uasort expects callable\\(mixed, mixed\\)\\: int, array\\('self', 'vlookupSort'\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\VLookup\\:\\:vlookupSort\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\VLookup\\:\\:vlookupSort\\(\\) has parameter \\$a with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\VLookup\\:\\:vlookupSort\\(\\) has parameter \\$b with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\VLookup\\:\\:vLookupSearch\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\VLookup\\:\\:vLookupSearch\\(\\) has parameter \\$column with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\VLookup\\:\\:vLookupSearch\\(\\) has parameter \\$lookupArray with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\VLookup\\:\\:vLookupSearch\\(\\) has parameter \\$lookupValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\LookupRef\\\\VLookup\\:\\:vLookupSearch\\(\\) has parameter \\$notExactMatch with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/LookupRef/VLookup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:COMBIN\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:EVEN\\(\\) should return int\\|string but returns float\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:FACT\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:FACTDOUBLE\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:MOD\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:ODD\\(\\) should return int\\|string but returns float\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\:\\:SUMIFS\\(\\) should return float\\|string but returns float\\|string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig.php
+
+ -
+ message: "#^Else branch is unreachable because ternary operator condition is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Arabic.php
+
+ -
+ message: "#^Parameter \\#1 \\$number of function base_convert expects string, int\\<0, 9007199254740991\\> given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Base.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Helpers\\:\\:validateNumericNullBool\\(\\) should return float\\|int but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Helpers.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Helpers\\:\\:validateNumericNullSubstitution\\(\\) should return float\\|int but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Helpers.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Lcm\\:\\:factors\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Lcm.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Lcm\\:\\:factors\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Lcm.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Roman\\:\\:romanCut\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Roman.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Roman\\:\\:romanCut\\(\\) has parameter \\$n with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Roman.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Roman\\:\\:romanCut\\(\\) has parameter \\$num with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Roman.php
+
+ -
+ message: "#^Parameter \\#2 \\$precision of function round expects int, float\\|int given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/MathTrig/RoundDown.php
+
+ -
+ message: "#^Parameter \\#2 \\$precision of function round expects int, float\\|int given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/MathTrig/RoundUp.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterHiddenArgs\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterHiddenArgs\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterHiddenArgs\\(\\) has parameter \\$cellReference with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterFormulaArgs\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterFormulaArgs\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Subtotal\\:\\:filterFormulaArgs\\(\\) has parameter \\$cellReference with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
+
+ -
+ message: "#^Parameter \\#1 \\$function of function call_user_func_array expects callable\\(\\)\\: mixed, array\\('PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…'\\|'PhpOffice…', string\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Subtotal.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function rtrim expects string, int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/MathTrig/Trunc.php
+
+ -
+ message: "#^Binary operation \"\\-\" between float\\|int and float\\|string results in an error\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Calculation/Statistical.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 typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Averages.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Averages\\:\\:filterArguments\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Averages.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Averages\\:\\:modeCalc\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Averages.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Averages\\:\\:modeCalc\\(\\) has parameter \\$data with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Averages.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Percentiles\\:\\:percentileFilterValues\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Percentiles\\:\\:rankFilterValues\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Percentiles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:checkTrendArrays\\(\\) has parameter \\$array1 with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Trends\\:\\:checkTrendArrays\\(\\) has parameter \\$array2 with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Trends.php
+
+ -
+ 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\\:\\:TREND\\(\\) should return array\\ but returns array\\\\>\\>\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Trends.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 typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Conditional\\:\\:buildConditionSetForValueRange\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Conditional\\:\\:buildConditions\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Conditional\\:\\:buildDatabase\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Conditional\\:\\:buildDatabaseWithValueRange\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Conditional\\:\\:buildDataSet\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Conditional.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\Beta\\:\\:\\$logBetaCacheP has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\Beta\\:\\:\\$logBetaCacheQ has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\Beta\\:\\:\\$logBetaCacheResult has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php
+
+ -
+ message: "#^Binary operation \"\\-\" between 1 and float\\|string results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:pchisq\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:pchisq\\(\\) has parameter \\$chi2 with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:pchisq\\(\\) has parameter \\$degrees with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gammp\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gammp\\(\\) has parameter \\$n with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gammp\\(\\) has parameter \\$x with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gser\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gser\\(\\) has parameter \\$n with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gser\\(\\) has parameter \\$x with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gcf\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gcf\\(\\) has parameter \\$n with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\ChiSquared\\:\\:gcf\\(\\) has parameter \\$x with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\Normal\\:\\:inverseNcdf\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\Normal\\:\\:inverseNcdf\\(\\) has parameter \\$p with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\GammaBase\\:\\:calculateDistribution\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\GammaBase\\:\\:calculateInverse\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\GammaBase\\:\\:\\$logGammaCacheResult has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\GammaBase\\:\\:\\$logGammaCacheX has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\GammaBase\\:\\:logGamma1\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\GammaBase\\:\\:logGamma2\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\GammaBase\\:\\:logGamma3\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\GammaBase\\:\\:logGamma4\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\NewtonRaphson\\:\\:\\$callback has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\Distributions\\\\NewtonRaphson\\:\\:execute\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php
+
+ -
+ message: "#^Binary operation \"\\-\" between 1 and float\\|string results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php
+
+ -
+ message: "#^Binary operation \"\\-\" between float\\|string and float\\|int\\|\\(string&numeric\\) results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\MaxMinBase\\:\\:datatypeAdjustmentAllowStrings\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/MaxMinBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\MaxMinBase\\:\\:datatypeAdjustmentAllowStrings\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/MaxMinBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\VarianceBase\\:\\:datatypeAdjustmentAllowStrings\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\VarianceBase\\:\\:datatypeAdjustmentAllowStrings\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\VarianceBase\\:\\:datatypeAdjustmentBooleans\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Statistical\\\\VarianceBase\\:\\:datatypeAdjustmentBooleans\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\:\\:TRIMNONPRINTABLE\\(\\) should return string but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\:\\:TRIMSPACES\\(\\) should return string but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\:\\:CONCATENATE\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\:\\:SEARCHSENSITIVE\\(\\) should return string but returns int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\:\\:SEARCHINSENSITIVE\\(\\) should return string but returns int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\CharacterConvert\\:\\:character\\(\\) should return string but returns string\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\CharacterConvert\\:\\:unicodeToOrd\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\CharacterConvert\\:\\:unicodeToOrd\\(\\) has parameter \\$character with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php
+
+ -
+ message: "#^Cannot access offset 1 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php
+
+ -
+ message: "#^Parameter \\#2 \\$data of function unpack expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\CharacterConvert\\:\\:convertBooleanValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\CharacterConvert\\:\\:convertBooleanValue\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/CharacterConvert.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\Concatenate\\:\\:CONCATENATE\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Concatenate.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\Concatenate\\:\\:convertBooleanValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Concatenate.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\Concatenate\\:\\:convertBooleanValue\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Concatenate.php
+
+ -
+ message: "#^Parameter \\#3 \\$length of function mb_substr expects int\\|null, float\\|int\\<0, max\\>\\|string given\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Calculation/TextData/Extract.php
+
+ -
+ message: "#^Parameter \\#2 \\$start of function mb_substr expects int, float\\|int given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/TextData/Extract.php
+
+ -
+ message: "#^Parameter \\#1 \\$number of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\MathTrig\\\\Mround\\:\\:funcMround\\(\\) expects float, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Format.php
+
+ -
+ message: "#^Parameter \\#1 \\$number of function floor expects float, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Format.php
+
+ -
+ message: "#^Parameter \\#1 \\$number of function round expects float, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Format.php
+
+ -
+ message: "#^Cannot cast array\\|float\\|int\\|string to float\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Format.php
+
+ -
+ message: "#^Parameter \\#3 \\$offset of function mb_strpos expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Search.php
+
+ -
+ message: "#^Parameter \\#3 \\$offset of function mb_stripos expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Search.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\TextData\\\\Trim\\:\\:\\$invalidChars has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Trim.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function trim expects string, float\\|int\\|string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Calculation/TextData/Trim.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function trim expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/TextData/Trim.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Token\\\\Stack\\:\\:getStackItem\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Token/Stack.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Token\\\\Stack\\:\\:getStackItem\\(\\) has parameter \\$onlyIf with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Token/Stack.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Token\\\\Stack\\:\\:getStackItem\\(\\) has parameter \\$onlyIfNot with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Token/Stack.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Token\\\\Stack\\:\\:getStackItem\\(\\) has parameter \\$reference with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Token/Stack.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Token\\\\Stack\\:\\:getStackItem\\(\\) has parameter \\$storeKey with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Token/Stack.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Token\\\\Stack\\:\\:getStackItem\\(\\) has parameter \\$type with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Token/Stack.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Token\\\\Stack\\:\\:getStackItem\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Calculation/Token/Stack.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:\\$formulaAttributes has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/Cell.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
+ path: src/PhpSpreadsheet/Cell/Cell.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/Cell.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\:\\:getFormulaAttributes\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/Cell.php
+
+ -
+ message: "#^Parameter \\#2 \\$str of function explode expects string, array\\\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/Coordinate.php
+
+ -
+ message: "#^Parameter \\#4 \\$currentRow of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:validateRange\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/Coordinate.php
+
+ -
+ message: "#^Parameter \\#5 \\$endRow of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:validateRange\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/Coordinate.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getHashCode\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/Coordinate.php
+
+ -
+ message: "#^Parameter \\#1 \\$input of function array_chunk expects array, array\\\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/Coordinate.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:substring\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Cell/DataType.php
+
+ -
+ message: "#^Parameter \\#2 \\$alpha of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\:\\:setShadowColor\\(\\) expects int, int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Axis.php
+
+ -
+ message: "#^Parameter \\#1 \\$blur of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\:\\:setShadowBlur\\(\\) expects float, float\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Axis.php
+
+ -
+ message: "#^Parameter \\#1 \\$angle of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\:\\:setShadowAngle\\(\\) expects int, int\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Axis.php
+
+ -
+ message: "#^Parameter \\#1 \\$distance of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\:\\:setShadowDistance\\(\\) expects float, float\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Axis.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\\:\\:\\$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\\:\\:\\$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\\:\\:\\$yAxisLabel \\(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\\:\\:\\$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\\:\\:\\$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\\:\\:\\$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\\:\\:\\$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\\:\\:\\$worksheet \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setTopLeftXOffset\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setTopLeftXOffset\\(\\) has parameter \\$xOffset with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:getTopLeftXOffset\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setTopLeftYOffset\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setTopLeftYOffset\\(\\) has parameter \\$yOffset with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:getTopLeftYOffset\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setBottomRightCell\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setBottomRightCell\\(\\) has parameter \\$cell with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setBottomRightXOffset\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setBottomRightXOffset\\(\\) has parameter \\$xOffset with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:getBottomRightXOffset\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setBottomRightYOffset\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:setBottomRightYOffset\\(\\) has parameter \\$yOffset with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\:\\:getBottomRightYOffset\\(\\) has no return typehint specified\\.$#"
+ 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\\\\DataSeriesValues\\:\\:\\$dataTypeValues has no typehint 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\\:\\:\\$fillColor \\(array\\\\|string\\) does not accept array\\\\|string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/DataSeriesValues.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\:\\:refresh\\(\\) has parameter \\$flatten with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/DataSeriesValues.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$objectState has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/GridLines.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$lineProperties has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/GridLines.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$shadowProperties has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/GridLines.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$glowProperties has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/GridLines.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:\\$softEdges has no typehint specified\\.$#"
+ 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 \\#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 \\$type of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setGlowColor\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/GridLines.php
+
+ -
+ message: "#^Parameter \\#1 \\$blur of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setShadowBlur\\(\\) expects float, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/GridLines.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 \\$distance of method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\:\\:setShadowDistance\\(\\) expects float, float\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/GridLines.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend\\:\\:\\$positionXLref has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Legend.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\\\\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\\:\\:getTrueAlpha\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getTrueAlpha\\(\\) has parameter \\$alpha with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:setColorProperties\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:setColorProperties\\(\\) has parameter \\$alpha with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:setColorProperties\\(\\) has parameter \\$color with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:setColorProperties\\(\\) has parameter \\$type with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has parameter \\$array_kay_selector with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getLineStyleArrowSize\\(\\) has parameter \\$array_selector with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getShadowPresetsMap\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getShadowPresetsMap\\(\\) has parameter \\$shadow_presets_option with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has parameter \\$elements with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Properties\\:\\:getArrayElementsValue\\(\\) has parameter \\$properties with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Properties.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:\\$width has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:\\$height has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:\\$colourSet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:\\$markSet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:\\$chart has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:\\$graph has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:\\$plotColour has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:\\$plotMark has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatPointMarker\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatPointMarker\\(\\) has parameter \\$markerID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatPointMarker\\(\\) has parameter \\$seriesPlot with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatDataSetLabels\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatDataSetLabels\\(\\) has parameter \\$datasetLabels with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatDataSetLabels\\(\\) has parameter \\$groupID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatDataSetLabels\\(\\) has parameter \\$labelCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:formatDataSetLabels\\(\\) has parameter \\$rotation with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:percentageSumCalculation\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:percentageSumCalculation\\(\\) has parameter \\$groupID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:percentageSumCalculation\\(\\) has parameter \\$seriesCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:percentageAdjustValues\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:percentageAdjustValues\\(\\) has parameter \\$dataValues with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:percentageAdjustValues\\(\\) has parameter \\$sumValues with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:getCaption\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:getCaption\\(\\) has parameter \\$captionElement with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderCartesianPlotArea\\(\\) has parameter \\$type with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotLine\\(\\) has parameter \\$combination with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotLine\\(\\) has parameter \\$dimensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotLine\\(\\) has parameter \\$filled with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotLine\\(\\) has parameter \\$groupID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotBar\\(\\) has parameter \\$dimensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotBar\\(\\) has parameter \\$groupID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotScatter\\(\\) has parameter \\$bubble with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotScatter\\(\\) has parameter \\$groupID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotRadar\\(\\) has parameter \\$groupID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotContour\\(\\) has parameter \\$groupID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPlotStock\\(\\) has parameter \\$groupID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderAreaChart\\(\\) has parameter \\$dimensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderAreaChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderLineChart\\(\\) has parameter \\$dimensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderLineChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderBarChart\\(\\) has parameter \\$dimensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderBarChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderScatterChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderBubbleChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPieChart\\(\\) has parameter \\$dimensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPieChart\\(\\) has parameter \\$doughnut with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPieChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderPieChart\\(\\) has parameter \\$multiplePlots with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderRadarChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderStockChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderContourChart\\(\\) has parameter \\$dimensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderContourChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderCombinationChart\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderCombinationChart\\(\\) has parameter \\$dimensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderCombinationChart\\(\\) has parameter \\$groupCount with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Renderer\\\\JpGraph\\:\\:renderCombinationChart\\(\\) has parameter \\$outputDestination with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\:\\:\\$layout \\(PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Layout\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Chart/Title.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\:\\:getParent\\(\\) should return PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet but returns PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Collection/Cells.php
+
+ -
+ message: "#^Parameter \\#1 \\$string of function substr expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Collection/Cells.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\:\\:getCurrentCoordinate\\(\\) should return string but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Collection/Cells.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function sscanf expects string, string\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Collection/Cells.php
+
+ -
+ message: "#^Parameter \\#1 \\$columnIndex of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:stringFromColumnIndex\\(\\) expects int, int\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Collection/Cells.php
+
+ -
+ message: "#^Possibly invalid array key type \\(array\\|string\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Collection/Cells.php
+
+ -
+ message: "#^Cannot call method detach\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Collection/Cells.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Memory\\:\\:\\$cache has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Collection/Memory.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\:\\:\\$worksheet \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/DefinedName.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\:\\:\\$scope \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/DefinedName.php
+
+ -
+ message: "#^Parameter \\#1 \\$namedRange of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:addNamedRange\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\NamedRange, \\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/DefinedName.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:\\$created \\(int\\) does not accept int\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Document/Properties.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:\\$modified \\(int\\) does not accept int\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Document/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:identifyPropertyType\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Document/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:identifyPropertyType\\(\\) has parameter \\$propertyValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Document/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:convertProperty\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Document/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:convertProperty\\(\\) has parameter \\$propertyValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Document/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\DocumentGenerator\\:\\:getPhpSpreadsheetFunctionText\\(\\) has parameter \\$functionCall with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/DocumentGenerator.php
+
+ -
+ message: "#^Cannot access offset 0 on \\(int\\|string\\)\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/DocumentGenerator.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\HashTable\\:\\:getIndexForHashCode\\(\\) should return int but returns int\\|string\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/HashTable.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$colourMap has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$face has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$size has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$color has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$bold has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$italic has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$underline has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$superscript has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$subscript has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$strikethrough has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$startTagCallbacks has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$endTagCallbacks has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$stack has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:\\$stringData has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$text of method PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\ITextElement\\:\\:setText\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Cannot call method setStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:rgbToColour\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:rgbToColour\\(\\) has parameter \\$rgb with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\:\\:startFontTag\\(\\) has parameter \\$tag with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$function of function call_user_func expects callable\\(\\)\\: mixed, array\\(\\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Html\\), mixed\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$directory of class RecursiveDirectoryIterator constructor expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Sample.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Sample.php
+
+ -
+ message: "#^Parameter \\#1 \\$path of function pathinfo expects string, array\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Sample.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Sample.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Sample\\:\\:getSamples\\(\\) should return array\\\\> but returns array\\\\>\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Sample.php
+
+ -
+ message: "#^Parameter \\#1 \\$filename of function unlink expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Sample.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Helper\\\\Sample\\:\\:log\\(\\) has parameter \\$message with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Helper/Sample.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\IOFactory\\:\\:\\$readers has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/IOFactory.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\IOFactory\\:\\:\\$writers has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/IOFactory.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\BaseReader\\:\\:\\$fileHandle has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/BaseReader.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\BaseReader\\:\\:getSecurityScanner\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/BaseReader.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\:\\:\\$delimiter \\(string\\) does not accept string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv.php
+
+ -
+ message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, array\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\:\\:openFileOrMemory\\(\\) has parameter \\$pFilename with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:convertEncoding\\(\\) expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv.php
+
+ -
+ message: "#^Parameter \\#1 \\$fp of function fwrite expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv.php
+
+ -
+ message: "#^Argument of an invalid type array\\|null supplied for foreach, only iterables are supported\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv.php
+
+ -
+ message: "#^Parameter \\#2 \\$newvalue of function ini_set expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv.php
+
+ -
+ message: "#^Call to function is_array\\(\\) with string will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:\\$fileHandle has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:\\$escapeCharacter has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:\\$enclosure has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:\\$counts has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:\\$numberLines has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:\\$delimiter has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:__construct\\(\\) has parameter \\$enclosure with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:__construct\\(\\) has parameter \\$escapeCharacter with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:__construct\\(\\) has parameter \\$fileHandle with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Csv\\\\Delimiter\\:\\:getNextLine\\(\\) should return string\\|false but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Csv/Delimiter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:\\$referenceHelper has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Parameter \\#1 \\$fp of function fread expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Parameter \\#1 \\$fp of function fclose expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:\\$mappings has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Offset 'No' does not exist on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Offset 'Unit' does not exist on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Offset 'DefaultSizePts' does not exist on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseBorderAttributes\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseBorderAttributes\\(\\) has parameter \\$borderAttributes with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseRichText\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseRichText\\(\\) has parameter \\$is with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseGnumericColour\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Gnumeric\\:\\:parseGnumericColour\\(\\) has parameter \\$gnmColour with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Gnumeric.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:\\$rowspan has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:readBeginning\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:readEnding\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Parameter \\#2 \\$length of function fread expects int, int\\\\|int\\<1, 2048\\>\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:startsWithTag\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:startsWithTag\\(\\) has parameter \\$data with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:endsWithTag\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:endsWithTag\\(\\) has parameter \\$data with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:containsTags\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:containsTags\\(\\) has parameter \\$data with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:\\$dataArray has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:\\$tableLevel has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:\\$nestedColumn has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:setTableStartColumn\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:setTableStartColumn\\(\\) has parameter \\$column with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:getTableStartColumn\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:releaseTableStartColumn\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:flushCell\\(\\) has parameter \\$cellContent with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:flushCell\\(\\) has parameter \\$column with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:flushCell\\(\\) has parameter \\$row with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Argument of an invalid type DOMNamedNodeMap\\|null supplied for foreach, only iterables are supported\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:\\$spanEtc has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:\\$h1Etc has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Parameter \\#2 \\$styleValue of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:setBorderStyle\\(\\) expects string, string\\|null given\\.$#"
+ count: 5
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Alignment\\:\\:setHorizontal\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Alignment\\:\\:setVertical\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:getStyleColor\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Html\\:\\:\\$borderMappings has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Html.php
+
+ -
+ message: "#^Cannot call method getNamespaces\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Cannot call method children\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:listWorksheetNames\\(\\) should return array\\ but returns array\\\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Cannot call method getElementsByTagNameNS\\(\\) on DOMElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Parameter \\#1 \\$element of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:scanElementForText\\(\\) expects DOMNode, DOMElement\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Cannot call method getAttributeNS\\(\\) on DOMElement\\|null\\.$#"
+ 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 call method setSelectedCellByColumnAndRow\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Cannot call method getNamedItem\\(\\) on DOMNamedNodeMap\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^If condition is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#"
+ count: 7
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\:\\:convertToExcelAddressValue\\(\\) should return string but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Parameter \\#3 \\$formula of static method PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\:\\:translateSeparator\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$officeNs has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$stylesNs has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$stylesFo has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$pageLayoutStyles has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$masterStylesCrossReference has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\PageSettings\\:\\:\\$masterPrintStylesCrossReference has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php
+
+ -
+ message: "#^Cannot call method getElementsByTagNameNS\\(\\) on DOMElement\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Ods/PageSettings.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\Properties\\:\\:\\$spreadsheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\Properties\\:\\:load\\(\\) has parameter \\$namespacesMeta with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/Properties.php
+
+ -
+ message: "#^Parameter \\#1 \\$timestamp of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setCreated\\(\\) expects int\\|string\\|null, int\\|false given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Ods/Properties.php
+
+ -
+ message: "#^Parameter \\#1 \\$timestamp of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setModified\\(\\) expects int\\|string\\|null, int\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\Properties\\:\\:setMetaProperties\\(\\) has parameter \\$namespacesMeta with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\Properties\\:\\:setMetaProperties\\(\\) has parameter \\$propertyName with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\Properties\\:\\:setUserDefinedProperty\\(\\) has parameter \\$propertyValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Ods\\\\Properties\\:\\:setUserDefinedProperty\\(\\) has parameter \\$propertyValueAttributes with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Ods/Properties.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Security\\\\XmlScanner\\:\\:\\$callback has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Security/XmlScanner.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Security\\\\XmlScanner\\:\\:\\$libxmlDisableEntityLoaderValue has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Security/XmlScanner.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Security\\\\XmlScanner\\:\\:__construct\\(\\) has parameter \\$pattern with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Security/XmlScanner.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Security\\\\XmlScanner\\:\\:getInstance\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Security/XmlScanner.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Security\\\\XmlScanner\\:\\:threadSafeLibxmlDisableEntityLoaderAvailability\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Security/XmlScanner.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Security\\\\XmlScanner\\:\\:toUtf8\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Security/XmlScanner.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Security\\\\XmlScanner\\:\\:toUtf8\\(\\) has parameter \\$xml with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Security/XmlScanner.php
+
+ -
+ message: "#^Parameter \\#2 \\$subject of function preg_match expects string, array\\\\|string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Security/XmlScanner.php
+
+ -
+ message: "#^Parameter \\#1 \\$haystack of function substr_count expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Slk.php
+
+ -
+ message: "#^Parameter \\#2 \\$str of function explode expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Slk.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Slk\\:\\:\\$colorArray has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Slk.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Slk\\:\\:\\$fontStyleMappings has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Slk.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Slk\\:\\:\\$styleSettingsFont has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Slk.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Slk\\:\\:\\$styleSettingsBorder has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Slk.php
+
+ -
+ message: "#^Parameter \\#1 \\$columnIndex of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:stringFromColumnIndex\\(\\) expects int, string given\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Slk.php
+
+ -
+ message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Slk.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:getDgContainer\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getNestingLevel\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getStartCoordinates\\(\\)\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getEndCoordinates\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getStartOffsetX\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getStartOffsetY\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getEndOffsetX\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getEndOffsetY\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#2 \\$startRow of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Xls\\:\\:getDistanceY\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#4 \\$endRow of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Xls\\:\\:getDistanceY\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#2 \\$row of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Xls\\:\\:sizeRow\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:getOPT\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:getDggContainer\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^If condition is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\MemoryDrawing\\:\\:setImageResource\\(\\) expects GdImage\\|resource, resource\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\BaseDrawing\\:\\:setOffsetX\\(\\) expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\BaseDrawing\\:\\:setOffsetY\\(\\) expects int, float\\|int 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
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Negated boolean expression is always false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$block of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:makeKey\\(\\) expects int, float given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:\\$data \\(string\\) does not accept string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:\\$summaryInformation \\(string\\) does not accept string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:\\$documentSummaryInformation \\(string\\) does not accept string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$codePage of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\CodePage\\:\\:numberToName\\(\\) expects int, int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$title of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setTitle\\(\\) expects string, int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$subject of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setSubject\\(\\) expects string, int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$creator of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setCreator\\(\\) expects string, int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$keywords of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setKeywords\\(\\) expects string, int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$description of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setDescription\\(\\) expects string, int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$modifier of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setLastModifiedBy\\(\\) expects string, int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$codePage of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\CodePage\\:\\:numberToName\\(\\) expects int, bool\\|int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$category of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setCategory\\(\\) expects string, bool\\|int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$manager of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setManager\\(\\) expects string, bool\\|int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$company of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setCompany\\(\\) expects string, bool\\|int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#2 \\$pos of static method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:getUInt2d\\(\\) expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#2 \\$pos of static method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:getInt4d\\(\\) expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#2 \\$start of function substr expects int, float\\|int given\\.$#"
+ count: 5
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:setShowSummaryBelow\\(\\) expects bool, int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:setShowSummaryRight\\(\\) expects bool, int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:includeCellRangeFiltered\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:includeCellRangeFiltered\\(\\) has parameter \\$cellRangeAddress with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataValidation\\:\\:setType\\(\\) expects string, int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataValidation\\:\\:setErrorStyle\\(\\) expects string, int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\DataValidation\\:\\:setOperator\\(\\) expects string, int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 8
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Cannot access offset 1 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:parseRichText\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\:\\:parseRichText\\(\\) has parameter \\$is with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\Color\\\\BIFF5\\:\\:\\$map has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Color/BIFF5.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\Color\\\\BIFF8\\:\\:\\$map has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Color/BIFF8.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\Color\\\\BuiltIn\\:\\:\\$map has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Color/BuiltIn.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\ErrorCode\\:\\:\\$map has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/ErrorCode.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setDggContainer\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setBstoreContainer\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:addBSE\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setBlip\\(\\)\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setDgContainer\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:addChild\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:addChild\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setStartCoordinates\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setStartOffsetX\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setStartOffsetY\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setEndCoordinates\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setEndOffsetX\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setEndOffsetY\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\\\SpContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\|PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setOPT\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Escher.php
+
+ -
+ message: "#^Parameter \\#1 \\$input of function array_values expects array, array\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/MD5.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\MD5\\:\\:f\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/MD5.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\MD5\\:\\:g\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/MD5.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\MD5\\:\\:h\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/MD5.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\MD5\\:\\:i\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/MD5.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\MD5\\:\\:step\\(\\) has parameter \\$func with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/MD5.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\MD5\\:\\:rotate\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/MD5.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\RC4\\:\\:\\$s has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/RC4.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\RC4\\:\\:\\$i has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/RC4.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\RC4\\:\\:\\$j has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/RC4.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\Style\\\\Border\\:\\:\\$map has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Style/Border.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xls\\\\Style\\\\FillPattern\\:\\:\\$map has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xls/Style/FillPattern.php
+
+ -
+ message: "#^Cannot access property \\$Relationship on SimpleXMLElement\\|false\\.$#"
+ count: 12
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$sheets on SimpleXMLElement\\|false\\.$#"
+ count: 6
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot call method registerXPathNamespace\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToBoolean\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToBoolean\\(\\) has parameter \\$c with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToError\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToError\\(\\) has parameter \\$c with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToString\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToString\\(\\) has parameter \\$c with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$c with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$calculatedValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$castBaseType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$cellDataType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$r with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$sharedFormulas with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:castToFormula\\(\\) has parameter \\$value with no typehint 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: "#^Offset 'name' does not exist on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot call method xpath\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Parameter \\#1 \\$is of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:parseRichText\\(\\) expects SimpleXMLElement\\|null, object given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Parameter \\#1 \\$styleXml of class PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles constructor expects SimpleXMLElement, SimpleXMLElement\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$workbookPr on SimpleXMLElement\\|false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Parameter \\#2 \\$xmlWorkbook of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readProtection\\(\\) expects SimpleXMLElement, SimpleXMLElement\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Parameter \\#1 \\$relsWorksheet of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Hyperlinks\\:\\:readHyperlinks\\(\\) expects SimpleXMLElement, SimpleXMLElement\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$authors on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$commentList on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Argument of an invalid type array\\\\|false supplied for foreach, only iterables are supported\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Negated boolean expression is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$drawing on SimpleXMLElement\\|false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot call method children\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot call method count\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot call method asXML\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$definedNames on SimpleXMLElement\\|false\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Argument of an invalid type array\\\\|false supplied for foreach, only iterables are supported\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Parameter \\#1 \\$pName of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getSheetByName\\(\\) expects string, array\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access offset 0 on array\\\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$bookViews on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$Default on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$Override on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Parameter \\#1 \\$chartElements of static method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readChart\\(\\) expects SimpleXMLElement, SimpleXMLElement\\|false given\\.$#"
+ count: 1
+ 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: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readColor\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readColor\\(\\) has parameter \\$background with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readColor\\(\\) has parameter \\$color with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Parameter \\#1 \\$hex of static method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Color\\:\\:changeBrightness\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\:\\:setSize\\(\\) expects float, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Cannot access property \\$r on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ 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 setColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|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 setItalic\\(\\) 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 setSubscript\\(\\) 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 call method setStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has parameter \\$array with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:getArrayItem\\(\\) has parameter \\$key with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:dirAdd\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:dirAdd\\(\\) has parameter \\$add with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:dirAdd\\(\\) has parameter \\$base with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:toCSSArray\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:toCSSArray\\(\\) has parameter \\$style with no typehint specified\\.$#"
+ 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 \\#3 \\$subject of function str_replace expects array\\|string, int\\|string given\\.$#"
+ count: 2
+ 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 \\#1 \\$sizeInCm of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:centimeterSizeToPixels\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:stripWhiteSpaceFromStyleString\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:stripWhiteSpaceFromStyleString\\(\\) has parameter \\$string with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:boolean\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:boolean\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Offset 'id' does not exist on SimpleXMLElement\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$dir with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$docSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readFormControlProperties\\(\\) has parameter \\$fileWorksheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$dir with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$docSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\:\\:readPrinterSettings\\(\\) has parameter \\$fileWorksheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:\\$worksheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:\\$worksheetXml has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:readAutoFilter\\(\\) has parameter \\$autoFilterRange with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\AutoFilter\\:\\:readAutoFilter\\(\\) has parameter \\$xmlSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#1 \\$pOperator of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:setRule\\(\\) expects string, null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xlsx/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\BaseParserClass\\:\\:boolean\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\BaseParserClass\\:\\:boolean\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/BaseParserClass.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readColor\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readColor\\(\\) has parameter \\$background with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readColor\\(\\) has parameter \\$color with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#1 \\$position of class PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend constructor expects string, bool\\|float\\|int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#3 \\$overlay of class PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Legend constructor expects bool, bool\\|float\\|int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#6 \\$displayBlanksAs of class PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart constructor expects string, bool\\|float\\|int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartTitle\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartLayoutDetails\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartLayoutDetails\\(\\) has parameter \\$chartDetail with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartLayoutDetails\\(\\) has parameter \\$namespacesChartMeta with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeries\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeries\\(\\) has parameter \\$chartDetail with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeries\\(\\) has parameter \\$namespacesChartMeta with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeries\\(\\) has parameter \\$plotType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#3 \\$plotOrder of class PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeries constructor expects array\\, array\\ given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#7 \\$plotDirection of class PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeries constructor expects string\\|null, bool\\|float\\|int\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValueSet\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValueSet\\(\\) has parameter \\$marker with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValueSet\\(\\) has parameter \\$namespacesChartMeta with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValueSet\\(\\) has parameter \\$seriesDetail with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#4 \\$pointCount of class PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues constructor expects int, null given\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValues\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValues\\(\\) has parameter \\$dataType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValues\\(\\) has parameter \\$seriesValueSet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValuesMultiLevel\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValuesMultiLevel\\(\\) has parameter \\$dataType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:chartDataSeriesValuesMultiLevel\\(\\) has parameter \\$seriesValueSet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:parseRichText\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method getFont\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\Run\\|null\\.$#"
+ count: 12
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method setStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readChartAttributes\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Chart\\:\\:readChartAttributes\\(\\) has parameter \\$chartDetail with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:\\$worksheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:\\$worksheetXml has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredColumn\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredColumn\\(\\) has parameter \\$columnCoordinate with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnAttributes\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnAttributes\\(\\) has parameter \\$readDataOnly with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnRangeAttributes\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readColumnRangeAttributes\\(\\) has parameter \\$readDataOnly with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredRow\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:isFilteredRow\\(\\) has parameter \\$rowCoordinate with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readRowAttributes\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ColumnAndRowAttributes\\:\\:readRowAttributes\\(\\) has parameter \\$readDataOnly with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ColumnAndRowAttributes.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$worksheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$worksheetXml has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:\\$dxfs has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readConditionalStyles\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readConditionalStyles\\(\\) has parameter \\$xmlSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:setConditionalStyles\\(\\) has parameter \\$xmlExtLst with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has parameter \\$cfRules with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readStyleRules\\(\\) has parameter \\$extLst with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarOfConditionalRule\\(\\) has parameter \\$cfRule with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarOfConditionalRule\\(\\) has parameter \\$conditionalFormattingRuleExtensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarExtLstOfConditionalRule\\(\\) has parameter \\$cfRule with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\ConditionalStyles\\:\\:readDataBarExtLstOfConditionalRule\\(\\) has parameter \\$conditionalFormattingRuleExtensions with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\DataValidations\\:\\:\\$worksheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\DataValidations\\:\\:\\$worksheetXml has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/DataValidations.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Hyperlinks\\:\\:\\$worksheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Hyperlinks\\:\\:\\$hyperlinks has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:\\$worksheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:\\$worksheetXml has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:load\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\PageSetup\\:\\:pageSetup\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/PageSetup.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:\\$securityScanner has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:\\$docProps has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:extractPropertyData\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:extractPropertyData\\(\\) has parameter \\$propertyData with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:readCoreProperties\\(\\) has parameter \\$propertyData with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:registerXPathNamespace\\(\\)\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Call to an undefined method object\\:\\:xpath\\(\\)\\.$#"
+ count: 9
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:readExtendedProperties\\(\\) has parameter \\$propertyData with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:readCustomProperties\\(\\) has parameter \\$propertyData with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Argument of an invalid type object supplied for foreach, only iterables are supported\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:getArrayItem\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Properties\\:\\:getArrayItem\\(\\) has parameter \\$key with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Properties.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\SheetViewOptions\\:\\:\\$worksheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\SheetViewOptions\\:\\:\\$worksheetXml has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/SheetViewOptions.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\SheetViews\\:\\:\\$sheetViewXml has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/SheetViews.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\SheetViews\\:\\:\\$worksheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/SheetViews.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:\\$styles has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:\\$cellStyles has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:\\$styleXml has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:setStyleBaseData\\(\\) has parameter \\$cellStyles with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:setStyleBaseData\\(\\) has parameter \\$styles with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Static property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:\\$theme \\(PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Theme\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Theme\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Cannot call method count\\(\\) on SimpleXMLElement\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readStyle\\(\\) has parameter \\$style with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Parameter \\#2 \\$alignmentXml of static method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readAlignmentStyle\\(\\) expects SimpleXMLElement, object given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readProtectionLocked\\(\\) has parameter \\$style with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readProtectionHidden\\(\\) has parameter \\$style with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readColor\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readColor\\(\\) has parameter \\$background with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:readColor\\(\\) has parameter \\$color with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Parameter \\#1 \\$hex of static method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Color\\:\\:changeBrightness\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:dxfs\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:dxfs\\(\\) has parameter \\$readDataOnly with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:styles\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:getArrayItem\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:getArrayItem\\(\\) has parameter \\$array with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xlsx\\\\Styles\\:\\:getArrayItem\\(\\) has parameter \\$key with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:\\$fileContents has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:\\$mappings has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Parameter \\#1 \\$haystack of function strpos expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:convertEncoding\\(\\) expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Cannot call method getNamespaces\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Cannot call method children\\(\\) on SimpleXMLElement\\|false\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:identifyFixedStyleValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:identifyFixedStyleValue\\(\\) has parameter \\$styleAttributeValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:identifyFixedStyleValue\\(\\) has parameter \\$styleList with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:hex2str\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:hex2str\\(\\) has parameter \\$hex with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Cannot access property \\$DocumentProperties on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Parameter \\#1 \\$timestamp of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setCreated\\(\\) expects int\\|string\\|null, int\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Parameter \\#1 \\$timestamp of method PhpOffice\\\\PhpSpreadsheet\\\\Document\\\\Properties\\:\\:setModified\\(\\) expects int\\|string\\|null, int\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Parameter \\#2 \\$callback of function preg_replace_callback expects callable\\(\\)\\: mixed, array\\('self', 'hex2str'\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Parameter \\#1 \\$xml of method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:parseStyles\\(\\) expects SimpleXMLElement, SimpleXMLElement\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Cannot access property \\$Names on SimpleXMLElement\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:parseRichText\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:parseRichText\\(\\) has parameter \\$is with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:\\$borderPositions has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:parseStyleBorders\\(\\) has parameter \\$styleID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:\\$underlineStyles has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:parseStyleInterior\\(\\) has parameter \\$styleID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Reader\\\\Xml\\:\\:parseStyleNumberFormat\\(\\) has parameter \\$styleID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Reader/Xml.php
+
+ -
+ message: "#^Parameter \\#2 \\$cmp_function of function uksort expects callable\\(mixed, mixed\\)\\: int, array\\('self', 'cellReverseSort'\\) given\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Parameter \\#2 \\$cmp_function of function uksort expects callable\\(mixed, mixed\\)\\: int, array\\('self', 'cellSort'\\) given\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Parameter \\#2 \\$pPassword of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:protectCells\\(\\) expects string, array given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Parameter \\#1 \\$index of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\:\\:setRowIndex\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method getRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method setRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method getVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method getOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method setOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method getCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method setCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Parameter \\#1 \\$columnIndex of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:stringFromColumnIndex\\(\\) expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Parameter \\#1 \\$pCellRange of method PhpOffice\\\\PhpSpreadsheet\\\\ReferenceHelper\\:\\:updateCellReference\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/ReferenceHelper.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\Run\\:\\:\\$font \\(PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/RichText/Run.php
+
+ -
+ message: "#^Result of && is always false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Settings.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between int and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Settings.php
+
+ -
+ message: "#^Negated boolean expression is always false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Settings.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:getHttpClient\\(\\) should return Psr\\\\Http\\\\Client\\\\ClientInterface but returns Psr\\\\Http\\\\Client\\\\ClientInterface\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Settings.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Settings\\:\\:getRequestFactory\\(\\) should return Psr\\\\Http\\\\Message\\\\RequestFactoryInterface but returns Psr\\\\Http\\\\Message\\\\RequestFactoryInterface\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Settings.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\CodePage\\:\\:\\$pageArray has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/CodePage.php
+
+ -
+ message: "#^Parameter \\#1 \\$dateValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Date\\:\\:timestampToExcel\\(\\) expects int, float\\|int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Date.php
+
+ -
+ message: "#^Parameter \\#1 \\$string of function substr expects string, int given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Shared/Date.php
+
+ -
+ message: "#^Parameter \\#1 \\$pFormatCode of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Date\\:\\:isDateTimeFormatCode\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Date.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Date\\:\\:\\$possibleDateFormatCharacters has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Date.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Drawing\\:\\:pixelsToCellDimension\\(\\) should return int but returns float\\|int\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#1 \\$fp of function fread expects resource, resource\\|false given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#1 \\$fp of function feof expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#2 \\$data of function unpack expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Cannot access offset 1 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#1 \\$x_size of function imagecreatetruecolor expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#2 \\$y_size of function imagecreatetruecolor expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagecolorallocate expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#2 \\$red of function imagecolorallocate expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#3 \\$green of function imagecolorallocate expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#4 \\$blue of function imagecolorallocate expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagesetpixel expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#3 \\$y of function imagesetpixel expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Parameter \\#4 \\$col of function imagesetpixel expects int, int\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Drawing\\:\\:imagecreatefrombmp\\(\\) should return GdImage\\|resource but returns resource\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Drawing.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:\\$spgrContainer has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:getDgId\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:setDgId\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:getLastSpId\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:setLastSpId\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:getSpgrContainer\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:setSpgrContainer\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\:\\:setSpgrContainer\\(\\) has parameter \\$spgrContainer with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DgContainer\\\\SpgrContainer\\:\\:getChildren\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Escher/DgContainer/SpgrContainer.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between string\\|false and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/File.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\File\\:\\:realpath\\(\\) should return string but returns string\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/File.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\File\\:\\:sysGetTempDir\\(\\) should return string but returns string\\|false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Shared/File.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:\\$autoSizeMethods has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Drawing\\:\\:pixelsToCellDimension\\(\\) expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Parameter \\#2 \\$pDefaultFont of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Drawing\\:\\:pixelsToCellDimension\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Parameter \\#1 \\$size of function imagettfbbox expects float, float\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Cannot access offset 0 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Cannot access offset 2 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Cannot access offset 4 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Cannot access offset 6 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Font.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\EigenvalueDecomposition\\:\\:\\$e has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\EigenvalueDecomposition\\:\\:\\$cdivi has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php
+
+ -
+ message: "#^Else branch is unreachable because previous condition is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\LUDecomposition\\:\\:getDoublePivot\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:__construct\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 19
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:getMatrix\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:plus\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:plusEquals\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Call to function is_string\\(\\) with float\\|int will always evaluate to false\\.$#"
+ count: 5
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Result of && is always false\\.$#"
+ count: 10
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:minus\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:minusEquals\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:arrayTimes\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:arrayTimesEquals\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:arrayRightDivide\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Parameter \\#3 \\$c of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:set\\(\\) expects float\\|int\\|null, string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:arrayRightDivideEquals\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:arrayLeftDivide\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:arrayLeftDivideEquals\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:times\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:power\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\JAMA\\\\Matrix\\:\\:concat\\(\\) has parameter \\$args with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function trim expects string, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+
+ -
+ message: "#^Left side of && is always true\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php
+
+ -
+ message: "#^If condition is always true\\.$#"
+ count: 7
+ path: src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\:\\:getStream\\(\\) should return resource but returns resource\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#2 \\$data of function unpack expects string, string\\|false given\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#1 \\$string of function substr expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#1 \\$time_1st of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#2 \\$time_2nd of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#1 \\$No of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#2 \\$name of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects string, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#3 \\$type of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#4 \\$prev of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#5 \\$next of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#6 \\$dir of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#7 \\$time_1st of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#8 \\$time_2nd of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#9 \\$data of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS constructor expects string, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#1 \\$oleTimestamp of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\:\\:OLE2LocalDate\\(\\) expects string, string\\|false given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\:\\:getData\\(\\) should return string but returns string\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Cannot access offset 3 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Cannot access offset 4 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Cannot access offset 1 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Cannot access offset 2 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE.php
+
+ -
+ message: "#^Parameter \\#1 \\$var of function count expects array\\|Countable, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php
+
+ -
+ message: "#^Parameter \\#3 \\$length of function array_slice expects int\\|null, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS.php
+
+ -
+ message: "#^Parameter \\#2 \\$offset of function array_slice expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS.php
+
+ -
+ message: "#^Parameter \\#1 \\$No of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/File.php
+
+ -
+ message: "#^Parameter \\#4 \\$prev of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/File.php
+
+ -
+ message: "#^Parameter \\#5 \\$next of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/File.php
+
+ -
+ message: "#^Parameter \\#6 \\$dir of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/File.php
+
+ -
+ message: "#^Parameter \\#7 \\$time_1st of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/File.php
+
+ -
+ message: "#^Parameter \\#8 \\$time_2nd of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/File.php
+
+ -
+ message: "#^Parameter \\#1 \\$No of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#4 \\$prev of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#5 \\$next of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#6 \\$dir of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#9 \\$data of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\:\\:__construct\\(\\) expects string, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#1 \\$iSBDcnt of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root\\:\\:saveHeader\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#2 \\$iBBcnt of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root\\:\\:saveHeader\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#3 \\$iPPScnt of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root\\:\\:saveHeader\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#1 \\$iStBlk of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root\\:\\:saveBigData\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#1 \\$iSbdSize of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root\\:\\:saveBbd\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#2 \\$iBsize of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root\\:\\:saveBbd\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Parameter \\#3 \\$iPpsCnt of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLE\\\\PPS\\\\Root\\:\\:saveBbd\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLERead\\:\\:\\$data has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLERead.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLERead\\:\\:\\$wrkbook has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLERead.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLERead\\:\\:\\$summaryInformation has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLERead.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLERead\\:\\:\\$documentSummaryInformation has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLERead.php
+
+ -
+ message: "#^Parameter \\#1 \\$data of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\OLERead\\:\\:getInt4d\\(\\) expects string, string\\|false given\\.$#"
+ count: 8
+ path: src/PhpSpreadsheet/Shared/OLERead.php
+
+ -
+ message: "#^Parameter \\#1 \\$string of function substr expects string, string\\|false given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Shared/OLERead.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between int and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/OLERead.php
+
+ -
+ message: "#^Argument of an invalid type array\\\\|false supplied for foreach, only iterables are supported\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/PasswordHasher.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:sanitizeUTF8\\(\\) should return string but returns string\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:formatNumber\\(\\) should return string but returns array\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:countCharacters\\(\\) should return int but returns int\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:mbIsUpper\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:mbIsUpper\\(\\) has parameter \\$char with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:mbStrSplit\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:mbStrSplit\\(\\) has parameter \\$string with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Parameter \\#1 \\$string of function strlen expects string, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/StringHelper.php
+
+ -
+ message: "#^Else branch is unreachable because previous condition is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/TimeZone.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$goodnessOfFit has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$stdevOfResiduals has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$covariance has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$correlation has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$SSRegression has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$SSResiduals has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$DFResiduals has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$f has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$slope has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$slopeSE has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$intersect has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$intersectSE has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$xOffset has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:\\$yOffset has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:getError\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:getBestFitType\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$const with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$meanX with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$meanY with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumX with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumX2 with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumXY with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumY with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:calculateGoodnessOfFit\\(\\) has parameter \\$sumY2 with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\BestFit\\:\\:sumSquares\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/BestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\PolynomialBestFit\\:\\:getCoefficients\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\PolynomialBestFit\\:\\:getCoefficients\\(\\) has parameter \\$dp with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php
+
+ -
+ message: "#^Parameter \\#2 \\.\\.\\.\\$args of function array_merge expects array, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/Trend.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$const with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/Trend.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$trendType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/Trend.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$xValues with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/Trend.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\Trend\\:\\:calculate\\(\\) has parameter \\$yValues with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Trend/Trend.php
+
+ -
+ message: "#^Parameter \\#1 \\$order of class PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Trend\\\\PolynomialBestFit constructor expects int, string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Shared/Trend/Trend.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\XMLWriter\\:\\:\\$debugEnabled has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/XMLWriter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\XMLWriter\\:\\:\\$tempFileName \\(string\\) does not accept string\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/XMLWriter.php
+
+ -
+ message: "#^Parameter \\#1 \\$uri of method XMLWriter\\:\\:openUri\\(\\) expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/XMLWriter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\XMLWriter\\:\\:getData\\(\\) should return string but returns string\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/XMLWriter.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Drawing\\:\\:pointsToPixels\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$fontSizeInPoints of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:fontSizeToPixels\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Shared/Xls.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:\\$workbookViewVisibilityValues has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Call to function is_array\\(\\) with string will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$pSheet of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getIndex\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet, PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Cannot call method getTitle\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Comparison operation \"\\<\\=\" between int\\ and 1000 is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Result of \\|\\| is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Spreadsheet.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getSharedComponent\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Alignment.php
+
+ -
+ message: "#^Parameter \\#1 \\$parent of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Supervisor\\:\\:bindParent\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style, \\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Border\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Border.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getSharedComponent\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Border.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getStyleArray\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Border.php
+
+ -
+ message: "#^Right side of && is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Border.php
+
+ -
+ message: "#^Parameter \\#1 \\$parent of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Supervisor\\:\\:bindParent\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style, \\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Borders\\) given\\.$#"
+ count: 10
+ path: src/PhpSpreadsheet/Style/Borders.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getSharedComponent\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Borders.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getSharedComponent\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Color.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Border\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Fill\\:\\:getEndColor\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Color.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Border\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Fill\\:\\:getStartColor\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Color.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Border\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Fill\\:\\:getColor\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Color.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getStyleArray\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Color.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Color\\:\\:getColourComponent\\(\\) should return int\\|string but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Color.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Conditional\\:\\:\\$condition \\(array\\\\) does not accept array\\\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Conditional.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Conditional\\:\\:\\$style \\(PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Conditional.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBar\\:\\:setShowValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBar\\:\\:setMinimumConditionalFormatValueObject\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBar\\:\\:setMaximumConditionalFormatValueObject\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBar\\:\\:setConditionalFormattingRuleExt\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBarExtension\\:\\:getXmlAttributes\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBarExtension\\:\\:getXmlElements\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBarExtension\\:\\:setMaximumConditionalFormatValueObject\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalDataBarExtension\\:\\:setMinimumConditionalFormatValueObject\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormatValueObject\\:\\:\\$type has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormatValueObject\\:\\:\\$value has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormatValueObject\\:\\:\\$cellFormula has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormatValueObject\\:\\:__construct\\(\\) has parameter \\$type with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormatValueObject\\:\\:__construct\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormatValueObject\\:\\:setType\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormatValueObject\\:\\:setValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormatValueObject\\:\\:setCellFormula\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormattingRuleExtension\\:\\:\\$id has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormattingRuleExtension\\:\\:__construct\\(\\) has parameter \\$id with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormattingRuleExtension\\:\\:generateUuid\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormattingRuleExtension\\:\\:parseExtLstXml\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormattingRuleExtension\\:\\:parseExtLstXml\\(\\) has parameter \\$extLstXml with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Cannot access property \\$minLength on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Cannot access property \\$maxLength on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Cannot access property \\$border on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Cannot access property \\$gradient on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Cannot access property \\$direction on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Cannot access property \\$negativeBarBorderColorSameAsPositive on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Cannot access property \\$axisPosition on SimpleXMLElement\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\ConditionalFormatting\\\\ConditionalFormattingRuleExtension\\:\\:parseExtDataBarElementChildrenFromXml\\(\\) has parameter \\$ns with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Offset 'rgb' does not exist on SimpleXMLElement\\|null\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Offset 'theme' does not exist on SimpleXMLElement\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Offset 'tint' does not exist on SimpleXMLElement\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
+
+ -
+ message: "#^Parameter \\#1 \\$parent of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Supervisor\\:\\:bindParent\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style, \\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Fill\\) given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/Fill.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getSharedComponent\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Fill.php
+
+ -
+ message: "#^Parameter \\#1 \\$parent of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Supervisor\\:\\:bindParent\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style, \\$this\\(PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Font.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getSharedComponent\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Font.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getSharedComponent\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\:\\:\\$builtInFormatCode \\(int\\|false\\) does not accept bool\\|int\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\DateFormatter\\:\\:format\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Parameter \\#2 \\$callback of function preg_replace_callback expects callable\\(\\)\\: mixed, array\\('self', 'setLowercaseCallback'\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function preg_replace_callback expects array\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Parameter \\#2 \\$str of function explode expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Parameter \\#2 \\$replace of function str_replace expects array\\|string, int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Parameter \\#2 \\$callback of function preg_replace_callback expects callable\\(\\)\\: mixed, array\\('self', 'escapeQuotesCallback'\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Parameter \\#1 \\$format of method DateTime\\:\\:format\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\DateFormatter\\:\\:setLowercaseCallback\\(\\) has parameter \\$matches with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\DateFormatter\\:\\:escapeQuotesCallback\\(\\) has parameter \\$matches with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/DateFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormatCompare\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormatCompare\\(\\) has parameter \\$cond with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormatCompare\\(\\) has parameter \\$dfcond with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormatCompare\\(\\) has parameter \\$dfval with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormatCompare\\(\\) has parameter \\$val with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormatCompare\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormat\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormat\\(\\) has parameter \\$sections with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:splitFormat\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\Formatter\\:\\:toFormattedString\\(\\) should return string but returns float\\|int\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Parameter \\#2 \\$subject of function preg_split expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\FractionFormatter\\:\\:format\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/FractionFormatter.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function trim expects string, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/FractionFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:mergeComplexNumberFormatMasks\\(\\) has parameter \\$masks with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:mergeComplexNumberFormatMasks\\(\\) has parameter \\$numbers with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:processComplexNumberFormatMask\\(\\) has parameter \\$mask with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:processComplexNumberFormatMask\\(\\) has parameter \\$number with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:complexNumberFormatMask\\(\\) has parameter \\$mask with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:complexNumberFormatMask\\(\\) has parameter \\$number with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:complexNumberFormatMask\\(\\) has parameter \\$splitOnPoint with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Parameter \\#1 \\$haystack of function strpos expects string, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Parameter \\#2 \\$str of function explode expects string, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:formatStraightNumericValue\\(\\) has parameter \\$format with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:formatStraightNumericValue\\(\\) has parameter \\$useThousands with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:formatStraightNumericValue\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:format\\(\\) has parameter \\$format with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\NumberFormatter\\:\\:format\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, array\\|string\\|null given\\.$#"
+ count: 6
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Parameter \\#2 \\$subject of function preg_match expects string, array\\|string\\|null given\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Parameter \\#2 \\$format of static method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\FractionFormatter\\:\\:format\\(\\) expects string, array\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/NumberFormat/NumberFormatter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\NumberFormat\\\\PercentageFormatter\\:\\:format\\(\\) has parameter \\$value with no typehint specified\\.$#"
+ 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: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getSharedComponent\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Protection.php
+
+ -
+ message: "#^Call to an undefined method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getCellXfByIndex\\(\\)\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Style.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\:\\:getParent\\(\\) should return PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet but returns PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Style\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Style.php
+
+ -
+ message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/Style.php
+
+ -
+ message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Style.php
+
+ -
+ message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Style/Style.php
+
+ -
+ message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Style.php
+
+ -
+ message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Style/Style.php
+
+ -
+ message: "#^Cannot call method setXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Style/Style.php
+
+ -
+ message: "#^Result of && is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#1 \\$excelTimestamp of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Date\\:\\:excelToTimestamp\\(\\) expects float\\|int, float\\|int\\|string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#1 \\$number of function floor expects float, float\\|int\\<1, max\\>\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:\\$toReplace has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#2 \\$now of function strtotime expects int, int\\|false given\\.$#"
+ count: 6
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#5 \\$day of function gmmktime expects int, string given\\.$#"
+ count: 8
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#6 \\$year of function gmmktime expects int, string given\\.$#"
+ count: 13
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#4 \\$mon of function gmmktime expects int, string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#5 \\$day of function gmmktime expects int, float given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#1 \\$attributes of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\:\\:setAttributes\\(\\) expects array\\, array\\ given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$columnID with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$endRow with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$ruleType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$ruleValue with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:calculateTopTenValue\\(\\) has parameter \\$startRow with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot call method rangeToArray\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot call method getRowDimension\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot assign offset 'year' to array\\\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot assign offset 'month' to array\\\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot assign offset 'day' to array\\\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot assign offset 'hour' to array\\\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot assign offset 'minute' to array\\\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot assign offset 'second' to array\\\\|string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function preg_quote expects string, array\\\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Binary operation \"\\*\" between 0\\|array\\\\|string and float\\|int results in an error\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Left side of && is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Parameter \\#1 \\$function of function call_user_func_array expects callable\\(\\)\\: mixed, array\\('PhpOffice\\\\\\\\PhpSpreadsheet\\\\\\\\Worksheet\\\\\\\\AutoFilter', mixed\\) given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$ruleTypes has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$dateTimeGroups has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$dynamicTypes has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$operators has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$topTenValue has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$topTenType has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\\\Rule\\:\\:\\$parent \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\\\Column\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+
+ -
+ message: "#^Cannot call method getCell\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/BaseDrawing.php
+
+ -
+ message: "#^Cannot call method getDrawingCollection\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/BaseDrawing.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\BaseDrawing\\:\\:\\$shadow \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Drawing\\\\Shadow\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Drawing\\\\Shadow\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/BaseDrawing.php
+
+ -
+ message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/BaseDrawing.php
+
+ -
+ message: "#^Class PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\CellIterator implements generic interface Iterator but does not specify its types\\: TKey, TValue$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/CellIterator.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\CellIterator\\:\\:adjustForExistingOnlyRange\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/CellIterator.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Column\\:\\:\\$parent \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Column.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\CellIterator\\:\\:\\$worksheet \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php
+
+ -
+ message: "#^Class PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnIterator implements generic interface Iterator but does not specify its types\\: TKey, TValue$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/ColumnIterator.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Drawing\\\\Shadow\\:\\:\\$color \\(PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Color\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Color\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Drawing/Shadow.php
+
+ -
+ message: "#^Class PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Iterator implements generic interface Iterator but does not specify its types\\: TKey, TValue$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Iterator.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagesx expects resource, GdImage\\|resource given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagesy expects resource, GdImage\\|resource given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\PageSetup\\:\\:\\$pageOrder has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/PageSetup.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between int\\ and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/PageSetup.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\PageSetup\\:\\:getPrintArea\\(\\) should return string but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/PageSetup.php
+
+ -
+ message: "#^Parameter \\#2 \\$str of function explode expects string, string\\|null given\\.$#"
+ count: 5
+ path: src/PhpSpreadsheet/Worksheet/PageSetup.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\PageSetup\\:\\:setFirstPageNumber\\(\\) expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/PageSetup.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Row\\:\\:\\$worksheet \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Row.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\CellIterator\\:\\:\\$worksheet \\(PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/RowCellIterator.php
+
+ -
+ message: "#^Class PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowIterator implements generic interface Iterator but does not specify its types\\: TKey, TValue$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/RowIterator.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\SheetView\\:\\:\\$sheetViewTypes has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/SheetView.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between int\\ and null will always evaluate to false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/SheetView.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/SheetView.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:\\$drawingCollection with generic class ArrayObject does not specify its types\\: TKey, TValue$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:\\$chartCollection with generic class ArrayObject does not specify its types\\: TKey, TValue$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:\\$parent \\(PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$pIndex of class PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension constructor expects int, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$pIndex of class PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension constructor expects string, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$pRange of class PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter constructor expects string, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getDrawingCollection\\(\\) return type with generic class ArrayObject does not specify its types\\: TKey, TValue$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getChartCollection\\(\\) return type with generic class ArrayObject does not specify its types\\: TKey, TValue$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$input of function array_splice expects array, ArrayObject&iterable\\ given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between string and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$pRange of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:rangeDimension\\(\\) expects string, string\\|false 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
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#3 \\$rotation of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:calculateColumnWidth\\(\\) expects int, int\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^If condition is always true\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Left side of && is always true\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method renameCalculationCacheForWorksheet\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Calculation\\\\Calculation\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method setValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method setValueExplicit\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$start of function substr expects int, int\\<0, max\\>\\|false given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$pRow of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getRowDimension\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Result of && is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$pRange of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\AutoFilter\\:\\:setRange\\(\\) expects string, null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getFreezePane\\(\\) should return string but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\:\\:removeRow\\(\\) expects string, int given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$coord of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:coordinateIsRange\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$pRange of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:splitRange\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:\\$activeCell \\(string\\) does not accept string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:\\$selectedCells \\(string\\) does not accept string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method getValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method getCalculatedValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Right side of && is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method getWorksheet\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method getValue\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\DefinedName\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Cannot call method rangeToArray\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Worksheet/Worksheet.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Csv\\:\\:\\$enclosureRequired has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Csv.php
+
+ -
+ message: "#^Call to function array_key_exists\\(\\) with int and array\\('none' \\=\\> 'none', 'dashDot' \\=\\> '1px dashed', 'dashDotDot' \\=\\> '1px dotted', 'dashed' \\=\\> '1px dashed', 'dotted' \\=\\> '1px dotted', 'double' \\=\\> '3px double', 'hair' \\=\\> '1px solid', 'medium' \\=\\> '2px solid', \\.\\.\\.\\) will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:getSheetIndex\\(\\) should return int but returns int\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateMeta\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateMeta\\(\\) has parameter \\$desc with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateMeta\\(\\) has parameter \\$val with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetPrep\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetStarts\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetStarts\\(\\) has parameter \\$rowMin with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetStarts\\(\\) has parameter \\$sheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has parameter \\$row with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has parameter \\$tbodyStart with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has parameter \\$theadEnd with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateSheetTags\\(\\) has parameter \\$theadStart with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$string of function htmlspecialchars expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Cannot access offset 'mime' on array\\|false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagepng expects resource, GdImage\\|resource given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$str of function base64_encode expects string, string\\|false given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Ternary operator condition is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#3 \\$use_include_path of function fopen expects bool, int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#2 \\$length of function fread expects int, int\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Cannot access offset 0 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Cannot access offset 1 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$vAlign of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:mapVAlign\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$hAlign of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:mapHAlign\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$borderStyle of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:mapBorderStyle\\(\\) expects int, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateHTMLFooter\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTagInline\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTagInline\\(\\) has parameter \\$id with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTagInline\\(\\) has parameter \\$pSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTag\\(\\) has parameter \\$html with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTag\\(\\) has parameter \\$id with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTag\\(\\) has parameter \\$pSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableTag\\(\\) has parameter \\$sheetIndex with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateTableFooter\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has parameter \\$cellAddress with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has parameter \\$colNum with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has parameter \\$pRow with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellCss\\(\\) has parameter \\$pSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValueRich\\(\\) has parameter \\$cell with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValueRich\\(\\) has parameter \\$cellData with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Parameter \\#1 \\$pStyle of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:createCSSStyleFont\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Cannot call method getSuperscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Cannot call method getSubscript\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValue\\(\\) has parameter \\$cell with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValue\\(\\) has parameter \\$cellData with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellDataValue\\(\\) has parameter \\$pSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has parameter \\$cell with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has parameter \\$cellType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has parameter \\$cssClass with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowCellData\\(\\) has parameter \\$pSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowIncludeCharts\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowIncludeCharts\\(\\) has parameter \\$coordinate with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowIncludeCharts\\(\\) has parameter \\$pSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowSpans\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowSpans\\(\\) has parameter \\$colSpan with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowSpans\\(\\) has parameter \\$html with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowSpans\\(\\) has parameter \\$rowSpan with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$cellData with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$cellType with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$colNum with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$colSpan with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$coordinate with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$cssClass with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$html with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$pRow with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$pSheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$rowSpan with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:generateRowWriteCell\\(\\) has parameter \\$sheetIndex with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:calculateSpansOmitRows\\(\\) has parameter \\$candidateSpannedRow with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:calculateSpansOmitRows\\(\\) has parameter \\$sheet with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Html\\:\\:calculateSpansOmitRows\\(\\) has parameter \\$sheetIndex with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Html.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\IWriter\\:\\:save\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/IWriter.php
+
+ -
+ message: "#^Negated boolean expression is always false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Ods\\\\Cell\\\\Style\\:\\:\\$writer has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods/Cell/Style.php
+
+ -
+ message: "#^If condition is always true\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Ods/Cell/Style.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Ods\\\\Content\\:\\:\\$formulaConvertor has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods/Content.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Writer/Ods/Content.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<2, max\\> given\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Ods/Content.php
+
+ -
+ message: "#^Parameter \\#1 \\$pRange of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:splitRange\\(\\) expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods/Content.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Ods\\\\Formula\\:\\:\\$definedNames has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods/Formula.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Ods\\\\NamedExpressions\\:\\:\\$objWriter has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Ods\\\\NamedExpressions\\:\\:\\$spreadsheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Ods\\\\NamedExpressions\\:\\:\\$formulaConvertor has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Ods\\\\NamedExpressions\\:\\:__construct\\(\\) has parameter \\$formulaConvertor with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
+
+ -
+ message: "#^Cannot call method getTitle\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
+
+ -
+ message: "#^Parameter \\#1 \\$content of method XMLWriter\\:\\:text\\(\\) expects string, int given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Ods/Settings.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between int and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Pdf/Dompdf.php
+
+ -
+ message: "#^Parameter \\#2 \\$str of function fwrite expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Pdf/Dompdf.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between null and int will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Pdf/Mpdf.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between int and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php
+
+ -
+ message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$font of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Workbook\\:\\:addFont\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font, PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Offset 'startCoordinates' does not exist on array\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Offset 'startOffsetX' does not exist on array\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Offset 'startOffsetY' does not exist on array\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Offset 'endCoordinates' does not exist on array\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Offset 'endOffsetX' does not exist on array\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Offset 'endOffsetY' does not exist on array\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$data of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\\\Blip\\:\\:setData\\(\\) expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagepng expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagepng expects resource, GdImage\\|resource given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Parameter \\#1 \\$blipType of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\\\DggContainer\\\\BstoreContainer\\\\BSE\\:\\:setBlipType\\(\\) expects int, int\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Parameter \\#2 \\$pad_length of function str_pad expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\BIFFwriter\\:\\:writeEof\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/BIFFwriter.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Escher\\:\\:\\$object has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Escher.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Escher\\:\\:\\$data has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Escher.php
+
+ -
+ message: "#^If condition is always true\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Xls/Escher.php
+
+ -
+ message: "#^Elseif condition is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Escher.php
+
+ -
+ message: "#^Parameter \\#1 \\$name of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Font\\:\\:getCharsetFromFontName\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Font.php
+
+ -
+ message: "#^If condition is always false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xls/Font.php
+
+ -
+ message: "#^Parameter \\#1 \\$bold of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Font\\:\\:mapBold\\(\\) expects bool, bool\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Font.php
+
+ -
+ message: "#^Parameter \\#1 \\$underline of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Font\\:\\:mapUnderline\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Font.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:UTF8toBIFF8UnicodeShort\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Font.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Parser\\:\\:\\$spreadsheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Parser.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 5
+ path: src/PhpSpreadsheet/Writer/Xls/Parser.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Parser.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function str_replace expects array\\|string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Parser.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Parser\\:\\:advance\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Parser.php
+
+ -
+ message: "#^Offset 'left' does not exist on \\(array&nonEmpty\\)\\|string\\.$#"
+ count: 6
+ path: src/PhpSpreadsheet/Writer/Xls/Parser.php
+
+ -
+ message: "#^Offset 'right' does not exist on \\(array&nonEmpty\\)\\|string\\.$#"
+ count: 5
+ path: src/PhpSpreadsheet/Writer/Xls/Parser.php
+
+ -
+ message: "#^Offset 'value' does not exist on \\(array&nonEmpty\\)\\|string\\.$#"
+ count: 7
+ path: src/PhpSpreadsheet/Writer/Xls/Parser.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Workbook\\:\\:\\$colors has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Cannot call method getTitle\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Workbook\\:\\:writeAllDefinedNamesBiff8\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Parameter \\#1 \\$pSheet of method PhpOffice\\\\PhpSpreadsheet\\\\Spreadsheet\\:\\:getIndex\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet, PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Workbook\\:\\:writeSupbookInternal\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Workbook\\:\\:writeExternalsheetBiff8\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Cannot access offset 'encoding' on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Workbook\\:\\:writeMsoDrawingGroup\\(\\) has no return typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Workbook\\:\\:\\$escher \\(PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Workbook.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:\\$colors has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$height of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:writeRow\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#4 \\$hidden of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:writeRow\\(\\) expects bool, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Cannot call method getHashCode\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#4 \\$isError of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:writeBoolErr\\(\\) expects bool, int given\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$pieces of function implode expects array, array\\\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#3 \\$subject of function preg_replace expects array\\|string, string\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$subject of function preg_match expects string, string\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$subject of function preg_match_all expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$hexadecimal_number of function hexdec expects string, array given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$coordinates of static method PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Coordinate\\:\\:indexesFromString\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:\\$activePane \\(int\\) does not accept int\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#5 \\$width of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:positionImage\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#6 \\$height of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:positionImage\\(\\) expects int, float given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagesx expects resource, GdImage\\|resource given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagesy expects resource, GdImage\\|resource given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagecolorat expects resource, GdImage\\|resource given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagecolorsforindex expects resource, GdImage\\|resource given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$col of function imagecolorsforindex expects int, int\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$ascii of function chr expects int, float given\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$length of function fread expects int, int\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$string of function strlen expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$data of function unpack expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Cannot access offset 'ident' on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$string of function substr expects string, string\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Cannot access offset 'sa' on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Cannot access offset 1 on array\\|false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Cannot access offset 2 on array\\|false\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Cannot access offset 'comp' on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Worksheet\\:\\:\\$escher \\(PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\) does not accept PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\Escher\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of static method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\StringHelper\\:\\:UTF8toBIFF8UnicodeLong\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+
+ -
+ message: "#^Parameter \\#1 \\$fillType of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:mapFillType\\(\\) expects string, string\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xls/Xf.php
+
+ -
+ message: "#^Parameter \\#1 \\$hAlign of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:mapHAlign\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Xf.php
+
+ -
+ message: "#^Parameter \\#1 \\$vAlign of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:mapVAlign\\(\\) expects string, string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Xf.php
+
+ -
+ message: "#^Parameter \\#1 \\$textRotation of static method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xls\\\\Xf\\:\\:mapTextRotation\\(\\) expects int, int\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xls/Xf.php
+
+ -
+ message: "#^Possibly invalid array key type array\\|string\\|null\\.$#"
+ 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: "#^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 \\$function of function call_user_func expects callable\\(\\)\\: mixed, string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\:\\:\\$pathNames has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:\\$calculateCellValues has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
+ count: 45
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Call to function is_array\\(\\) with string will always evaluate to false\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Result of && is always false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\PlotArea and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Argument of an invalid type array\\|string supplied for foreach, only iterables are supported\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#2 \\$yAxisLabel of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#4 \\$id1 of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects string, int\\|string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#5 \\$id2 of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects string, int\\|string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#7 \\$xAxis of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#8 \\$majorGridlines of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#9 \\$minorGridlines of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeValueAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\GridLines\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#2 \\$xAxisLabel of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeCategoryAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Title\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#3 \\$id1 of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeCategoryAxis\\(\\) expects string, int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#4 \\$id2 of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeCategoryAxis\\(\\) expects string, int\\|string given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#6 \\$yAxis of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeCategoryAxis\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Axis\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Part \\$xAxis\\-\\>getShadowProperty\\('effect'\\) \\(array\\|int\\|string\\|null\\) of encapsed string cannot be cast to string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array\\|int\\|string given\\.$#"
+ count: 8
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Part \\$xAxis\\-\\>getShadowProperty\\(\\['color', 'type'\\]\\) \\(array\\|int\\|string\\|null\\) of encapsed string cannot be cast to string\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array\\|int\\|string\\|null given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Else branch is unreachable because previous condition is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:getChartType\\(\\) never returns string so it can be removed from the return typehint\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeries and null will always evaluate to false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method getFillColor\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Cannot call method getDataValues\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#1 \\$plotSeriesValues of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Chart\\:\\:writeBubbles\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Strict comparison using \\=\\=\\= between PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\DataSeriesValues and null will always evaluate to false\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#1 \\$text of method PhpOffice\\\\PhpSpreadsheet\\\\Shared\\\\XMLWriter\\:\\:writeRawData\\(\\) expects array\\\\|string, int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, float\\|int given\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, float given\\.$#"
+ count: 6
+ path: src/PhpSpreadsheet/Writer/Xlsx/Chart.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: "#^Parameter \\#1 \\$arr1 of function array_diff expects array, array\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php
+
+ -
+ message: "#^Cannot access offset 2 on array\\|false\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\DefinedNames\\:\\:\\$objWriter has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php
+
+ -
+ message: "#^Property PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\DefinedNames\\:\\:\\$spreadsheet has no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php
+
+ -
+ message: "#^Cannot call method getTitle\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ 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: "#^Parameter \\#1 \\$index of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\:\\:getChartByIndex\\(\\) expects string, int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
+
+ -
+ message: "#^Parameter \\#2 \\$pChart of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Drawing\\:\\:writeChart\\(\\) expects PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart, PhpOffice\\\\PhpSpreadsheet\\\\Chart\\\\Chart\\|false given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
+
+ -
+ message: "#^Parameter \\#2 \\$content of method XMLWriter\\:\\:writeElement\\(\\) expects string\\|null, int given\\.$#"
+ count: 12
+ path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
+ count: 8
+ path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
+
+ -
+ message: "#^Parameter \\#4 \\$pTarget of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeRelationship\\(\\) expects string, array\\|string\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php
+
+ -
+ message: "#^Parameter \\#2 \\$pId of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeRelationship\\(\\) expects int, string given\\.$#"
+ count: 4
+ path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeUnparsedRelationship\\(\\) has parameter \\$relationship with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeUnparsedRelationship\\(\\) has parameter \\$type with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeDrawingHyperLink\\(\\) has parameter \\$i with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeDrawingHyperLink\\(\\) has parameter \\$objWriter with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php
+
+ -
+ message: "#^Parameter \\#2 \\$pId of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeRelationship\\(\\) expects int, float\\|int given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Rels.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Rels\\:\\:writeDrawingHyperLink\\(\\) should return int but returns float\\|int\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Rels.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: "#^Instanceof between string and PhpOffice\\\\PhpSpreadsheet\\\\RichText\\\\RichText will always evaluate to false\\.$#"
+ 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: "#^Cannot call method getName\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 2
+ 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 getBold\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php
+
+ -
+ message: "#^Cannot call method getItalic\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 2
+ 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 getStrikethrough\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 2
+ 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 getSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ 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: "#^Cannot call method getUnderline\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Font\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.php
+
+ -
+ message: "#^Parameter \\#1 \\$pText 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, int given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/StringTable.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 \\$pNumberFormat 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 \\$pFont 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 \\$pFill 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 \\$pBorders 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 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<0, max\\> given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Style.php
+
+ -
+ message: "#^Cannot call method getStyle\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Conditional\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Style.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, string\\|null given\\.$#"
+ count: 4
+ 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: "#^Comparison operation \"\\<\" between int\\ and 0 is always true\\.$#"
+ 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, int\\<1, max\\> given\\.$#"
+ count: 2
+ 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: "#^Parameter \\#3 \\$pStringTable of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeSheetData\\(\\) expects array\\, array\\\\|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: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int given\\.$#"
+ count: 19
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, int\\<1, max\\> given\\.$#"
+ count: 7
+ 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\\|null given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeAttributeIf\\(\\) has parameter \\$condition with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Worksheet\\:\\:writeElementIf\\(\\) has parameter \\$condition with no typehint specified\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Parameter \\#3 \\$namespace of method XMLWriter\\:\\:startElementNs\\(\\) expects string, null given\\.$#"
+ count: 8
+ 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\\:\\:writeDataBarElements\\(\\) has parameter \\$dataBar with no typehint specified\\.$#"
+ 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: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array given\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Parameter \\#2 \\$value of method XMLWriter\\:\\:writeAttribute\\(\\) expects string, array\\\\|string given\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Argument of an invalid type array\\\\|string supplied for foreach, only iterables are supported\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Cannot call method getCollapsed\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Cannot call method getOutlineLevel\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Cannot call method getRowHeight\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 3
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Cannot call method getVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 2
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Cannot call method getXfIndex\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 3
+ 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: "#^Right side of && is always true\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\Xlsx\\\\Xlfn\\:\\:addXlfn\\(\\) should return string but returns string\\|null\\.$#"
+ count: 1
+ path: src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php
+
+ -
+ message: "#^Unreachable statement \\- code above always terminates\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Calculation/Engine/RangeTest.php
+
+ -
+ message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SubTotalTest.php
+
+ -
+ message: "#^Cannot call method setVisible\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\RowDimension\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SubTotalTest.php
+
+ -
+ message: "#^Cannot call method setAutoSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php
+
+ -
+ message: "#^Call to static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertSame\\(\\) with arguments PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell, null and 'should get exact…' will always evaluate to false\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Collection/CellsTest.php
+
+ -
+ message: "#^Cannot call method getParent\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Collection/CellsTest.php
+
+ -
+ message: "#^Cannot call method getCoordinate\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Cell\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Collection/CellsTest.php
+
+ -
+ message: "#^Parameter \\#1 \\$row of method PhpOffice\\\\PhpSpreadsheet\\\\Collection\\\\Cells\\:\\:getHighestColumn\\(\\) expects string\\|null, int given\\.$#"
+ count: 3
+ path: tests/PhpSpreadsheetTests/Collection/CellsTest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheetTests\\\\Functional\\\\ColumnWidthTest\\:\\:testReadColumnWidth\\(\\) has parameter \\$format with no typehint specified\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
+
+ -
+ message: "#^Cannot call method setWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
+
+ -
+ message: "#^Cannot call method getWidth\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
+
+ -
+ message: "#^Method PhpOffice\\\\PhpSpreadsheetTests\\\\Functional\\\\CommentsTest\\:\\:testComments\\(\\) has parameter \\$format with no typehint specified\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/CommentsTest.php
+
+ -
+ message: "#^Parameter \\#1 \\$pValue of method PhpOffice\\\\PhpSpreadsheet\\\\Style\\\\Conditional\\:\\:addCondition\\(\\) expects string, float given\\.$#"
+ count: 2
+ path: tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php
+
+ -
+ message: "#^Cannot call method setAutoSize\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\ColumnDimension\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/ConditionalTextTest.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagecolorallocate expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php
+
+ -
+ message: "#^Parameter \\#1 \\$im of function imagestring expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php
+
+ -
+ message: "#^Parameter \\#6 \\$col of function imagestring expects int, int\\|false given\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php
+
+ -
+ message: "#^Parameter \\#1 \\$value of method PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\MemoryDrawing\\:\\:setImageResource\\(\\) expects GdImage\\|resource, resource\\|false given\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php
+
+ -
+ message: "#^Cannot call method getUrl\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Cell\\\\Hyperlink\\|null\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php
+
+ -
+ message: "#^Cannot call method getPageSetup\\(\\) on PhpOffice\\\\PhpSpreadsheet\\\\Worksheet\\\\Worksheet\\|null\\.$#"
+ count: 5
+ path: tests/PhpSpreadsheetTests/Functional/PrintAreaTest.php
+
+ -
+ message: "#^Cannot access offset 'size' on array\\(0 \\=\\> int, 1 \\=\\> int, 2 \\=\\> int, 3 \\=\\> int, 4 \\=\\> int, 5 \\=\\> int, 6 \\=\\> int, 7 \\=\\> int, \\.\\.\\.\\)\\|false\\.$#"
+ count: 2
+ path: tests/PhpSpreadsheetTests/Functional/StreamTest.php
+
+ -
+ message: "#^Parameter \\#1 \\$fp of function fstat expects resource, resource\\|false given\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/StreamTest.php
+
+ -
+ message: "#^Parameter \\#1 \\$pFilename of method PhpOffice\\\\PhpSpreadsheet\\\\Writer\\\\IWriter\\:\\:save\\(\\) expects resource\\|string, resource\\|false given\\.$#"
+ count: 1
+ path: tests/PhpSpreadsheetTests/Functional/StreamTest.php
+
+ -
+ message: "#^Parameter \\#1 \\$expected of static method PHPUnit\\\\Framework\\\\Assert\\:\\:assertInstanceOf\\(\\) expects class\\-string\\
- *
- * From the original documentation:
- *
- *
- * This routine calculates the LOG(GAMMA) function for a positive real argument X.
- * Computation is based on an algorithm outlined in references 1 and 2.
- * The program uses rational functions that theoretically approximate LOG(GAMMA)
- * to at least 18 significant decimal digits. The approximation for X > 12 is from
- * reference 3, while approximations for X < 12.0 are similar to those in reference
- * 1, but are unpublished. The accuracy achieved depends on the arithmetic system,
- * the compiler, the intrinsic functions, and proper selection of the
- * machine-dependent constants.
- *
- *
- * Error returns:
- * The program returns the value XINF for X .LE. 0.0 or when overflow would occur.
- * The computation is believed to be free of underflow and overflow.
- *
- *
- * @return float MAX_VALUE for x < 0.0 or when overflow would occur, i.e. x > 2.55E305
- */
-
- // Function cache for logGamma
- private static $logGammaCacheResult = 0.0;
-
- private static $logGammaCacheX = 0.0;
-
- private static function logGamma($x)
- {
- // Log Gamma related constants
- static $lg_d1 = -0.5772156649015328605195174;
- static $lg_d2 = 0.4227843350984671393993777;
- static $lg_d4 = 1.791759469228055000094023;
-
- static $lg_p1 = [
- 4.945235359296727046734888,
- 201.8112620856775083915565,
- 2290.838373831346393026739,
- 11319.67205903380828685045,
- 28557.24635671635335736389,
- 38484.96228443793359990269,
- 26377.48787624195437963534,
- 7225.813979700288197698961,
- ];
- static $lg_p2 = [
- 4.974607845568932035012064,
- 542.4138599891070494101986,
- 15506.93864978364947665077,
- 184793.2904445632425417223,
- 1088204.76946882876749847,
- 3338152.967987029735917223,
- 5106661.678927352456275255,
- 3074109.054850539556250927,
- ];
- static $lg_p4 = [
- 14745.02166059939948905062,
- 2426813.369486704502836312,
- 121475557.4045093227939592,
- 2663432449.630976949898078,
- 29403789566.34553899906876,
- 170266573776.5398868392998,
- 492612579337.743088758812,
- 560625185622.3951465078242,
- ];
- static $lg_q1 = [
- 67.48212550303777196073036,
- 1113.332393857199323513008,
- 7738.757056935398733233834,
- 27639.87074403340708898585,
- 54993.10206226157329794414,
- 61611.22180066002127833352,
- 36351.27591501940507276287,
- 8785.536302431013170870835,
- ];
- static $lg_q2 = [
- 183.0328399370592604055942,
- 7765.049321445005871323047,
- 133190.3827966074194402448,
- 1136705.821321969608938755,
- 5267964.117437946917577538,
- 13467014.54311101692290052,
- 17827365.30353274213975932,
- 9533095.591844353613395747,
- ];
- static $lg_q4 = [
- 2690.530175870899333379843,
- 639388.5654300092398984238,
- 41355999.30241388052042842,
- 1120872109.61614794137657,
- 14886137286.78813811542398,
- 101680358627.2438228077304,
- 341747634550.7377132798597,
- 446315818741.9713286462081,
- ];
- static $lg_c = [
- -0.001910444077728,
- 8.4171387781295e-4,
- -5.952379913043012e-4,
- 7.93650793500350248e-4,
- -0.002777777777777681622553,
- 0.08333333333333333331554247,
- 0.0057083835261,
- ];
-
- // Rough estimate of the fourth root of logGamma_xBig
- static $lg_frtbig = 2.25e76;
- static $pnt68 = 0.6796875;
-
- if ($x == self::$logGammaCacheX) {
- return self::$logGammaCacheResult;
- }
- $y = $x;
- if ($y > 0.0 && $y <= self::LOG_GAMMA_X_MAX_VALUE) {
- if ($y <= self::EPS) {
- $res = -log($y);
- } elseif ($y <= 1.5) {
- // ---------------------
- // EPS .LT. X .LE. 1.5
- // ---------------------
- if ($y < $pnt68) {
- $corr = -log($y);
- $xm1 = $y;
- } else {
- $corr = 0.0;
- $xm1 = $y - 1.0;
- }
- if ($y <= 0.5 || $y >= $pnt68) {
- $xden = 1.0;
- $xnum = 0.0;
- for ($i = 0; $i < 8; ++$i) {
- $xnum = $xnum * $xm1 + $lg_p1[$i];
- $xden = $xden * $xm1 + $lg_q1[$i];
- }
- $res = $corr + $xm1 * ($lg_d1 + $xm1 * ($xnum / $xden));
- } else {
- $xm2 = $y - 1.0;
- $xden = 1.0;
- $xnum = 0.0;
- for ($i = 0; $i < 8; ++$i) {
- $xnum = $xnum * $xm2 + $lg_p2[$i];
- $xden = $xden * $xm2 + $lg_q2[$i];
- }
- $res = $corr + $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden));
- }
- } elseif ($y <= 4.0) {
- // ---------------------
- // 1.5 .LT. X .LE. 4.0
- // ---------------------
- $xm2 = $y - 2.0;
- $xden = 1.0;
- $xnum = 0.0;
- for ($i = 0; $i < 8; ++$i) {
- $xnum = $xnum * $xm2 + $lg_p2[$i];
- $xden = $xden * $xm2 + $lg_q2[$i];
- }
- $res = $xm2 * ($lg_d2 + $xm2 * ($xnum / $xden));
- } elseif ($y <= 12.0) {
- // ----------------------
- // 4.0 .LT. X .LE. 12.0
- // ----------------------
- $xm4 = $y - 4.0;
- $xden = -1.0;
- $xnum = 0.0;
- for ($i = 0; $i < 8; ++$i) {
- $xnum = $xnum * $xm4 + $lg_p4[$i];
- $xden = $xden * $xm4 + $lg_q4[$i];
- }
- $res = $lg_d4 + $xm4 * ($xnum / $xden);
- } else {
- // ---------------------------------
- // Evaluate for argument .GE. 12.0
- // ---------------------------------
- $res = 0.0;
- if ($y <= $lg_frtbig) {
- $res = $lg_c[6];
- $ysq = $y * $y;
- for ($i = 0; $i < 6; ++$i) {
- $res = $res / $ysq + $lg_c[$i];
- }
- $res /= $y;
- $corr = log($y);
- $res = $res + log(self::SQRT2PI) - 0.5 * $corr;
- $res += $y * ($corr - 1.0);
- }
- }
- } else {
- // --------------------------
- // Return for bad arguments
- // --------------------------
- $res = self::MAX_VALUE;
- }
- // ------------------------------
- // Final adjustments and return
- // ------------------------------
- self::$logGammaCacheX = $x;
- self::$logGammaCacheResult = $res;
-
- return $res;
- }
-
- //
- // Private implementation of the incomplete Gamma function
- //
- private static function incompleteGamma($a, $x)
- {
- static $max = 32;
- $summer = 0;
- for ($n = 0; $n <= $max; ++$n) {
- $divisor = $a;
- for ($i = 1; $i <= $n; ++$i) {
- $divisor *= ($a + $i);
- }
- $summer += ($x ** $n / $divisor);
- }
-
- return $x ** $a * exp(0 - $x) * $summer;
- }
-
- //
- // Private implementation of the Gamma function
- //
- private static function gamma($data)
- {
- if ($data == 0.0) {
- return 0;
- }
-
- static $p0 = 1.000000000190015;
- static $p = [
- 1 => 76.18009172947146,
- 2 => -86.50532032941677,
- 3 => 24.01409824083091,
- 4 => -1.231739572450155,
- 5 => 1.208650973866179e-3,
- 6 => -5.395239384953e-6,
- ];
-
- $y = $x = $data;
- $tmp = $x + 5.5;
- $tmp -= ($x + 0.5) * log($tmp);
-
- $summer = $p0;
- for ($j = 1; $j <= 6; ++$j) {
- $summer += ($p[$j] / ++$y);
- }
-
- return exp(0 - $tmp + log(self::SQRT2PI * $summer / $x));
- }
-
- /*
- * inverse_ncdf.php
- * -------------------
- * begin : Friday, January 16, 2004
- * copyright : (C) 2004 Michael Nickerson
- * email : nickersonm@yahoo.com
- *
- */
- private static function inverseNcdf($p)
- {
- // Inverse ncdf approximation by Peter J. Acklam, implementation adapted to
- // PHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as
- // a guide. http://home.online.no/~pjacklam/notes/invnorm/index.html
- // I have not checked the accuracy of this implementation. Be aware that PHP
- // will truncate the coeficcients to 14 digits.
-
- // You have permission to use and distribute this function freely for
- // whatever purpose you want, but please show common courtesy and give credit
- // where credit is due.
-
- // Input paramater is $p - probability - where 0 < p < 1.
-
- // Coefficients in rational approximations
- static $a = [
- 1 => -3.969683028665376e+01,
- 2 => 2.209460984245205e+02,
- 3 => -2.759285104469687e+02,
- 4 => 1.383577518672690e+02,
- 5 => -3.066479806614716e+01,
- 6 => 2.506628277459239e+00,
- ];
-
- static $b = [
- 1 => -5.447609879822406e+01,
- 2 => 1.615858368580409e+02,
- 3 => -1.556989798598866e+02,
- 4 => 6.680131188771972e+01,
- 5 => -1.328068155288572e+01,
- ];
-
- static $c = [
- 1 => -7.784894002430293e-03,
- 2 => -3.223964580411365e-01,
- 3 => -2.400758277161838e+00,
- 4 => -2.549732539343734e+00,
- 5 => 4.374664141464968e+00,
- 6 => 2.938163982698783e+00,
- ];
-
- static $d = [
- 1 => 7.784695709041462e-03,
- 2 => 3.224671290700398e-01,
- 3 => 2.445134137142996e+00,
- 4 => 3.754408661907416e+00,
- ];
-
- // Define lower and upper region break-points.
- $p_low = 0.02425; //Use lower region approx. below this
- $p_high = 1 - $p_low; //Use upper region approx. above this
-
- if (0 < $p && $p < $p_low) {
- // Rational approximation for lower region.
- $q = sqrt(-2 * log($p));
-
- return ((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) /
- (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1);
- } elseif ($p_low <= $p && $p <= $p_high) {
- // Rational approximation for central region.
- $q = $p - 0.5;
- $r = $q * $q;
-
- return ((((($a[1] * $r + $a[2]) * $r + $a[3]) * $r + $a[4]) * $r + $a[5]) * $r + $a[6]) * $q /
- ((((($b[1] * $r + $b[2]) * $r + $b[3]) * $r + $b[4]) * $r + $b[5]) * $r + 1);
- } elseif ($p_high < $p && $p < 1) {
- // Rational approximation for upper region.
- $q = sqrt(-2 * log(1 - $p));
-
- return -((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) /
- (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1);
- }
- // If 0 < p < 1, return a null value
- return Functions::NULL();
- }
-
- /**
- * MS Excel does not count Booleans if passed as cell values, but they are counted if passed as literals.
- * OpenOffice Calc always counts Booleans.
- * Gnumeric never counts Booleans.
- *
- * @param mixed $arg
- * @param mixed $k
- *
- * @return int|mixed
- */
- private static function testAcceptedBoolean($arg, $k)
- {
- if (
- (is_bool($arg)) &&
- ((!Functions::isCellValue($k) && (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_EXCEL)) ||
- (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE))
- ) {
- $arg = (int) $arg;
- }
-
- return $arg;
- }
-
- /**
- * @param mixed $arg
- * @param mixed $k
- *
- * @return bool
- */
- private static function isAcceptedCountable($arg, $k)
- {
- if (
- ((is_numeric($arg)) && (!is_string($arg))) ||
- ((is_numeric($arg)) && (!Functions::isCellValue($k)) &&
- (Functions::getCompatibilityMode() !== Functions::COMPATIBILITY_GNUMERIC))
- ) {
- return true;
- }
-
- return false;
- }
-
/**
* AVEDEV.
*
@@ -569,45 +30,18 @@ class Statistical
* Excel Function:
* AVEDEV(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Averages::averageDeviations()
+ * Use the averageDeviations() method in the Statistical\Averages class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function AVEDEV(...$args)
{
- $aArgs = Functions::flattenArrayIndexed($args);
-
- // Return value
- $returnValue = 0;
-
- $aMean = self::AVERAGE(...$args);
- if ($aMean === Functions::DIV0()) {
- return Functions::NAN();
- } elseif ($aMean === Functions::VALUE()) {
- return Functions::VALUE();
- }
-
- $aCount = 0;
- foreach ($aArgs as $k => $arg) {
- $arg = self::testAcceptedBoolean($arg, $k);
- // Is it a numeric value?
- // Strings containing numeric values are only counted if they are string literals (not cell values)
- // and then only in MS Excel and in Open Office, not in Gnumeric
- if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
- return Functions::VALUE();
- }
- if (self::isAcceptedCountable($arg, $k)) {
- $returnValue += abs($arg - $aMean);
- ++$aCount;
- }
- }
-
- // Return
- if ($aCount === 0) {
- return Functions::DIV0();
- }
-
- return $returnValue / $aCount;
+ return Averages::averageDeviations(...$args);
}
/**
@@ -618,35 +52,18 @@ class Statistical
* Excel Function:
* AVERAGE(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Averages::average()
+ * Use the average() method in the Statistical\Averages class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function AVERAGE(...$args)
{
- $returnValue = $aCount = 0;
-
- // Loop through arguments
- foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
- $arg = self::testAcceptedBoolean($arg, $k);
- // Is it a numeric value?
- // Strings containing numeric values are only counted if they are string literals (not cell values)
- // and then only in MS Excel and in Open Office, not in Gnumeric
- if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
- return Functions::VALUE();
- }
- if (self::isAcceptedCountable($arg, $k)) {
- $returnValue += $arg;
- ++$aCount;
- }
- }
-
- // Return
- if ($aCount > 0) {
- return $returnValue / $aCount;
- }
-
- return Functions::DIV0();
+ return Averages::average(...$args);
}
/**
@@ -657,39 +74,18 @@ class Statistical
* Excel Function:
* AVERAGEA(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Averages::averageA()
+ * Use the averageA() method in the Statistical\Averages class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function AVERAGEA(...$args)
{
- $returnValue = null;
-
- $aCount = 0;
- // Loop through arguments
- foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
- if (
- (is_bool($arg)) &&
- (!Functions::isMatrixValue($k))
- ) {
- } else {
- if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- } elseif (is_string($arg)) {
- $arg = 0;
- }
- $returnValue += $arg;
- ++$aCount;
- }
- }
- }
-
- if ($aCount > 0) {
- return $returnValue / $aCount;
- }
-
- return Functions::DIV0();
+ return Averages::averageA(...$args);
}
/**
@@ -700,47 +96,20 @@ class Statistical
* Excel Function:
* AVERAGEIF(value1[,value2[, ...]],condition)
*
- * @param mixed $aArgs Data values
- * @param string $condition the criteria that defines which cells will be checked
- * @param mixed[] $averageArgs Data values
+ * @Deprecated 1.17.0
*
- * @return float|string
+ * @see Statistical\Conditional::AVERAGEIF()
+ * Use the AVERAGEIF() method in the Statistical\Conditional class instead
+ *
+ * @param mixed $range Data values
+ * @param string $condition the criteria that defines which cells will be checked
+ * @param mixed[] $averageRange Data values
+ *
+ * @return null|float|string
*/
- public static function AVERAGEIF($aArgs, $condition, $averageArgs = [])
+ public static function AVERAGEIF($range, $condition, $averageRange = [])
{
- $returnValue = 0;
-
- $aArgs = Functions::flattenArray($aArgs);
- $averageArgs = Functions::flattenArray($averageArgs);
- if (empty($averageArgs)) {
- $averageArgs = $aArgs;
- }
- $condition = Functions::ifCondition($condition);
- $conditionIsNumeric = strpos($condition, '"') === false;
-
- // Loop through arguments
- $aCount = 0;
- foreach ($aArgs as $key => $arg) {
- if (!is_numeric($arg)) {
- if ($conditionIsNumeric) {
- continue;
- }
- $arg = Calculation::wrapResult(strtoupper($arg));
- } elseif (!$conditionIsNumeric) {
- continue;
- }
- $testCondition = '=' . $arg . $condition;
- if (Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
- $returnValue += $averageArgs[$key];
- ++$aCount;
- }
- }
-
- if ($aCount > 0) {
- return $returnValue / $aCount;
- }
-
- return Functions::DIV0();
+ return Conditional::AVERAGEIF($range, $condition, $averageRange);
}
/**
@@ -748,6 +117,11 @@ class Statistical
*
* Returns the beta distribution.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Beta::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Beta class instead
+ *
* @param float $value Value at which you want to evaluate the distribution
* @param float $alpha Parameter to the distribution
* @param float $beta Parameter to the distribution
@@ -758,28 +132,7 @@ class Statistical
*/
public static function BETADIST($value, $alpha, $beta, $rMin = 0, $rMax = 1)
{
- $value = Functions::flattenSingleValue($value);
- $alpha = Functions::flattenSingleValue($alpha);
- $beta = Functions::flattenSingleValue($beta);
- $rMin = Functions::flattenSingleValue($rMin);
- $rMax = Functions::flattenSingleValue($rMax);
-
- if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) {
- if (($value < $rMin) || ($value > $rMax) || ($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax)) {
- return Functions::NAN();
- }
- if ($rMin > $rMax) {
- $tmp = $rMin;
- $rMin = $rMax;
- $rMax = $tmp;
- }
- $value -= $rMin;
- $value /= ($rMax - $rMin);
-
- return self::incompleteBeta($value, $alpha, $beta);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Beta::distribution($value, $alpha, $beta, $rMin, $rMax);
}
/**
@@ -787,6 +140,11 @@ class Statistical
*
* Returns the inverse of the Beta distribution.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Beta::inverse()
+ * Use the inverse() method in the Statistical\Distributions\Beta class instead
+ *
* @param float $probability Probability at which you want to evaluate the distribution
* @param float $alpha Parameter to the distribution
* @param float $beta Parameter to the distribution
@@ -797,44 +155,7 @@ class Statistical
*/
public static function BETAINV($probability, $alpha, $beta, $rMin = 0, $rMax = 1)
{
- $probability = Functions::flattenSingleValue($probability);
- $alpha = Functions::flattenSingleValue($alpha);
- $beta = Functions::flattenSingleValue($beta);
- $rMin = Functions::flattenSingleValue($rMin);
- $rMax = Functions::flattenSingleValue($rMax);
-
- if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta)) && (is_numeric($rMin)) && (is_numeric($rMax))) {
- if (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0) || ($probability > 1)) {
- return Functions::NAN();
- }
- if ($rMin > $rMax) {
- $tmp = $rMin;
- $rMin = $rMax;
- $rMax = $tmp;
- }
- $a = 0;
- $b = 2;
-
- $i = 0;
- while ((($b - $a) > Functions::PRECISION) && ($i++ < self::MAX_ITERATIONS)) {
- $guess = ($a + $b) / 2;
- $result = self::BETADIST($guess, $alpha, $beta);
- if (($result == $probability) || ($result == 0)) {
- $b = $a;
- } elseif ($result > $probability) {
- $b = $guess;
- } else {
- $a = $guess;
- }
- }
- if ($i == self::MAX_ITERATIONS) {
- return Functions::NA();
- }
-
- return round($rMin + $guess * ($rMax - $rMin), 12);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Beta::inverse($probability, $alpha, $beta, $rMin, $rMax);
}
/**
@@ -846,43 +167,21 @@ class Statistical
* experiment. For example, BINOMDIST can calculate the probability that two of the next three
* babies born are male.
*
- * @param float $value Number of successes in trials
- * @param float $trials Number of trials
- * @param float $probability Probability of success on each trial
- * @param bool $cumulative
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Binomial::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Binomial class instead
+ *
+ * @param mixed $value Number of successes in trials
+ * @param mixed $trials Number of trials
+ * @param mixed $probability Probability of success on each trial
+ * @param mixed $cumulative
*
* @return float|string
*/
public static function BINOMDIST($value, $trials, $probability, $cumulative)
{
- $value = Functions::flattenSingleValue($value);
- $trials = Functions::flattenSingleValue($trials);
- $probability = Functions::flattenSingleValue($probability);
-
- if ((is_numeric($value)) && (is_numeric($trials)) && (is_numeric($probability))) {
- $value = floor($value);
- $trials = floor($trials);
- if (($value < 0) || ($value > $trials)) {
- return Functions::NAN();
- }
- if (($probability < 0) || ($probability > 1)) {
- return Functions::NAN();
- }
- if ((is_numeric($cumulative)) || (is_bool($cumulative))) {
- if ($cumulative) {
- $summer = 0;
- for ($i = 0; $i <= $value; ++$i) {
- $summer += MathTrig::COMBIN($trials, $i) * $probability ** $i * (1 - $probability) ** ($trials - $i);
- }
-
- return $summer;
- }
-
- return MathTrig::COMBIN($trials, $value) * $probability ** $value * (1 - $probability) ** ($trials - $value);
- }
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Binomial::distribution($value, $trials, $probability, $cumulative);
}
/**
@@ -890,6 +189,11 @@ class Statistical
*
* Returns the one-tailed probability of the chi-squared distribution.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\ChiSquared::distributionRightTail()
+ * Use the distributionRightTail() method in the Statistical\Distributions\ChiSquared class instead
+ *
* @param float $value Value for the function
* @param float $degrees degrees of freedom
*
@@ -897,26 +201,7 @@ class Statistical
*/
public static function CHIDIST($value, $degrees)
{
- $value = Functions::flattenSingleValue($value);
- $degrees = Functions::flattenSingleValue($degrees);
-
- if ((is_numeric($value)) && (is_numeric($degrees))) {
- $degrees = floor($degrees);
- if ($degrees < 1) {
- return Functions::NAN();
- }
- if ($value < 0) {
- if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) {
- return 1;
- }
-
- return Functions::NAN();
- }
-
- return 1 - (self::incompleteGamma($degrees / 2, $value / 2) / self::gamma($degrees / 2));
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\ChiSquared::distributionRightTail($value, $degrees);
}
/**
@@ -924,6 +209,11 @@ class Statistical
*
* Returns the one-tailed probability of the chi-squared distribution.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\ChiSquared::inverseRightTail()
+ * Use the inverseRightTail() method in the Statistical\Distributions\ChiSquared class instead
+ *
* @param float $probability Probability for the function
* @param float $degrees degrees of freedom
*
@@ -931,52 +221,7 @@ class Statistical
*/
public static function CHIINV($probability, $degrees)
{
- $probability = Functions::flattenSingleValue($probability);
- $degrees = Functions::flattenSingleValue($degrees);
-
- if ((is_numeric($probability)) && (is_numeric($degrees))) {
- $degrees = floor($degrees);
-
- $xLo = 100;
- $xHi = 0;
-
- $x = $xNew = 1;
- $dx = 1;
- $i = 0;
-
- while ((abs($dx) > Functions::PRECISION) && ($i++ < self::MAX_ITERATIONS)) {
- // Apply Newton-Raphson step
- $result = 1 - (self::incompleteGamma($degrees / 2, $x / 2) / self::gamma($degrees / 2));
- $error = $result - $probability;
- if ($error == 0.0) {
- $dx = 0;
- } elseif ($error < 0.0) {
- $xLo = $x;
- } else {
- $xHi = $x;
- }
- // Avoid division by zero
- if ($result != 0.0) {
- $dx = $error / $result;
- $xNew = $x - $dx;
- }
- // If the NR fails to converge (which for example may be the
- // case if the initial guess is too rough) we apply a bisection
- // step to determine a more narrow interval around the root.
- if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) {
- $xNew = ($xLo + $xHi) / 2;
- $dx = $xNew - $x;
- }
- $x = $xNew;
- }
- if ($i == self::MAX_ITERATIONS) {
- return Functions::NA();
- }
-
- return round($x, 12);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\ChiSquared::inverseRightTail($probability, $degrees);
}
/**
@@ -984,6 +229,11 @@ class Statistical
*
* Returns the confidence interval for a population mean
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Confidence::CONFIDENCE()
+ * Use the CONFIDENCE() method in the Statistical\Confidence class instead
+ *
* @param float $alpha
* @param float $stdDev Standard Deviation
* @param float $size
@@ -992,23 +242,7 @@ class Statistical
*/
public static function CONFIDENCE($alpha, $stdDev, $size)
{
- $alpha = Functions::flattenSingleValue($alpha);
- $stdDev = Functions::flattenSingleValue($stdDev);
- $size = Functions::flattenSingleValue($size);
-
- if ((is_numeric($alpha)) && (is_numeric($stdDev)) && (is_numeric($size))) {
- $size = floor($size);
- if (($alpha <= 0) || ($alpha >= 1)) {
- return Functions::NAN();
- }
- if (($stdDev <= 0) || ($size < 1)) {
- return Functions::NAN();
- }
-
- return self::NORMSINV(1 - $alpha / 2) * $stdDev / sqrt($size);
- }
-
- return Functions::VALUE();
+ return Confidence::CONFIDENCE($alpha, $stdDev, $size);
}
/**
@@ -1016,6 +250,11 @@ class Statistical
*
* Returns covariance, the average of the products of deviations for each data point pair.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::CORREL()
+ * Use the CORREL() method in the Statistical\Trends class instead
+ *
* @param mixed $yValues array of mixed Data Series Y
* @param null|mixed $xValues array of mixed Data Series X
*
@@ -1023,24 +262,7 @@ class Statistical
*/
public static function CORREL($yValues, $xValues = null)
{
- if (($xValues === null) || (!is_array($yValues)) || (!is_array($xValues))) {
- return Functions::VALUE();
- }
- if (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return Functions::DIV0();
- }
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
-
- return $bestFitLinear->getCorrelation();
+ return Trends::CORREL($xValues, $yValues);
}
/**
@@ -1051,27 +273,18 @@ class Statistical
* Excel Function:
* COUNT(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Counts::COUNT()
+ * Use the COUNT() method in the Statistical\Counts class instead
+ *
* @param mixed ...$args Data values
*
* @return int
*/
public static function COUNT(...$args)
{
- $returnValue = 0;
-
- // Loop through arguments
- $aArgs = Functions::flattenArrayIndexed($args);
- foreach ($aArgs as $k => $arg) {
- $arg = self::testAcceptedBoolean($arg, $k);
- // Is it a numeric value?
- // Strings containing numeric values are only counted if they are string literals (not cell values)
- // and then only in MS Excel and in Open Office, not in Gnumeric
- if (self::isAcceptedCountable($arg, $k)) {
- ++$returnValue;
- }
- }
-
- return $returnValue;
+ return Counts::COUNT(...$args);
}
/**
@@ -1082,24 +295,18 @@ class Statistical
* Excel Function:
* COUNTA(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Counts::COUNTA()
+ * Use the COUNTA() method in the Statistical\Counts class instead
+ *
* @param mixed ...$args Data values
*
* @return int
*/
public static function COUNTA(...$args)
{
- $returnValue = 0;
-
- // Loop through arguments
- $aArgs = Functions::flattenArrayIndexed($args);
- foreach ($aArgs as $k => $arg) {
- // Nulls are counted if literals, but not if cell values
- if ($arg !== null || (!Functions::isCellValue($k))) {
- ++$returnValue;
- }
- }
-
- return $returnValue;
+ return Counts::COUNTA(...$args);
}
/**
@@ -1110,24 +317,18 @@ class Statistical
* Excel Function:
* COUNTBLANK(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Counts::COUNTBLANK()
+ * Use the COUNTBLANK() method in the Statistical\Counts class instead
+ *
* @param mixed ...$args Data values
*
* @return int
*/
public static function COUNTBLANK(...$args)
{
- $returnValue = 0;
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- foreach ($aArgs as $arg) {
- // Is it a blank cell?
- if (($arg === null) || ((is_string($arg)) && ($arg == ''))) {
- ++$returnValue;
- }
- }
-
- return $returnValue;
+ return Counts::COUNTBLANK(...$args);
}
/**
@@ -1136,38 +337,21 @@ class Statistical
* Counts the number of cells that contain numbers within the list of arguments
*
* Excel Function:
- * COUNTIF(value1[,value2[, ...]],condition)
+ * COUNTIF(range,condition)
*
- * @param mixed $aArgs Data values
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Conditional::COUNTIF()
+ * Use the COUNTIF() method in the Statistical\Conditional class instead
+ *
+ * @param mixed $range Data values
* @param string $condition the criteria that defines which cells will be counted
*
* @return int
*/
- public static function COUNTIF($aArgs, $condition)
+ public static function COUNTIF($range, $condition)
{
- $returnValue = 0;
-
- $aArgs = Functions::flattenArray($aArgs);
- $condition = Functions::ifCondition($condition);
- $conditionIsNumeric = strpos($condition, '"') === false;
- // Loop through arguments
- foreach ($aArgs as $arg) {
- if (!is_numeric($arg)) {
- if ($conditionIsNumeric) {
- continue;
- }
- $arg = Calculation::wrapResult(strtoupper($arg));
- } elseif (!$conditionIsNumeric) {
- continue;
- }
- $testCondition = '=' . $arg . $condition;
- if (Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
- // Is it a value within our criteria
- ++$returnValue;
- }
- }
-
- return $returnValue;
+ return Conditional::COUNTIF($range, $condition);
}
/**
@@ -1178,66 +362,18 @@ class Statistical
* Excel Function:
* COUNTIFS(criteria_range1, criteria1, [criteria_range2, criteria2]…)
*
- * @param mixed $args Criterias
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Conditional::COUNTIFS()
+ * Use the COUNTIFS() method in the Statistical\Conditional class instead
+ *
+ * @param mixed $args Pairs of Ranges and Criteria
*
* @return int
*/
public static function COUNTIFS(...$args)
{
- $arrayList = $args;
-
- // Return value
- $returnValue = 0;
-
- if (empty($arrayList)) {
- return $returnValue;
- }
-
- $aArgsArray = [];
- $conditions = [];
-
- while (count($arrayList) > 0) {
- $aArgsArray[] = Functions::flattenArray(array_shift($arrayList));
- $conditions[] = Functions::ifCondition(array_shift($arrayList));
- }
-
- // Loop through each arg and see if arguments and conditions are true
- foreach (array_keys($aArgsArray[0]) as $index) {
- $valid = true;
-
- foreach ($conditions as $cidx => $condition) {
- $conditionIsNumeric = strpos($condition, '"') === false;
- $arg = $aArgsArray[$cidx][$index];
-
- // Loop through arguments
- if (!is_numeric($arg)) {
- if ($conditionIsNumeric) {
- $valid = false;
-
- break; // if false found, don't need to check other conditions
- }
- $arg = Calculation::wrapResult(strtoupper($arg));
- } elseif (!$conditionIsNumeric) {
- $valid = false;
-
- break; // if false found, don't need to check other conditions
- }
- $testCondition = '=' . $arg . $condition;
- if (!Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
- // Is not a value within our criteria
- $valid = false;
-
- break; // if false found, don't need to check other conditions
- }
- }
-
- if ($valid) {
- ++$returnValue;
- }
- }
-
- // Return
- return $returnValue;
+ return Conditional::COUNTIFS(...$args);
}
/**
@@ -1245,6 +381,11 @@ class Statistical
*
* Returns covariance, the average of the products of deviations for each data point pair.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::COVAR()
+ * Use the COVAR() method in the Statistical\Trends class instead
+ *
* @param mixed $yValues array of mixed Data Series Y
* @param mixed $xValues array of mixed Data Series X
*
@@ -1252,21 +393,7 @@ class Statistical
*/
public static function COVAR($yValues, $xValues)
{
- if (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return Functions::DIV0();
- }
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
-
- return $bestFitLinear->getCovariance();
+ return Trends::COVAR($yValues, $xValues);
}
/**
@@ -1277,123 +404,20 @@ class Statistical
*
* See https://support.microsoft.com/en-us/help/828117/ for details of the algorithm used
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Binomial::inverse()
+ * Use the inverse() method in the Statistical\Distributions\Binomial class instead
+ *
* @param float $trials number of Bernoulli trials
* @param float $probability probability of a success on each trial
* @param float $alpha criterion value
*
* @return int|string
- *
- * @TODO Warning. This implementation differs from the algorithm detailed on the MS
- * web site in that $CumPGuessMinus1 = $CumPGuess - 1 rather than $CumPGuess - $PGuess
- * This eliminates a potential endless loop error, but may have an adverse affect on the
- * accuracy of the function (although all my tests have so far returned correct results).
*/
public static function CRITBINOM($trials, $probability, $alpha)
{
- $trials = floor(Functions::flattenSingleValue($trials));
- $probability = Functions::flattenSingleValue($probability);
- $alpha = Functions::flattenSingleValue($alpha);
-
- if ((is_numeric($trials)) && (is_numeric($probability)) && (is_numeric($alpha))) {
- $trials = (int) $trials;
- if ($trials < 0) {
- return Functions::NAN();
- } elseif (($probability < 0.0) || ($probability > 1.0)) {
- return Functions::NAN();
- } elseif (($alpha < 0.0) || ($alpha > 1.0)) {
- return Functions::NAN();
- }
-
- if ($alpha <= 0.5) {
- $t = sqrt(log(1 / ($alpha * $alpha)));
- $trialsApprox = 0 - ($t + (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t));
- } else {
- $t = sqrt(log(1 / (1 - $alpha) ** 2));
- $trialsApprox = $t - (2.515517 + 0.802853 * $t + 0.010328 * $t * $t) / (1 + 1.432788 * $t + 0.189269 * $t * $t + 0.001308 * $t * $t * $t);
- }
-
- $Guess = floor($trials * $probability + $trialsApprox * sqrt($trials * $probability * (1 - $probability)));
- if ($Guess < 0) {
- $Guess = 0;
- } elseif ($Guess > $trials) {
- $Guess = $trials;
- }
-
- $TotalUnscaledProbability = $UnscaledPGuess = $UnscaledCumPGuess = 0.0;
- $EssentiallyZero = 10e-12;
-
- $m = floor($trials * $probability);
- ++$TotalUnscaledProbability;
- if ($m == $Guess) {
- ++$UnscaledPGuess;
- }
- if ($m <= $Guess) {
- ++$UnscaledCumPGuess;
- }
-
- $PreviousValue = 1;
- $Done = false;
- $k = $m + 1;
- while ((!$Done) && ($k <= $trials)) {
- $CurrentValue = $PreviousValue * ($trials - $k + 1) * $probability / ($k * (1 - $probability));
- $TotalUnscaledProbability += $CurrentValue;
- if ($k == $Guess) {
- $UnscaledPGuess += $CurrentValue;
- }
- if ($k <= $Guess) {
- $UnscaledCumPGuess += $CurrentValue;
- }
- if ($CurrentValue <= $EssentiallyZero) {
- $Done = true;
- }
- $PreviousValue = $CurrentValue;
- ++$k;
- }
-
- $PreviousValue = 1;
- $Done = false;
- $k = $m - 1;
- while ((!$Done) && ($k >= 0)) {
- $CurrentValue = $PreviousValue * $k + 1 * (1 - $probability) / (($trials - $k) * $probability);
- $TotalUnscaledProbability += $CurrentValue;
- if ($k == $Guess) {
- $UnscaledPGuess += $CurrentValue;
- }
- if ($k <= $Guess) {
- $UnscaledCumPGuess += $CurrentValue;
- }
- if ($CurrentValue <= $EssentiallyZero) {
- $Done = true;
- }
- $PreviousValue = $CurrentValue;
- --$k;
- }
-
- $PGuess = $UnscaledPGuess / $TotalUnscaledProbability;
- $CumPGuess = $UnscaledCumPGuess / $TotalUnscaledProbability;
-
- $CumPGuessMinus1 = $CumPGuess - 1;
-
- while (true) {
- if (($CumPGuessMinus1 < $alpha) && ($CumPGuess >= $alpha)) {
- return $Guess;
- } elseif (($CumPGuessMinus1 < $alpha) && ($CumPGuess < $alpha)) {
- $PGuessPlus1 = $PGuess * ($trials - $Guess) * $probability / $Guess / (1 - $probability);
- $CumPGuessMinus1 = $CumPGuess;
- $CumPGuess = $CumPGuess + $PGuessPlus1;
- $PGuess = $PGuessPlus1;
- ++$Guess;
- } elseif (($CumPGuessMinus1 >= $alpha) && ($CumPGuess >= $alpha)) {
- $PGuessMinus1 = $PGuess * $Guess * (1 - $probability) / ($trials - $Guess + 1) / $probability;
- $CumPGuess = $CumPGuessMinus1;
- $CumPGuessMinus1 = $CumPGuessMinus1 - $PGuess;
- $PGuess = $PGuessMinus1;
- --$Guess;
- }
- }
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Binomial::inverse($trials, $probability, $alpha);
}
/**
@@ -1415,7 +439,7 @@ class Statistical
// Return value
$returnValue = null;
- $aMean = self::AVERAGE($aArgs);
+ $aMean = Averages::average($aArgs);
if ($aMean != Functions::DIV0()) {
$aCount = -1;
foreach ($aArgs as $k => $arg) {
@@ -1455,6 +479,11 @@ class Statistical
* such as how long an automated bank teller takes to deliver cash. For example, you can
* use EXPONDIST to determine the probability that the process takes at most 1 minute.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Exponential::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Exponential class instead
+ *
* @param float $value Value of the function
* @param float $lambda The parameter value
* @param bool $cumulative
@@ -1463,34 +492,7 @@ class Statistical
*/
public static function EXPONDIST($value, $lambda, $cumulative)
{
- $value = Functions::flattenSingleValue($value);
- $lambda = Functions::flattenSingleValue($lambda);
- $cumulative = Functions::flattenSingleValue($cumulative);
-
- if ((is_numeric($value)) && (is_numeric($lambda))) {
- if (($value < 0) || ($lambda < 0)) {
- return Functions::NAN();
- }
- if ((is_numeric($cumulative)) || (is_bool($cumulative))) {
- if ($cumulative) {
- return 1 - exp(0 - $value * $lambda);
- }
-
- return $lambda * exp(0 - $value * $lambda);
- }
- }
-
- return Functions::VALUE();
- }
-
- private static function betaFunction($a, $b)
- {
- return (self::gamma($a) * self::gamma($b)) / self::gamma($a + $b);
- }
-
- private static function regularizedIncompleteBeta($value, $a, $b)
- {
- return self::incompleteBeta($value, $a, $b) / self::betaFunction($a, $b);
+ return Statistical\Distributions\Exponential::distribution($value, $lambda, $cumulative);
}
/**
@@ -1501,6 +503,11 @@ class Statistical
* For example, you can examine the test scores of men and women entering high school, and determine
* if the variability in the females is different from that found in the males.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\F::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Exponential class instead
+ *
* @param float $value Value of the function
* @param int $u The numerator degrees of freedom
* @param int $v The denominator degrees of freedom
@@ -1511,32 +518,7 @@ class Statistical
*/
public static function FDIST2($value, $u, $v, $cumulative)
{
- $value = Functions::flattenSingleValue($value);
- $u = Functions::flattenSingleValue($u);
- $v = Functions::flattenSingleValue($v);
- $cumulative = Functions::flattenSingleValue($cumulative);
-
- if (is_numeric($value) && is_numeric($u) && is_numeric($v)) {
- if ($value < 0 || $u < 1 || $v < 1) {
- return Functions::NAN();
- }
-
- $cumulative = (bool) $cumulative;
- $u = (int) $u;
- $v = (int) $v;
-
- if ($cumulative) {
- $adjustedValue = ($u * $value) / ($u * $value + $v);
-
- return self::incompleteBeta($adjustedValue, $u / 2, $v / 2);
- }
-
- return (self::gamma(($v + $u) / 2) / (self::gamma($u / 2) * self::gamma($v / 2))) *
- (($u / $v) ** ($u / 2)) *
- (($value ** (($u - 2) / 2)) / ((1 + ($u / $v) * $value) ** (($u + $v) / 2)));
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\F::distribution($value, $u, $v, $cumulative);
}
/**
@@ -1546,23 +528,18 @@ class Statistical
* is normally distributed rather than skewed. Use this function to perform hypothesis
* testing on the correlation coefficient.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Fisher::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Fisher class instead
+ *
* @param float $value
*
* @return float|string
*/
public static function FISHER($value)
{
- $value = Functions::flattenSingleValue($value);
-
- if (is_numeric($value)) {
- if (($value <= -1) || ($value >= 1)) {
- return Functions::NAN();
- }
-
- return 0.5 * log((1 + $value) / (1 - $value));
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Fisher::distribution($value);
}
/**
@@ -1572,19 +549,18 @@ class Statistical
* analyzing correlations between ranges or arrays of data. If y = FISHER(x), then
* FISHERINV(y) = x.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Fisher::inverse()
+ * Use the inverse() method in the Statistical\Distributions\Fisher class instead
+ *
* @param float $value
*
* @return float|string
*/
public static function FISHERINV($value)
{
- $value = Functions::flattenSingleValue($value);
-
- if (is_numeric($value)) {
- return (exp(2 * $value) - 1) / (exp(2 * $value) + 1);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Fisher::inverse($value);
}
/**
@@ -1592,6 +568,11 @@ class Statistical
*
* Calculates, or predicts, a future value by using existing values. The predicted value is a y-value for a given x-value.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::FORECAST()
+ * Use the FORECAST() method in the Statistical\Trends class instead
+ *
* @param float $xValue Value of X for which we want to find Y
* @param mixed $yValues array of mixed Data Series Y
* @param mixed $xValues of mixed Data Series X
@@ -1600,30 +581,18 @@ class Statistical
*/
public static function FORECAST($xValue, $yValues, $xValues)
{
- $xValue = Functions::flattenSingleValue($xValue);
- if (!is_numeric($xValue)) {
- return Functions::VALUE();
- } elseif (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return Functions::DIV0();
- }
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
-
- return $bestFitLinear->getValueOfYForX($xValue);
+ return Trends::FORECAST($xValue, $yValues, $xValues);
}
/**
* GAMMA.
*
- * Return the gamma function value.
+ * Returns the gamma function value.
+ *
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Gamma::gamma()
+ * Use the gamma() method in the Statistical\Distributions\Gamma class instead
*
* @param float $value
*
@@ -1631,14 +600,7 @@ class Statistical
*/
public static function GAMMAFunction($value)
{
- $value = Functions::flattenSingleValue($value);
- if (!is_numeric($value)) {
- return Functions::VALUE();
- } elseif ((((int) $value) == ((float) $value)) && $value <= 0.0) {
- return Functions::NAN();
- }
-
- return self::gamma($value);
+ return Statistical\Distributions\Gamma::gamma($value);
}
/**
@@ -1646,6 +608,11 @@ class Statistical
*
* Returns the gamma distribution.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Gamma::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Gamma class instead
+ *
* @param float $value Value at which you want to evaluate the distribution
* @param float $a Parameter to the distribution
* @param float $b Parameter to the distribution
@@ -1655,24 +622,7 @@ class Statistical
*/
public static function GAMMADIST($value, $a, $b, $cumulative)
{
- $value = Functions::flattenSingleValue($value);
- $a = Functions::flattenSingleValue($a);
- $b = Functions::flattenSingleValue($b);
-
- if ((is_numeric($value)) && (is_numeric($a)) && (is_numeric($b))) {
- if (($value < 0) || ($a <= 0) || ($b <= 0)) {
- return Functions::NAN();
- }
- if ((is_numeric($cumulative)) || (is_bool($cumulative))) {
- if ($cumulative) {
- return self::incompleteGamma($a, $value / $b) / self::gamma($a);
- }
-
- return (1 / ($b ** $a * self::gamma($a))) * $value ** ($a - 1) * exp(0 - ($value / $b));
- }
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Gamma::distribution($value, $a, $b, $cumulative);
}
/**
@@ -1680,6 +630,11 @@ class Statistical
*
* Returns the inverse of the Gamma distribution.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Gamma::inverse()
+ * Use the inverse() method in the Statistical\Distributions\Gamma class instead
+ *
* @param float $probability Probability at which you want to evaluate the distribution
* @param float $alpha Parameter to the distribution
* @param float $beta Parameter to the distribution
@@ -1688,53 +643,7 @@ class Statistical
*/
public static function GAMMAINV($probability, $alpha, $beta)
{
- $probability = Functions::flattenSingleValue($probability);
- $alpha = Functions::flattenSingleValue($alpha);
- $beta = Functions::flattenSingleValue($beta);
-
- if ((is_numeric($probability)) && (is_numeric($alpha)) && (is_numeric($beta))) {
- if (($alpha <= 0) || ($beta <= 0) || ($probability < 0) || ($probability > 1)) {
- return Functions::NAN();
- }
-
- $xLo = 0;
- $xHi = $alpha * $beta * 5;
-
- $x = $xNew = 1;
- $dx = 1024;
- $i = 0;
-
- while ((abs($dx) > Functions::PRECISION) && ($i++ < self::MAX_ITERATIONS)) {
- // Apply Newton-Raphson step
- $error = self::GAMMADIST($x, $alpha, $beta, true) - $probability;
- if ($error < 0.0) {
- $xLo = $x;
- } else {
- $xHi = $x;
- }
- $pdf = self::GAMMADIST($x, $alpha, $beta, false);
- // Avoid division by zero
- if ($pdf != 0.0) {
- $dx = $error / $pdf;
- $xNew = $x - $dx;
- }
- // If the NR fails to converge (which for example may be the
- // case if the initial guess is too rough) we apply a bisection
- // step to determine a more narrow interval around the root.
- if (($xNew < $xLo) || ($xNew > $xHi) || ($pdf == 0.0)) {
- $xNew = ($xLo + $xHi) / 2;
- $dx = $xNew - $x;
- }
- $x = $xNew;
- }
- if ($i == self::MAX_ITERATIONS) {
- return Functions::NA();
- }
-
- return $x;
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Gamma::inverse($probability, $alpha, $beta);
}
/**
@@ -1742,23 +651,18 @@ class Statistical
*
* Returns the natural logarithm of the gamma function.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Gamma::ln()
+ * Use the ln() method in the Statistical\Distributions\Gamma class instead
+ *
* @param float $value
*
* @return float|string
*/
public static function GAMMALN($value)
{
- $value = Functions::flattenSingleValue($value);
-
- if (is_numeric($value)) {
- if ($value <= 0) {
- return Functions::NAN();
- }
-
- return log(self::gamma($value));
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Gamma::ln($value);
}
/**
@@ -1778,7 +682,7 @@ class Statistical
return Functions::VALUE();
}
- return self::NORMDIST($value, 0, 1, true) - 0.5;
+ return Statistical\Distributions\Normal::distribution($value, 0, 1, true) - 0.5;
}
/**
@@ -1799,10 +703,10 @@ class Statistical
{
$aArgs = Functions::flattenArray($args);
- $aMean = MathTrig::PRODUCT($aArgs);
+ $aMean = MathTrig\Product::funcProduct($aArgs);
if (is_numeric($aMean) && ($aMean > 0)) {
- $aCount = self::COUNT($aArgs);
- if (self::MIN($aArgs) > 0) {
+ $aCount = Counts::COUNT($aArgs);
+ if (Minimum::MIN($aArgs) > 0) {
return $aMean ** (1 / $aCount);
}
}
@@ -1815,31 +719,21 @@ class Statistical
*
* Returns values along a predicted exponential Trend
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::GROWTH()
+ * Use the GROWTH() method in the Statistical\Trends class instead
+ *
* @param mixed[] $yValues Data Series Y
* @param mixed[] $xValues Data Series X
* @param mixed[] $newValues Values of X for which we want to find Y
* @param bool $const a logical value specifying whether to force the intersect to equal 0
*
- * @return array of float
+ * @return float[]
*/
public static function GROWTH($yValues, $xValues = [], $newValues = [], $const = true)
{
- $yValues = Functions::flattenArray($yValues);
- $xValues = Functions::flattenArray($xValues);
- $newValues = Functions::flattenArray($newValues);
- $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const);
-
- $bestFitExponential = Trend::calculate(Trend::TREND_EXPONENTIAL, $yValues, $xValues, $const);
- if (empty($newValues)) {
- $newValues = $bestFitExponential->getXValues();
- }
-
- $returnArray = [];
- foreach ($newValues as $xValue) {
- $returnArray[0][] = $bestFitExponential->getValueOfYForX($xValue);
- }
-
- return $returnArray;
+ return Trends::GROWTH($yValues, $xValues, $newValues, $const);
}
/**
@@ -1862,7 +756,7 @@ class Statistical
// Loop through arguments
$aArgs = Functions::flattenArray($args);
- if (self::MIN($aArgs) < 0) {
+ if (Minimum::MIN($aArgs) < 0) {
return Functions::NAN();
}
$aCount = 0;
@@ -1891,42 +785,26 @@ class Statistical
* Returns the hypergeometric distribution. HYPGEOMDIST returns the probability of a given number of
* sample successes, given the sample size, population successes, and population size.
*
- * @param float $sampleSuccesses Number of successes in the sample
- * @param float $sampleNumber Size of the sample
- * @param float $populationSuccesses Number of successes in the population
- * @param float $populationNumber Population size
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\HyperGeometric::distribution()
+ * Use the distribution() method in the Statistical\Distributions\HyperGeometric class instead
+ *
+ * @param mixed $sampleSuccesses Number of successes in the sample
+ * @param mixed $sampleNumber Size of the sample
+ * @param mixed $populationSuccesses Number of successes in the population
+ * @param mixed $populationNumber Population size
*
* @return float|string
*/
public static function HYPGEOMDIST($sampleSuccesses, $sampleNumber, $populationSuccesses, $populationNumber)
{
- $sampleSuccesses = Functions::flattenSingleValue($sampleSuccesses);
- $sampleNumber = Functions::flattenSingleValue($sampleNumber);
- $populationSuccesses = Functions::flattenSingleValue($populationSuccesses);
- $populationNumber = Functions::flattenSingleValue($populationNumber);
-
- if ((is_numeric($sampleSuccesses)) && (is_numeric($sampleNumber)) && (is_numeric($populationSuccesses)) && (is_numeric($populationNumber))) {
- $sampleSuccesses = floor($sampleSuccesses);
- $sampleNumber = floor($sampleNumber);
- $populationSuccesses = floor($populationSuccesses);
- $populationNumber = floor($populationNumber);
-
- if (($sampleSuccesses < 0) || ($sampleSuccesses > $sampleNumber) || ($sampleSuccesses > $populationSuccesses)) {
- return Functions::NAN();
- }
- if (($sampleNumber <= 0) || ($sampleNumber > $populationNumber)) {
- return Functions::NAN();
- }
- if (($populationSuccesses <= 0) || ($populationSuccesses > $populationNumber)) {
- return Functions::NAN();
- }
-
- return MathTrig::COMBIN($populationSuccesses, $sampleSuccesses) *
- MathTrig::COMBIN($populationNumber - $populationSuccesses, $sampleNumber - $sampleSuccesses) /
- MathTrig::COMBIN($populationNumber, $sampleNumber);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\HyperGeometric::distribution(
+ $sampleSuccesses,
+ $sampleNumber,
+ $populationSuccesses,
+ $populationNumber
+ );
}
/**
@@ -1934,6 +812,11 @@ class Statistical
*
* Calculates the point at which a line will intersect the y-axis by using existing x-values and y-values.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::INTERCEPT()
+ * Use the INTERCEPT() method in the Statistical\Trends class instead
+ *
* @param mixed[] $yValues Data Series Y
* @param mixed[] $xValues Data Series X
*
@@ -1941,21 +824,7 @@ class Statistical
*/
public static function INTERCEPT($yValues, $xValues)
{
- if (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return Functions::DIV0();
- }
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
-
- return $bestFitLinear->getIntersect();
+ return Trends::INTERCEPT($yValues, $xValues);
}
/**
@@ -1973,8 +842,8 @@ class Statistical
public static function KURT(...$args)
{
$aArgs = Functions::flattenArrayIndexed($args);
- $mean = self::AVERAGE($aArgs);
- $stdDev = self::STDEV($aArgs);
+ $mean = Averages::average($aArgs);
+ $stdDev = StandardDeviations::STDEV($aArgs);
if ($stdDev > 0) {
$count = $summer = 0;
@@ -2031,7 +900,7 @@ class Statistical
$mArgs[] = $arg;
}
}
- $count = self::COUNT($mArgs);
+ $count = Counts::COUNT($mArgs);
--$entry;
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
return Functions::NAN();
@@ -2050,6 +919,11 @@ class Statistical
* Calculates the statistics for a line by using the "least squares" method to calculate a straight line that best fits your data,
* and then returns an array that describes the line.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::LINEST()
+ * Use the LINEST() method in the Statistical\Trends class instead
+ *
* @param mixed[] $yValues Data Series Y
* @param null|mixed[] $xValues Data Series X
* @param bool $const a logical value specifying whether to force the intersect to equal 0
@@ -2059,48 +933,7 @@ class Statistical
*/
public static function LINEST($yValues, $xValues = null, $const = true, $stats = false)
{
- $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const);
- $stats = ($stats === null) ? false : (bool) Functions::flattenSingleValue($stats);
- if ($xValues === null) {
- $xValues = range(1, count(Functions::flattenArray($yValues)));
- }
-
- if (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return 0;
- }
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues, $const);
- if ($stats) {
- return [
- [
- $bestFitLinear->getSlope(),
- $bestFitLinear->getSlopeSE(),
- $bestFitLinear->getGoodnessOfFit(),
- $bestFitLinear->getF(),
- $bestFitLinear->getSSRegression(),
- ],
- [
- $bestFitLinear->getIntersect(),
- $bestFitLinear->getIntersectSE(),
- $bestFitLinear->getStdevOfResiduals(),
- $bestFitLinear->getDFResiduals(),
- $bestFitLinear->getSSResiduals(),
- ],
- ];
- }
-
- return [
- $bestFitLinear->getSlope(),
- $bestFitLinear->getIntersect(),
- ];
+ return Trends::LINEST($yValues, $xValues, $const, $stats);
}
/**
@@ -2109,6 +942,11 @@ class Statistical
* Calculates an exponential curve that best fits the X and Y data series,
* and then returns an array that describes the line.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::LOGEST()
+ * Use the LOGEST() method in the Statistical\Trends class instead
+ *
* @param mixed[] $yValues Data Series Y
* @param null|mixed[] $xValues Data Series X
* @param bool $const a logical value specifying whether to force the intersect to equal 0
@@ -2118,54 +956,7 @@ class Statistical
*/
public static function LOGEST($yValues, $xValues = null, $const = true, $stats = false)
{
- $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const);
- $stats = ($stats === null) ? false : (bool) Functions::flattenSingleValue($stats);
- if ($xValues === null) {
- $xValues = range(1, count(Functions::flattenArray($yValues)));
- }
-
- if (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- foreach ($yValues as $value) {
- if ($value <= 0.0) {
- return Functions::NAN();
- }
- }
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return 1;
- }
-
- $bestFitExponential = Trend::calculate(Trend::TREND_EXPONENTIAL, $yValues, $xValues, $const);
- if ($stats) {
- return [
- [
- $bestFitExponential->getSlope(),
- $bestFitExponential->getSlopeSE(),
- $bestFitExponential->getGoodnessOfFit(),
- $bestFitExponential->getF(),
- $bestFitExponential->getSSRegression(),
- ],
- [
- $bestFitExponential->getIntersect(),
- $bestFitExponential->getIntersectSE(),
- $bestFitExponential->getStdevOfResiduals(),
- $bestFitExponential->getDFResiduals(),
- $bestFitExponential->getSSResiduals(),
- ],
- ];
- }
-
- return [
- $bestFitExponential->getSlope(),
- $bestFitExponential->getIntersect(),
- ];
+ return Trends::LOGEST($yValues, $xValues, $const, $stats);
}
/**
@@ -2173,6 +964,11 @@ class Statistical
*
* Returns the inverse of the normal cumulative distribution
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\LogNormal::inverse()
+ * Use the inverse() method in the Statistical\Distributions\LogNormal class instead
+ *
* @param float $probability
* @param float $mean
* @param float $stdDev
@@ -2185,19 +981,7 @@ class Statistical
*/
public static function LOGINV($probability, $mean, $stdDev)
{
- $probability = Functions::flattenSingleValue($probability);
- $mean = Functions::flattenSingleValue($mean);
- $stdDev = Functions::flattenSingleValue($stdDev);
-
- if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) {
- if (($probability < 0) || ($probability > 1) || ($stdDev <= 0)) {
- return Functions::NAN();
- }
-
- return exp($mean + $stdDev * self::NORMSINV($probability));
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\LogNormal::inverse($probability, $mean, $stdDev);
}
/**
@@ -2206,6 +990,11 @@ class Statistical
* Returns the cumulative lognormal distribution of x, where ln(x) is normally distributed
* with parameters mean and standard_dev.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\LogNormal::cumulative()
+ * Use the cumulative() method in the Statistical\Distributions\LogNormal class instead
+ *
* @param float $value
* @param float $mean
* @param float $stdDev
@@ -2214,19 +1003,7 @@ class Statistical
*/
public static function LOGNORMDIST($value, $mean, $stdDev)
{
- $value = Functions::flattenSingleValue($value);
- $mean = Functions::flattenSingleValue($mean);
- $stdDev = Functions::flattenSingleValue($stdDev);
-
- if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) {
- if (($value <= 0) || ($stdDev <= 0)) {
- return Functions::NAN();
- }
-
- return self::NORMSDIST((log($value) - $mean) / $stdDev);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\LogNormal::cumulative($value, $mean, $stdDev);
}
/**
@@ -2235,6 +1012,11 @@ class Statistical
* Returns the lognormal distribution of x, where ln(x) is normally distributed
* with parameters mean and standard_dev.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\LogNormal::distribution()
+ * Use the distribution() method in the Statistical\Distributions\LogNormal class instead
+ *
* @param float $value
* @param float $mean
* @param float $stdDev
@@ -2244,25 +1026,7 @@ class Statistical
*/
public static function LOGNORMDIST2($value, $mean, $stdDev, $cumulative = false)
{
- $value = Functions::flattenSingleValue($value);
- $mean = Functions::flattenSingleValue($mean);
- $stdDev = Functions::flattenSingleValue($stdDev);
- $cumulative = (bool) Functions::flattenSingleValue($cumulative);
-
- if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) {
- if (($value <= 0) || ($stdDev <= 0)) {
- return Functions::NAN();
- }
-
- if ($cumulative === true) {
- return self::NORMSDIST2((log($value) - $mean) / $stdDev, true);
- }
-
- return (1 / (sqrt(2 * M_PI) * $stdDev * $value)) *
- exp(0 - ((log($value) - $mean) ** 2 / (2 * $stdDev ** 2)));
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\LogNormal::distribution($value, $mean, $stdDev, $cumulative);
}
/**
@@ -2274,30 +1038,18 @@ class Statistical
* Excel Function:
* MAX(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Maximum::MAX()
+ * Use the MAX() method in the Statistical\Maximum class instead
+ *
* @param mixed ...$args Data values
*
* @return float
*/
public static function MAX(...$args)
{
- $returnValue = null;
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- foreach ($aArgs as $arg) {
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- if (($returnValue === null) || ($arg > $returnValue)) {
- $returnValue = $arg;
- }
- }
- }
-
- if ($returnValue === null) {
- return 0;
- }
-
- return $returnValue;
+ return Maximum::MAX(...$args);
}
/**
@@ -2308,35 +1060,18 @@ class Statistical
* Excel Function:
* MAXA(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Maximum::MAXA()
+ * Use the MAXA() method in the Statistical\Maximum class instead
+ *
* @param mixed ...$args Data values
*
* @return float
*/
public static function MAXA(...$args)
{
- $returnValue = null;
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- foreach ($aArgs as $arg) {
- // Is it a numeric value?
- if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- } elseif (is_string($arg)) {
- $arg = 0;
- }
- if (($returnValue === null) || ($arg > $returnValue)) {
- $returnValue = $arg;
- }
- }
- }
-
- if ($returnValue === null) {
- return 0;
- }
-
- return $returnValue;
+ return Maximum::MAXA(...$args);
}
/**
@@ -2347,53 +1082,18 @@ class Statistical
* Excel Function:
* MAXIFS(max_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...)
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Conditional::MAXIFS()
+ * Use the MAXIFS() method in the Statistical\Conditional class instead
+ *
* @param mixed $args Data range and criterias
*
* @return float
*/
public static function MAXIFS(...$args)
{
- $arrayList = $args;
-
- // Return value
- $returnValue = null;
-
- $maxArgs = Functions::flattenArray(array_shift($arrayList));
- $aArgsArray = [];
- $conditions = [];
-
- while (count($arrayList) > 0) {
- $aArgsArray[] = Functions::flattenArray(array_shift($arrayList));
- $conditions[] = Functions::ifCondition(array_shift($arrayList));
- }
-
- // Loop through each arg and see if arguments and conditions are true
- foreach ($maxArgs as $index => $value) {
- $valid = true;
-
- foreach ($conditions as $cidx => $condition) {
- $arg = $aArgsArray[$cidx][$index];
-
- // Loop through arguments
- if (!is_numeric($arg)) {
- $arg = Calculation::wrapResult(strtoupper($arg));
- }
- $testCondition = '=' . $arg . $condition;
- if (!Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
- // Is not a value within our criteria
- $valid = false;
-
- break; // if false found, don't need to check other conditions
- }
- }
-
- if ($valid) {
- $returnValue = $returnValue === null ? $value : max($value, $returnValue);
- }
- }
-
- // Return
- return $returnValue;
+ return Conditional::MAXIFS(...$args);
}
/**
@@ -2404,37 +1104,18 @@ class Statistical
* Excel Function:
* MEDIAN(value1[,value2[, ...]])
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Averages::median()
+ * Use the median() method in the Statistical\Averages class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string The result, or a string containing an error
*/
public static function MEDIAN(...$args)
{
- $returnValue = Functions::NAN();
-
- $mArgs = [];
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- foreach ($aArgs as $arg) {
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- $mArgs[] = $arg;
- }
- }
-
- $mValueCount = count($mArgs);
- if ($mValueCount > 0) {
- sort($mArgs, SORT_NUMERIC);
- $mValueCount = $mValueCount / 2;
- if ($mValueCount == floor($mValueCount)) {
- $returnValue = ($mArgs[$mValueCount--] + $mArgs[$mValueCount]) / 2;
- } else {
- $mValueCount = floor($mValueCount);
- $returnValue = $mArgs[$mValueCount];
- }
- }
-
- return $returnValue;
+ return Statistical\Averages::median(...$args);
}
/**
@@ -2446,30 +1127,18 @@ class Statistical
* Excel Function:
* MIN(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Minimum::MIN()
+ * Use the MIN() method in the Statistical\Minimum class instead
+ *
* @param mixed ...$args Data values
*
* @return float
*/
public static function MIN(...$args)
{
- $returnValue = null;
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- foreach ($aArgs as $arg) {
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- if (($returnValue === null) || ($arg < $returnValue)) {
- $returnValue = $arg;
- }
- }
- }
-
- if ($returnValue === null) {
- return 0;
- }
-
- return $returnValue;
+ return Minimum::MIN(...$args);
}
/**
@@ -2480,35 +1149,18 @@ class Statistical
* Excel Function:
* MINA(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Minimum::MINA()
+ * Use the MINA() method in the Statistical\Minimum class instead
+ *
* @param mixed ...$args Data values
*
* @return float
*/
public static function MINA(...$args)
{
- $returnValue = null;
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- foreach ($aArgs as $arg) {
- // Is it a numeric value?
- if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- } elseif (is_string($arg)) {
- $arg = 0;
- }
- if (($returnValue === null) || ($arg < $returnValue)) {
- $returnValue = $arg;
- }
- }
- }
-
- if ($returnValue === null) {
- return 0;
- }
-
- return $returnValue;
+ return Minimum::MINA(...$args);
}
/**
@@ -2519,102 +1171,18 @@ class Statistical
* Excel Function:
* MINIFS(min_range, criteria_range1, criteria1, [criteria_range2, criteria2], ...)
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Conditional::MINIFS()
+ * Use the MINIFS() method in the Statistical\Conditional class instead
+ *
* @param mixed $args Data range and criterias
*
* @return float
*/
public static function MINIFS(...$args)
{
- $arrayList = $args;
-
- // Return value
- $returnValue = null;
-
- $minArgs = Functions::flattenArray(array_shift($arrayList));
- $aArgsArray = [];
- $conditions = [];
-
- while (count($arrayList) > 0) {
- $aArgsArray[] = Functions::flattenArray(array_shift($arrayList));
- $conditions[] = Functions::ifCondition(array_shift($arrayList));
- }
-
- // Loop through each arg and see if arguments and conditions are true
- foreach ($minArgs as $index => $value) {
- $valid = true;
-
- foreach ($conditions as $cidx => $condition) {
- $arg = $aArgsArray[$cidx][$index];
-
- // Loop through arguments
- if (!is_numeric($arg)) {
- $arg = Calculation::wrapResult(strtoupper($arg));
- }
- $testCondition = '=' . $arg . $condition;
- if (!Calculation::getInstance()->_calculateFormulaValue($testCondition)) {
- // Is not a value within our criteria
- $valid = false;
-
- break; // if false found, don't need to check other conditions
- }
- }
-
- if ($valid) {
- $returnValue = $returnValue === null ? $value : min($value, $returnValue);
- }
- }
-
- // Return
- return $returnValue;
- }
-
- //
- // Special variant of array_count_values that isn't limited to strings and integers,
- // but can work with floating point numbers as values
- //
- private static function modeCalc($data)
- {
- $frequencyArray = [];
- $index = 0;
- $maxfreq = 0;
- $maxfreqkey = '';
- $maxfreqdatum = '';
- foreach ($data as $datum) {
- $found = false;
- ++$index;
- foreach ($frequencyArray as $key => $value) {
- if ((string) $value['value'] == (string) $datum) {
- ++$frequencyArray[$key]['frequency'];
- $freq = $frequencyArray[$key]['frequency'];
- if ($freq > $maxfreq) {
- $maxfreq = $freq;
- $maxfreqkey = $key;
- $maxfreqdatum = $datum;
- } elseif ($freq == $maxfreq) {
- if ($frequencyArray[$key]['index'] < $frequencyArray[$maxfreqkey]['index']) {
- $maxfreqkey = $key;
- $maxfreqdatum = $datum;
- }
- }
- $found = true;
-
- break;
- }
- }
- if (!$found) {
- $frequencyArray[] = [
- 'value' => $datum,
- 'frequency' => 1,
- 'index' => $index,
- ];
- }
- }
-
- if ($maxfreq <= 1) {
- return Functions::NA();
- }
-
- return $maxfreqdatum;
+ return Conditional::MINIFS(...$args);
}
/**
@@ -2625,30 +1193,18 @@ class Statistical
* Excel Function:
* MODE(value1[,value2[, ...]])
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Averages::mode()
+ * Use the mode() method in the Statistical\Averages class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string The result, or a string containing an error
*/
public static function MODE(...$args)
{
- $returnValue = Functions::NA();
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
-
- $mArgs = [];
- foreach ($aArgs as $arg) {
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- $mArgs[] = $arg;
- }
- }
-
- if (!empty($mArgs)) {
- return self::modeCalc($mArgs);
- }
-
- return $returnValue;
+ return Statistical\Averages::mode(...$args);
}
/**
@@ -2660,34 +1216,20 @@ class Statistical
* distribution, except that the number of successes is fixed, and the number of trials is
* variable. Like the binomial, trials are assumed to be independent.
*
- * @param float $failures Number of Failures
- * @param float $successes Threshold number of Successes
- * @param float $probability Probability of success on each trial
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Binomial::negative()
+ * Use the negative() method in the Statistical\Distributions\Binomial class instead
+ *
+ * @param mixed $failures Number of Failures
+ * @param mixed $successes Threshold number of Successes
+ * @param mixed $probability Probability of success on each trial
*
* @return float|string The result, or a string containing an error
*/
public static function NEGBINOMDIST($failures, $successes, $probability)
{
- $failures = floor(Functions::flattenSingleValue($failures));
- $successes = floor(Functions::flattenSingleValue($successes));
- $probability = Functions::flattenSingleValue($probability);
-
- if ((is_numeric($failures)) && (is_numeric($successes)) && (is_numeric($probability))) {
- if (($failures < 0) || ($successes < 1)) {
- return Functions::NAN();
- } elseif (($probability < 0) || ($probability > 1)) {
- return Functions::NAN();
- }
- if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) {
- if (($failures + $successes - 1) <= 0) {
- return Functions::NAN();
- }
- }
-
- return (MathTrig::COMBIN($failures + $successes - 1, $successes - 1)) * ($probability ** $successes) * ((1 - $probability) ** $failures);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Binomial::negative($failures, $successes, $probability);
}
/**
@@ -2697,33 +1239,21 @@ class Statistical
* function has a very wide range of applications in statistics, including hypothesis
* testing.
*
- * @param float $value
- * @param float $mean Mean Value
- * @param float $stdDev Standard Deviation
- * @param bool $cumulative
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Normal::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Normal class instead
+ *
+ * @param mixed $value
+ * @param mixed $mean Mean Value
+ * @param mixed $stdDev Standard Deviation
+ * @param mixed $cumulative
*
* @return float|string The result, or a string containing an error
*/
public static function NORMDIST($value, $mean, $stdDev, $cumulative)
{
- $value = Functions::flattenSingleValue($value);
- $mean = Functions::flattenSingleValue($mean);
- $stdDev = Functions::flattenSingleValue($stdDev);
-
- if ((is_numeric($value)) && (is_numeric($mean)) && (is_numeric($stdDev))) {
- if ($stdDev < 0) {
- return Functions::NAN();
- }
- if ((is_numeric($cumulative)) || (is_bool($cumulative))) {
- if ($cumulative) {
- return 0.5 * (1 + Engineering::erfVal(($value - $mean) / ($stdDev * sqrt(2))));
- }
-
- return (1 / (self::SQRT2PI * $stdDev)) * exp(0 - (($value - $mean) ** 2 / (2 * ($stdDev * $stdDev))));
- }
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Normal::distribution($value, $mean, $stdDev, $cumulative);
}
/**
@@ -2731,30 +1261,20 @@ class Statistical
*
* Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation.
*
- * @param float $probability
- * @param float $mean Mean Value
- * @param float $stdDev Standard Deviation
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Normal::inverse()
+ * Use the inverse() method in the Statistical\Distributions\Normal class instead
+ *
+ * @param mixed $probability
+ * @param mixed $mean Mean Value
+ * @param mixed $stdDev Standard Deviation
*
* @return float|string The result, or a string containing an error
*/
public static function NORMINV($probability, $mean, $stdDev)
{
- $probability = Functions::flattenSingleValue($probability);
- $mean = Functions::flattenSingleValue($mean);
- $stdDev = Functions::flattenSingleValue($stdDev);
-
- if ((is_numeric($probability)) && (is_numeric($mean)) && (is_numeric($stdDev))) {
- if (($probability < 0) || ($probability > 1)) {
- return Functions::NAN();
- }
- if ($stdDev < 0) {
- return Functions::NAN();
- }
-
- return (self::inverseNcdf($probability) * $stdDev) + $mean;
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Normal::inverse($probability, $mean, $stdDev);
}
/**
@@ -2764,18 +1284,18 @@ class Statistical
* a mean of 0 (zero) and a standard deviation of one. Use this function in place of a
* table of standard normal curve areas.
*
- * @param float $value
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\StandardNormal::cumulative()
+ * Use the cumulative() method in the Statistical\Distributions\StandardNormal class instead
+ *
+ * @param mixed $value
*
* @return float|string The result, or a string containing an error
*/
public static function NORMSDIST($value)
{
- $value = Functions::flattenSingleValue($value);
- if (!is_numeric($value)) {
- return Functions::VALUE();
- }
-
- return self::NORMDIST($value, 0, 1, true);
+ return Statistical\Distributions\StandardNormal::cumulative($value);
}
/**
@@ -2785,20 +1305,19 @@ class Statistical
* a mean of 0 (zero) and a standard deviation of one. Use this function in place of a
* table of standard normal curve areas.
*
- * @param float $value
- * @param bool $cumulative
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\StandardNormal::distribution()
+ * Use the distribution() method in the Statistical\Distributions\StandardNormal class instead
+ *
+ * @param mixed $value
+ * @param mixed $cumulative
*
* @return float|string The result, or a string containing an error
*/
public static function NORMSDIST2($value, $cumulative)
{
- $value = Functions::flattenSingleValue($value);
- if (!is_numeric($value)) {
- return Functions::VALUE();
- }
- $cumulative = (bool) Functions::flattenSingleValue($cumulative);
-
- return self::NORMDIST($value, 0, 1, $cumulative);
+ return Statistical\Distributions\StandardNormal::distribution($value, $cumulative);
}
/**
@@ -2806,13 +1325,18 @@ class Statistical
*
* Returns the inverse of the standard normal cumulative distribution
*
- * @param float $value
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\StandardNormal::inverse()
+ * Use the inverse() method in the Statistical\Distributions\StandardNormal class instead
+ *
+ * @param mixed $value
*
* @return float|string The result, or a string containing an error
*/
public static function NORMSINV($value)
{
- return self::NORMINV($value, 0, 1);
+ return Statistical\Distributions\StandardNormal::inverse($value);
}
/**
@@ -2823,92 +1347,42 @@ class Statistical
* Excel Function:
* PERCENTILE(value1[,value2[, ...]],entry)
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Percentiles::PERCENTILE()
+ * Use the PERCENTILE() method in the Statistical\Percentiles class instead
+ *
* @param mixed $args Data values
*
* @return float|string The result, or a string containing an error
*/
public static function PERCENTILE(...$args)
{
- $aArgs = Functions::flattenArray($args);
-
- // Calculate
- $entry = array_pop($aArgs);
-
- if ((is_numeric($entry)) && (!is_string($entry))) {
- if (($entry < 0) || ($entry > 1)) {
- return Functions::NAN();
- }
- $mArgs = [];
- foreach ($aArgs as $arg) {
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- $mArgs[] = $arg;
- }
- }
- $mValueCount = count($mArgs);
- if ($mValueCount > 0) {
- sort($mArgs);
- $count = self::COUNT($mArgs);
- $index = $entry * ($count - 1);
- $iBase = floor($index);
- if ($index == $iBase) {
- return $mArgs[$index];
- }
- $iNext = $iBase + 1;
- $iProportion = $index - $iBase;
-
- return $mArgs[$iBase] + (($mArgs[$iNext] - $mArgs[$iBase]) * $iProportion);
- }
- }
-
- return Functions::VALUE();
+ return Statistical\Percentiles::PERCENTILE(...$args);
}
/**
* PERCENTRANK.
*
* Returns the rank of a value in a data set as a percentage of the data set.
+ * Note that the returned rank is simply rounded to the appropriate significant digits,
+ * rather than floored (as MS Excel), so value 3 for a value set of 1, 2, 3, 4 will return
+ * 0.667 rather than 0.666
*
- * @param float[] $valueSet An array of, or a reference to, a list of numbers
- * @param int $value the number whose rank you want to find
- * @param int $significance the number of significant digits for the returned percentage value
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Percentiles::PERCENTRANK()
+ * Use the PERCENTRANK() method in the Statistical\Percentiles class instead
+ *
+ * @param mixed $valueSet An array of, or a reference to, a list of numbers
+ * @param mixed $value the number whose rank you want to find
+ * @param mixed $significance the number of significant digits for the returned percentage value
*
* @return float|string (string if result is an error)
*/
public static function PERCENTRANK($valueSet, $value, $significance = 3)
{
- $valueSet = Functions::flattenArray($valueSet);
- $value = Functions::flattenSingleValue($value);
- $significance = ($significance === null) ? 3 : (int) Functions::flattenSingleValue($significance);
-
- foreach ($valueSet as $key => $valueEntry) {
- if (!is_numeric($valueEntry)) {
- unset($valueSet[$key]);
- }
- }
- sort($valueSet, SORT_NUMERIC);
- $valueCount = count($valueSet);
- if ($valueCount == 0) {
- return Functions::NAN();
- }
-
- $valueAdjustor = $valueCount - 1;
- if (($value < $valueSet[0]) || ($value > $valueSet[$valueAdjustor])) {
- return Functions::NA();
- }
-
- $pos = array_search($value, $valueSet);
- if ($pos === false) {
- $pos = 0;
- $testValue = $valueSet[0];
- while ($testValue < $value) {
- $testValue = $valueSet[++$pos];
- }
- --$pos;
- $pos += (($value - $valueSet[$pos]) / ($testValue - $valueSet[$pos]));
- }
-
- return round($pos / $valueAdjustor, $significance);
+ return Statistical\Percentiles::PERCENTRANK($valueSet, $value, $significance);
}
/**
@@ -2920,6 +1394,11 @@ class Statistical
* combinations, for which the internal order is not significant. Use this function
* for lottery-style probability calculations.
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Permutations::PERMUT()
+ * Use the PERMUT() method in the Statistical\Permutations class instead
+ *
* @param int $numObjs Number of different objects
* @param int $numInSet Number of objects in each permutation
*
@@ -2927,19 +1406,7 @@ class Statistical
*/
public static function PERMUT($numObjs, $numInSet)
{
- $numObjs = Functions::flattenSingleValue($numObjs);
- $numInSet = Functions::flattenSingleValue($numInSet);
-
- if ((is_numeric($numObjs)) && (is_numeric($numInSet))) {
- $numInSet = floor($numInSet);
- if ($numObjs < $numInSet) {
- return Functions::NAN();
- }
-
- return round(MathTrig::FACT($numObjs) / MathTrig::FACT($numObjs - $numInSet));
- }
-
- return Functions::VALUE();
+ return Permutations::PERMUT($numObjs, $numInSet);
}
/**
@@ -2949,37 +1416,20 @@ class Statistical
* is predicting the number of events over a specific time, such as the number of
* cars arriving at a toll plaza in 1 minute.
*
- * @param float $value
- * @param float $mean Mean Value
- * @param bool $cumulative
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Poisson::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Poisson class instead
+ *
+ * @param mixed $value
+ * @param mixed $mean Mean Value
+ * @param mixed $cumulative
*
* @return float|string The result, or a string containing an error
*/
public static function POISSON($value, $mean, $cumulative)
{
- $value = Functions::flattenSingleValue($value);
- $mean = Functions::flattenSingleValue($mean);
-
- if ((is_numeric($value)) && (is_numeric($mean))) {
- if (($value < 0) || ($mean <= 0)) {
- return Functions::NAN();
- }
- if ((is_numeric($cumulative)) || (is_bool($cumulative))) {
- if ($cumulative) {
- $summer = 0;
- $floor = floor($value);
- for ($i = 0; $i <= $floor; ++$i) {
- $summer += $mean ** $i / MathTrig::FACT($i);
- }
-
- return exp(0 - $mean) * $summer;
- }
-
- return (exp(0 - $mean) * $mean ** $value) / MathTrig::FACT($value);
- }
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Poisson::distribution($value, $mean, $cumulative);
}
/**
@@ -2990,27 +1440,18 @@ class Statistical
* Excel Function:
* QUARTILE(value1[,value2[, ...]],entry)
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Percentiles::QUARTILE()
+ * Use the QUARTILE() method in the Statistical\Percentiles class instead
+ *
* @param mixed $args Data values
*
* @return float|string The result, or a string containing an error
*/
public static function QUARTILE(...$args)
{
- $aArgs = Functions::flattenArray($args);
-
- // Calculate
- $entry = floor(array_pop($aArgs));
-
- if ((is_numeric($entry)) && (!is_string($entry))) {
- $entry /= 4;
- if (($entry < 0) || ($entry > 1)) {
- return Functions::NAN();
- }
-
- return self::PERCENTILE($aArgs, $entry);
- }
-
- return Functions::VALUE();
+ return Statistical\Percentiles::QUARTILE(...$args);
}
/**
@@ -3018,35 +1459,20 @@ class Statistical
*
* Returns the rank of a number in a list of numbers.
*
- * @param int $value the number whose rank you want to find
- * @param float[] $valueSet An array of, or a reference to, a list of numbers
- * @param int $order Order to sort the values in the value set
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Percentiles::RANK()
+ * Use the RANK() method in the Statistical\Percentiles class instead
+ *
+ * @param mixed $value the number whose rank you want to find
+ * @param mixed $valueSet An array of, or a reference to, a list of numbers
+ * @param mixed $order Order to sort the values in the value set
*
* @return float|string The result, or a string containing an error
*/
public static function RANK($value, $valueSet, $order = 0)
{
- $value = Functions::flattenSingleValue($value);
- $valueSet = Functions::flattenArray($valueSet);
- $order = ($order === null) ? 0 : (int) Functions::flattenSingleValue($order);
-
- foreach ($valueSet as $key => $valueEntry) {
- if (!is_numeric($valueEntry)) {
- unset($valueSet[$key]);
- }
- }
-
- if ($order == 0) {
- rsort($valueSet, SORT_NUMERIC);
- } else {
- sort($valueSet, SORT_NUMERIC);
- }
- $pos = array_search($value, $valueSet);
- if ($pos === false) {
- return Functions::NA();
- }
-
- return ++$pos;
+ return Statistical\Percentiles::RANK($value, $valueSet, $order);
}
/**
@@ -3054,6 +1480,11 @@ class Statistical
*
* Returns the square of the Pearson product moment correlation coefficient through data points in known_y's and known_x's.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::RSQ()
+ * Use the RSQ() method in the Statistical\Trends class instead
+ *
* @param mixed[] $yValues Data Series Y
* @param mixed[] $xValues Data Series X
*
@@ -3061,21 +1492,7 @@ class Statistical
*/
public static function RSQ($yValues, $xValues)
{
- if (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return Functions::DIV0();
- }
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
-
- return $bestFitLinear->getGoodnessOfFit();
+ return Trends::RSQ($yValues, $xValues);
}
/**
@@ -3093,16 +1510,19 @@ class Statistical
public static function SKEW(...$args)
{
$aArgs = Functions::flattenArrayIndexed($args);
- $mean = self::AVERAGE($aArgs);
- $stdDev = self::STDEV($aArgs);
+ $mean = Averages::average($aArgs);
+ $stdDev = StandardDeviations::STDEV($aArgs);
+
+ if ($stdDev === 0.0 || is_string($stdDev)) {
+ return Functions::DIV0();
+ }
$count = $summer = 0;
// Loop through arguments
foreach ($aArgs as $k => $arg) {
- if (
- (is_bool($arg)) &&
- (!Functions::isMatrixValue($k))
- ) {
+ if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
+ } elseif (!is_numeric($arg)) {
+ return Functions::VALUE();
} else {
// Is it a numeric value?
if ((is_numeric($arg)) && (!is_string($arg))) {
@@ -3124,6 +1544,11 @@ class Statistical
*
* Returns the slope of the linear regression line through data points in known_y's and known_x's.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::SLOPE()
+ * Use the SLOPE() method in the Statistical\Trends class instead
+ *
* @param mixed[] $yValues Data Series Y
* @param mixed[] $xValues Data Series X
*
@@ -3131,21 +1556,7 @@ class Statistical
*/
public static function SLOPE($yValues, $xValues)
{
- if (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return Functions::DIV0();
- }
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
-
- return $bestFitLinear->getSlope();
+ return Trends::SLOPE($yValues, $xValues);
}
/**
@@ -3178,7 +1589,7 @@ class Statistical
$mArgs[] = $arg;
}
}
- $count = self::COUNT($mArgs);
+ $count = Counts::COUNT($mArgs);
--$entry;
if (($entry < 0) || ($entry >= $count) || ($count == 0)) {
return Functions::NAN();
@@ -3228,45 +1639,18 @@ class Statistical
* Excel Function:
* STDEV(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\StandardDeviations::STDEV()
+ * Use the STDEV() method in the Statistical\StandardDeviations class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string The result, or a string containing an error
*/
public static function STDEV(...$args)
{
- $aArgs = Functions::flattenArrayIndexed($args);
-
- // Return value
- $returnValue = null;
-
- $aMean = self::AVERAGE($aArgs);
- if ($aMean !== null) {
- $aCount = -1;
- foreach ($aArgs as $k => $arg) {
- if (
- (is_bool($arg)) &&
- ((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
- ) {
- $arg = (int) $arg;
- }
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- if ($returnValue === null) {
- $returnValue = ($arg - $aMean) ** 2;
- } else {
- $returnValue += ($arg - $aMean) ** 2;
- }
- ++$aCount;
- }
- }
-
- // Return
- if (($aCount > 0) && ($returnValue >= 0)) {
- return sqrt($returnValue / $aCount);
- }
- }
-
- return Functions::DIV0();
+ return StandardDeviations::STDEV(...$args);
}
/**
@@ -3277,48 +1661,18 @@ class Statistical
* Excel Function:
* STDEVA(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\StandardDeviations::STDEVA()
+ * Use the STDEVA() method in the Statistical\StandardDeviations class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function STDEVA(...$args)
{
- $aArgs = Functions::flattenArrayIndexed($args);
-
- $returnValue = null;
-
- $aMean = self::AVERAGEA($aArgs);
- if ($aMean !== null) {
- $aCount = -1;
- foreach ($aArgs as $k => $arg) {
- if (
- (is_bool($arg)) &&
- (!Functions::isMatrixValue($k))
- ) {
- } else {
- // Is it a numeric value?
- if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- } elseif (is_string($arg)) {
- $arg = 0;
- }
- if ($returnValue === null) {
- $returnValue = ($arg - $aMean) ** 2;
- } else {
- $returnValue += ($arg - $aMean) ** 2;
- }
- ++$aCount;
- }
- }
- }
-
- if (($aCount > 0) && ($returnValue >= 0)) {
- return sqrt($returnValue / $aCount);
- }
- }
-
- return Functions::DIV0();
+ return StandardDeviations::STDEVA(...$args);
}
/**
@@ -3329,43 +1683,18 @@ class Statistical
* Excel Function:
* STDEVP(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\StandardDeviations::STDEVP()
+ * Use the STDEVP() method in the Statistical\StandardDeviations class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function STDEVP(...$args)
{
- $aArgs = Functions::flattenArrayIndexed($args);
-
- $returnValue = null;
-
- $aMean = self::AVERAGE($aArgs);
- if ($aMean !== null) {
- $aCount = 0;
- foreach ($aArgs as $k => $arg) {
- if (
- (is_bool($arg)) &&
- ((!Functions::isCellValue($k)) || (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE))
- ) {
- $arg = (int) $arg;
- }
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- if ($returnValue === null) {
- $returnValue = ($arg - $aMean) ** 2;
- } else {
- $returnValue += ($arg - $aMean) ** 2;
- }
- ++$aCount;
- }
- }
-
- if (($aCount > 0) && ($returnValue >= 0)) {
- return sqrt($returnValue / $aCount);
- }
- }
-
- return Functions::DIV0();
+ return StandardDeviations::STDEVP(...$args);
}
/**
@@ -3376,53 +1705,28 @@ class Statistical
* Excel Function:
* STDEVPA(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\StandardDeviations::STDEVPA()
+ * Use the STDEVPA() method in the Statistical\StandardDeviations class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string
*/
public static function STDEVPA(...$args)
{
- $aArgs = Functions::flattenArrayIndexed($args);
-
- $returnValue = null;
-
- $aMean = self::AVERAGEA($aArgs);
- if ($aMean !== null) {
- $aCount = 0;
- foreach ($aArgs as $k => $arg) {
- if (
- (is_bool($arg)) &&
- (!Functions::isMatrixValue($k))
- ) {
- } else {
- // Is it a numeric value?
- if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- } elseif (is_string($arg)) {
- $arg = 0;
- }
- if ($returnValue === null) {
- $returnValue = ($arg - $aMean) ** 2;
- } else {
- $returnValue += ($arg - $aMean) ** 2;
- }
- ++$aCount;
- }
- }
- }
-
- if (($aCount > 0) && ($returnValue >= 0)) {
- return sqrt($returnValue / $aCount);
- }
- }
-
- return Functions::DIV0();
+ return StandardDeviations::STDEVPA(...$args);
}
/**
* STEYX.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::STEYX()
+ * Use the STEYX() method in the Statistical\Trends class instead
+ *
* Returns the standard error of the predicted y-value for each x in the regression.
*
* @param mixed[] $yValues Data Series Y
@@ -3432,21 +1736,7 @@ class Statistical
*/
public static function STEYX($yValues, $xValues)
{
- if (!self::checkTrendArrays($yValues, $xValues)) {
- return Functions::VALUE();
- }
- $yValueCount = count($yValues);
- $xValueCount = count($xValues);
-
- if (($yValueCount == 0) || ($yValueCount != $xValueCount)) {
- return Functions::NA();
- } elseif ($yValueCount == 1) {
- return Functions::DIV0();
- }
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
-
- return $bestFitLinear->getStdevOfResiduals();
+ return Trends::STEYX($yValues, $xValues);
}
/**
@@ -3454,6 +1744,11 @@ class Statistical
*
* Returns the probability of Student's T distribution.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\StudentT::distribution()
+ * Use the distribution() method in the Statistical\Distributions\StudentT class instead
+ *
* @param float $value Value for the function
* @param float $degrees degrees of freedom
* @param float $tails number of tails (1 or 2)
@@ -3462,61 +1757,18 @@ class Statistical
*/
public static function TDIST($value, $degrees, $tails)
{
- $value = Functions::flattenSingleValue($value);
- $degrees = floor(Functions::flattenSingleValue($degrees));
- $tails = floor(Functions::flattenSingleValue($tails));
-
- if ((is_numeric($value)) && (is_numeric($degrees)) && (is_numeric($tails))) {
- if (($value < 0) || ($degrees < 1) || ($tails < 1) || ($tails > 2)) {
- return Functions::NAN();
- }
- // tdist, which finds the probability that corresponds to a given value
- // of t with k degrees of freedom. This algorithm is translated from a
- // pascal function on p81 of "Statistical Computing in Pascal" by D
- // Cooke, A H Craven & G M Clark (1985: Edward Arnold (Pubs.) Ltd:
- // London). The above Pascal algorithm is itself a translation of the
- // fortran algoritm "AS 3" by B E Cooper of the Atlas Computer
- // Laboratory as reported in (among other places) "Applied Statistics
- // Algorithms", editied by P Griffiths and I D Hill (1985; Ellis
- // Horwood Ltd.; W. Sussex, England).
- $tterm = $degrees;
- $ttheta = atan2($value, sqrt($tterm));
- $tc = cos($ttheta);
- $ts = sin($ttheta);
-
- if (($degrees % 2) == 1) {
- $ti = 3;
- $tterm = $tc;
- } else {
- $ti = 2;
- $tterm = 1;
- }
-
- $tsum = $tterm;
- while ($ti < $degrees) {
- $tterm *= $tc * $tc * ($ti - 1) / $ti;
- $tsum += $tterm;
- $ti += 2;
- }
- $tsum *= $ts;
- if (($degrees % 2) == 1) {
- $tsum = Functions::M_2DIVPI * ($tsum + $ttheta);
- }
- $tValue = 0.5 * (1 + $tsum);
- if ($tails == 1) {
- return 1 - abs($tValue);
- }
-
- return 1 - abs((1 - $tValue) - $tValue);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\StudentT::distribution($value, $degrees, $tails);
}
/**
* TINV.
*
- * Returns the one-tailed probability of the chi-squared distribution.
+ * Returns the one-tailed probability of the Student-T distribution.
+ *
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\StudentT::inverse()
+ * Use the inverse() method in the Statistical\Distributions\StudentT class instead
*
* @param float $probability Probability for the function
* @param float $degrees degrees of freedom
@@ -3525,50 +1777,7 @@ class Statistical
*/
public static function TINV($probability, $degrees)
{
- $probability = Functions::flattenSingleValue($probability);
- $degrees = floor(Functions::flattenSingleValue($degrees));
-
- if ((is_numeric($probability)) && (is_numeric($degrees))) {
- $xLo = 100;
- $xHi = 0;
-
- $x = $xNew = 1;
- $dx = 1;
- $i = 0;
-
- while ((abs($dx) > Functions::PRECISION) && ($i++ < self::MAX_ITERATIONS)) {
- // Apply Newton-Raphson step
- $result = self::TDIST($x, $degrees, 2);
- $error = $result - $probability;
- if ($error == 0.0) {
- $dx = 0;
- } elseif ($error < 0.0) {
- $xLo = $x;
- } else {
- $xHi = $x;
- }
- // Avoid division by zero
- if ($result != 0.0) {
- $dx = $error / $result;
- $xNew = $x - $dx;
- }
- // If the NR fails to converge (which for example may be the
- // case if the initial guess is too rough) we apply a bisection
- // step to determine a more narrow interval around the root.
- if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) {
- $xNew = ($xLo + $xHi) / 2;
- $dx = $xNew - $x;
- }
- $x = $xNew;
- }
- if ($i == self::MAX_ITERATIONS) {
- return Functions::NA();
- }
-
- return round($x, 12);
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\StudentT::inverse($probability, $degrees);
}
/**
@@ -3576,31 +1785,21 @@ class Statistical
*
* Returns values along a linear Trend
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Trends::TREND()
+ * Use the TREND() method in the Statistical\Trends class instead
+ *
* @param mixed[] $yValues Data Series Y
* @param mixed[] $xValues Data Series X
* @param mixed[] $newValues Values of X for which we want to find Y
* @param bool $const a logical value specifying whether to force the intersect to equal 0
*
- * @return array of float
+ * @return float[]
*/
public static function TREND($yValues, $xValues = [], $newValues = [], $const = true)
{
- $yValues = Functions::flattenArray($yValues);
- $xValues = Functions::flattenArray($xValues);
- $newValues = Functions::flattenArray($newValues);
- $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const);
-
- $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues, $const);
- if (empty($newValues)) {
- $newValues = $bestFitLinear->getXValues();
- }
-
- $returnArray = [];
- foreach ($newValues as $xValue) {
- $returnArray[0][] = $bestFitLinear->getValueOfYForX($xValue);
- }
-
- return $returnArray;
+ return Trends::TREND($yValues, $xValues, $newValues, $const);
}
/**
@@ -3628,6 +1827,7 @@ class Statistical
if (($percent < 0) || ($percent > 1)) {
return Functions::NAN();
}
+
$mArgs = [];
foreach ($aArgs as $arg) {
// Is it a numeric value?
@@ -3635,14 +1835,16 @@ class Statistical
$mArgs[] = $arg;
}
}
- $discard = floor(self::COUNT($mArgs) * $percent / 2);
+
+ $discard = floor(Counts::COUNT($mArgs) * $percent / 2);
sort($mArgs);
+
for ($i = 0; $i < $discard; ++$i) {
array_pop($mArgs);
array_shift($mArgs);
}
- return self::AVERAGE($mArgs);
+ return Averages::average($mArgs);
}
return Functions::VALUE();
@@ -3656,38 +1858,18 @@ class Statistical
* Excel Function:
* VAR(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
+ *
+ *@see Statistical\Variances::VAR()
+ * Use the VAR() method in the Statistical\Variances class instead
*/
public static function VARFunc(...$args)
{
- $returnValue = Functions::DIV0();
-
- $summerA = $summerB = 0;
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- $aCount = 0;
- foreach ($aArgs as $arg) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- }
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- $summerA += ($arg * $arg);
- $summerB += $arg;
- ++$aCount;
- }
- }
-
- if ($aCount > 1) {
- $summerA *= $aCount;
- $summerB *= $summerB;
- $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
- }
-
- return $returnValue;
+ return Variances::VAR(...$args);
}
/**
@@ -3698,51 +1880,18 @@ class Statistical
* Excel Function:
* VARA(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Variances::VARA()
+ * Use the VARA() method in the Statistical\Variances class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function VARA(...$args)
{
- $returnValue = Functions::DIV0();
-
- $summerA = $summerB = 0;
-
- // Loop through arguments
- $aArgs = Functions::flattenArrayIndexed($args);
- $aCount = 0;
- foreach ($aArgs as $k => $arg) {
- if (
- (is_string($arg)) &&
- (Functions::isValue($k))
- ) {
- return Functions::VALUE();
- } elseif (
- (is_string($arg)) &&
- (!Functions::isMatrixValue($k))
- ) {
- } else {
- // Is it a numeric value?
- if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- } elseif (is_string($arg)) {
- $arg = 0;
- }
- $summerA += ($arg * $arg);
- $summerB += $arg;
- ++$aCount;
- }
- }
- }
-
- if ($aCount > 1) {
- $summerA *= $aCount;
- $summerB *= $summerB;
- $returnValue = ($summerA - $summerB) / ($aCount * ($aCount - 1));
- }
-
- return $returnValue;
+ return Variances::VARA(...$args);
}
/**
@@ -3753,39 +1902,18 @@ class Statistical
* Excel Function:
* VARP(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Variances::VARP()
+ * Use the VARP() method in the Statistical\Variances class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function VARP(...$args)
{
- // Return value
- $returnValue = Functions::DIV0();
-
- $summerA = $summerB = 0;
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- $aCount = 0;
- foreach ($aArgs as $arg) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- }
- // Is it a numeric value?
- if ((is_numeric($arg)) && (!is_string($arg))) {
- $summerA += ($arg * $arg);
- $summerB += $arg;
- ++$aCount;
- }
- }
-
- if ($aCount > 0) {
- $summerA *= $aCount;
- $summerB *= $summerB;
- $returnValue = ($summerA - $summerB) / ($aCount * $aCount);
- }
-
- return $returnValue;
+ return Variances::VARP(...$args);
}
/**
@@ -3796,51 +1924,18 @@ class Statistical
* Excel Function:
* VARPA(value1[,value2[, ...]])
*
+ * @Deprecated 1.17.0
+ *
+ * @see Statistical\Variances::VARPA()
+ * Use the VARPA() method in the Statistical\Variances class instead
+ *
* @param mixed ...$args Data values
*
* @return float|string (string if result is an error)
*/
public static function VARPA(...$args)
{
- $returnValue = Functions::DIV0();
-
- $summerA = $summerB = 0;
-
- // Loop through arguments
- $aArgs = Functions::flattenArrayIndexed($args);
- $aCount = 0;
- foreach ($aArgs as $k => $arg) {
- if (
- (is_string($arg)) &&
- (Functions::isValue($k))
- ) {
- return Functions::VALUE();
- } elseif (
- (is_string($arg)) &&
- (!Functions::isMatrixValue($k))
- ) {
- } else {
- // Is it a numeric value?
- if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
- if (is_bool($arg)) {
- $arg = (int) $arg;
- } elseif (is_string($arg)) {
- $arg = 0;
- }
- $summerA += ($arg * $arg);
- $summerB += $arg;
- ++$aCount;
- }
- }
- }
-
- if ($aCount > 0) {
- $summerA *= $aCount;
- $summerB *= $summerB;
- $returnValue = ($summerA - $summerB) / ($aCount * $aCount);
- }
-
- return $returnValue;
+ return Variances::VARPA(...$args);
}
/**
@@ -3849,6 +1944,11 @@ class Statistical
* Returns the Weibull distribution. Use this distribution in reliability
* analysis, such as calculating a device's mean time to failure.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\Weibull::distribution()
+ * Use the distribution() method in the Statistical\Distributions\Weibull class instead
+ *
* @param float $value
* @param float $alpha Alpha Parameter
* @param float $beta Beta Parameter
@@ -3858,31 +1958,21 @@ class Statistical
*/
public static function WEIBULL($value, $alpha, $beta, $cumulative)
{
- $value = Functions::flattenSingleValue($value);
- $alpha = Functions::flattenSingleValue($alpha);
- $beta = Functions::flattenSingleValue($beta);
-
- if ((is_numeric($value)) && (is_numeric($alpha)) && (is_numeric($beta))) {
- if (($value < 0) || ($alpha <= 0) || ($beta <= 0)) {
- return Functions::NAN();
- }
- if ((is_numeric($cumulative)) || (is_bool($cumulative))) {
- if ($cumulative) {
- return 1 - exp(0 - ($value / $beta) ** $alpha);
- }
-
- return ($alpha / $beta ** $alpha) * $value ** ($alpha - 1) * exp(0 - ($value / $beta) ** $alpha);
- }
- }
-
- return Functions::VALUE();
+ return Statistical\Distributions\Weibull::distribution($value, $alpha, $beta, $cumulative);
}
/**
* ZTEST.
*
- * Returns the Weibull distribution. Use this distribution in reliability
- * analysis, such as calculating a device's mean time to failure.
+ * Returns the one-tailed P-value of a z-test.
+ *
+ * For a given hypothesized population mean, x, Z.TEST returns the probability that the sample mean would be
+ * greater than the average of observations in the data set (array) — that is, the observed sample mean.
+ *
+ * @Deprecated 1.18.0
+ *
+ * @see Statistical\Distributions\StandardNormal::zTest()
+ * Use the zTest() method in the Statistical\Distributions\StandardNormal class instead
*
* @param float $dataSet
* @param float $m0 Alpha Parameter
@@ -3892,15 +1982,6 @@ class Statistical
*/
public static function ZTEST($dataSet, $m0, $sigma = null)
{
- $dataSet = Functions::flattenArrayIndexed($dataSet);
- $m0 = Functions::flattenSingleValue($m0);
- $sigma = Functions::flattenSingleValue($sigma);
-
- if ($sigma === null) {
- $sigma = self::STDEV($dataSet);
- }
- $n = count($dataSet);
-
- return 1 - self::NORMSDIST((self::AVERAGE($dataSet) - $m0) / ($sigma / sqrt($n)));
+ return Statistical\Distributions\StandardNormal::zTest($dataSet, $m0, $sigma);
}
}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/AggregateBase.php b/src/PhpSpreadsheet/Calculation/Statistical/AggregateBase.php
new file mode 100644
index 00000000..75c012dc
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/AggregateBase.php
@@ -0,0 +1,50 @@
+ $arg) {
+ $arg = self::testAcceptedBoolean($arg, $k);
+ // Is it a numeric value?
+ // Strings containing numeric values are only counted if they are string literals (not cell values)
+ // and then only in MS Excel and in Open Office, not in Gnumeric
+ if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
+ return Functions::VALUE();
+ }
+ if (self::isAcceptedCountable($arg, $k)) {
+ $returnValue += abs($arg - $aMean);
+ ++$aCount;
+ }
+ }
+
+ // Return
+ if ($aCount === 0) {
+ return Functions::DIV0();
+ }
+
+ return $returnValue / $aCount;
+ }
+
+ /**
+ * AVERAGE.
+ *
+ * Returns the average (arithmetic mean) of the arguments
+ *
+ * Excel Function:
+ * AVERAGE(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return float|string (string if result is an error)
+ */
+ public static function average(...$args)
+ {
+ $returnValue = $aCount = 0;
+
+ // Loop through arguments
+ foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
+ $arg = self::testAcceptedBoolean($arg, $k);
+ // Is it a numeric value?
+ // Strings containing numeric values are only counted if they are string literals (not cell values)
+ // and then only in MS Excel and in Open Office, not in Gnumeric
+ if ((is_string($arg)) && (!is_numeric($arg)) && (!Functions::isCellValue($k))) {
+ return Functions::VALUE();
+ }
+ if (self::isAcceptedCountable($arg, $k)) {
+ $returnValue += $arg;
+ ++$aCount;
+ }
+ }
+
+ // Return
+ if ($aCount > 0) {
+ return $returnValue / $aCount;
+ }
+
+ return Functions::DIV0();
+ }
+
+ /**
+ * AVERAGEA.
+ *
+ * Returns the average of its arguments, including numbers, text, and logical values
+ *
+ * Excel Function:
+ * AVERAGEA(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return float|string (string if result is an error)
+ */
+ public static function averageA(...$args)
+ {
+ $returnValue = null;
+
+ $aCount = 0;
+ // Loop through arguments
+ foreach (Functions::flattenArrayIndexed($args) as $k => $arg) {
+ if ((is_bool($arg)) && (!Functions::isMatrixValue($k))) {
+ } else {
+ if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
+ if (is_bool($arg)) {
+ $arg = (int) $arg;
+ } elseif (is_string($arg)) {
+ $arg = 0;
+ }
+ $returnValue += $arg;
+ ++$aCount;
+ }
+ }
+ }
+
+ if ($aCount > 0) {
+ return $returnValue / $aCount;
+ }
+
+ return Functions::DIV0();
+ }
+
+ /**
+ * MEDIAN.
+ *
+ * Returns the median of the given numbers. The median is the number in the middle of a set of numbers.
+ *
+ * Excel Function:
+ * MEDIAN(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return float|string The result, or a string containing an error
+ */
+ public static function median(...$args)
+ {
+ $aArgs = Functions::flattenArray($args);
+
+ $returnValue = Functions::NAN();
+
+ $aArgs = self::filterArguments($aArgs);
+ $valueCount = count($aArgs);
+ if ($valueCount > 0) {
+ sort($aArgs, SORT_NUMERIC);
+ $valueCount = $valueCount / 2;
+ if ($valueCount == floor($valueCount)) {
+ $returnValue = ($aArgs[$valueCount--] + $aArgs[$valueCount]) / 2;
+ } else {
+ $valueCount = floor($valueCount);
+ $returnValue = $aArgs[$valueCount];
+ }
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * MODE.
+ *
+ * Returns the most frequently occurring, or repetitive, value in an array or range of data
+ *
+ * Excel Function:
+ * MODE(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return float|string The result, or a string containing an error
+ */
+ public static function mode(...$args)
+ {
+ $returnValue = Functions::NA();
+
+ // Loop through arguments
+ $aArgs = Functions::flattenArray($args);
+ $aArgs = self::filterArguments($aArgs);
+
+ if (!empty($aArgs)) {
+ return self::modeCalc($aArgs);
+ }
+
+ return $returnValue;
+ }
+
+ protected static function filterArguments($args)
+ {
+ return array_filter(
+ $args,
+ function ($value) {
+ // Is it a numeric value?
+ return (is_numeric($value)) && (!is_string($value));
+ }
+ );
+ }
+
+ //
+ // Special variant of array_count_values that isn't limited to strings and integers,
+ // but can work with floating point numbers as values
+ //
+ private static function modeCalc($data)
+ {
+ $frequencyArray = [];
+ $index = 0;
+ $maxfreq = 0;
+ $maxfreqkey = '';
+ $maxfreqdatum = '';
+ foreach ($data as $datum) {
+ $found = false;
+ ++$index;
+ foreach ($frequencyArray as $key => $value) {
+ if ((string) $value['value'] == (string) $datum) {
+ ++$frequencyArray[$key]['frequency'];
+ $freq = $frequencyArray[$key]['frequency'];
+ if ($freq > $maxfreq) {
+ $maxfreq = $freq;
+ $maxfreqkey = $key;
+ $maxfreqdatum = $datum;
+ } elseif ($freq == $maxfreq) {
+ if ($frequencyArray[$key]['index'] < $frequencyArray[$maxfreqkey]['index']) {
+ $maxfreqkey = $key;
+ $maxfreqdatum = $datum;
+ }
+ }
+ $found = true;
+
+ break;
+ }
+ }
+
+ if ($found === false) {
+ $frequencyArray[] = [
+ 'value' => $datum,
+ 'frequency' => 1,
+ 'index' => $index,
+ ];
+ }
+ }
+
+ if ($maxfreq <= 1) {
+ return Functions::NA();
+ }
+
+ return $maxfreqdatum;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php b/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php
new file mode 100644
index 00000000..51e6b004
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Conditional.php
@@ -0,0 +1,304 @@
+getMessage();
+ }
+
+ if (($alpha <= 0) || ($alpha >= 1) || ($stdDev <= 0) || ($size < 1)) {
+ return Functions::NAN();
+ }
+
+ return Distributions\StandardNormal::inverse(1 - $alpha / 2) * $stdDev / sqrt($size);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Counts.php b/src/PhpSpreadsheet/Calculation/Statistical/Counts.php
new file mode 100644
index 00000000..13e7af79
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Counts.php
@@ -0,0 +1,95 @@
+ $arg) {
+ $arg = self::testAcceptedBoolean($arg, $k);
+ // Is it a numeric value?
+ // Strings containing numeric values are only counted if they are string literals (not cell values)
+ // and then only in MS Excel and in Open Office, not in Gnumeric
+ if (self::isAcceptedCountable($arg, $k)) {
+ ++$returnValue;
+ }
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * COUNTA.
+ *
+ * Counts the number of cells that are not empty within the list of arguments
+ *
+ * Excel Function:
+ * COUNTA(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return int
+ */
+ public static function COUNTA(...$args)
+ {
+ $returnValue = 0;
+
+ // Loop through arguments
+ $aArgs = Functions::flattenArrayIndexed($args);
+ foreach ($aArgs as $k => $arg) {
+ // Nulls are counted if literals, but not if cell values
+ if ($arg !== null || (!Functions::isCellValue($k))) {
+ ++$returnValue;
+ }
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * COUNTBLANK.
+ *
+ * Counts the number of empty cells within the list of arguments
+ *
+ * Excel Function:
+ * COUNTBLANK(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return int
+ */
+ public static function COUNTBLANK(...$args)
+ {
+ $returnValue = 0;
+
+ // Loop through arguments
+ $aArgs = Functions::flattenArray($args);
+ foreach ($aArgs as $arg) {
+ // Is it a blank cell?
+ if (($arg === null) || ((is_string($arg)) && ($arg == ''))) {
+ ++$returnValue;
+ }
+ }
+
+ return $returnValue;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php
new file mode 100644
index 00000000..63e6eb4d
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Beta.php
@@ -0,0 +1,260 @@
+getMessage();
+ }
+
+ if ($rMin > $rMax) {
+ $tmp = $rMin;
+ $rMin = $rMax;
+ $rMax = $tmp;
+ }
+ if (($value < $rMin) || ($value > $rMax) || ($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax)) {
+ return Functions::NAN();
+ }
+
+ $value -= $rMin;
+ $value /= ($rMax - $rMin);
+
+ return self::incompleteBeta($value, $alpha, $beta);
+ }
+
+ /**
+ * BETAINV.
+ *
+ * Returns the inverse of the Beta distribution.
+ *
+ * @param mixed $probability Float probability at which you want to evaluate the distribution
+ * @param mixed $alpha Parameter to the distribution as a float
+ * @param mixed $beta Parameter to the distribution as a float
+ * @param mixed $rMin Minimum value as a float
+ * @param mixed $rMax Maximum value as a float
+ *
+ * @return float|string
+ */
+ public static function inverse($probability, $alpha, $beta, $rMin = 0.0, $rMax = 1.0)
+ {
+ $probability = Functions::flattenSingleValue($probability);
+ $alpha = Functions::flattenSingleValue($alpha);
+ $beta = Functions::flattenSingleValue($beta);
+ $rMin = ($rMin === null) ? 0.0 : Functions::flattenSingleValue($rMin);
+ $rMax = ($rMax === null) ? 1.0 : Functions::flattenSingleValue($rMax);
+
+ try {
+ $probability = DistributionValidations::validateProbability($probability);
+ $alpha = DistributionValidations::validateFloat($alpha);
+ $beta = DistributionValidations::validateFloat($beta);
+ $rMax = DistributionValidations::validateFloat($rMax);
+ $rMin = DistributionValidations::validateFloat($rMin);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($rMin > $rMax) {
+ $tmp = $rMin;
+ $rMin = $rMax;
+ $rMax = $tmp;
+ }
+ if (($alpha <= 0) || ($beta <= 0) || ($rMin == $rMax) || ($probability <= 0.0)) {
+ return Functions::NAN();
+ }
+
+ return self::calculateInverse($probability, $alpha, $beta, $rMin, $rMax);
+ }
+
+ /**
+ * @return float|string
+ */
+ private static function calculateInverse(float $probability, float $alpha, float $beta, float $rMin, float $rMax)
+ {
+ $a = 0;
+ $b = 2;
+
+ $i = 0;
+ while ((($b - $a) > Functions::PRECISION) && (++$i <= self::MAX_ITERATIONS)) {
+ $guess = ($a + $b) / 2;
+ $result = self::distribution($guess, $alpha, $beta);
+ if (($result === $probability) || ($result === 0.0)) {
+ $b = $a;
+ } elseif ($result > $probability) {
+ $b = $guess;
+ } else {
+ $a = $guess;
+ }
+ }
+
+ if ($i === self::MAX_ITERATIONS) {
+ return Functions::NA();
+ }
+
+ return round($rMin + $guess * ($rMax - $rMin), 12);
+ }
+
+ /**
+ * Incomplete beta function.
+ *
+ * @author Jaco van Kooten
+ * @author Paul Meagher
+ *
+ * The computation is based on formulas from Numerical Recipes, Chapter 6.4 (W.H. Press et al, 1992).
+ *
+ * @param float $x require 0<=x<=1
+ * @param float $p require p>0
+ * @param float $q require q>0
+ *
+ * @return float 0 if x<0, p<=0, q<=0 or p+q>2.55E305 and 1 if x>1 to avoid errors and over/underflow
+ */
+ public static function incompleteBeta(float $x, float $p, float $q): float
+ {
+ if ($x <= 0.0) {
+ return 0.0;
+ } elseif ($x >= 1.0) {
+ return 1.0;
+ } elseif (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > self::LOG_GAMMA_X_MAX_VALUE)) {
+ return 0.0;
+ }
+
+ $beta_gam = exp((0 - self::logBeta($p, $q)) + $p * log($x) + $q * log(1.0 - $x));
+ if ($x < ($p + 1.0) / ($p + $q + 2.0)) {
+ return $beta_gam * self::betaFraction($x, $p, $q) / $p;
+ }
+
+ return 1.0 - ($beta_gam * self::betaFraction(1 - $x, $q, $p) / $q);
+ }
+
+ // Function cache for logBeta function
+ private static $logBetaCacheP = 0.0;
+
+ private static $logBetaCacheQ = 0.0;
+
+ private static $logBetaCacheResult = 0.0;
+
+ /**
+ * The natural logarithm of the beta function.
+ *
+ * @param float $p require p>0
+ * @param float $q require q>0
+ *
+ * @return float 0 if p<=0, q<=0 or p+q>2.55E305 to avoid errors and over/underflow
+ *
+ * @author Jaco van Kooten
+ */
+ private static function logBeta(float $p, float $q): float
+ {
+ if ($p != self::$logBetaCacheP || $q != self::$logBetaCacheQ) {
+ self::$logBetaCacheP = $p;
+ self::$logBetaCacheQ = $q;
+ if (($p <= 0.0) || ($q <= 0.0) || (($p + $q) > self::LOG_GAMMA_X_MAX_VALUE)) {
+ self::$logBetaCacheResult = 0.0;
+ } else {
+ self::$logBetaCacheResult = Gamma::logGamma($p) + Gamma::logGamma($q) - Gamma::logGamma($p + $q);
+ }
+ }
+
+ return self::$logBetaCacheResult;
+ }
+
+ /**
+ * Evaluates of continued fraction part of incomplete beta function.
+ * Based on an idea from Numerical Recipes (W.H. Press et al, 1992).
+ *
+ * @author Jaco van Kooten
+ */
+ private static function betaFraction(float $x, float $p, float $q): float
+ {
+ $c = 1.0;
+ $sum_pq = $p + $q;
+ $p_plus = $p + 1.0;
+ $p_minus = $p - 1.0;
+ $h = 1.0 - $sum_pq * $x / $p_plus;
+ if (abs($h) < self::XMININ) {
+ $h = self::XMININ;
+ }
+ $h = 1.0 / $h;
+ $frac = $h;
+ $m = 1;
+ $delta = 0.0;
+ while ($m <= self::MAX_ITERATIONS && abs($delta - 1.0) > Functions::PRECISION) {
+ $m2 = 2 * $m;
+ // even index for d
+ $d = $m * ($q - $m) * $x / (($p_minus + $m2) * ($p + $m2));
+ $h = 1.0 + $d * $h;
+ if (abs($h) < self::XMININ) {
+ $h = self::XMININ;
+ }
+ $h = 1.0 / $h;
+ $c = 1.0 + $d / $c;
+ if (abs($c) < self::XMININ) {
+ $c = self::XMININ;
+ }
+ $frac *= $h * $c;
+ // odd index for d
+ $d = -($p + $m) * ($sum_pq + $m) * $x / (($p + $m2) * ($p_plus + $m2));
+ $h = 1.0 + $d * $h;
+ if (abs($h) < self::XMININ) {
+ $h = self::XMININ;
+ }
+ $h = 1.0 / $h;
+ $c = 1.0 + $d / $c;
+ if (abs($c) < self::XMININ) {
+ $c = self::XMININ;
+ }
+ $delta = $h * $c;
+ $frac *= $delta;
+ ++$m;
+ }
+
+ return $frac;
+ }
+
+ private static function betaValue(float $a, float $b): float
+ {
+ return (Gamma::gammaValue($a) * Gamma::gammaValue($b)) /
+ Gamma::gammaValue($a + $b);
+ }
+
+ private static function regularizedIncompleteBeta(float $value, float $a, float $b): float
+ {
+ return self::incompleteBeta($value, $a, $b) / self::betaValue($a, $b);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php
new file mode 100644
index 00000000..9631236a
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Binomial.php
@@ -0,0 +1,202 @@
+getMessage();
+ }
+
+ if (($value < 0) || ($value > $trials)) {
+ return Functions::NAN();
+ }
+
+ if ($cumulative) {
+ return self::calculateCumulativeBinomial($value, $trials, $probability);
+ }
+
+ return Combinations::withoutRepetition($trials, $value) * $probability ** $value
+ * (1 - $probability) ** ($trials - $value);
+ }
+
+ /**
+ * BINOM.DIST.RANGE.
+ *
+ * Returns returns the Binomial Distribution probability for the number of successes from a specified number
+ * of trials falling into a specified range.
+ *
+ * @param mixed $trials Integer number of trials
+ * @param mixed $probability Probability of success on each trial as a float
+ * @param mixed $successes The integer number of successes in trials
+ * @param mixed $limit Upper limit for successes in trials as null, or an integer
+ * If null, then this will indicate the same as the number of Successes
+ *
+ * @return float|string
+ */
+ public static function range($trials, $probability, $successes, $limit = null)
+ {
+ $trials = Functions::flattenSingleValue($trials);
+ $probability = Functions::flattenSingleValue($probability);
+ $successes = Functions::flattenSingleValue($successes);
+ $limit = ($limit === null) ? $successes : Functions::flattenSingleValue($limit);
+
+ try {
+ $trials = DistributionValidations::validateInt($trials);
+ $probability = DistributionValidations::validateProbability($probability);
+ $successes = DistributionValidations::validateInt($successes);
+ $limit = DistributionValidations::validateInt($limit);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if (($successes < 0) || ($successes > $trials)) {
+ return Functions::NAN();
+ }
+ if (($limit < 0) || ($limit > $trials) || $limit < $successes) {
+ return Functions::NAN();
+ }
+
+ $summer = 0;
+ for ($i = $successes; $i <= $limit; ++$i) {
+ $summer += Combinations::withoutRepetition($trials, $i) * $probability ** $i
+ * (1 - $probability) ** ($trials - $i);
+ }
+
+ return $summer;
+ }
+
+ /**
+ * NEGBINOMDIST.
+ *
+ * Returns the negative binomial distribution. NEGBINOMDIST returns the probability that
+ * there will be number_f failures before the number_s-th success, when the constant
+ * probability of a success is probability_s. This function is similar to the binomial
+ * distribution, except that the number of successes is fixed, and the number of trials is
+ * variable. Like the binomial, trials are assumed to be independent.
+ *
+ * @param mixed $failures Number of Failures as an integer
+ * @param mixed $successes Threshold number of Successes as an integer
+ * @param mixed $probability Probability of success on each trial as a float
+ *
+ * @return float|string The result, or a string containing an error
+ *
+ * TODO Add support for the cumulative flag not present for NEGBINOMDIST, but introduced for NEGBINOM.DIST
+ * The cumulative default should be false to reflect the behaviour of NEGBINOMDIST
+ */
+ public static function negative($failures, $successes, $probability)
+ {
+ $failures = Functions::flattenSingleValue($failures);
+ $successes = Functions::flattenSingleValue($successes);
+ $probability = Functions::flattenSingleValue($probability);
+
+ try {
+ $failures = DistributionValidations::validateInt($failures);
+ $successes = DistributionValidations::validateInt($successes);
+ $probability = DistributionValidations::validateProbability($probability);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if (($failures < 0) || ($successes < 1)) {
+ return Functions::NAN();
+ }
+ if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) {
+ if (($failures + $successes - 1) <= 0) {
+ return Functions::NAN();
+ }
+ }
+
+ return (Combinations::withoutRepetition($failures + $successes - 1, $successes - 1))
+ * ($probability ** $successes) * ((1 - $probability) ** $failures);
+ }
+
+ /**
+ * CRITBINOM.
+ *
+ * Returns the smallest value for which the cumulative binomial distribution is greater
+ * than or equal to a criterion value
+ *
+ * @param mixed $trials number of Bernoulli trials as an integer
+ * @param mixed $probability probability of a success on each trial as a float
+ * @param mixed $alpha criterion value as a float
+ *
+ * @return int|string
+ */
+ public static function inverse($trials, $probability, $alpha)
+ {
+ $trials = Functions::flattenSingleValue($trials);
+ $probability = Functions::flattenSingleValue($probability);
+ $alpha = Functions::flattenSingleValue($alpha);
+
+ try {
+ $trials = DistributionValidations::validateInt($trials);
+ $probability = DistributionValidations::validateProbability($probability);
+ $alpha = DistributionValidations::validateFloat($alpha);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($trials < 0) {
+ return Functions::NAN();
+ } elseif (($alpha < 0.0) || ($alpha > 1.0)) {
+ return Functions::NAN();
+ }
+
+ $successes = 0;
+ while ($successes <= $trials) {
+ $result = self::calculateCumulativeBinomial($successes, $trials, $probability);
+ if ($result >= $alpha) {
+ break;
+ }
+ ++$successes;
+ }
+
+ return $successes;
+ }
+
+ /**
+ * @return float|int
+ */
+ private static function calculateCumulativeBinomial(int $value, int $trials, float $probability)
+ {
+ $summer = 0;
+ for ($i = 0; $i <= $value; ++$i) {
+ $summer += Combinations::withoutRepetition($trials, $i) * $probability ** $i
+ * (1 - $probability) ** ($trials - $i);
+ }
+
+ return $summer;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
new file mode 100644
index 00000000..5165d639
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/ChiSquared.php
@@ -0,0 +1,311 @@
+getMessage();
+ }
+
+ if ($degrees < 1) {
+ return Functions::NAN();
+ }
+ if ($value < 0) {
+ if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) {
+ return 1;
+ }
+
+ return Functions::NAN();
+ }
+
+ return 1 - (Gamma::incompleteGamma($degrees / 2, $value / 2) / Gamma::gammaValue($degrees / 2));
+ }
+
+ /**
+ * CHIDIST.
+ *
+ * Returns the one-tailed probability of the chi-squared distribution.
+ *
+ * @param mixed $value Float value for which we want the probability
+ * @param mixed $degrees Integer degrees of freedom
+ * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false)
+ *
+ * @return float|string
+ */
+ public static function distributionLeftTail($value, $degrees, $cumulative)
+ {
+ $value = Functions::flattenSingleValue($value);
+ $degrees = Functions::flattenSingleValue($degrees);
+ $cumulative = Functions::flattenSingleValue($cumulative);
+
+ try {
+ $value = DistributionValidations::validateFloat($value);
+ $degrees = DistributionValidations::validateInt($degrees);
+ $cumulative = DistributionValidations::validateBool($cumulative);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($degrees < 1) {
+ return Functions::NAN();
+ }
+ if ($value < 0) {
+ if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC) {
+ return 1;
+ }
+
+ return Functions::NAN();
+ }
+
+ if ($cumulative === true) {
+ return 1 - self::distributionRightTail($value, $degrees);
+ }
+
+ return (($value ** (($degrees / 2) - 1) * exp(-$value / 2))) /
+ ((2 ** ($degrees / 2)) * Gamma::gammaValue($degrees / 2));
+ }
+
+ /**
+ * CHIINV.
+ *
+ * Returns the inverse of the right-tailed probability of the chi-squared distribution.
+ *
+ * @param mixed $probability Float probability at which you want to evaluate the distribution
+ * @param mixed $degrees Integer degrees of freedom
+ *
+ * @return float|string
+ */
+ public static function inverseRightTail($probability, $degrees)
+ {
+ $probability = Functions::flattenSingleValue($probability);
+ $degrees = Functions::flattenSingleValue($degrees);
+
+ try {
+ $probability = DistributionValidations::validateProbability($probability);
+ $degrees = DistributionValidations::validateInt($degrees);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($degrees < 1) {
+ return Functions::NAN();
+ }
+
+ $callback = function ($value) use ($degrees) {
+ return 1 - (Gamma::incompleteGamma($degrees / 2, $value / 2)
+ / Gamma::gammaValue($degrees / 2));
+ };
+
+ $newtonRaphson = new NewtonRaphson($callback);
+
+ return $newtonRaphson->execute($probability);
+ }
+
+ /**
+ * CHIINV.
+ *
+ * Returns the inverse of the left-tailed probability of the chi-squared distribution.
+ *
+ * @param mixed $probability Float probability at which you want to evaluate the distribution
+ * @param mixed $degrees Integer degrees of freedom
+ *
+ * @return float|string
+ */
+ public static function inverseLeftTail($probability, $degrees)
+ {
+ $probability = Functions::flattenSingleValue($probability);
+ $degrees = Functions::flattenSingleValue($degrees);
+
+ try {
+ $probability = DistributionValidations::validateProbability($probability);
+ $degrees = DistributionValidations::validateInt($degrees);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($degrees < 1) {
+ return Functions::NAN();
+ }
+
+ return self::inverseLeftTailCalculation($probability, $degrees);
+ }
+
+ /**
+ * CHITEST.
+ *
+ * Uses the chi-square test to calculate the probability that the differences between two supplied data sets
+ * (of observed and expected frequencies), are likely to be simply due to sampling error,
+ * or if they are likely to be real.
+ *
+ * @param mixed $actual an array of observed frequencies
+ * @param mixed $expected an array of expected frequencies
+ *
+ * @return float|string
+ */
+ public static function test($actual, $expected)
+ {
+ $rows = count($actual);
+ $actual = Functions::flattenArray($actual);
+ $expected = Functions::flattenArray($expected);
+ $columns = count($actual) / $rows;
+
+ $countActuals = count($actual);
+ $countExpected = count($expected);
+ if ($countActuals !== $countExpected || $countActuals === 1) {
+ return Functions::NAN();
+ }
+
+ $result = 0.0;
+ for ($i = 0; $i < $countActuals; ++$i) {
+ if ($expected[$i] == 0.0) {
+ return Functions::DIV0();
+ } elseif ($expected[$i] < 0.0) {
+ return Functions::NAN();
+ }
+ $result += (($actual[$i] - $expected[$i]) ** 2) / $expected[$i];
+ }
+
+ $degrees = self::degrees($rows, $columns);
+
+ $result = self::distributionRightTail($result, $degrees);
+
+ return $result;
+ }
+
+ protected static function degrees(int $rows, int $columns): int
+ {
+ if ($rows === 1) {
+ return $columns - 1;
+ } elseif ($columns === 1) {
+ return $rows - 1;
+ }
+
+ return ($columns - 1) * ($rows - 1);
+ }
+
+ private static function inverseLeftTailCalculation(float $probability, int $degrees): float
+ {
+ // bracket the root
+ $min = 0;
+ $sd = sqrt(2.0 * $degrees);
+ $max = 2 * $sd;
+ $s = -1;
+
+ while ($s * self::pchisq($max, $degrees) > $probability * $s) {
+ $min = $max;
+ $max += 2 * $sd;
+ }
+
+ // Find root using bisection
+ $chi2 = 0.5 * ($min + $max);
+
+ while (($max - $min) > self::EPS * $chi2) {
+ if ($s * self::pchisq($chi2, $degrees) > $probability * $s) {
+ $min = $chi2;
+ } else {
+ $max = $chi2;
+ }
+ $chi2 = 0.5 * ($min + $max);
+ }
+
+ return $chi2;
+ }
+
+ private static function pchisq($chi2, $degrees)
+ {
+ return self::gammp($degrees, 0.5 * $chi2);
+ }
+
+ private static function gammp($n, $x)
+ {
+ if ($x < 0.5 * $n + 1) {
+ return self::gser($n, $x);
+ }
+
+ return 1 - self::gcf($n, $x);
+ }
+
+ // Return the incomplete gamma function P(n/2,x) evaluated by
+ // series representation. Algorithm from numerical recipe.
+ // Assume that n is a positive integer and x>0, won't check arguments.
+ // Relative error controlled by the eps parameter
+ private static function gser($n, $x)
+ {
+ $gln = Gamma::ln($n / 2);
+ $a = 0.5 * $n;
+ $ap = $a;
+ $sum = 1.0 / $a;
+ $del = $sum;
+ for ($i = 1; $i < 101; ++$i) {
+ ++$ap;
+ $del = $del * $x / $ap;
+ $sum += $del;
+ if ($del < $sum * self::EPS) {
+ break;
+ }
+ }
+
+ return $sum * exp(-$x + $a * log($x) - $gln);
+ }
+
+ // Return the incomplete gamma function Q(n/2,x) evaluated by
+ // its continued fraction representation. Algorithm from numerical recipe.
+ // Assume that n is a postive integer and x>0, won't check arguments.
+ // Relative error controlled by the eps parameter
+ private static function gcf($n, $x)
+ {
+ $gln = Gamma::ln($n / 2);
+ $a = 0.5 * $n;
+ $b = $x + 1 - $a;
+ $fpmin = 1.e-300;
+ $c = 1 / $fpmin;
+ $d = 1 / $b;
+ $h = $d;
+ for ($i = 1; $i < 101; ++$i) {
+ $an = -$i * ($i - $a);
+ $b += 2;
+ $d = $an * $d + $b;
+ if (abs($d) < $fpmin) {
+ $d = $fpmin;
+ }
+ $c = $b + $an / $c;
+ if (abs($c) < $fpmin) {
+ $c = $fpmin;
+ }
+ $d = 1 / $d;
+ $del = $d * $c;
+ $h = $h * $del;
+ if (abs($del - 1) < self::EPS) {
+ break;
+ }
+ }
+
+ return $h * exp(-$x + $a * log($x) - $gln);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/DistributionValidations.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/DistributionValidations.php
new file mode 100644
index 00000000..57ef00af
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/DistributionValidations.php
@@ -0,0 +1,24 @@
+ 1.0) {
+ throw new Exception(Functions::NAN());
+ }
+
+ return $probability;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php
new file mode 100644
index 00000000..b3fd9460
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Exponential.php
@@ -0,0 +1,47 @@
+getMessage();
+ }
+
+ if (($value < 0) || ($lambda < 0)) {
+ return Functions::NAN();
+ }
+
+ if ($cumulative === true) {
+ return 1 - exp(0 - $value * $lambda);
+ }
+
+ return $lambda * exp(0 - $value * $lambda);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php
new file mode 100644
index 00000000..54b1950d
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/F.php
@@ -0,0 +1,56 @@
+getMessage();
+ }
+
+ if ($value < 0 || $u < 1 || $v < 1) {
+ return Functions::NAN();
+ }
+
+ if ($cumulative) {
+ $adjustedValue = ($u * $value) / ($u * $value + $v);
+
+ return Beta::incompleteBeta($adjustedValue, $u / 2, $v / 2);
+ }
+
+ return (Gamma::gammaValue(($v + $u) / 2) /
+ (Gamma::gammaValue($u / 2) * Gamma::gammaValue($v / 2))) *
+ (($u / $v) ** ($u / 2)) *
+ (($value ** (($u - 2) / 2)) / ((1 + ($u / $v) * $value) ** (($u + $v) / 2)));
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php
new file mode 100644
index 00000000..923bf02d
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Fisher.php
@@ -0,0 +1,61 @@
+getMessage();
+ }
+
+ if (($value <= -1) || ($value >= 1)) {
+ return Functions::NAN();
+ }
+
+ return 0.5 * log((1 + $value) / (1 - $value));
+ }
+
+ /**
+ * FISHERINV.
+ *
+ * Returns the inverse of the Fisher transformation. Use this transformation when
+ * analyzing correlations between ranges or arrays of data. If y = FISHER(x), then
+ * FISHERINV(y) = x.
+ *
+ * @param mixed $probability Float probability at which you want to evaluate the distribution
+ *
+ * @return float|string
+ */
+ public static function inverse($probability)
+ {
+ $probability = Functions::flattenSingleValue($probability);
+
+ try {
+ DistributionValidations::validateFloat($probability);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ return (exp(2 * $probability) - 1) / (exp(2 * $probability) + 1);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php
new file mode 100644
index 00000000..2c6ed670
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Gamma.php
@@ -0,0 +1,127 @@
+getMessage();
+ }
+
+ if ((((int) $value) == ((float) $value)) && $value <= 0.0) {
+ return Functions::NAN();
+ }
+
+ return self::gammaValue($value);
+ }
+
+ /**
+ * GAMMADIST.
+ *
+ * Returns the gamma distribution.
+ *
+ * @param mixed $value Float Value at which you want to evaluate the distribution
+ * @param mixed $a Parameter to the distribution as a float
+ * @param mixed $b Parameter to the distribution as a float
+ * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false)
+ *
+ * @return float|string
+ */
+ public static function distribution($value, $a, $b, $cumulative)
+ {
+ $value = Functions::flattenSingleValue($value);
+ $a = Functions::flattenSingleValue($a);
+ $b = Functions::flattenSingleValue($b);
+
+ try {
+ $value = DistributionValidations::validateFloat($value);
+ $a = DistributionValidations::validateFloat($a);
+ $b = DistributionValidations::validateFloat($b);
+ $cumulative = DistributionValidations::validateBool($cumulative);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if (($value < 0) || ($a <= 0) || ($b <= 0)) {
+ return Functions::NAN();
+ }
+
+ return self::calculateDistribution($value, $a, $b, $cumulative);
+ }
+
+ /**
+ * GAMMAINV.
+ *
+ * Returns the inverse of the Gamma distribution.
+ *
+ * @param mixed $probability Float probability at which you want to evaluate the distribution
+ * @param mixed $alpha Parameter to the distribution as a float
+ * @param mixed $beta Parameter to the distribution as a float
+ *
+ * @return float|string
+ */
+ public static function inverse($probability, $alpha, $beta)
+ {
+ $probability = Functions::flattenSingleValue($probability);
+ $alpha = Functions::flattenSingleValue($alpha);
+ $beta = Functions::flattenSingleValue($beta);
+
+ try {
+ $probability = DistributionValidations::validateProbability($probability);
+ $alpha = DistributionValidations::validateFloat($alpha);
+ $beta = DistributionValidations::validateFloat($beta);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if (($alpha <= 0.0) || ($beta <= 0.0)) {
+ return Functions::NAN();
+ }
+
+ return self::calculateInverse($probability, $alpha, $beta);
+ }
+
+ /**
+ * GAMMALN.
+ *
+ * Returns the natural logarithm of the gamma function.
+ *
+ * @param mixed $value Float Value at which you want to evaluate the distribution
+ *
+ * @return float|string
+ */
+ public static function ln($value)
+ {
+ $value = Functions::flattenSingleValue($value);
+
+ try {
+ $value = DistributionValidations::validateFloat($value);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($value <= 0) {
+ return Functions::NAN();
+ }
+
+ return log(self::gammaValue($value));
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
new file mode 100644
index 00000000..89170f7c
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/GammaBase.php
@@ -0,0 +1,381 @@
+ Functions::PRECISION) && (++$i <= self::MAX_ITERATIONS)) {
+ // Apply Newton-Raphson step
+ $result = self::calculateDistribution($x, $alpha, $beta, true);
+ $error = $result - $probability;
+
+ if ($error == 0.0) {
+ $dx = 0;
+ } elseif ($error < 0.0) {
+ $xLo = $x;
+ } else {
+ $xHi = $x;
+ }
+
+ $pdf = self::calculateDistribution($x, $alpha, $beta, false);
+ // Avoid division by zero
+ if ($pdf !== 0.0) {
+ $dx = $error / $pdf;
+ $xNew = $x - $dx;
+ }
+
+ // If the NR fails to converge (which for example may be the
+ // case if the initial guess is too rough) we apply a bisection
+ // step to determine a more narrow interval around the root.
+ if (($xNew < $xLo) || ($xNew > $xHi) || ($pdf == 0.0)) {
+ $xNew = ($xLo + $xHi) / 2;
+ $dx = $xNew - $x;
+ }
+ $x = $xNew;
+ }
+
+ if ($i === self::MAX_ITERATIONS) {
+ return Functions::NA();
+ }
+
+ return $x;
+ }
+
+ //
+ // Implementation of the incomplete Gamma function
+ //
+ public static function incompleteGamma(float $a, float $x): float
+ {
+ static $max = 32;
+ $summer = 0;
+ for ($n = 0; $n <= $max; ++$n) {
+ $divisor = $a;
+ for ($i = 1; $i <= $n; ++$i) {
+ $divisor *= ($a + $i);
+ }
+ $summer += ($x ** $n / $divisor);
+ }
+
+ return $x ** $a * exp(0 - $x) * $summer;
+ }
+
+ //
+ // Implementation of the Gamma function
+ //
+ public static function gammaValue(float $value): float
+ {
+ if ($value == 0.0) {
+ return 0;
+ }
+
+ static $p0 = 1.000000000190015;
+ static $p = [
+ 1 => 76.18009172947146,
+ 2 => -86.50532032941677,
+ 3 => 24.01409824083091,
+ 4 => -1.231739572450155,
+ 5 => 1.208650973866179e-3,
+ 6 => -5.395239384953e-6,
+ ];
+
+ $y = $x = $value;
+ $tmp = $x + 5.5;
+ $tmp -= ($x + 0.5) * log($tmp);
+
+ $summer = $p0;
+ for ($j = 1; $j <= 6; ++$j) {
+ $summer += ($p[$j] / ++$y);
+ }
+
+ return exp(0 - $tmp + log(self::SQRT2PI * $summer / $x));
+ }
+
+ /**
+ * logGamma function.
+ *
+ * @version 1.1
+ *
+ * @author Jaco van Kooten
+ *
+ * Original author was Jaco van Kooten. Ported to PHP by Paul Meagher.
+ *
+ * The natural logarithm of the gamma function.
+ * Based on public domain NETLIB (Fortran) code by W. J. Cody and L. Stoltz
+ * Applied Mathematics Division
+ * Argonne National Laboratory
+ * Argonne, IL 60439
+ *
+ * References:
+ *
+ *
W. J. Cody and K. E. Hillstrom, 'Chebyshev Approximations for the Natural
+ * Logarithm of the Gamma Function,' Math. Comp. 21, 1967, pp. 198-203.
+ *
K. E. Hillstrom, ANL/AMD Program ANLC366S, DGAMMA/DLGAMA, May, 1969.
+ *
Hart, Et. Al., Computer Approximations, Wiley and sons, New York, 1968.
+ *
+ *
+ *
+ * From the original documentation:
+ *
+ *
+ * This routine calculates the LOG(GAMMA) function for a positive real argument X.
+ * Computation is based on an algorithm outlined in references 1 and 2.
+ * The program uses rational functions that theoretically approximate LOG(GAMMA)
+ * to at least 18 significant decimal digits. The approximation for X > 12 is from
+ * reference 3, while approximations for X < 12.0 are similar to those in reference
+ * 1, but are unpublished. The accuracy achieved depends on the arithmetic system,
+ * the compiler, the intrinsic functions, and proper selection of the
+ * machine-dependent constants.
+ *
+ *
+ * Error returns:
+ * The program returns the value XINF for X .LE. 0.0 or when overflow would occur.
+ * The computation is believed to be free of underflow and overflow.
+ *
+ *
+ * @return float MAX_VALUE for x < 0.0 or when overflow would occur, i.e. x > 2.55E305
+ */
+
+ // Log Gamma related constants
+ private const LG_D1 = -0.5772156649015328605195174;
+
+ private const LG_D2 = 0.4227843350984671393993777;
+
+ private const LG_D4 = 1.791759469228055000094023;
+
+ private const LG_P1 = [
+ 4.945235359296727046734888,
+ 201.8112620856775083915565,
+ 2290.838373831346393026739,
+ 11319.67205903380828685045,
+ 28557.24635671635335736389,
+ 38484.96228443793359990269,
+ 26377.48787624195437963534,
+ 7225.813979700288197698961,
+ ];
+
+ private const LG_P2 = [
+ 4.974607845568932035012064,
+ 542.4138599891070494101986,
+ 15506.93864978364947665077,
+ 184793.2904445632425417223,
+ 1088204.76946882876749847,
+ 3338152.967987029735917223,
+ 5106661.678927352456275255,
+ 3074109.054850539556250927,
+ ];
+
+ private const LG_P4 = [
+ 14745.02166059939948905062,
+ 2426813.369486704502836312,
+ 121475557.4045093227939592,
+ 2663432449.630976949898078,
+ 29403789566.34553899906876,
+ 170266573776.5398868392998,
+ 492612579337.743088758812,
+ 560625185622.3951465078242,
+ ];
+
+ private const LG_Q1 = [
+ 67.48212550303777196073036,
+ 1113.332393857199323513008,
+ 7738.757056935398733233834,
+ 27639.87074403340708898585,
+ 54993.10206226157329794414,
+ 61611.22180066002127833352,
+ 36351.27591501940507276287,
+ 8785.536302431013170870835,
+ ];
+
+ private const LG_Q2 = [
+ 183.0328399370592604055942,
+ 7765.049321445005871323047,
+ 133190.3827966074194402448,
+ 1136705.821321969608938755,
+ 5267964.117437946917577538,
+ 13467014.54311101692290052,
+ 17827365.30353274213975932,
+ 9533095.591844353613395747,
+ ];
+
+ private const LG_Q4 = [
+ 2690.530175870899333379843,
+ 639388.5654300092398984238,
+ 41355999.30241388052042842,
+ 1120872109.61614794137657,
+ 14886137286.78813811542398,
+ 101680358627.2438228077304,
+ 341747634550.7377132798597,
+ 446315818741.9713286462081,
+ ];
+
+ private const LG_C = [
+ -0.001910444077728,
+ 8.4171387781295e-4,
+ -5.952379913043012e-4,
+ 7.93650793500350248e-4,
+ -0.002777777777777681622553,
+ 0.08333333333333333331554247,
+ 0.0057083835261,
+ ];
+
+ // Rough estimate of the fourth root of logGamma_xBig
+ private const LG_FRTBIG = 2.25e76;
+
+ private const PNT68 = 0.6796875;
+
+ // Function cache for logGamma
+ private static $logGammaCacheResult = 0.0;
+
+ private static $logGammaCacheX = 0.0;
+
+ public static function logGamma(float $x): float
+ {
+ if ($x == self::$logGammaCacheX) {
+ return self::$logGammaCacheResult;
+ }
+
+ $y = $x;
+ if ($y > 0.0 && $y <= self::LOG_GAMMA_X_MAX_VALUE) {
+ if ($y <= self::EPS) {
+ $res = -log($y);
+ } elseif ($y <= 1.5) {
+ $res = self::logGamma1($y);
+ } elseif ($y <= 4.0) {
+ $res = self::logGamma2($y);
+ } elseif ($y <= 12.0) {
+ $res = self::logGamma3($y);
+ } else {
+ $res = self::logGamma4($y);
+ }
+ } else {
+ // --------------------------
+ // Return for bad arguments
+ // --------------------------
+ $res = self::MAX_VALUE;
+ }
+
+ // ------------------------------
+ // Final adjustments and return
+ // ------------------------------
+ self::$logGammaCacheX = $x;
+ self::$logGammaCacheResult = $res;
+
+ return $res;
+ }
+
+ private static function logGamma1(float $y)
+ {
+ // ---------------------
+ // EPS .LT. X .LE. 1.5
+ // ---------------------
+ if ($y < self::PNT68) {
+ $corr = -log($y);
+ $xm1 = $y;
+ } else {
+ $corr = 0.0;
+ $xm1 = $y - 1.0;
+ }
+
+ $xden = 1.0;
+ $xnum = 0.0;
+ if ($y <= 0.5 || $y >= self::PNT68) {
+ for ($i = 0; $i < 8; ++$i) {
+ $xnum = $xnum * $xm1 + self::LG_P1[$i];
+ $xden = $xden * $xm1 + self::LG_Q1[$i];
+ }
+
+ return $corr + $xm1 * (self::LG_D1 + $xm1 * ($xnum / $xden));
+ }
+
+ $xm2 = $y - 1.0;
+ for ($i = 0; $i < 8; ++$i) {
+ $xnum = $xnum * $xm2 + self::LG_P2[$i];
+ $xden = $xden * $xm2 + self::LG_Q2[$i];
+ }
+
+ return $corr + $xm2 * (self::LG_D2 + $xm2 * ($xnum / $xden));
+ }
+
+ private static function logGamma2(float $y)
+ {
+ // ---------------------
+ // 1.5 .LT. X .LE. 4.0
+ // ---------------------
+ $xm2 = $y - 2.0;
+ $xden = 1.0;
+ $xnum = 0.0;
+ for ($i = 0; $i < 8; ++$i) {
+ $xnum = $xnum * $xm2 + self::LG_P2[$i];
+ $xden = $xden * $xm2 + self::LG_Q2[$i];
+ }
+
+ return $xm2 * (self::LG_D2 + $xm2 * ($xnum / $xden));
+ }
+
+ protected static function logGamma3(float $y)
+ {
+ // ----------------------
+ // 4.0 .LT. X .LE. 12.0
+ // ----------------------
+ $xm4 = $y - 4.0;
+ $xden = -1.0;
+ $xnum = 0.0;
+ for ($i = 0; $i < 8; ++$i) {
+ $xnum = $xnum * $xm4 + self::LG_P4[$i];
+ $xden = $xden * $xm4 + self::LG_Q4[$i];
+ }
+
+ return self::LG_D4 + $xm4 * ($xnum / $xden);
+ }
+
+ protected static function logGamma4(float $y)
+ {
+ // ---------------------------------
+ // Evaluate for argument .GE. 12.0
+ // ---------------------------------
+ $res = 0.0;
+ if ($y <= self::LG_FRTBIG) {
+ $res = self::LG_C[6];
+ $ysq = $y * $y;
+ for ($i = 0; $i < 6; ++$i) {
+ $res = $res / $ysq + self::LG_C[$i];
+ }
+ $res /= $y;
+ $corr = log($y);
+ $res = $res + log(self::SQRT2PI) - 0.5 * $corr;
+ $res += $y * ($corr - 1.0);
+ }
+
+ return $res;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php
new file mode 100644
index 00000000..fe30c087
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/HyperGeometric.php
@@ -0,0 +1,59 @@
+getMessage();
+ }
+
+ if (($sampleSuccesses < 0) || ($sampleSuccesses > $sampleNumber) || ($sampleSuccesses > $populationSuccesses)) {
+ return Functions::NAN();
+ }
+ if (($sampleNumber <= 0) || ($sampleNumber > $populationNumber)) {
+ return Functions::NAN();
+ }
+ if (($populationSuccesses <= 0) || ($populationSuccesses > $populationNumber)) {
+ return Functions::NAN();
+ }
+
+ $successesPopulationAndSample = (float) Combinations::withoutRepetition($populationSuccesses, $sampleSuccesses);
+ $numbersPopulationAndSample = (float) Combinations::withoutRepetition($populationNumber, $sampleNumber);
+ $adjustedPopulationAndSample = (float) Combinations::withoutRepetition(
+ $populationNumber - $populationSuccesses,
+ $sampleNumber - $sampleSuccesses
+ );
+
+ return $successesPopulationAndSample * $adjustedPopulationAndSample / $numbersPopulationAndSample;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php
new file mode 100644
index 00000000..e1523773
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/LogNormal.php
@@ -0,0 +1,119 @@
+getMessage();
+ }
+
+ if (($value <= 0) || ($stdDev <= 0)) {
+ return Functions::NAN();
+ }
+
+ return StandardNormal::cumulative((log($value) - $mean) / $stdDev);
+ }
+
+ /**
+ * LOGNORM.DIST.
+ *
+ * Returns the lognormal distribution of x, where ln(x) is normally distributed
+ * with parameters mean and standard_dev.
+ *
+ * @param mixed $value Float value for which we want the probability
+ * @param mixed $mean Mean value as a float
+ * @param mixed $stdDev Standard Deviation as a float
+ * @param mixed $cumulative Boolean value indicating if we want the cdf (true) or the pdf (false)
+ *
+ * @return float|string The result, or a string containing an error
+ */
+ public static function distribution($value, $mean, $stdDev, $cumulative = false)
+ {
+ $value = Functions::flattenSingleValue($value);
+ $mean = Functions::flattenSingleValue($mean);
+ $stdDev = Functions::flattenSingleValue($stdDev);
+ $cumulative = Functions::flattenSingleValue($cumulative);
+
+ try {
+ $value = DistributionValidations::validateFloat($value);
+ $mean = DistributionValidations::validateFloat($mean);
+ $stdDev = DistributionValidations::validateFloat($stdDev);
+ $cumulative = DistributionValidations::validateBool($cumulative);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if (($value <= 0) || ($stdDev <= 0)) {
+ return Functions::NAN();
+ }
+
+ if ($cumulative === true) {
+ return StandardNormal::distribution((log($value) - $mean) / $stdDev, true);
+ }
+
+ return (1 / (sqrt(2 * M_PI) * $stdDev * $value)) *
+ exp(0 - ((log($value) - $mean) ** 2 / (2 * $stdDev ** 2)));
+ }
+
+ /**
+ * LOGINV.
+ *
+ * Returns the inverse of the lognormal cumulative distribution
+ *
+ * @param mixed $probability Float probability for which we want the value
+ * @param mixed $mean Mean Value as a float
+ * @param mixed $stdDev Standard Deviation as a float
+ *
+ * @return float|string The result, or a string containing an error
+ *
+ * @TODO Try implementing P J Acklam's refinement algorithm for greater
+ * accuracy if I can get my head round the mathematics
+ * (as described at) http://home.online.no/~pjacklam/notes/invnorm/
+ */
+ public static function inverse($probability, $mean, $stdDev)
+ {
+ $probability = Functions::flattenSingleValue($probability);
+ $mean = Functions::flattenSingleValue($mean);
+ $stdDev = Functions::flattenSingleValue($stdDev);
+
+ try {
+ $probability = DistributionValidations::validateProbability($probability);
+ $mean = DistributionValidations::validateFloat($mean);
+ $stdDev = DistributionValidations::validateFloat($stdDev);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($stdDev <= 0) {
+ return Functions::NAN();
+ }
+
+ return exp($mean + $stdDev * StandardNormal::inverse($probability));
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php
new file mode 100644
index 00000000..26211672
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/NewtonRaphson.php
@@ -0,0 +1,62 @@
+callback = $callback;
+ }
+
+ public function execute(float $probability)
+ {
+ $xLo = 100;
+ $xHi = 0;
+
+ $dx = 1;
+ $x = $xNew = 1;
+ $i = 0;
+
+ while ((abs($dx) > Functions::PRECISION) && ($i++ < self::MAX_ITERATIONS)) {
+ // Apply Newton-Raphson step
+ $result = call_user_func($this->callback, $x);
+ $error = $result - $probability;
+
+ if ($error == 0.0) {
+ $dx = 0;
+ } elseif ($error < 0.0) {
+ $xLo = $x;
+ } else {
+ $xHi = $x;
+ }
+
+ // Avoid division by zero
+ if ($result != 0.0) {
+ $dx = $error / $result;
+ $xNew = $x - $dx;
+ }
+
+ // If the NR fails to converge (which for example may be the
+ // case if the initial guess is too rough) we apply a bisection
+ // step to determine a more narrow interval around the root.
+ if (($xNew < $xLo) || ($xNew > $xHi) || ($result == 0.0)) {
+ $xNew = ($xLo + $xHi) / 2;
+ $dx = $xNew - $x;
+ }
+ $x = $xNew;
+ }
+
+ if ($i == self::MAX_ITERATIONS) {
+ return Functions::NA();
+ }
+
+ return $x;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php
new file mode 100644
index 00000000..4d158b8c
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Normal.php
@@ -0,0 +1,166 @@
+getMessage();
+ }
+
+ if ($stdDev < 0) {
+ return Functions::NAN();
+ }
+
+ if ($cumulative) {
+ return 0.5 * (1 + Engineering\Erf::erfValue(($value - $mean) / ($stdDev * sqrt(2))));
+ }
+
+ return (1 / (self::SQRT2PI * $stdDev)) * exp(0 - (($value - $mean) ** 2 / (2 * ($stdDev * $stdDev))));
+ }
+
+ /**
+ * NORMINV.
+ *
+ * Returns the inverse of the normal cumulative distribution for the specified mean and standard deviation.
+ *
+ * @param mixed $probability Float probability for which we want the value
+ * @param mixed $mean Mean Value as a float
+ * @param mixed $stdDev Standard Deviation as a float
+ *
+ * @return float|string The result, or a string containing an error
+ */
+ public static function inverse($probability, $mean, $stdDev)
+ {
+ $probability = Functions::flattenSingleValue($probability);
+ $mean = Functions::flattenSingleValue($mean);
+ $stdDev = Functions::flattenSingleValue($stdDev);
+
+ try {
+ $probability = DistributionValidations::validateProbability($probability);
+ $mean = DistributionValidations::validateFloat($mean);
+ $stdDev = DistributionValidations::validateFloat($stdDev);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($stdDev < 0) {
+ return Functions::NAN();
+ }
+
+ return (self::inverseNcdf($probability) * $stdDev) + $mean;
+ }
+
+ /*
+ * inverse_ncdf.php
+ * -------------------
+ * begin : Friday, January 16, 2004
+ * copyright : (C) 2004 Michael Nickerson
+ * email : nickersonm@yahoo.com
+ *
+ */
+ private static function inverseNcdf($p)
+ {
+ // Inverse ncdf approximation by Peter J. Acklam, implementation adapted to
+ // PHP by Michael Nickerson, using Dr. Thomas Ziegler's C implementation as
+ // a guide. http://home.online.no/~pjacklam/notes/invnorm/index.html
+ // I have not checked the accuracy of this implementation. Be aware that PHP
+ // will truncate the coeficcients to 14 digits.
+
+ // You have permission to use and distribute this function freely for
+ // whatever purpose you want, but please show common courtesy and give credit
+ // where credit is due.
+
+ // Input paramater is $p - probability - where 0 < p < 1.
+
+ // Coefficients in rational approximations
+ static $a = [
+ 1 => -3.969683028665376e+01,
+ 2 => 2.209460984245205e+02,
+ 3 => -2.759285104469687e+02,
+ 4 => 1.383577518672690e+02,
+ 5 => -3.066479806614716e+01,
+ 6 => 2.506628277459239e+00,
+ ];
+
+ static $b = [
+ 1 => -5.447609879822406e+01,
+ 2 => 1.615858368580409e+02,
+ 3 => -1.556989798598866e+02,
+ 4 => 6.680131188771972e+01,
+ 5 => -1.328068155288572e+01,
+ ];
+
+ static $c = [
+ 1 => -7.784894002430293e-03,
+ 2 => -3.223964580411365e-01,
+ 3 => -2.400758277161838e+00,
+ 4 => -2.549732539343734e+00,
+ 5 => 4.374664141464968e+00,
+ 6 => 2.938163982698783e+00,
+ ];
+
+ static $d = [
+ 1 => 7.784695709041462e-03,
+ 2 => 3.224671290700398e-01,
+ 3 => 2.445134137142996e+00,
+ 4 => 3.754408661907416e+00,
+ ];
+
+ // Define lower and upper region break-points.
+ $p_low = 0.02425; //Use lower region approx. below this
+ $p_high = 1 - $p_low; //Use upper region approx. above this
+
+ if (0 < $p && $p < $p_low) {
+ // Rational approximation for lower region.
+ $q = sqrt(-2 * log($p));
+
+ return ((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) /
+ (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1);
+ } elseif ($p_high < $p && $p < 1) {
+ // Rational approximation for upper region.
+ $q = sqrt(-2 * log(1 - $p));
+
+ return -((((($c[1] * $q + $c[2]) * $q + $c[3]) * $q + $c[4]) * $q + $c[5]) * $q + $c[6]) /
+ (((($d[1] * $q + $d[2]) * $q + $d[3]) * $q + $d[4]) * $q + 1);
+ }
+
+ // Rational approximation for central region.
+ $q = $p - 0.5;
+ $r = $q * $q;
+
+ return ((((($a[1] * $r + $a[2]) * $r + $a[3]) * $r + $a[4]) * $r + $a[5]) * $r + $a[6]) * $q /
+ ((((($b[1] * $r + $b[2]) * $r + $b[3]) * $r + $b[4]) * $r + $b[5]) * $r + 1);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php
new file mode 100644
index 00000000..c25194a7
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Poisson.php
@@ -0,0 +1,53 @@
+getMessage();
+ }
+
+ if (($value < 0) || ($mean < 0)) {
+ return Functions::NAN();
+ }
+
+ if ($cumulative) {
+ $summer = 0;
+ $floor = floor($value);
+ for ($i = 0; $i <= $floor; ++$i) {
+ $summer += $mean ** $i / MathTrig\Fact::funcFact($i);
+ }
+
+ return exp(0 - $mean) * $summer;
+ }
+
+ return (exp(0 - $mean) * $mean ** $value) / MathTrig\Fact::funcFact($value);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php
new file mode 100644
index 00000000..0dde2006
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/StandardNormal.php
@@ -0,0 +1,90 @@
+getMessage();
+ }
+
+ if (($value < 0) || ($degrees < 1) || ($tails < 1) || ($tails > 2)) {
+ return Functions::NAN();
+ }
+
+ return self::calculateDistribution($value, $degrees, $tails);
+ }
+
+ /**
+ * TINV.
+ *
+ * Returns the one-tailed probability of the chi-squared distribution.
+ *
+ * @param mixed $probability Float probability for the function
+ * @param mixed $degrees Integer value for degrees of freedom
+ *
+ * @return float|string The result, or a string containing an error
+ */
+ public static function inverse($probability, $degrees)
+ {
+ $probability = Functions::flattenSingleValue($probability);
+ $degrees = Functions::flattenSingleValue($degrees);
+
+ try {
+ $probability = DistributionValidations::validateProbability($probability);
+ $degrees = DistributionValidations::validateInt($degrees);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($degrees <= 0) {
+ return Functions::NAN();
+ }
+
+ $callback = function ($value) use ($degrees) {
+ return self::distribution($value, $degrees, 2);
+ };
+
+ $newtonRaphson = new NewtonRaphson($callback);
+
+ return $newtonRaphson->execute($probability);
+ }
+
+ /**
+ * @return float
+ */
+ private static function calculateDistribution(float $value, int $degrees, int $tails)
+ {
+ // tdist, which finds the probability that corresponds to a given value
+ // of t with k degrees of freedom. This algorithm is translated from a
+ // pascal function on p81 of "Statistical Computing in Pascal" by D
+ // Cooke, A H Craven & G M Clark (1985: Edward Arnold (Pubs.) Ltd:
+ // London). The above Pascal algorithm is itself a translation of the
+ // fortran algoritm "AS 3" by B E Cooper of the Atlas Computer
+ // Laboratory as reported in (among other places) "Applied Statistics
+ // Algorithms", editied by P Griffiths and I D Hill (1985; Ellis
+ // Horwood Ltd.; W. Sussex, England).
+ $tterm = $degrees;
+ $ttheta = atan2($value, sqrt($tterm));
+ $tc = cos($ttheta);
+ $ts = sin($ttheta);
+
+ if (($degrees % 2) === 1) {
+ $ti = 3;
+ $tterm = $tc;
+ } else {
+ $ti = 2;
+ $tterm = 1;
+ }
+
+ $tsum = $tterm;
+ while ($ti < $degrees) {
+ $tterm *= $tc * $tc * ($ti - 1) / $ti;
+ $tsum += $tterm;
+ $ti += 2;
+ }
+
+ $tsum *= $ts;
+ if (($degrees % 2) == 1) {
+ $tsum = Functions::M_2DIVPI * ($tsum + $ttheta);
+ }
+
+ $tValue = 0.5 * (1 + $tsum);
+ if ($tails == 1) {
+ return 1 - abs($tValue);
+ }
+
+ return 1 - abs((1 - $tValue) - $tValue);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Weibull.php b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Weibull.php
new file mode 100644
index 00000000..ecec8a85
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Distributions/Weibull.php
@@ -0,0 +1,49 @@
+getMessage();
+ }
+
+ if (($value < 0) || ($alpha <= 0) || ($beta <= 0)) {
+ return Functions::NAN();
+ }
+
+ if ($cumulative) {
+ return 1 - exp(0 - ($value / $beta) ** $alpha);
+ }
+
+ return ($alpha / $beta ** $alpha) * $value ** ($alpha - 1) * exp(0 - ($value / $beta) ** $alpha);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/MaxMinBase.php b/src/PhpSpreadsheet/Calculation/Statistical/MaxMinBase.php
new file mode 100644
index 00000000..bd17b062
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/MaxMinBase.php
@@ -0,0 +1,17 @@
+ $returnValue)) {
+ $returnValue = $arg;
+ }
+ }
+ }
+
+ if ($returnValue === null) {
+ return 0;
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * MAXA.
+ *
+ * Returns the greatest value in a list of arguments, including numbers, text, and logical values
+ *
+ * Excel Function:
+ * MAXA(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return float
+ */
+ public static function MAXA(...$args)
+ {
+ $returnValue = null;
+
+ // Loop through arguments
+ $aArgs = Functions::flattenArray($args);
+ foreach ($aArgs as $arg) {
+ // Is it a numeric value?
+ if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) && ($arg != '')))) {
+ $arg = self::datatypeAdjustmentAllowStrings($arg);
+ if (($returnValue === null) || ($arg > $returnValue)) {
+ $returnValue = $arg;
+ }
+ }
+ }
+
+ if ($returnValue === null) {
+ return 0;
+ }
+
+ return $returnValue;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Minimum.php b/src/PhpSpreadsheet/Calculation/Statistical/Minimum.php
new file mode 100644
index 00000000..bd46882e
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Minimum.php
@@ -0,0 +1,78 @@
+getMessage();
+ }
+
+ if (($entry < 0) || ($entry > 1)) {
+ return Functions::NAN();
+ }
+
+ $mArgs = self::percentileFilterValues($aArgs);
+ $mValueCount = count($mArgs);
+ if ($mValueCount > 0) {
+ sort($mArgs);
+ $count = Counts::COUNT($mArgs);
+ $index = $entry * ($count - 1);
+ $iBase = floor($index);
+ if ($index == $iBase) {
+ return $mArgs[$index];
+ }
+ $iNext = $iBase + 1;
+ $iProportion = $index - $iBase;
+
+ return $mArgs[$iBase] + (($mArgs[$iNext] - $mArgs[$iBase]) * $iProportion);
+ }
+
+ return Functions::NAN();
+ }
+
+ /**
+ * PERCENTRANK.
+ *
+ * Returns the rank of a value in a data set as a percentage of the data set.
+ * Note that the returned rank is simply rounded to the appropriate significant digits,
+ * rather than floored (as MS Excel), so value 3 for a value set of 1, 2, 3, 4 will return
+ * 0.667 rather than 0.666
+ *
+ * @param mixed $valueSet An array of (float) values, or a reference to, a list of numbers
+ * @param mixed $value The number whose rank you want to find
+ * @param mixed $significance The (integer) number of significant digits for the returned percentage value
+ *
+ * @return float|string (string if result is an error)
+ */
+ public static function PERCENTRANK($valueSet, $value, $significance = 3)
+ {
+ $valueSet = Functions::flattenArray($valueSet);
+ $value = Functions::flattenSingleValue($value);
+ $significance = ($significance === null) ? 3 : Functions::flattenSingleValue($significance);
+
+ try {
+ $value = StatisticalValidations::validateFloat($value);
+ $significance = StatisticalValidations::validateInt($significance);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $valueSet = self::rankFilterValues($valueSet);
+ $valueCount = count($valueSet);
+ if ($valueCount == 0) {
+ return Functions::NA();
+ }
+ sort($valueSet, SORT_NUMERIC);
+
+ $valueAdjustor = $valueCount - 1;
+ if (($value < $valueSet[0]) || ($value > $valueSet[$valueAdjustor])) {
+ return Functions::NA();
+ }
+
+ $pos = array_search($value, $valueSet);
+ if ($pos === false) {
+ $pos = 0;
+ $testValue = $valueSet[0];
+ while ($testValue < $value) {
+ $testValue = $valueSet[++$pos];
+ }
+ --$pos;
+ $pos += (($value - $valueSet[$pos]) / ($testValue - $valueSet[$pos]));
+ }
+
+ return round($pos / $valueAdjustor, $significance);
+ }
+
+ /**
+ * QUARTILE.
+ *
+ * Returns the quartile of a data set.
+ *
+ * Excel Function:
+ * QUARTILE(value1[,value2[, ...]],entry)
+ *
+ * @param mixed $args Data values
+ *
+ * @return float|string The result, or a string containing an error
+ */
+ public static function QUARTILE(...$args)
+ {
+ $aArgs = Functions::flattenArray($args);
+ $entry = array_pop($aArgs);
+
+ try {
+ $entry = StatisticalValidations::validateFloat($entry);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $entry = floor($entry);
+ $entry /= 4;
+ if (($entry < 0) || ($entry > 1)) {
+ return Functions::NAN();
+ }
+
+ return self::PERCENTILE($aArgs, $entry);
+ }
+
+ /**
+ * RANK.
+ *
+ * Returns the rank of a number in a list of numbers.
+ *
+ * @param mixed $value The number whose rank you want to find
+ * @param mixed $valueSet An array of float values, or a reference to, a list of numbers
+ * @param mixed $order Order to sort the values in the value set
+ *
+ * @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)
+ {
+ $value = Functions::flattenSingleValue($value);
+ $valueSet = Functions::flattenArray($valueSet);
+ $order = ($order === null) ? self::RANK_SORT_DESCENDING : Functions::flattenSingleValue($order);
+
+ try {
+ $value = StatisticalValidations::validateFloat($value);
+ $order = StatisticalValidations::validateInt($order);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $valueSet = self::rankFilterValues($valueSet);
+ if ($order === self::RANK_SORT_DESCENDING) {
+ rsort($valueSet, SORT_NUMERIC);
+ } else {
+ sort($valueSet, SORT_NUMERIC);
+ }
+
+ $pos = array_search($value, $valueSet);
+ if ($pos === false) {
+ return Functions::NA();
+ }
+
+ return ++$pos;
+ }
+
+ protected static function percentileFilterValues(array $dataSet)
+ {
+ return array_filter(
+ $dataSet,
+ function ($value): bool {
+ return is_numeric($value) && !is_string($value);
+ }
+ );
+ }
+
+ protected static function rankFilterValues(array $dataSet)
+ {
+ return array_filter(
+ $dataSet,
+ function ($value): bool {
+ return is_numeric($value);
+ }
+ );
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php b/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php
new file mode 100644
index 00000000..6330d39f
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/Permutations.php
@@ -0,0 +1,73 @@
+getMessage();
+ }
+
+ if ($numObjs < $numInSet) {
+ return Functions::NAN();
+ }
+
+ return (int) round(MathTrig\Fact::funcFact($numObjs) / MathTrig\Fact::funcFact($numObjs - $numInSet));
+ }
+
+ /**
+ * PERMUTATIONA.
+ *
+ * Returns the number of permutations for a given number of objects (with repetitions)
+ * that can be selected from the total objects.
+ *
+ * @param mixed $numObjs Integer number of different objects
+ * @param mixed $numInSet Integer number of objects in each permutation
+ *
+ * @return int|string Number of permutations, or a string containing an error
+ */
+ public static function PERMUTATIONA($numObjs, $numInSet)
+ {
+ $numObjs = Functions::flattenSingleValue($numObjs);
+ $numInSet = Functions::flattenSingleValue($numInSet);
+
+ try {
+ $numObjs = StatisticalValidations::validateInt($numObjs);
+ $numInSet = StatisticalValidations::validateInt($numInSet);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ if ($numObjs < 0 || $numInSet < 0) {
+ return Functions::NAN();
+ }
+
+ return (int) ($numObjs ** $numInSet);
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php b/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php
new file mode 100644
index 00000000..af271205
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/StandardDeviations.php
@@ -0,0 +1,95 @@
+ $value) {
+ if ((is_bool($value)) || (is_string($value)) || ($value === null)) {
+ unset($array1[$key], $array2[$key]);
+ }
+ }
+ }
+
+ private static function checkTrendArrays(&$array1, &$array2): void
+ {
+ if (!is_array($array1)) {
+ $array1 = [$array1];
+ }
+ if (!is_array($array2)) {
+ $array2 = [$array2];
+ }
+
+ $array1 = Functions::flattenArray($array1);
+ $array2 = Functions::flattenArray($array2);
+
+ self::filterTrendValues($array1, $array2);
+ self::filterTrendValues($array2, $array1);
+
+ // Reset the array indexes
+ $array1 = array_merge($array1);
+ $array2 = array_merge($array2);
+ }
+
+ protected static function validateTrendArrays(array $yValues, array $xValues): void
+ {
+ $yValueCount = count($yValues);
+ $xValueCount = count($xValues);
+
+ if (($yValueCount === 0) || ($yValueCount !== $xValueCount)) {
+ throw new Exception(Functions::NA());
+ } elseif ($yValueCount === 1) {
+ throw new Exception(Functions::DIV0());
+ }
+ }
+
+ /**
+ * CORREL.
+ *
+ * Returns covariance, the average of the products of deviations for each data point pair.
+ *
+ * @param mixed $yValues array of mixed Data Series Y
+ * @param null|mixed $xValues array of mixed Data Series X
+ *
+ * @return float|string
+ */
+ public static function CORREL($yValues, $xValues = null)
+ {
+ if (($xValues === null) || (!is_array($yValues)) || (!is_array($xValues))) {
+ return Functions::VALUE();
+ }
+
+ try {
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
+
+ return $bestFitLinear->getCorrelation();
+ }
+
+ /**
+ * COVAR.
+ *
+ * Returns covariance, the average of the products of deviations for each data point pair.
+ *
+ * @param mixed $yValues array of mixed Data Series Y
+ * @param mixed $xValues array of mixed Data Series X
+ *
+ * @return float|string
+ */
+ public static function COVAR($yValues, $xValues)
+ {
+ try {
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
+
+ return $bestFitLinear->getCovariance();
+ }
+
+ /**
+ * FORECAST.
+ *
+ * Calculates, or predicts, a future value by using existing values.
+ * The predicted value is a y-value for a given x-value.
+ *
+ * @param mixed $xValue Float value of X for which we want to find Y
+ * @param mixed $yValues array of mixed Data Series Y
+ * @param mixed $xValues of mixed Data Series X
+ *
+ * @return bool|float|string
+ */
+ public static function FORECAST($xValue, $yValues, $xValues)
+ {
+ $xValue = Functions::flattenSingleValue($xValue);
+
+ try {
+ $xValue = StatisticalValidations::validateFloat($xValue);
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
+
+ return $bestFitLinear->getValueOfYForX($xValue);
+ }
+
+ /**
+ * GROWTH.
+ *
+ * Returns values along a predicted exponential Trend
+ *
+ * @param mixed[] $yValues Data Series Y
+ * @param mixed[] $xValues Data Series X
+ * @param mixed[] $newValues Values of X for which we want to find Y
+ * @param mixed $const A logical (boolean) value specifying whether to force the intersect to equal 0 or not
+ *
+ * @return float[]
+ */
+ public static function GROWTH($yValues, $xValues = [], $newValues = [], $const = true)
+ {
+ $yValues = Functions::flattenArray($yValues);
+ $xValues = Functions::flattenArray($xValues);
+ $newValues = Functions::flattenArray($newValues);
+ $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const);
+
+ $bestFitExponential = Trend::calculate(Trend::TREND_EXPONENTIAL, $yValues, $xValues, $const);
+ if (empty($newValues)) {
+ $newValues = $bestFitExponential->getXValues();
+ }
+
+ $returnArray = [];
+ foreach ($newValues as $xValue) {
+ $returnArray[0][] = [$bestFitExponential->getValueOfYForX($xValue)];
+ }
+
+ return $returnArray;
+ }
+
+ /**
+ * INTERCEPT.
+ *
+ * Calculates the point at which a line will intersect the y-axis by using existing x-values and y-values.
+ *
+ * @param mixed[] $yValues Data Series Y
+ * @param mixed[] $xValues Data Series X
+ *
+ * @return float|string
+ */
+ public static function INTERCEPT($yValues, $xValues)
+ {
+ try {
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
+
+ return $bestFitLinear->getIntersect();
+ }
+
+ /**
+ * LINEST.
+ *
+ * Calculates the statistics for a line by using the "least squares" method to calculate a straight line
+ * that best fits your data, and then returns an array that describes the line.
+ *
+ * @param mixed[] $yValues Data Series Y
+ * @param null|mixed[] $xValues Data Series X
+ * @param mixed $const A logical (boolean) value specifying whether to force the intersect to equal 0 or not
+ * @param mixed $stats A logical (boolean) value specifying whether to return additional regression statistics
+ *
+ * @return array|int|string The result, or a string containing an error
+ */
+ public static function LINEST($yValues, $xValues = null, $const = true, $stats = false)
+ {
+ $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const);
+ $stats = ($stats === null) ? false : (bool) Functions::flattenSingleValue($stats);
+ if ($xValues === null) {
+ $xValues = $yValues;
+ }
+
+ try {
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues, $const);
+
+ if ($stats === true) {
+ return [
+ [
+ $bestFitLinear->getSlope(),
+ $bestFitLinear->getIntersect(),
+ ],
+ [
+ $bestFitLinear->getSlopeSE(),
+ ($const === false) ? Functions::NA() : $bestFitLinear->getIntersectSE(),
+ ],
+ [
+ $bestFitLinear->getGoodnessOfFit(),
+ $bestFitLinear->getStdevOfResiduals(),
+ ],
+ [
+ $bestFitLinear->getF(),
+ $bestFitLinear->getDFResiduals(),
+ ],
+ [
+ $bestFitLinear->getSSRegression(),
+ $bestFitLinear->getSSResiduals(),
+ ],
+ ];
+ }
+
+ return [
+ $bestFitLinear->getSlope(),
+ $bestFitLinear->getIntersect(),
+ ];
+ }
+
+ /**
+ * LOGEST.
+ *
+ * Calculates an exponential curve that best fits the X and Y data series,
+ * and then returns an array that describes the line.
+ *
+ * @param mixed[] $yValues Data Series Y
+ * @param null|mixed[] $xValues Data Series X
+ * @param mixed $const A logical (boolean) value specifying whether to force the intersect to equal 0 or not
+ * @param mixed $stats A logical (boolean) value specifying whether to return additional regression statistics
+ *
+ * @return array|int|string The result, or a string containing an error
+ */
+ public static function LOGEST($yValues, $xValues = null, $const = true, $stats = false)
+ {
+ $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const);
+ $stats = ($stats === null) ? false : (bool) Functions::flattenSingleValue($stats);
+ if ($xValues === null) {
+ $xValues = $yValues;
+ }
+
+ try {
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ foreach ($yValues as $value) {
+ if ($value < 0.0) {
+ return Functions::NAN();
+ }
+ }
+
+ $bestFitExponential = Trend::calculate(Trend::TREND_EXPONENTIAL, $yValues, $xValues, $const);
+
+ if ($stats === true) {
+ return [
+ [
+ $bestFitExponential->getSlope(),
+ $bestFitExponential->getIntersect(),
+ ],
+ [
+ $bestFitExponential->getSlopeSE(),
+ ($const === false) ? Functions::NA() : $bestFitExponential->getIntersectSE(),
+ ],
+ [
+ $bestFitExponential->getGoodnessOfFit(),
+ $bestFitExponential->getStdevOfResiduals(),
+ ],
+ [
+ $bestFitExponential->getF(),
+ $bestFitExponential->getDFResiduals(),
+ ],
+ [
+ $bestFitExponential->getSSRegression(),
+ $bestFitExponential->getSSResiduals(),
+ ],
+ ];
+ }
+
+ return [
+ $bestFitExponential->getSlope(),
+ $bestFitExponential->getIntersect(),
+ ];
+ }
+
+ /**
+ * RSQ.
+ *
+ * Returns the square of the Pearson product moment correlation coefficient through data points
+ * in known_y's and known_x's.
+ *
+ * @param mixed[] $yValues Data Series Y
+ * @param mixed[] $xValues Data Series X
+ *
+ * @return float|string The result, or a string containing an error
+ */
+ public static function RSQ($yValues, $xValues)
+ {
+ try {
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
+
+ return $bestFitLinear->getGoodnessOfFit();
+ }
+
+ /**
+ * SLOPE.
+ *
+ * Returns the slope of the linear regression line through data points in known_y's and known_x's.
+ *
+ * @param mixed[] $yValues Data Series Y
+ * @param mixed[] $xValues Data Series X
+ *
+ * @return float|string The result, or a string containing an error
+ */
+ public static function SLOPE($yValues, $xValues)
+ {
+ try {
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
+
+ return $bestFitLinear->getSlope();
+ }
+
+ /**
+ * STEYX.
+ *
+ * Returns the standard error of the predicted y-value for each x in the regression.
+ *
+ * @param mixed[] $yValues Data Series Y
+ * @param mixed[] $xValues Data Series X
+ *
+ * @return float|string
+ */
+ public static function STEYX($yValues, $xValues)
+ {
+ try {
+ self::checkTrendArrays($yValues, $xValues);
+ self::validateTrendArrays($yValues, $xValues);
+ } catch (Exception $e) {
+ return $e->getMessage();
+ }
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues);
+
+ return $bestFitLinear->getStdevOfResiduals();
+ }
+
+ /**
+ * TREND.
+ *
+ * Returns values along a linear Trend
+ *
+ * @param mixed[] $yValues Data Series Y
+ * @param mixed[] $xValues Data Series X
+ * @param mixed[] $newValues Values of X for which we want to find Y
+ * @param mixed $const A logical (boolean) value specifying whether to force the intersect to equal 0 or not
+ *
+ * @return float[]
+ */
+ public static function TREND($yValues, $xValues = [], $newValues = [], $const = true)
+ {
+ $yValues = Functions::flattenArray($yValues);
+ $xValues = Functions::flattenArray($xValues);
+ $newValues = Functions::flattenArray($newValues);
+ $const = ($const === null) ? true : (bool) Functions::flattenSingleValue($const);
+
+ $bestFitLinear = Trend::calculate(Trend::TREND_LINEAR, $yValues, $xValues, $const);
+ if (empty($newValues)) {
+ $newValues = $bestFitLinear->getXValues();
+ }
+
+ $returnArray = [];
+ foreach ($newValues as $xValue) {
+ $returnArray[0][] = [$bestFitLinear->getValueOfYForX($xValue)];
+ }
+
+ return $returnArray;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php b/src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php
new file mode 100644
index 00000000..e5334671
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/Statistical/VarianceBase.php
@@ -0,0 +1,28 @@
+ 1) {
+ $summerA *= $aCount;
+ $summerB *= $summerB;
+
+ return ($summerA - $summerB) / ($aCount * ($aCount - 1));
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * VARA.
+ *
+ * Estimates variance based on a sample, including numbers, text, and logical values
+ *
+ * Excel Function:
+ * VARA(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return float|string (string if result is an error)
+ */
+ public static function VARA(...$args)
+ {
+ $returnValue = Functions::DIV0();
+
+ $summerA = $summerB = 0.0;
+
+ // Loop through arguments
+ $aArgs = Functions::flattenArrayIndexed($args);
+ $aCount = 0;
+ foreach ($aArgs as $k => $arg) {
+ if ((is_string($arg)) && (Functions::isValue($k))) {
+ return Functions::VALUE();
+ } elseif ((is_string($arg)) && (!Functions::isMatrixValue($k))) {
+ } else {
+ // Is it a numeric value?
+ if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
+ $arg = self::datatypeAdjustmentAllowStrings($arg);
+ $summerA += ($arg * $arg);
+ $summerB += $arg;
+ ++$aCount;
+ }
+ }
+ }
+
+ if ($aCount > 1) {
+ $summerA *= $aCount;
+ $summerB *= $summerB;
+
+ return ($summerA - $summerB) / ($aCount * ($aCount - 1));
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * VARP.
+ *
+ * Calculates variance based on the entire population
+ *
+ * Excel Function:
+ * VARP(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return float|string (string if result is an error)
+ */
+ public static function VARP(...$args)
+ {
+ // Return value
+ $returnValue = Functions::DIV0();
+
+ $summerA = $summerB = 0.0;
+
+ // Loop through arguments
+ $aArgs = Functions::flattenArray($args);
+ $aCount = 0;
+ foreach ($aArgs as $arg) {
+ $arg = self::datatypeAdjustmentBooleans($arg);
+
+ // Is it a numeric value?
+ if ((is_numeric($arg)) && (!is_string($arg))) {
+ $summerA += ($arg * $arg);
+ $summerB += $arg;
+ ++$aCount;
+ }
+ }
+
+ if ($aCount > 0) {
+ $summerA *= $aCount;
+ $summerB *= $summerB;
+
+ return ($summerA - $summerB) / ($aCount * $aCount);
+ }
+
+ return $returnValue;
+ }
+
+ /**
+ * VARPA.
+ *
+ * Calculates variance based on the entire population, including numbers, text, and logical values
+ *
+ * Excel Function:
+ * VARPA(value1[,value2[, ...]])
+ *
+ * @param mixed ...$args Data values
+ *
+ * @return float|string (string if result is an error)
+ */
+ public static function VARPA(...$args)
+ {
+ $returnValue = Functions::DIV0();
+
+ $summerA = $summerB = 0.0;
+
+ // Loop through arguments
+ $aArgs = Functions::flattenArrayIndexed($args);
+ $aCount = 0;
+ foreach ($aArgs as $k => $arg) {
+ if ((is_string($arg)) && (Functions::isValue($k))) {
+ return Functions::VALUE();
+ } elseif ((is_string($arg)) && (!Functions::isMatrixValue($k))) {
+ } else {
+ // Is it a numeric value?
+ if ((is_numeric($arg)) || (is_bool($arg)) || ((is_string($arg) & ($arg != '')))) {
+ $arg = self::datatypeAdjustmentAllowStrings($arg);
+ $summerA += ($arg * $arg);
+ $summerB += $arg;
+ ++$aCount;
+ }
+ }
+ }
+
+ if ($aCount > 0) {
+ $summerA *= $aCount;
+ $summerB *= $summerB;
+
+ return ($summerA - $summerB) / ($aCount * $aCount);
+ }
+
+ return $returnValue;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/TextData.php b/src/PhpSpreadsheet/Calculation/TextData.php
index f8974402..0bde3b7f 100644
--- a/src/PhpSpreadsheet/Calculation/TextData.php
+++ b/src/PhpSpreadsheet/Calculation/TextData.php
@@ -3,141 +3,88 @@
namespace PhpOffice\PhpSpreadsheet\Calculation;
use DateTimeInterface;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
-use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
+/**
+ * @deprecated 1.18.0
+ */
class TextData
{
- private static $invalidChars;
-
- private static function unicodeToOrd($character)
- {
- return unpack('V', iconv('UTF-8', 'UCS-4LE', $character))[1];
- }
-
/**
* CHARACTER.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the character() method in the TextData\CharacterConvert class instead
+ *
* @param string $character Value
*
* @return string
*/
public static function CHARACTER($character)
{
- $character = Functions::flattenSingleValue($character);
-
- if (!is_numeric($character)) {
- return Functions::VALUE();
- }
- $character = (int) $character;
- if ($character < 1 || $character > 255) {
- return Functions::VALUE();
- }
-
- return iconv('UCS-4LE', 'UTF-8', pack('V', $character));
+ return TextData\CharacterConvert::character($character);
}
/**
* TRIMNONPRINTABLE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the nonPrintable() method in the TextData\Trim class instead
+ *
* @param mixed $stringValue Value to check
*
* @return string
*/
public static function TRIMNONPRINTABLE($stringValue = '')
{
- $stringValue = Functions::flattenSingleValue($stringValue);
-
- if (is_bool($stringValue)) {
- return ($stringValue) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- if (self::$invalidChars === null) {
- self::$invalidChars = range(chr(0), chr(31));
- }
-
- if (is_string($stringValue) || is_numeric($stringValue)) {
- return str_replace(self::$invalidChars, '', trim($stringValue, "\x00..\x1F"));
- }
-
- return null;
+ return TextData\Trim::nonPrintable($stringValue);
}
/**
* TRIMSPACES.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the spaces() method in the TextData\Trim class instead
+ *
* @param mixed $stringValue Value to check
*
* @return string
*/
public static function TRIMSPACES($stringValue = '')
{
- $stringValue = Functions::flattenSingleValue($stringValue);
- if (is_bool($stringValue)) {
- return ($stringValue) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- if (is_string($stringValue) || is_numeric($stringValue)) {
- return trim(preg_replace('/ +/', ' ', trim($stringValue, ' ')), ' ');
- }
-
- return null;
- }
-
- private static function convertBooleanValue($value)
- {
- if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) {
- return (int) $value;
- }
-
- return ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
+ return TextData\Trim::spaces($stringValue);
}
/**
* ASCIICODE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the code() method in the TextData\CharacterConvert class instead
+ *
* @param string $characters Value
*
* @return int|string A string if arguments are invalid
*/
public static function ASCIICODE($characters)
{
- if (($characters === null) || ($characters === '')) {
- return Functions::VALUE();
- }
- $characters = Functions::flattenSingleValue($characters);
- if (is_bool($characters)) {
- $characters = self::convertBooleanValue($characters);
- }
-
- $character = $characters;
- if (mb_strlen($characters, 'UTF-8') > 1) {
- $character = mb_substr($characters, 0, 1, 'UTF-8');
- }
-
- return self::unicodeToOrd($character);
+ return TextData\CharacterConvert::code($characters);
}
/**
* CONCATENATE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the CONCATENATE() method in the TextData\Concatenate class instead
+ *
* @return string
*/
public static function CONCATENATE(...$args)
{
- $returnValue = '';
-
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- foreach ($aArgs as $arg) {
- if (is_bool($arg)) {
- $arg = self::convertBooleanValue($arg);
- }
- $returnValue .= $arg;
- }
-
- return $returnValue;
+ return TextData\Concatenate::CONCATENATE(...$args);
}
/**
@@ -146,6 +93,10 @@ class TextData
* This function converts a number to text using currency format, with the decimals rounded to the specified place.
* The format used is $#,##0.00_);($#,##0.00)..
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the DOLLAR() method in the TextData\Format class instead
+ *
* @param float $value The value to format
* @param int $decimals The number of digits to display to the right of the decimal point.
* If decimals is negative, number is rounded to the left of the decimal point.
@@ -155,33 +106,16 @@ class TextData
*/
public static function DOLLAR($value = 0, $decimals = 2)
{
- $value = Functions::flattenSingleValue($value);
- $decimals = $decimals === null ? 0 : Functions::flattenSingleValue($decimals);
-
- // Validate parameters
- if (!is_numeric($value) || !is_numeric($decimals)) {
- return Functions::VALUE();
- }
- $decimals = floor($decimals);
-
- $mask = '$#,##0';
- if ($decimals > 0) {
- $mask .= '.' . str_repeat('0', $decimals);
- } else {
- $round = 10 ** abs($decimals);
- if ($value < 0) {
- $round = 0 - $round;
- }
- $value = MathTrig::MROUND($value, $round);
- }
- $mask = "$mask;($mask)";
-
- return NumberFormat::toFormattedString($value, $mask);
+ return TextData\Format::DOLLAR($value, $decimals);
}
/**
* SEARCHSENSITIVE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the sensitive() method in the TextData\Search class instead
+ *
* @param string $needle The string to look for
* @param string $haystack The string in which to look
* @param int $offset Offset within $haystack
@@ -190,33 +124,16 @@ class TextData
*/
public static function SEARCHSENSITIVE($needle, $haystack, $offset = 1)
{
- $needle = Functions::flattenSingleValue($needle);
- $haystack = Functions::flattenSingleValue($haystack);
- $offset = Functions::flattenSingleValue($offset);
-
- if (!is_bool($needle)) {
- if (is_bool($haystack)) {
- $haystack = ($haystack) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) {
- if (StringHelper::countCharacters($needle) === 0) {
- return $offset;
- }
-
- $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8');
- if ($pos !== false) {
- return ++$pos;
- }
- }
- }
-
- return Functions::VALUE();
+ return TextData\Search::sensitive($needle, $haystack, $offset);
}
/**
* SEARCHINSENSITIVE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the insensitive() method in the TextData\Search class instead
+ *
* @param string $needle The string to look for
* @param string $haystack The string in which to look
* @param int $offset Offset within $haystack
@@ -225,33 +142,16 @@ class TextData
*/
public static function SEARCHINSENSITIVE($needle, $haystack, $offset = 1)
{
- $needle = Functions::flattenSingleValue($needle);
- $haystack = Functions::flattenSingleValue($haystack);
- $offset = Functions::flattenSingleValue($offset);
-
- if (!is_bool($needle)) {
- if (is_bool($haystack)) {
- $haystack = ($haystack) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) {
- if (StringHelper::countCharacters($needle) === 0) {
- return $offset;
- }
-
- $pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8');
- if ($pos !== false) {
- return ++$pos;
- }
- }
- }
-
- return Functions::VALUE();
+ return TextData\Search::insensitive($needle, $haystack, $offset);
}
/**
* FIXEDFORMAT.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the FIXEDFORMAT() method in the TextData\Format class instead
+ *
* @param mixed $value Value to check
* @param int $decimals
* @param bool $no_commas
@@ -260,35 +160,16 @@ class TextData
*/
public static function FIXEDFORMAT($value, $decimals = 2, $no_commas = false)
{
- $value = Functions::flattenSingleValue($value);
- $decimals = Functions::flattenSingleValue($decimals);
- $no_commas = Functions::flattenSingleValue($no_commas);
-
- // Validate parameters
- if (!is_numeric($value) || !is_numeric($decimals)) {
- return Functions::VALUE();
- }
- $decimals = (int) floor($decimals);
-
- $valueResult = round($value, $decimals);
- if ($decimals < 0) {
- $decimals = 0;
- }
- if (!$no_commas) {
- $valueResult = number_format(
- $valueResult,
- $decimals,
- StringHelper::getDecimalSeparator(),
- StringHelper::getThousandsSeparator()
- );
- }
-
- return (string) $valueResult;
+ return TextData\Format::FIXEDFORMAT($value, $decimals, $no_commas);
}
/**
* LEFT.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the left() method in the TextData\Extract class instead
+ *
* @param string $value Value
* @param int $chars Number of characters
*
@@ -296,23 +177,16 @@ class TextData
*/
public static function LEFT($value = '', $chars = 1)
{
- $value = Functions::flattenSingleValue($value);
- $chars = Functions::flattenSingleValue($chars);
-
- if ($chars < 0) {
- return Functions::VALUE();
- }
-
- if (is_bool($value)) {
- $value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- return mb_substr($value, 0, $chars, 'UTF-8');
+ return TextData\Extract::left($value, $chars);
}
/**
* MID.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the mid() method in the TextData\Extract class instead
+ *
* @param string $value Value
* @param int $start Start character
* @param int $chars Number of characters
@@ -321,28 +195,16 @@ class TextData
*/
public static function MID($value = '', $start = 1, $chars = null)
{
- $value = Functions::flattenSingleValue($value);
- $start = Functions::flattenSingleValue($start);
- $chars = Functions::flattenSingleValue($chars);
-
- if (($start < 1) || ($chars < 0)) {
- return Functions::VALUE();
- }
-
- if (is_bool($value)) {
- $value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- if (empty($chars)) {
- return '';
- }
-
- return mb_substr($value, --$start, $chars, 'UTF-8');
+ return TextData\Extract::mid($value, $start, $chars);
}
/**
* RIGHT.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the right() method in the TextData\Extract class instead
+ *
* @param string $value Value
* @param int $chars Number of characters
*
@@ -350,36 +212,23 @@ class TextData
*/
public static function RIGHT($value = '', $chars = 1)
{
- $value = Functions::flattenSingleValue($value);
- $chars = Functions::flattenSingleValue($chars);
-
- if ($chars < 0) {
- return Functions::VALUE();
- }
-
- if (is_bool($value)) {
- $value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- return mb_substr($value, mb_strlen($value, 'UTF-8') - $chars, $chars, 'UTF-8');
+ return TextData\Extract::right($value, $chars);
}
/**
* STRINGLENGTH.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the length() method in the TextData\Text class instead
+ *
* @param string $value Value
*
* @return int
*/
public static function STRINGLENGTH($value = '')
{
- $value = Functions::flattenSingleValue($value);
-
- if (is_bool($value)) {
- $value = ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- return mb_strlen($value, 'UTF-8');
+ return TextData\Text::length($value);
}
/**
@@ -387,19 +236,17 @@ class TextData
*
* Converts a string value to upper case.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the lower() method in the TextData\CaseConvert class instead
+ *
* @param string $mixedCaseString
*
* @return string
*/
public static function LOWERCASE($mixedCaseString)
{
- $mixedCaseString = Functions::flattenSingleValue($mixedCaseString);
-
- if (is_bool($mixedCaseString)) {
- $mixedCaseString = ($mixedCaseString) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- return StringHelper::strToLower($mixedCaseString);
+ return TextData\CaseConvert::lower($mixedCaseString);
}
/**
@@ -407,19 +254,17 @@ class TextData
*
* Converts a string value to upper case.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the upper() method in the TextData\CaseConvert class instead
+ *
* @param string $mixedCaseString
*
* @return string
*/
public static function UPPERCASE($mixedCaseString)
{
- $mixedCaseString = Functions::flattenSingleValue($mixedCaseString);
-
- if (is_bool($mixedCaseString)) {
- $mixedCaseString = ($mixedCaseString) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- return StringHelper::strToUpper($mixedCaseString);
+ return TextData\CaseConvert::upper($mixedCaseString);
}
/**
@@ -427,24 +272,26 @@ class TextData
*
* Converts a string value to upper case.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the proper() method in the TextData\CaseConvert class instead
+ *
* @param string $mixedCaseString
*
* @return string
*/
public static function PROPERCASE($mixedCaseString)
{
- $mixedCaseString = Functions::flattenSingleValue($mixedCaseString);
-
- if (is_bool($mixedCaseString)) {
- $mixedCaseString = ($mixedCaseString) ? Calculation::getTRUE() : Calculation::getFALSE();
- }
-
- return StringHelper::strToTitle($mixedCaseString);
+ return TextData\CaseConvert::proper($mixedCaseString);
}
/**
* REPLACE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the replace() method in the TextData\Replace class instead
+ *
* @param string $oldText String to modify
* @param int $start Start character
* @param int $chars Number of characters
@@ -454,20 +301,16 @@ class TextData
*/
public static function REPLACE($oldText, $start, $chars, $newText)
{
- $oldText = Functions::flattenSingleValue($oldText);
- $start = Functions::flattenSingleValue($start);
- $chars = Functions::flattenSingleValue($chars);
- $newText = Functions::flattenSingleValue($newText);
-
- $left = self::LEFT($oldText, $start - 1);
- $right = self::RIGHT($oldText, self::STRINGLENGTH($oldText) - ($start + $chars) + 1);
-
- return $left . $newText . $right;
+ return TextData\Replace::replace($oldText, $start, $chars, $newText);
}
/**
* SUBSTITUTE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the substitute() method in the TextData\Replace class instead
+ *
* @param string $text Value
* @param string $fromText From Value
* @param string $toText To Value
@@ -477,52 +320,32 @@ class TextData
*/
public static function SUBSTITUTE($text = '', $fromText = '', $toText = '', $instance = 0)
{
- $text = Functions::flattenSingleValue($text);
- $fromText = Functions::flattenSingleValue($fromText);
- $toText = Functions::flattenSingleValue($toText);
- $instance = floor(Functions::flattenSingleValue($instance));
-
- if ($instance == 0) {
- return str_replace($fromText, $toText, $text);
- }
-
- $pos = -1;
- while ($instance > 0) {
- $pos = mb_strpos($text, $fromText, $pos + 1, 'UTF-8');
- if ($pos === false) {
- break;
- }
- --$instance;
- }
-
- if ($pos !== false) {
- return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText);
- }
-
- return $text;
+ return TextData\Replace::substitute($text, $fromText, $toText, $instance);
}
/**
* RETURNSTRING.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the test() method in the TextData\Text class instead
+ *
* @param mixed $testValue Value to check
*
* @return null|string
*/
public static function RETURNSTRING($testValue = '')
{
- $testValue = Functions::flattenSingleValue($testValue);
-
- if (is_string($testValue)) {
- return $testValue;
- }
-
- return null;
+ return TextData\Text::test($testValue);
}
/**
* TEXTFORMAT.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the TEXTFORMAT() method in the TextData\Format class instead
+ *
* @param mixed $value Value to check
* @param string $format Format mask to use
*
@@ -530,65 +353,32 @@ class TextData
*/
public static function TEXTFORMAT($value, $format)
{
- $value = Functions::flattenSingleValue($value);
- $format = Functions::flattenSingleValue($format);
-
- if ((is_string($value)) && (!is_numeric($value)) && Date::isDateTimeFormatCode($format)) {
- $value = DateTime::DATEVALUE($value);
- }
-
- return (string) NumberFormat::toFormattedString($value, $format);
+ return TextData\Format::TEXTFORMAT($value, $format);
}
/**
* VALUE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the VALUE() method in the TextData\Format class instead
+ *
* @param mixed $value Value to check
*
* @return DateTimeInterface|float|int|string A string if arguments are invalid
*/
public static function VALUE($value = '')
{
- $value = Functions::flattenSingleValue($value);
-
- if (!is_numeric($value)) {
- $numberValue = str_replace(
- StringHelper::getThousandsSeparator(),
- '',
- trim($value, " \t\n\r\0\x0B" . StringHelper::getCurrencyCode())
- );
- if (is_numeric($numberValue)) {
- return (float) $numberValue;
- }
-
- $dateSetting = Functions::getReturnDateType();
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
-
- if (strpos($value, ':') !== false) {
- $timeValue = DateTime::TIMEVALUE($value);
- if ($timeValue !== Functions::VALUE()) {
- Functions::setReturnDateType($dateSetting);
-
- return $timeValue;
- }
- }
- $dateValue = DateTime::DATEVALUE($value);
- if ($dateValue !== Functions::VALUE()) {
- Functions::setReturnDateType($dateSetting);
-
- return $dateValue;
- }
- Functions::setReturnDateType($dateSetting);
-
- return Functions::VALUE();
- }
-
- return (float) $value;
+ return TextData\Format::VALUE($value);
}
/**
* NUMBERVALUE.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the NUMBERVALUE() method in the TextData\Format class instead
+ *
* @param mixed $value Value to check
* @param string $decimalSeparator decimal separator, defaults to locale defined value
* @param string $groupSeparator group/thosands separator, defaults to locale defined value
@@ -597,39 +387,7 @@ class TextData
*/
public static function NUMBERVALUE($value = '', $decimalSeparator = null, $groupSeparator = null)
{
- $value = Functions::flattenSingleValue($value);
- $decimalSeparator = Functions::flattenSingleValue($decimalSeparator);
- $groupSeparator = Functions::flattenSingleValue($groupSeparator);
-
- if (!is_numeric($value)) {
- $decimalSeparator = empty($decimalSeparator) ? StringHelper::getDecimalSeparator() : $decimalSeparator;
- $groupSeparator = empty($groupSeparator) ? StringHelper::getThousandsSeparator() : $groupSeparator;
-
- $decimalPositions = preg_match_all('/' . preg_quote($decimalSeparator) . '/', $value, $matches, PREG_OFFSET_CAPTURE);
- if ($decimalPositions > 1) {
- return Functions::VALUE();
- }
- $decimalOffset = array_pop($matches[0])[1];
- if (strpos($value, $groupSeparator, $decimalOffset) !== false) {
- return Functions::VALUE();
- }
-
- $value = str_replace([$groupSeparator, $decimalSeparator], ['', '.'], $value);
-
- // Handle the special case of trailing % signs
- $percentageString = rtrim($value, '%');
- if (!is_numeric($percentageString)) {
- return Functions::VALUE();
- }
-
- $percentageAdjustment = strlen($value) - strlen($percentageString);
- if ($percentageAdjustment) {
- $value = (float) $percentageString;
- $value /= 10 ** ($percentageAdjustment * 2);
- }
- }
-
- return (float) $value;
+ return TextData\Format::NUMBERVALUE($value, $decimalSeparator, $groupSeparator);
}
/**
@@ -637,22 +395,27 @@ class TextData
* EXACT is case-sensitive but ignores formatting differences.
* Use EXACT to test text being entered into a document.
*
- * @param $value1
- * @param $value2
+ * @Deprecated 1.18.0
+ *
+ * @see Use the exact() method in the TextData\Text class instead
+ *
+ * @param mixed $value1
+ * @param mixed $value2
*
* @return bool
*/
public static function EXACT($value1, $value2)
{
- $value1 = Functions::flattenSingleValue($value1);
- $value2 = Functions::flattenSingleValue($value2);
-
- return (string) $value2 === (string) $value1;
+ return TextData\Text::exact($value1, $value2);
}
/**
* TEXTJOIN.
*
+ * @Deprecated 1.18.0
+ *
+ * @see Use the TEXTJOIN() method in the TextData\Concatenate class instead
+ *
* @param mixed $delimiter
* @param mixed $ignoreEmpty
* @param mixed $args
@@ -661,16 +424,25 @@ class TextData
*/
public static function TEXTJOIN($delimiter, $ignoreEmpty, ...$args)
{
- // Loop through arguments
- $aArgs = Functions::flattenArray($args);
- foreach ($aArgs as $key => &$arg) {
- if ($ignoreEmpty && trim($arg) == '') {
- unset($aArgs[$key]);
- } elseif (is_bool($arg)) {
- $arg = self::convertBooleanValue($arg);
- }
- }
+ return TextData\Concatenate::TEXTJOIN($delimiter, $ignoreEmpty, ...$args);
+ }
- return implode($delimiter, $aArgs);
+ /**
+ * REPT.
+ *
+ * Returns the result of builtin function repeat after validating args.
+ *
+ * @Deprecated 1.18.0
+ *
+ * @see Use the builtinREPT() method in the TextData\Concatenate class instead
+ *
+ * @param string $str Should be numeric
+ * @param mixed $number Should be int
+ *
+ * @return string
+ */
+ public static function builtinREPT($str, $number)
+ {
+ return TextData\Concatenate::builtinREPT($str, $number);
}
}
diff --git a/src/PhpSpreadsheet/Calculation/TextData/CaseConvert.php b/src/PhpSpreadsheet/Calculation/TextData/CaseConvert.php
new file mode 100644
index 00000000..36b5efbd
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/TextData/CaseConvert.php
@@ -0,0 +1,64 @@
+ 255) {
+ return Functions::VALUE();
+ }
+
+ return iconv('UCS-4LE', 'UTF-8', pack('V', $character));
+ }
+
+ /**
+ * ASCIICODE.
+ *
+ * @param mixed $characters String character to convert to its ASCII value
+ *
+ * @return int|string A string if arguments are invalid
+ */
+ public static function code($characters)
+ {
+ if (($characters === null) || ($characters === '')) {
+ return Functions::VALUE();
+ }
+ $characters = Functions::flattenSingleValue($characters);
+ if (is_bool($characters)) {
+ $characters = self::convertBooleanValue($characters);
+ }
+
+ $character = $characters;
+ if (mb_strlen($characters, 'UTF-8') > 1) {
+ $character = mb_substr($characters, 0, 1, 'UTF-8');
+ }
+
+ return self::unicodeToOrd($character);
+ }
+
+ private static function unicodeToOrd($character)
+ {
+ return unpack('V', iconv('UTF-8', 'UCS-4LE', $character))[1];
+ }
+
+ private static function convertBooleanValue($value)
+ {
+ if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) {
+ return (int) $value;
+ }
+
+ return ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php b/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php
new file mode 100644
index 00000000..5780bb6e
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/TextData/Concatenate.php
@@ -0,0 +1,82 @@
+ &$arg) {
+ if ($ignoreEmpty === true && is_string($arg) && trim($arg) === '') {
+ unset($aArgs[$key]);
+ } elseif (is_bool($arg)) {
+ $arg = self::convertBooleanValue($arg);
+ }
+ }
+
+ return implode($delimiter, $aArgs);
+ }
+
+ /**
+ * REPT.
+ *
+ * Returns the result of builtin function round after validating args.
+ *
+ * @param mixed $stringValue The value to repeat
+ * @param mixed $repeatCount The number of times the string value should be repeated
+ */
+ public static function builtinREPT($stringValue, $repeatCount): string
+ {
+ $repeatCount = Functions::flattenSingleValue($repeatCount);
+
+ if (!is_numeric($repeatCount) || $repeatCount < 0) {
+ return Functions::VALUE();
+ }
+
+ if (is_bool($stringValue)) {
+ $stringValue = self::convertBooleanValue($stringValue);
+ }
+
+ return str_repeat($stringValue, (int) $repeatCount);
+ }
+
+ private static function convertBooleanValue($value)
+ {
+ if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) {
+ return (int) $value;
+ }
+
+ return ($value) ? Calculation::getTRUE() : Calculation::getFALSE();
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/TextData/Extract.php b/src/PhpSpreadsheet/Calculation/TextData/Extract.php
new file mode 100644
index 00000000..2f994858
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/TextData/Extract.php
@@ -0,0 +1,77 @@
+ 0) {
+ $mask .= '.' . str_repeat('0', $decimals);
+ } else {
+ $round = 10 ** abs($decimals);
+ if ($value < 0) {
+ $round = 0 - $round;
+ }
+ $value = MathTrig\Mround::funcMround($value, $round);
+ }
+ $mask = "$mask;($mask)";
+
+ return NumberFormat::toFormattedString($value, $mask);
+ }
+
+ /**
+ * FIXEDFORMAT.
+ *
+ * @param mixed $value The value to format
+ * @param mixed $decimals Integer value for the number of decimal places that should be formatted
+ * @param mixed $noCommas Boolean value indicating whether the value should have thousands separators or not
+ */
+ public static function FIXEDFORMAT($value, $decimals = 2, $noCommas = false): string
+ {
+ $value = Functions::flattenSingleValue($value);
+ $decimals = $decimals === null ? 2 : Functions::flattenSingleValue($decimals);
+ $noCommas = Functions::flattenSingleValue($noCommas);
+
+ // Validate parameters
+ if (!is_numeric($value) || !is_numeric($decimals)) {
+ return Functions::VALUE();
+ }
+ $decimals = (int) floor($decimals);
+
+ $valueResult = round($value, $decimals);
+ if ($decimals < 0) {
+ $decimals = 0;
+ }
+ if ($noCommas === false) {
+ $valueResult = number_format(
+ $valueResult,
+ $decimals,
+ StringHelper::getDecimalSeparator(),
+ StringHelper::getThousandsSeparator()
+ );
+ }
+
+ return (string) $valueResult;
+ }
+
+ /**
+ * TEXTFORMAT.
+ *
+ * @param mixed $value The value to format
+ * @param mixed $format A string with the Format mask that should be used
+ */
+ public static function TEXTFORMAT($value, $format): string
+ {
+ $value = Functions::flattenSingleValue($value);
+ $format = Functions::flattenSingleValue($format);
+
+ if ((is_string($value)) && (!is_numeric($value)) && Date::isDateTimeFormatCode($format)) {
+ $value = DateTimeExcel\DateValue::funcDateValue($value);
+ }
+
+ return (string) NumberFormat::toFormattedString($value, $format);
+ }
+
+ /**
+ * VALUE.
+ *
+ * @param mixed $value Value to check
+ *
+ * @return DateTimeInterface|float|int|string A string if arguments are invalid
+ */
+ public static function VALUE($value = '')
+ {
+ $value = Functions::flattenSingleValue($value);
+
+ if (!is_numeric($value)) {
+ $numberValue = str_replace(
+ StringHelper::getThousandsSeparator(),
+ '',
+ trim($value, " \t\n\r\0\x0B" . StringHelper::getCurrencyCode())
+ );
+ if (is_numeric($numberValue)) {
+ return (float) $numberValue;
+ }
+
+ $dateSetting = Functions::getReturnDateType();
+ Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
+
+ if (strpos($value, ':') !== false) {
+ $timeValue = DateTimeExcel\TimeValue::funcTimeValue($value);
+ if ($timeValue !== Functions::VALUE()) {
+ Functions::setReturnDateType($dateSetting);
+
+ return $timeValue;
+ }
+ }
+ $dateValue = DateTimeExcel\DateValue::funcDateValue($value);
+ if ($dateValue !== Functions::VALUE()) {
+ Functions::setReturnDateType($dateSetting);
+
+ return $dateValue;
+ }
+ Functions::setReturnDateType($dateSetting);
+
+ return Functions::VALUE();
+ }
+
+ return (float) $value;
+ }
+
+ /**
+ * NUMBERVALUE.
+ *
+ * @param mixed $value The value to format
+ * @param mixed $decimalSeparator A string with the decimal separator to use, defaults to locale defined value
+ * @param mixed $groupSeparator A string with the group/thousands separator to use, defaults to locale defined value
+ *
+ * @return float|string
+ */
+ public static function NUMBERVALUE($value = '', $decimalSeparator = null, $groupSeparator = null)
+ {
+ $value = Functions::flattenSingleValue($value);
+ $decimalSeparator = Functions::flattenSingleValue($decimalSeparator);
+ $groupSeparator = Functions::flattenSingleValue($groupSeparator);
+
+ if (!is_numeric($value)) {
+ $decimalSeparator = empty($decimalSeparator) ? StringHelper::getDecimalSeparator() : $decimalSeparator;
+ $groupSeparator = empty($groupSeparator) ? StringHelper::getThousandsSeparator() : $groupSeparator;
+
+ $decimalPositions = preg_match_all('/' . preg_quote($decimalSeparator) . '/', $value, $matches, PREG_OFFSET_CAPTURE);
+ if ($decimalPositions > 1) {
+ return Functions::VALUE();
+ }
+ $decimalOffset = array_pop($matches[0])[1];
+ if (strpos($value, $groupSeparator, $decimalOffset) !== false) {
+ return Functions::VALUE();
+ }
+
+ $value = str_replace([$groupSeparator, $decimalSeparator], ['', '.'], $value);
+
+ // Handle the special case of trailing % signs
+ $percentageString = rtrim($value, '%');
+ if (!is_numeric($percentageString)) {
+ return Functions::VALUE();
+ }
+
+ $percentageAdjustment = strlen($value) - strlen($percentageString);
+ if ($percentageAdjustment) {
+ $value = (float) $percentageString;
+ $value /= 10 ** ($percentageAdjustment * 2);
+ }
+ }
+
+ return (float) $value;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/TextData/Replace.php b/src/PhpSpreadsheet/Calculation/TextData/Replace.php
new file mode 100644
index 00000000..7ca710ef
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/TextData/Replace.php
@@ -0,0 +1,64 @@
+ 0) {
+ $pos = mb_strpos($text, $fromText, $pos + 1, 'UTF-8');
+ if ($pos === false) {
+ break;
+ }
+ --$instance;
+ }
+
+ if ($pos !== false) {
+ return self::REPLACE($text, ++$pos, mb_strlen($fromText, 'UTF-8'), $toText);
+ }
+
+ return $text;
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/TextData/Search.php b/src/PhpSpreadsheet/Calculation/TextData/Search.php
new file mode 100644
index 00000000..2da688d8
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/TextData/Search.php
@@ -0,0 +1,80 @@
+ 0) && (StringHelper::countCharacters($haystack) > $offset)) {
+ if (StringHelper::countCharacters($needle) === 0) {
+ return $offset;
+ }
+
+ $pos = mb_strpos($haystack, $needle, --$offset, 'UTF-8');
+ if ($pos !== false) {
+ return ++$pos;
+ }
+ }
+ }
+
+ return Functions::VALUE();
+ }
+
+ /**
+ * SEARCHINSENSITIVE.
+ *
+ * @param mixed $needle The string to look for
+ * @param mixed $haystack The string in which to look
+ * @param mixed $offset Integer offset within $haystack to start searching from
+ *
+ * @return int|string
+ */
+ public static function insensitive($needle, $haystack, $offset = 1)
+ {
+ $needle = Functions::flattenSingleValue($needle);
+ $haystack = Functions::flattenSingleValue($haystack);
+ $offset = Functions::flattenSingleValue($offset);
+
+ if (!is_bool($needle)) {
+ if (is_bool($haystack)) {
+ $haystack = ($haystack) ? Calculation::getTRUE() : Calculation::getFALSE();
+ }
+
+ if (($offset > 0) && (StringHelper::countCharacters($haystack) > $offset)) {
+ if (StringHelper::countCharacters($needle) === 0) {
+ return $offset;
+ }
+
+ $pos = mb_stripos($haystack, $needle, --$offset, 'UTF-8');
+ if ($pos !== false) {
+ return ++$pos;
+ }
+ }
+ }
+
+ return Functions::VALUE();
+ }
+}
diff --git a/src/PhpSpreadsheet/Calculation/TextData/Text.php b/src/PhpSpreadsheet/Calculation/TextData/Text.php
new file mode 100644
index 00000000..6e408891
--- /dev/null
+++ b/src/PhpSpreadsheet/Calculation/TextData/Text.php
@@ -0,0 +1,59 @@
+setValueExplicit((float) $value, DataType::TYPE_NUMERIC);
-
- return true;
- }
-
- // Check for fraction
+ // Check for fractions
if (preg_match('/^([+-]?)\s*(\d+)\s?\/\s*(\d+)$/', $value, $matches)) {
- // Convert value to number
- $value = $matches[2] / $matches[3];
- if ($matches[1] == '-') {
- $value = 0 - $value;
- }
- $cell->setValueExplicit((float) $value, DataType::TYPE_NUMERIC);
- // Set style
- $cell->getWorksheet()->getStyle($cell->getCoordinate())
- ->getNumberFormat()->setFormatCode('??/??');
-
- return true;
+ return $this->setProperFraction($matches, $cell);
} elseif (preg_match('/^([+-]?)(\d*) +(\d*)\s?\/\s*(\d*)$/', $value, $matches)) {
- // Convert value to number
- $value = $matches[2] + ($matches[3] / $matches[4]);
- if ($matches[1] == '-') {
- $value = 0 - $value;
- }
- $cell->setValueExplicit((float) $value, DataType::TYPE_NUMERIC);
- // Set style
- $cell->getWorksheet()->getStyle($cell->getCoordinate())
- ->getNumberFormat()->setFormatCode('# ??/??');
-
- return true;
+ return $this->setImproperFraction($matches, $cell);
}
// Check for percentage
if (preg_match('/^\-?\d*\.?\d*\s?\%$/', $value)) {
- // Convert value to number
- $value = (float) str_replace('%', '', $value) / 100;
- $cell->setValueExplicit($value, DataType::TYPE_NUMERIC);
- // Set style
- $cell->getWorksheet()->getStyle($cell->getCoordinate())
- ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_PERCENTAGE_00);
-
- return true;
+ return $this->setPercentage($value, $cell);
}
// Check for currency
@@ -115,29 +83,12 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder
// Check for time without seconds e.g. '9:45', '09:45'
if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d$/', $value)) {
- // Convert value to number
- [$h, $m] = explode(':', $value);
- $days = $h / 24 + $m / 1440;
- $cell->setValueExplicit($days, DataType::TYPE_NUMERIC);
- // Set style
- $cell->getWorksheet()->getStyle($cell->getCoordinate())
- ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_TIME3);
-
- return true;
+ return $this->setTimeHoursMinutes($value, $cell);
}
// Check for time with seconds '9:45:59', '09:45:59'
if (preg_match('/^(\d|[0-1]\d|2[0-3]):[0-5]\d:[0-5]\d$/', $value)) {
- // Convert value to number
- [$h, $m, $s] = explode(':', $value);
- $days = $h / 24 + $m / 1440 + $s / 86400;
- // Convert value to number
- $cell->setValueExplicit($days, DataType::TYPE_NUMERIC);
- // Set style
- $cell->getWorksheet()->getStyle($cell->getCoordinate())
- ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_TIME4);
-
- return true;
+ return $this->setTimeHoursMinutesSeconds($value, $cell);
}
// Check for datetime, e.g. '2008-12-31', '2008-12-31 15:59', '2008-12-31 15:59:10'
@@ -158,7 +109,6 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder
// Check for newline character "\n"
if (strpos($value, "\n") !== false) {
- $value = StringHelper::sanitizeUTF8($value);
$cell->setValueExplicit($value, DataType::TYPE_STRING);
// Set style
$cell->getWorksheet()->getStyle($cell->getCoordinate())
@@ -171,4 +121,85 @@ class AdvancedValueBinder extends DefaultValueBinder implements IValueBinder
// Not bound yet? Use parent...
return parent::bindValue($cell, $value);
}
+
+ protected function setImproperFraction(array $matches, Cell $cell): bool
+ {
+ // Convert value to number
+ $value = $matches[2] + ($matches[3] / $matches[4]);
+ if ($matches[1] === '-') {
+ $value = 0 - $value;
+ }
+ $cell->setValueExplicit((float) $value, DataType::TYPE_NUMERIC);
+
+ // Build the number format mask based on the size of the matched values
+ $dividend = str_repeat('?', strlen($matches[3]));
+ $divisor = str_repeat('?', strlen($matches[4]));
+ $fractionMask = "# {$dividend}/{$divisor}";
+ // Set style
+ $cell->getWorksheet()->getStyle($cell->getCoordinate())
+ ->getNumberFormat()->setFormatCode($fractionMask);
+
+ return true;
+ }
+
+ protected function setProperFraction(array $matches, Cell $cell): bool
+ {
+ // Convert value to number
+ $value = $matches[2] / $matches[3];
+ if ($matches[1] === '-') {
+ $value = 0 - $value;
+ }
+ $cell->setValueExplicit((float) $value, DataType::TYPE_NUMERIC);
+
+ // Build the number format mask based on the size of the matched values
+ $dividend = str_repeat('?', strlen($matches[2]));
+ $divisor = str_repeat('?', strlen($matches[3]));
+ $fractionMask = "{$dividend}/{$divisor}";
+ // Set style
+ $cell->getWorksheet()->getStyle($cell->getCoordinate())
+ ->getNumberFormat()->setFormatCode($fractionMask);
+
+ return true;
+ }
+
+ protected function setPercentage(string $value, Cell $cell): bool
+ {
+ // Convert value to number
+ $value = ((float) str_replace('%', '', $value)) / 100;
+ $cell->setValueExplicit($value, DataType::TYPE_NUMERIC);
+
+ // Set style
+ $cell->getWorksheet()->getStyle($cell->getCoordinate())
+ ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_PERCENTAGE_00);
+
+ return true;
+ }
+
+ protected function setTimeHoursMinutes(string $value, Cell $cell): bool
+ {
+ // Convert value to number
+ [$hours, $minutes] = explode(':', $value);
+ $days = ($hours / 24) + ($minutes / 1440);
+ $cell->setValueExplicit($days, DataType::TYPE_NUMERIC);
+
+ // Set style
+ $cell->getWorksheet()->getStyle($cell->getCoordinate())
+ ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_TIME3);
+
+ return true;
+ }
+
+ protected function setTimeHoursMinutesSeconds(string $value, Cell $cell): bool
+ {
+ // Convert value to number
+ [$hours, $minutes, $seconds] = explode(':', $value);
+ $days = ($hours / 24) + ($minutes / 1440) + ($seconds / 86400);
+ $cell->setValueExplicit($days, DataType::TYPE_NUMERIC);
+
+ // Set style
+ $cell->getWorksheet()->getStyle($cell->getCoordinate())
+ ->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_DATE_TIME4);
+
+ return true;
+ }
}
diff --git a/src/PhpSpreadsheet/Cell/Cell.php b/src/PhpSpreadsheet/Cell/Cell.php
index 5dee411b..89aa32cd 100644
--- a/src/PhpSpreadsheet/Cell/Cell.php
+++ b/src/PhpSpreadsheet/Cell/Cell.php
@@ -78,6 +78,7 @@ class Cell
public function detach(): void
{
+ // @phpstan-ignore-next-line
$this->parent = null;
}
@@ -201,7 +202,7 @@ class Cell
break;
case DataType::TYPE_STRING2:
$pDataType = DataType::TYPE_STRING;
- // no break
+ // no break
case DataType::TYPE_STRING:
// Synonym for string
case DataType::TYPE_INLINE:
@@ -252,9 +253,11 @@ class Cell
if ($this->dataType == DataType::TYPE_FORMULA) {
try {
$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)) {
@@ -561,7 +564,7 @@ class Cell
// Verify if cell is in range
return ($rangeStart[0] <= $myColumn) && ($rangeEnd[0] >= $myColumn) &&
- ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow);
+ ($rangeStart[1] <= $myRow) && ($rangeEnd[1] >= $myRow);
}
/**
diff --git a/src/PhpSpreadsheet/Cell/Coordinate.php b/src/PhpSpreadsheet/Cell/Coordinate.php
index 2afeebe9..0b3917f2 100644
--- a/src/PhpSpreadsheet/Cell/Coordinate.php
+++ b/src/PhpSpreadsheet/Cell/Coordinate.php
@@ -25,7 +25,7 @@ abstract class Coordinate
*
* @param string $pCoordinateString eg: 'A1'
*
- * @return string[] Array containing column and row (indexes 0 and 1)
+ * @return array{0: string, 1: string} Array containing column and row (indexes 0 and 1)
*/
public static function coordinateFromString($pCoordinateString)
{
@@ -40,6 +40,23 @@ abstract class Coordinate
throw new Exception('Invalid cell coordinate ' . $pCoordinateString);
}
+ /**
+ * Get indexes from a string coordinates.
+ *
+ * @param string $coordinates eg: 'A1', '$B$12'
+ *
+ * @return array{0: int, 1: int} Array containing column index and row index (indexes 0 and 1)
+ */
+ public static function indexesFromString(string $coordinates): array
+ {
+ [$col, $row] = self::coordinateFromString($coordinates);
+
+ return [
+ self::columnIndexFromString(ltrim($col, '$')),
+ (int) ltrim($row, '$'),
+ ];
+ }
+
/**
* Checks if a coordinate represents a range of cells.
*
@@ -339,7 +356,8 @@ abstract class Coordinate
private static function processRangeSetOperators(array $operators, array $cells): array
{
- for ($offset = 0; $offset < count($operators); ++$offset) {
+ $operatorCount = count($operators);
+ for ($offset = 0; $offset < $operatorCount; ++$offset) {
$operator = $operators[$offset];
if ($operator !== ' ') {
continue;
@@ -350,6 +368,7 @@ abstract class Coordinate
$operators = array_values($operators);
$cells = array_values($cells);
--$offset;
+ --$operatorCount;
}
return $cells;
diff --git a/src/PhpSpreadsheet/Cell/DefaultValueBinder.php b/src/PhpSpreadsheet/Cell/DefaultValueBinder.php
index 693446e6..6fae5e76 100644
--- a/src/PhpSpreadsheet/Cell/DefaultValueBinder.php
+++ b/src/PhpSpreadsheet/Cell/DefaultValueBinder.php
@@ -40,39 +40,39 @@ class DefaultValueBinder implements IValueBinder
/**
* DataType for value.
*
- * @param mixed $pValue
+ * @param mixed $value
*
* @return string
*/
- public static function dataTypeForValue($pValue)
+ public static function dataTypeForValue($value)
{
// Match the value against a few data types
- if ($pValue === null) {
+ if ($value === null) {
return DataType::TYPE_NULL;
- } elseif (is_float($pValue) || is_int($pValue)) {
+ } elseif (is_float($value) || is_int($value)) {
return DataType::TYPE_NUMERIC;
- } elseif (is_bool($pValue)) {
+ } elseif (is_bool($value)) {
return DataType::TYPE_BOOL;
- } elseif ($pValue === '') {
+ } elseif ($value === '') {
return DataType::TYPE_STRING;
- } elseif ($pValue instanceof RichText) {
+ } elseif ($value instanceof RichText) {
return DataType::TYPE_INLINE;
- } elseif (is_string($pValue) && $pValue[0] === '=' && strlen($pValue) > 1) {
+ } elseif (is_string($value) && $value[0] === '=' && strlen($value) > 1) {
return DataType::TYPE_FORMULA;
- } elseif (preg_match('/^[\+\-]?(\d+\\.?\d*|\d*\\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $pValue)) {
- $tValue = ltrim($pValue, '+-');
- if (is_string($pValue) && $tValue[0] === '0' && strlen($tValue) > 1 && $tValue[1] !== '.') {
+ } elseif (preg_match('/^[\+\-]?(\d+\\.?\d*|\d*\\.?\d+)([Ee][\-\+]?[0-2]?\d{1,3})?$/', $value)) {
+ $tValue = ltrim($value, '+-');
+ if (is_string($value) && $tValue[0] === '0' && strlen($tValue) > 1 && $tValue[1] !== '.') {
return DataType::TYPE_STRING;
- } elseif ((strpos($pValue, '.') === false) && ($pValue > PHP_INT_MAX)) {
+ } elseif ((strpos($value, '.') === false) && ($value > PHP_INT_MAX)) {
return DataType::TYPE_STRING;
- } elseif (!is_numeric($pValue)) {
+ } elseif (!is_numeric($value)) {
return DataType::TYPE_STRING;
}
return DataType::TYPE_NUMERIC;
- } elseif (is_string($pValue)) {
+ } elseif (is_string($value)) {
$errorCodes = DataType::getErrorCodes();
- if (isset($errorCodes[$pValue])) {
+ if (isset($errorCodes[$value])) {
return DataType::TYPE_ERROR;
}
}
diff --git a/src/PhpSpreadsheet/Chart/Axis.php b/src/PhpSpreadsheet/Chart/Axis.php
index 7995c3b3..27e61060 100644
--- a/src/PhpSpreadsheet/Chart/Axis.php
+++ b/src/PhpSpreadsheet/Chart/Axis.php
@@ -13,7 +13,7 @@ class Axis extends Properties
/**
* Axis Number.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $axisNumber = [
'format' => self::FORMAT_CODE_GENERAL,
@@ -23,7 +23,7 @@ class Axis extends Properties
/**
* Axis Options.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $axisOptions = [
'minimum' => null,
@@ -41,7 +41,7 @@ class Axis extends Properties
/**
* Fill Properties.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $fillProperties = [
'type' => self::EXCEL_COLOR_TYPE_ARGB,
@@ -52,7 +52,7 @@ class Axis extends Properties
/**
* Line Properties.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $lineProperties = [
'type' => self::EXCEL_COLOR_TYPE_ARGB,
@@ -63,7 +63,7 @@ class Axis extends Properties
/**
* Line Style Properties.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $lineStyleProperties = [
'width' => '9525',
@@ -86,7 +86,7 @@ class Axis extends Properties
/**
* Shadow Properties.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $shadowProperties = [
'presets' => self::SHADOW_PRESETS_NOSHADOW,
@@ -111,7 +111,7 @@ class Axis extends Properties
/**
* Glow Properties.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $glowProperties = [
'size' => null,
@@ -125,7 +125,7 @@ class Axis extends Properties
/**
* Soft Edge Properties.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $softEdges = [
'size' => null,
@@ -135,10 +135,8 @@ class Axis extends Properties
* Get Series Data Type.
*
* @param mixed $format_code
- *
- * @return string
*/
- public function setAxisNumberProperties($format_code)
+ public function setAxisNumberProperties($format_code): void
{
$this->axisNumber['format'] = (string) $format_code;
$this->axisNumber['source_linked'] = 0;
@@ -340,9 +338,9 @@ class Axis extends Properties
{
$this->setShadowPresetsProperties((int) $sh_presets)
->setShadowColor(
- $sh_color_value === null ? $this->shadowProperties['color']['value'] : $sh_color_value,
- $sh_color_alpha === null ? (int) $this->shadowProperties['color']['alpha'] : $sh_color_alpha,
- $sh_color_type === null ? $this->shadowProperties['color']['type'] : $sh_color_type
+ $sh_color_value ?? $this->shadowProperties['color']['value'],
+ $sh_color_alpha ?? (int) $this->shadowProperties['color']['alpha'],
+ $sh_color_type ?? $this->shadowProperties['color']['type']
)
->setShadowBlur($sh_blur)
->setShadowAngle($sh_angle)
@@ -367,7 +365,7 @@ class Axis extends Properties
/**
* Set Shadow Properties from Mapped Values.
*
- * @param mixed &$reference
+ * @param mixed $reference
*
* @return $this
*/
@@ -482,9 +480,9 @@ class Axis extends Properties
{
$this->setGlowSize($size)
->setGlowColor(
- $color_value === null ? $this->glowProperties['color']['value'] : $color_value,
- $color_alpha === null ? (int) $this->glowProperties['color']['alpha'] : $color_alpha,
- $color_type === null ? $this->glowProperties['color']['type'] : $color_type
+ $color_value ?? $this->glowProperties['color']['value'],
+ $color_alpha ?? (int) $this->glowProperties['color']['alpha'],
+ $color_type ?? $this->glowProperties['color']['type']
);
}
diff --git a/src/PhpSpreadsheet/Chart/Chart.php b/src/PhpSpreadsheet/Chart/Chart.php
index 20eb2aee..4fdff6ff 100644
--- a/src/PhpSpreadsheet/Chart/Chart.php
+++ b/src/PhpSpreadsheet/Chart/Chart.php
@@ -424,7 +424,7 @@ class Chart
/**
* Get the top left position of the chart.
*
- * @return array an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
+ * @return array{cell: string, xOffset: int, yOffset: int} an associative array containing the cell address, X-Offset and Y-Offset from the top left of that cell
*/
public function getTopLeftPosition()
{
diff --git a/src/PhpSpreadsheet/Chart/DataSeries.php b/src/PhpSpreadsheet/Chart/DataSeries.php
index 3a44b335..067d30e5 100644
--- a/src/PhpSpreadsheet/Chart/DataSeries.php
+++ b/src/PhpSpreadsheet/Chart/DataSeries.php
@@ -75,21 +75,21 @@ class DataSeries
/**
* Order of plots in Series.
*
- * @var array of integer
+ * @var int[]
*/
private $plotOrder = [];
/**
* Plot Label.
*
- * @var array of DataSeriesValues
+ * @var DataSeriesValues[]
*/
private $plotLabel = [];
/**
* Plot Category.
*
- * @var array of DataSeriesValues
+ * @var DataSeriesValues[]
*/
private $plotCategory = [];
@@ -103,7 +103,7 @@ class DataSeries
/**
* Plot Values.
*
- * @var array of DataSeriesValues
+ * @var DataSeriesValues[]
*/
private $plotValues = [];
@@ -231,7 +231,7 @@ class DataSeries
/**
* Get Plot Labels.
*
- * @return array of DataSeriesValues
+ * @return DataSeriesValues[]
*/
public function getPlotLabels()
{
@@ -243,7 +243,7 @@ class DataSeries
*
* @param mixed $index
*
- * @return DataSeriesValues
+ * @return DataSeriesValues|false
*/
public function getPlotLabelByIndex($index)
{
@@ -260,7 +260,7 @@ class DataSeries
/**
* Get Plot Categories.
*
- * @return array of DataSeriesValues
+ * @return DataSeriesValues[]
*/
public function getPlotCategories()
{
@@ -272,7 +272,7 @@ class DataSeries
*
* @param mixed $index
*
- * @return DataSeriesValues
+ * @return DataSeriesValues|false
*/
public function getPlotCategoryByIndex($index)
{
@@ -313,7 +313,7 @@ class DataSeries
/**
* Get Plot Values.
*
- * @return array of DataSeriesValues
+ * @return DataSeriesValues[]
*/
public function getPlotValues()
{
@@ -325,7 +325,7 @@ class DataSeries
*
* @param mixed $index
*
- * @return DataSeriesValues
+ * @return DataSeriesValues|false
*/
public function getPlotValuesByIndex($index)
{
diff --git a/src/PhpSpreadsheet/Chart/DataSeriesValues.php b/src/PhpSpreadsheet/Chart/DataSeriesValues.php
index c1bd973a..88063336 100644
--- a/src/PhpSpreadsheet/Chart/DataSeriesValues.php
+++ b/src/PhpSpreadsheet/Chart/DataSeriesValues.php
@@ -55,7 +55,7 @@ class DataSeriesValues
/**
* Data Values.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $dataValues = [];
@@ -313,7 +313,7 @@ class DataSeriesValues
/**
* Get Series Data Values.
*
- * @return array of mixed
+ * @return mixed[]
*/
public function getDataValues()
{
diff --git a/src/PhpSpreadsheet/Chart/GridLines.php b/src/PhpSpreadsheet/Chart/GridLines.php
index 2e424bc2..c388f2c9 100644
--- a/src/PhpSpreadsheet/Chart/GridLines.php
+++ b/src/PhpSpreadsheet/Chart/GridLines.php
@@ -291,9 +291,9 @@ class GridLines extends Properties
$this->activateObject()
->setShadowPresetsProperties((int) $sh_presets)
->setShadowColor(
- $sh_color_value === null ? $this->shadowProperties['color']['value'] : $sh_color_value,
+ $sh_color_value ?? $this->shadowProperties['color']['value'],
$sh_color_alpha === null ? (int) $this->shadowProperties['color']['alpha'] : $this->getTrueAlpha($sh_color_alpha),
- $sh_color_type === null ? $this->shadowProperties['color']['type'] : $sh_color_type
+ $sh_color_type ?? $this->shadowProperties['color']['type']
)
->setShadowBlur($sh_blur)
->setShadowAngle($sh_angle)
@@ -318,7 +318,7 @@ class GridLines extends Properties
/**
* Set Shadow Properties Values.
*
- * @param mixed &$reference
+ * @param mixed $reference
*
* @return $this
*/
diff --git a/src/PhpSpreadsheet/Chart/Legend.php b/src/PhpSpreadsheet/Chart/Legend.php
index fc0ed140..2f003cd8 100644
--- a/src/PhpSpreadsheet/Chart/Legend.php
+++ b/src/PhpSpreadsheet/Chart/Legend.php
@@ -131,18 +131,10 @@ class Legend
* Set allow overlay of other elements?
*
* @param bool $overlay
- *
- * @return bool
*/
- public function setOverlay($overlay)
+ public function setOverlay($overlay): void
{
- if (!is_bool($overlay)) {
- return false;
- }
-
$this->overlay = $overlay;
-
- return true;
}
/**
diff --git a/src/PhpSpreadsheet/Chart/PlotArea.php b/src/PhpSpreadsheet/Chart/PlotArea.php
index 954777cf..ecb7b6c9 100644
--- a/src/PhpSpreadsheet/Chart/PlotArea.php
+++ b/src/PhpSpreadsheet/Chart/PlotArea.php
@@ -43,10 +43,8 @@ class PlotArea
/**
* Get Number of Plot Groups.
- *
- * @return array of DataSeries
*/
- public function getPlotGroupCount()
+ public function getPlotGroupCount(): int
{
return count($this->plotSeries);
}
@@ -69,7 +67,7 @@ class PlotArea
/**
* Get Plot Series.
*
- * @return array of DataSeries
+ * @return DataSeries[]
*/
public function getPlotGroup()
{
diff --git a/src/PhpSpreadsheet/Chart/Renderer/JpGraph.php b/src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
index 02fbfed7..0ab70870 100644
--- a/src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
+++ b/src/PhpSpreadsheet/Chart/Renderer/JpGraph.php
@@ -301,6 +301,8 @@ class JpGraph implements IRenderer
$seriesPlots = [];
if ($grouping == 'percentStacked') {
$sumValues = $this->percentageSumCalculation($groupID, $seriesCount);
+ } else {
+ $sumValues = [];
}
// Loop through each data series in turn
@@ -376,6 +378,8 @@ class JpGraph implements IRenderer
$seriesPlots = [];
if ($grouping == 'percentStacked') {
$sumValues = $this->percentageSumCalculation($groupID, $seriesCount);
+ } else {
+ $sumValues = [];
}
// Loop through each data series in turn
diff --git a/src/PhpSpreadsheet/Collection/Cells.php b/src/PhpSpreadsheet/Collection/Cells.php
index 48f34f41..c5247090 100644
--- a/src/PhpSpreadsheet/Collection/Cells.php
+++ b/src/PhpSpreadsheet/Collection/Cells.php
@@ -12,28 +12,28 @@ use Psr\SimpleCache\CacheInterface;
class Cells
{
/**
- * @var \Psr\SimpleCache\CacheInterface
+ * @var CacheInterface
*/
private $cache;
/**
* Parent worksheet.
*
- * @var Worksheet
+ * @var null|Worksheet
*/
private $parent;
/**
* The currently active Cell.
*
- * @var Cell
+ * @var null|Cell
*/
private $currentCell;
/**
* Coordinate of the currently active Cell.
*
- * @var string
+ * @var null|string
*/
private $currentCoordinate;
@@ -405,7 +405,7 @@ class Cells
* @param string $pCoord Coordinate of the cell to update
* @param Cell $cell Cell to update
*
- * @return \PhpOffice\PhpSpreadsheet\Cell\Cell
+ * @return Cell
*/
public function add($pCoord, Cell $cell)
{
@@ -426,7 +426,7 @@ class Cells
*
* @param string $pCoord Coordinate of the cell
*
- * @return null|\PhpOffice\PhpSpreadsheet\Cell\Cell Cell that was found, or null if not found
+ * @return null|Cell Cell that was found, or null if not found
*/
public function get($pCoord)
{
diff --git a/src/PhpSpreadsheet/Document/Properties.php b/src/PhpSpreadsheet/Document/Properties.php
index 0876a9ed..c099bccc 100644
--- a/src/PhpSpreadsheet/Document/Properties.php
+++ b/src/PhpSpreadsheet/Document/Properties.php
@@ -5,12 +5,20 @@ namespace PhpOffice\PhpSpreadsheet\Document;
class Properties
{
/** constants */
- const PROPERTY_TYPE_BOOLEAN = 'b';
- const PROPERTY_TYPE_INTEGER = 'i';
- const PROPERTY_TYPE_FLOAT = 'f';
- const PROPERTY_TYPE_DATE = 'd';
- const PROPERTY_TYPE_STRING = 's';
- const PROPERTY_TYPE_UNKNOWN = 'u';
+ public const PROPERTY_TYPE_BOOLEAN = 'b';
+ public const PROPERTY_TYPE_INTEGER = 'i';
+ public const PROPERTY_TYPE_FLOAT = 'f';
+ public const PROPERTY_TYPE_DATE = 'd';
+ public const PROPERTY_TYPE_STRING = 's';
+ public const PROPERTY_TYPE_UNKNOWN = 'u';
+
+ private const VALID_PROPERTY_TYPE_LIST = [
+ self::PROPERTY_TYPE_BOOLEAN,
+ self::PROPERTY_TYPE_INTEGER,
+ self::PROPERTY_TYPE_FLOAT,
+ self::PROPERTY_TYPE_DATE,
+ self::PROPERTY_TYPE_STRING,
+ ];
/**
* Creator.
@@ -92,7 +100,7 @@ class Properties
/**
* Custom Properties.
*
- * @var string
+ * @var array{value: mixed, type: string}[]
*/
private $customProperties = [];
@@ -109,10 +117,8 @@ class Properties
/**
* Get Creator.
- *
- * @return string
*/
- public function getCreator()
+ public function getCreator(): string
{
return $this->creator;
}
@@ -120,11 +126,9 @@ class Properties
/**
* Set Creator.
*
- * @param string $creator
- *
* @return $this
*/
- public function setCreator($creator)
+ public function setCreator(string $creator): self
{
$this->creator = $creator;
@@ -133,10 +137,8 @@ class Properties
/**
* Get Last Modified By.
- *
- * @return string
*/
- public function getLastModifiedBy()
+ public function getLastModifiedBy(): string
{
return $this->lastModifiedBy;
}
@@ -144,23 +146,19 @@ class Properties
/**
* Set Last Modified By.
*
- * @param string $pValue
- *
* @return $this
*/
- public function setLastModifiedBy($pValue)
+ public function setLastModifiedBy(string $modifier): self
{
- $this->lastModifiedBy = $pValue;
+ $this->lastModifiedBy = $modifier;
return $this;
}
/**
* Get Created.
- *
- * @return int
*/
- public function getCreated()
+ public function getCreated(): int
{
return $this->created;
}
@@ -168,33 +166,31 @@ class Properties
/**
* Set Created.
*
- * @param int|string $time
+ * @param null|int|string $timestamp
*
* @return $this
*/
- public function setCreated($time)
+ public function setCreated($timestamp): self
{
- if ($time === null) {
- $time = time();
- } elseif (is_string($time)) {
- if (is_numeric($time)) {
- $time = (int) $time;
+ if ($timestamp === null) {
+ $timestamp = time();
+ } elseif (is_string($timestamp)) {
+ if (is_numeric($timestamp)) {
+ $timestamp = (int) $timestamp;
} else {
- $time = strtotime($time);
+ $timestamp = strtotime($timestamp);
}
}
- $this->created = $time;
+ $this->created = $timestamp;
return $this;
}
/**
* Get Modified.
- *
- * @return int
*/
- public function getModified()
+ public function getModified(): int
{
return $this->modified;
}
@@ -202,33 +198,31 @@ class Properties
/**
* Set Modified.
*
- * @param int|string $time
+ * @param null|int|string $timestamp
*
* @return $this
*/
- public function setModified($time)
+ public function setModified($timestamp): self
{
- if ($time === null) {
- $time = time();
- } elseif (is_string($time)) {
- if (is_numeric($time)) {
- $time = (int) $time;
+ if ($timestamp === null) {
+ $timestamp = time();
+ } elseif (is_string($timestamp)) {
+ if (is_numeric($timestamp)) {
+ $timestamp = (int) $timestamp;
} else {
- $time = strtotime($time);
+ $timestamp = strtotime($timestamp);
}
}
- $this->modified = $time;
+ $this->modified = $timestamp;
return $this;
}
/**
* Get Title.
- *
- * @return string
*/
- public function getTitle()
+ public function getTitle(): string
{
return $this->title;
}
@@ -236,11 +230,9 @@ class Properties
/**
* Set Title.
*
- * @param string $title
- *
* @return $this
*/
- public function setTitle($title)
+ public function setTitle(string $title): self
{
$this->title = $title;
@@ -249,10 +241,8 @@ class Properties
/**
* Get Description.
- *
- * @return string
*/
- public function getDescription()
+ public function getDescription(): string
{
return $this->description;
}
@@ -260,11 +250,9 @@ class Properties
/**
* Set Description.
*
- * @param string $description
- *
* @return $this
*/
- public function setDescription($description)
+ public function setDescription(string $description): self
{
$this->description = $description;
@@ -273,10 +261,8 @@ class Properties
/**
* Get Subject.
- *
- * @return string
*/
- public function getSubject()
+ public function getSubject(): string
{
return $this->subject;
}
@@ -284,11 +270,9 @@ class Properties
/**
* Set Subject.
*
- * @param string $subject
- *
* @return $this
*/
- public function setSubject($subject)
+ public function setSubject(string $subject): self
{
$this->subject = $subject;
@@ -297,10 +281,8 @@ class Properties
/**
* Get Keywords.
- *
- * @return string
*/
- public function getKeywords()
+ public function getKeywords(): string
{
return $this->keywords;
}
@@ -308,11 +290,9 @@ class Properties
/**
* Set Keywords.
*
- * @param string $keywords
- *
* @return $this
*/
- public function setKeywords($keywords)
+ public function setKeywords(string $keywords): self
{
$this->keywords = $keywords;
@@ -321,10 +301,8 @@ class Properties
/**
* Get Category.
- *
- * @return string
*/
- public function getCategory()
+ public function getCategory(): string
{
return $this->category;
}
@@ -332,11 +310,9 @@ class Properties
/**
* Set Category.
*
- * @param string $category
- *
* @return $this
*/
- public function setCategory($category)
+ public function setCategory(string $category): self
{
$this->category = $category;
@@ -345,10 +321,8 @@ class Properties
/**
* Get Company.
- *
- * @return string
*/
- public function getCompany()
+ public function getCompany(): string
{
return $this->company;
}
@@ -356,11 +330,9 @@ class Properties
/**
* Set Company.
*
- * @param string $company
- *
* @return $this
*/
- public function setCompany($company)
+ public function setCompany(string $company): self
{
$this->company = $company;
@@ -369,10 +341,8 @@ class Properties
/**
* Get Manager.
- *
- * @return string
*/
- public function getManager()
+ public function getManager(): string
{
return $this->manager;
}
@@ -380,11 +350,9 @@ class Properties
/**
* Set Manager.
*
- * @param string $manager
- *
* @return $this
*/
- public function setManager($manager)
+ public function setManager(string $manager): self
{
$this->manager = $manager;
@@ -394,33 +362,27 @@ class Properties
/**
* Get a List of Custom Property Names.
*
- * @return array of string
+ * @return string[]
*/
- public function getCustomProperties()
+ public function getCustomProperties(): array
{
return array_keys($this->customProperties);
}
/**
* Check if a Custom Property is defined.
- *
- * @param string $propertyName
- *
- * @return bool
*/
- public function isCustomPropertySet($propertyName)
+ public function isCustomPropertySet(string $propertyName): bool
{
- return isset($this->customProperties[$propertyName]);
+ return array_key_exists($propertyName, $this->customProperties);
}
/**
* Get a Custom Property Value.
*
- * @param string $propertyName
- *
* @return mixed
*/
- public function getCustomPropertyValue($propertyName)
+ public function getCustomPropertyValue(string $propertyName)
{
if (isset($this->customProperties[$propertyName])) {
return $this->customProperties[$propertyName]['value'];
@@ -430,24 +392,34 @@ class Properties
/**
* Get a Custom Property Type.
*
- * @param string $propertyName
- *
- * @return string
+ * @return null|string
*/
- public function getCustomPropertyType($propertyName)
+ public function getCustomPropertyType(string $propertyName)
{
- if (isset($this->customProperties[$propertyName])) {
- return $this->customProperties[$propertyName]['type'];
+ return $this->customProperties[$propertyName]['type'] ?? null;
+ }
+
+ private function identifyPropertyType($propertyValue)
+ {
+ if ($propertyValue === null) {
+ return self::PROPERTY_TYPE_STRING;
+ } elseif (is_float($propertyValue)) {
+ return self::PROPERTY_TYPE_FLOAT;
+ } elseif (is_int($propertyValue)) {
+ return self::PROPERTY_TYPE_INTEGER;
+ } elseif (is_bool($propertyValue)) {
+ return self::PROPERTY_TYPE_BOOLEAN;
}
+
+ return self::PROPERTY_TYPE_STRING;
}
/**
* Set a Custom Property.
*
- * @param string $propertyName
* @param mixed $propertyValue
* @param string $propertyType
- * 'i' : Integer
+ * 'i' : Integer
* 'f' : Floating Point
* 's' : String
* 'd' : Date/Time
@@ -455,27 +427,10 @@ class Properties
*
* @return $this
*/
- public function setCustomProperty($propertyName, $propertyValue = '', $propertyType = null)
+ public function setCustomProperty(string $propertyName, $propertyValue = '', $propertyType = null): self
{
- if (
- ($propertyType === null) || (!in_array($propertyType, [self::PROPERTY_TYPE_INTEGER,
- self::PROPERTY_TYPE_FLOAT,
- self::PROPERTY_TYPE_STRING,
- self::PROPERTY_TYPE_DATE,
- self::PROPERTY_TYPE_BOOLEAN,
- ]))
- ) {
- if ($propertyValue === null) {
- $propertyType = self::PROPERTY_TYPE_STRING;
- } elseif (is_float($propertyValue)) {
- $propertyType = self::PROPERTY_TYPE_FLOAT;
- } elseif (is_int($propertyValue)) {
- $propertyType = self::PROPERTY_TYPE_INTEGER;
- } elseif (is_bool($propertyValue)) {
- $propertyType = self::PROPERTY_TYPE_BOOLEAN;
- } else {
- $propertyType = self::PROPERTY_TYPE_STRING;
- }
+ if (($propertyType === null) || (!in_array($propertyType, self::VALID_PROPERTY_TYPE_LIST))) {
+ $propertyType = $this->identifyPropertyType($propertyValue);
}
$this->customProperties[$propertyName] = [
@@ -501,54 +456,38 @@ class Properties
}
}
- public static function convertProperty($propertyValue, $propertyType)
+ public static function convertProperty($propertyValue, string $propertyType)
{
switch ($propertyType) {
case 'empty': // Empty
return '';
-
- break;
case 'null': // Null
return null;
-
- break;
case 'i1': // 1-Byte Signed Integer
case 'i2': // 2-Byte Signed Integer
case 'i4': // 4-Byte Signed Integer
case 'i8': // 8-Byte Signed Integer
case 'int': // Integer
return (int) $propertyValue;
-
- break;
case 'ui1': // 1-Byte Unsigned Integer
case 'ui2': // 2-Byte Unsigned Integer
case 'ui4': // 4-Byte Unsigned Integer
case 'ui8': // 8-Byte Unsigned Integer
case 'uint': // Unsigned Integer
return abs((int) $propertyValue);
-
- break;
case 'r4': // 4-Byte Real Number
case 'r8': // 8-Byte Real Number
case 'decimal': // Decimal
return (float) $propertyValue;
-
- break;
case 'lpstr': // LPSTR
case 'lpwstr': // LPWSTR
case 'bstr': // Basic String
return $propertyValue;
-
- break;
case 'date': // Date and Time
case 'filetime': // File Time
return strtotime($propertyValue);
-
- break;
case 'bool': // Boolean
return $propertyValue == 'true';
-
- break;
case 'cy': // Currency
case 'error': // Error Status Code
case 'vector': // Vector
@@ -563,14 +502,12 @@ class Properties
case 'clsid': // Class ID
case 'cf': // Clipboard Data
return $propertyValue;
-
- break;
}
return $propertyValue;
}
- public static function convertPropertyType($propertyType)
+ public static function convertPropertyType(string $propertyType): string
{
switch ($propertyType) {
case 'i1': // 1-Byte Signed Integer
@@ -584,31 +521,21 @@ class Properties
case 'ui8': // 8-Byte Unsigned Integer
case 'uint': // Unsigned Integer
return self::PROPERTY_TYPE_INTEGER;
-
- break;
case 'r4': // 4-Byte Real Number
case 'r8': // 8-Byte Real Number
case 'decimal': // Decimal
return self::PROPERTY_TYPE_FLOAT;
-
- break;
case 'empty': // Empty
case 'null': // Null
case 'lpstr': // LPSTR
case 'lpwstr': // LPWSTR
case 'bstr': // Basic String
return self::PROPERTY_TYPE_STRING;
-
- break;
case 'date': // Date and Time
case 'filetime': // File Time
return self::PROPERTY_TYPE_DATE;
-
- break;
case 'bool': // Boolean
return self::PROPERTY_TYPE_BOOLEAN;
-
- break;
case 'cy': // Currency
case 'error': // Error Status Code
case 'vector': // Vector
@@ -623,8 +550,6 @@ class Properties
case 'clsid': // Class ID
case 'cf': // Clipboard Data
return self::PROPERTY_TYPE_UNKNOWN;
-
- break;
}
return self::PROPERTY_TYPE_UNKNOWN;
diff --git a/src/PhpSpreadsheet/HashTable.php b/src/PhpSpreadsheet/HashTable.php
index 90ea806b..5d4444e7 100644
--- a/src/PhpSpreadsheet/HashTable.php
+++ b/src/PhpSpreadsheet/HashTable.php
@@ -2,12 +2,15 @@
namespace PhpOffice\PhpSpreadsheet;
+/**
+ * @template T of IComparable
+ */
class HashTable
{
/**
* HashTable elements.
*
- * @var IComparable[]
+ * @var T[]
*/
protected $items = [];
@@ -21,7 +24,7 @@ class HashTable
/**
* Create a new \PhpOffice\PhpSpreadsheet\HashTable.
*
- * @param IComparable[] $pSource Optional source array to create HashTable from
+ * @param T[] $pSource Optional source array to create HashTable from
*/
public function __construct($pSource = null)
{
@@ -34,7 +37,7 @@ class HashTable
/**
* Add HashTable items from source.
*
- * @param IComparable[] $pSource Source array to create HashTable from
+ * @param T[] $pSource Source array to create HashTable from
*/
public function addFromSource(?array $pSource = null): void
{
@@ -51,7 +54,7 @@ class HashTable
/**
* Add HashTable item.
*
- * @param IComparable $pSource Item to add
+ * @param T $pSource Item to add
*/
public function add(IComparable $pSource): void
{
@@ -65,7 +68,7 @@ class HashTable
/**
* Remove HashTable item.
*
- * @param IComparable $pSource Item to remove
+ * @param T $pSource Item to remove
*/
public function remove(IComparable $pSource): void
{
@@ -123,7 +126,7 @@ class HashTable
*
* @param int $pIndex
*
- * @return IComparable
+ * @return null|T
*/
public function getByIndex($pIndex)
{
@@ -139,7 +142,7 @@ class HashTable
*
* @param string $pHashCode
*
- * @return IComparable
+ * @return null|T
*/
public function getByHashCode($pHashCode)
{
@@ -153,7 +156,7 @@ class HashTable
/**
* HashTable to array.
*
- * @return IComparable[]
+ * @return T[]
*/
public function toArray()
{
diff --git a/src/PhpSpreadsheet/Helper/Html.php b/src/PhpSpreadsheet/Helper/Html.php
index 6c4cbf9b..f07bc961 100644
--- a/src/PhpSpreadsheet/Helper/Html.php
+++ b/src/PhpSpreadsheet/Helper/Html.php
@@ -711,7 +711,7 @@ class Html
} elseif (strpos(trim($attributeValue), '#') === 0) {
$this->$attributeName = ltrim($attributeValue, '#');
} else {
- $this->$attributeName = $this->colourNameLookup($attributeValue);
+ $this->$attributeName = static::colourNameLookup($attributeValue);
}
} else {
$this->$attributeName = $attributeValue;
diff --git a/src/PhpSpreadsheet/Helper/Sample.php b/src/PhpSpreadsheet/Helper/Sample.php
index a91b195e..c84c3930 100644
--- a/src/PhpSpreadsheet/Helper/Sample.php
+++ b/src/PhpSpreadsheet/Helper/Sample.php
@@ -71,7 +71,7 @@ class Sample
/**
* Returns an array of all known samples.
*
- * @return string[] [$name => $path]
+ * @return string[][] [$name => $path]
*/
public function getSamples()
{
@@ -132,6 +132,11 @@ class Sample
$this->logEndingNotes();
}
+ protected function isDirOrMkdir(string $folder): bool
+ {
+ return \is_dir($folder) || \mkdir($folder);
+ }
+
/**
* Returns the temporary directory and make sure it exists.
*
@@ -140,10 +145,8 @@ class Sample
private function getTemporaryFolder()
{
$tempFolder = sys_get_temp_dir() . '/phpspreadsheet';
- if (!is_dir($tempFolder)) {
- if (!mkdir($tempFolder) && !is_dir($tempFolder)) {
- throw new RuntimeException(sprintf('Directory "%s" was not created', $tempFolder));
- }
+ if (!$this->isDirOrMkdir($tempFolder)) {
+ throw new RuntimeException(sprintf('Directory "%s" was not created', $tempFolder));
}
return $tempFolder;
diff --git a/src/PhpSpreadsheet/IOFactory.php b/src/PhpSpreadsheet/IOFactory.php
index ab04e969..06006edc 100644
--- a/src/PhpSpreadsheet/IOFactory.php
+++ b/src/PhpSpreadsheet/IOFactory.php
@@ -120,7 +120,7 @@ abstract class IOFactory
$reader = self::createReader($guessedReader);
// Let's see if we are lucky
- if (isset($reader) && $reader->canRead($filename)) {
+ if ($reader->canRead($filename)) {
return $reader;
}
}
diff --git a/src/PhpSpreadsheet/NamedFormula.php b/src/PhpSpreadsheet/NamedFormula.php
index eeddbbcb..500151f0 100644
--- a/src/PhpSpreadsheet/NamedFormula.php
+++ b/src/PhpSpreadsheet/NamedFormula.php
@@ -17,7 +17,7 @@ class NamedFormula extends DefinedName
?Worksheet $scope = null
) {
// Validate data
- if (empty($formula)) {
+ if (!isset($formula)) {
throw new Exception('You must specify a Formula value for a Named Formula');
}
parent::__construct($name, $worksheet, $formula, $localOnly, $scope);
diff --git a/src/PhpSpreadsheet/Reader/BaseReader.php b/src/PhpSpreadsheet/Reader/BaseReader.php
index eb0e3ba2..80348132 100644
--- a/src/PhpSpreadsheet/Reader/BaseReader.php
+++ b/src/PhpSpreadsheet/Reader/BaseReader.php
@@ -38,7 +38,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 array of string
+ * @var null|string[]
*/
protected $loadSheetsOnly;
diff --git a/src/PhpSpreadsheet/Reader/Csv.php b/src/PhpSpreadsheet/Reader/Csv.php
index 1495d102..dc746735 100644
--- a/src/PhpSpreadsheet/Reader/Csv.php
+++ b/src/PhpSpreadsheet/Reader/Csv.php
@@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader;
use InvalidArgumentException;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
+use PhpOffice\PhpSpreadsheet\Reader\Csv\Delimiter;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
@@ -138,118 +139,26 @@ class Csv extends BaseReader
return;
}
- $potentialDelimiters = [',', ';', "\t", '|', ':', ' ', '~'];
- $counts = [];
- foreach ($potentialDelimiters as $delimiter) {
- $counts[$delimiter] = [];
- }
-
- // Count how many times each of the potential delimiters appears in each line
- $numberLines = 0;
- while (($line = $this->getNextLine()) !== false && (++$numberLines < 1000)) {
- $countLine = [];
- for ($i = strlen($line) - 1; $i >= 0; --$i) {
- $char = $line[$i];
- if (isset($counts[$char])) {
- if (!isset($countLine[$char])) {
- $countLine[$char] = 0;
- }
- ++$countLine[$char];
- }
- }
- foreach ($potentialDelimiters as $delimiter) {
- $counts[$delimiter][] = $countLine[$delimiter]
- ?? 0;
- }
- }
+ $inferenceEngine = new Delimiter($this->fileHandle, $this->escapeCharacter, $this->enclosure);
// If number of lines is 0, nothing to infer : fall back to the default
- if ($numberLines === 0) {
- $this->delimiter = reset($potentialDelimiters);
+ if ($inferenceEngine->linesCounted() === 0) {
+ $this->delimiter = $inferenceEngine->getDefaultDelimiter();
$this->skipBOM();
return;
}
- // Calculate the mean square deviations for each delimiter (ignoring delimiters that haven't been found consistently)
- $meanSquareDeviations = [];
- $middleIdx = floor(($numberLines - 1) / 2);
-
- foreach ($potentialDelimiters as $delimiter) {
- $series = $counts[$delimiter];
- sort($series);
-
- $median = ($numberLines % 2)
- ? $series[$middleIdx]
- : ($series[$middleIdx] + $series[$middleIdx + 1]) / 2;
-
- if ($median === 0) {
- continue;
- }
-
- $meanSquareDeviations[$delimiter] = array_reduce(
- $series,
- function ($sum, $value) use ($median) {
- return $sum + ($value - $median) ** 2;
- }
- ) / count($series);
- }
-
- // ... and pick the delimiter with the smallest mean square deviation (in case of ties, the order in potentialDelimiters is respected)
- $min = INF;
- foreach ($potentialDelimiters as $delimiter) {
- if (!isset($meanSquareDeviations[$delimiter])) {
- continue;
- }
-
- if ($meanSquareDeviations[$delimiter] < $min) {
- $min = $meanSquareDeviations[$delimiter];
- $this->delimiter = $delimiter;
- }
- }
+ $this->delimiter = $inferenceEngine->infer();
// If no delimiter could be detected, fall back to the default
if ($this->delimiter === null) {
- $this->delimiter = reset($potentialDelimiters);
+ $this->delimiter = $inferenceEngine->getDefaultDelimiter();
}
$this->skipBOM();
}
- /**
- * Get the next full line from the file.
- *
- * @return false|string
- */
- private function getNextLine()
- {
- $line = '';
- $enclosure = ($this->escapeCharacter === '' ? ''
- : ('(?escapeCharacter, '/') . ')'))
- . preg_quote($this->enclosure, '/');
-
- do {
- // Get the next line in the file
- $newLine = fgets($this->fileHandle);
-
- // Return false if there is no next line
- if ($newLine === false) {
- return false;
- }
-
- // Add the new line to the line passed in
- $line = $line . $newLine;
-
- // Drop everything that is enclosed to avoid counting false positives in enclosures
- $line = preg_replace('/(' . $enclosure . '.*' . $enclosure . ')/Us', '', $line);
-
- // See if we have any enclosures left in the line
- // if we still have an enclosure then we need to read the next line as well
- } while (preg_match('/(' . $enclosure . ')/', $line) > 0);
-
- return $line;
- }
-
/**
* Return worksheet info (Name, Last Column Letter, Last Column Index, Total Rows, Total Columns).
*
@@ -334,7 +243,7 @@ class Csv extends BaseReader
public function loadIntoExisting($pFilename, Spreadsheet $spreadsheet)
{
$lineEnding = ini_get('auto_detect_line_endings');
- ini_set('auto_detect_line_endings', true);
+ ini_set('auto_detect_line_endings', '1');
// Open file
$this->openFileOrMemory($pFilename);
@@ -528,7 +437,8 @@ class Csv extends BaseReader
fclose($this->fileHandle);
// Trust file extension if any
- $extension = strtolower(pathinfo($pFilename, PATHINFO_EXTENSION));
+ $extension = pathinfo($pFilename, PATHINFO_EXTENSION);
+ $extension = is_array($extension) ? '' : strtolower($extension);
if (in_array($extension, ['csv', 'tsv'])) {
return true;
}
diff --git a/src/PhpSpreadsheet/Reader/Csv/Delimiter.php b/src/PhpSpreadsheet/Reader/Csv/Delimiter.php
new file mode 100644
index 00000000..eb62c9ac
--- /dev/null
+++ b/src/PhpSpreadsheet/Reader/Csv/Delimiter.php
@@ -0,0 +1,144 @@
+fileHandle = $fileHandle;
+ $this->escapeCharacter = $escapeCharacter;
+ $this->enclosure = $enclosure;
+
+ $this->countPotentialDelimiters();
+ }
+
+ public function getDefaultDelimiter(): string
+ {
+ return self::POTENTIAL_DELIMETERS[0];
+ }
+
+ public function linesCounted(): int
+ {
+ return $this->numberLines;
+ }
+
+ protected function countPotentialDelimiters(): void
+ {
+ $this->counts = array_fill_keys(self::POTENTIAL_DELIMETERS, []);
+ $delimiterKeys = array_flip(self::POTENTIAL_DELIMETERS);
+
+ // Count how many times each of the potential delimiters appears in each line
+ $this->numberLines = 0;
+ while (($line = $this->getNextLine()) !== false && (++$this->numberLines < 1000)) {
+ $this->countDelimiterValues($line, $delimiterKeys);
+ }
+ }
+
+ protected function countDelimiterValues(string $line, array $delimiterKeys): void
+ {
+ $splitString = str_split($line, 1);
+ if (!is_array($splitString)) {
+ return;
+ }
+
+ $distribution = array_count_values($splitString);
+ $countLine = array_intersect_key($distribution, $delimiterKeys);
+
+ foreach (self::POTENTIAL_DELIMETERS as $delimiter) {
+ $this->counts[$delimiter][] = $countLine[$delimiter] ?? 0;
+ }
+ }
+
+ public function infer(): ?string
+ {
+ // Calculate the mean square deviations for each delimiter
+ // (ignoring delimiters that haven't been found consistently)
+ $meanSquareDeviations = [];
+ $middleIdx = floor(($this->numberLines - 1) / 2);
+
+ foreach (self::POTENTIAL_DELIMETERS as $delimiter) {
+ $series = $this->counts[$delimiter];
+ sort($series);
+
+ $median = ($this->numberLines % 2)
+ ? $series[$middleIdx]
+ : ($series[$middleIdx] + $series[$middleIdx + 1]) / 2;
+
+ if ($median === 0) {
+ continue;
+ }
+
+ $meanSquareDeviations[$delimiter] = array_reduce(
+ $series,
+ function ($sum, $value) use ($median) {
+ return $sum + ($value - $median) ** 2;
+ }
+ ) / count($series);
+ }
+
+ // ... and pick the delimiter with the smallest mean square deviation
+ // (in case of ties, the order in potentialDelimiters is respected)
+ $min = INF;
+ foreach (self::POTENTIAL_DELIMETERS as $delimiter) {
+ if (!isset($meanSquareDeviations[$delimiter])) {
+ continue;
+ }
+
+ if ($meanSquareDeviations[$delimiter] < $min) {
+ $min = $meanSquareDeviations[$delimiter];
+ $this->delimiter = $delimiter;
+ }
+ }
+
+ return $this->delimiter;
+ }
+
+ /**
+ * Get the next full line from the file.
+ *
+ * @return false|string
+ */
+ public function getNextLine()
+ {
+ $line = '';
+ $enclosure = ($this->escapeCharacter === '' ? ''
+ : ('(?escapeCharacter, '/') . ')'))
+ . preg_quote($this->enclosure, '/');
+
+ do {
+ // Get the next line in the file
+ $newLine = fgets($this->fileHandle);
+
+ // Return false if there is no next line
+ if ($newLine === false) {
+ return false;
+ }
+
+ // Add the new line to the line passed in
+ $line = $line . $newLine;
+
+ // Drop everything that is enclosed to avoid counting false positives in enclosures
+ $line = preg_replace('/(' . $enclosure . '.*' . $enclosure . ')/Us', '', $line);
+
+ // See if we have any enclosures left in the line
+ // if we still have an enclosure then we need to read the next line as well
+ } while (preg_match('/(' . $enclosure . ')/', $line) > 0);
+
+ return $line;
+ }
+}
diff --git a/src/PhpSpreadsheet/Reader/Gnumeric.php b/src/PhpSpreadsheet/Reader/Gnumeric.php
index dc921c1e..d3cdf1b0 100644
--- a/src/PhpSpreadsheet/Reader/Gnumeric.php
+++ b/src/PhpSpreadsheet/Reader/Gnumeric.php
@@ -6,6 +6,7 @@ use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\DefinedName;
use PhpOffice\PhpSpreadsheet\Reader\Gnumeric\PageSetup;
+use PhpOffice\PhpSpreadsheet\Reader\Gnumeric\Properties;
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
use PhpOffice\PhpSpreadsheet\ReferenceHelper;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
@@ -262,148 +263,6 @@ class Gnumeric extends BaseReader
return self::$mappings;
}
- private function docPropertiesOld(SimpleXMLElement $gnmXML): void
- {
- $docProps = $this->spreadsheet->getProperties();
- foreach ($gnmXML->Summary->Item as $summaryItem) {
- $propertyName = $summaryItem->name;
- $propertyValue = $summaryItem->{'val-string'};
- switch ($propertyName) {
- case 'title':
- $docProps->setTitle(trim($propertyValue));
-
- break;
- case 'comments':
- $docProps->setDescription(trim($propertyValue));
-
- break;
- case 'keywords':
- $docProps->setKeywords(trim($propertyValue));
-
- break;
- case 'category':
- $docProps->setCategory(trim($propertyValue));
-
- break;
- case 'manager':
- $docProps->setManager(trim($propertyValue));
-
- break;
- case 'author':
- $docProps->setCreator(trim($propertyValue));
- $docProps->setLastModifiedBy(trim($propertyValue));
-
- break;
- case 'company':
- $docProps->setCompany(trim($propertyValue));
-
- break;
- }
- }
- }
-
- private function docPropertiesDC(SimpleXMLElement $officePropertyDC): void
- {
- $docProps = $this->spreadsheet->getProperties();
- foreach ($officePropertyDC as $propertyName => $propertyValue) {
- $propertyValue = trim((string) $propertyValue);
- switch ($propertyName) {
- case 'title':
- $docProps->setTitle($propertyValue);
-
- break;
- case 'subject':
- $docProps->setSubject($propertyValue);
-
- break;
- case 'creator':
- $docProps->setCreator($propertyValue);
- $docProps->setLastModifiedBy($propertyValue);
-
- break;
- case 'date':
- $creationDate = strtotime($propertyValue);
- $docProps->setCreated($creationDate);
- $docProps->setModified($creationDate);
-
- break;
- case 'description':
- $docProps->setDescription($propertyValue);
-
- break;
- }
- }
- }
-
- private function docPropertiesMeta(SimpleXMLElement $officePropertyMeta, array $namespacesMeta): void
- {
- $docProps = $this->spreadsheet->getProperties();
- foreach ($officePropertyMeta as $propertyName => $propertyValue) {
- $attributes = $propertyValue->attributes($namespacesMeta['meta']);
- $propertyValue = trim((string) $propertyValue);
- switch ($propertyName) {
- case 'keyword':
- $docProps->setKeywords($propertyValue);
-
- break;
- case 'initial-creator':
- $docProps->setCreator($propertyValue);
- $docProps->setLastModifiedBy($propertyValue);
-
- break;
- case 'creation-date':
- $creationDate = strtotime($propertyValue);
- $docProps->setCreated($creationDate);
- $docProps->setModified($creationDate);
-
- break;
- case 'user-defined':
- [, $attrName] = explode(':', $attributes['name']);
- switch ($attrName) {
- case 'publisher':
- $docProps->setCompany($propertyValue);
-
- break;
- case 'category':
- $docProps->setCategory($propertyValue);
-
- break;
- case 'manager':
- $docProps->setManager($propertyValue);
-
- break;
- }
-
- break;
- }
- }
- }
-
- private function docProperties(SimpleXMLElement $xml, SimpleXMLElement $gnmXML, array $namespacesMeta): void
- {
- if (isset($namespacesMeta['office'])) {
- $officeXML = $xml->children($namespacesMeta['office']);
- $officeDocXML = $officeXML->{'document-meta'};
- $officeDocMetaXML = $officeDocXML->meta;
-
- foreach ($officeDocMetaXML as $officePropertyData) {
- $officePropertyDC = [];
- if (isset($namespacesMeta['dc'])) {
- $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
- }
- $this->docPropertiesDC($officePropertyDC);
-
- $officePropertyMeta = [];
- if (isset($namespacesMeta['meta'])) {
- $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
- }
- $this->docPropertiesMeta($officePropertyMeta, $namespacesMeta);
- }
- } elseif (isset($gnmXML->Summary)) {
- $this->docPropertiesOld($gnmXML);
- }
- }
-
private function processComments(SimpleXMLElement $sheet): void
{
if ((!$this->readDataOnly) && (isset($sheet->Objects))) {
@@ -450,7 +309,7 @@ class Gnumeric extends BaseReader
$this->gnm = array_key_exists('gmr', $namespacesMeta) ? 'gmr' : 'gnm';
$gnmXML = $xml->children($namespacesMeta[$this->gnm]);
- $this->docProperties($xml, $gnmXML, $namespacesMeta);
+ (new Properties($this->spreadsheet))->readProperties($xml, $gnmXML, $namespacesMeta);
$worksheetID = 0;
foreach ($gnmXML->Sheets->Sheet as $sheet) {
@@ -657,7 +516,7 @@ class Gnumeric extends BaseReader
$column = $columnAttributes['No'];
$columnWidth = ((float) $columnAttributes['Unit']) / 5.4;
$hidden = (isset($columnAttributes['Hidden'])) && ((string) $columnAttributes['Hidden'] == '1');
- $columnCount = (isset($columnAttributes['Count'])) ? $columnAttributes['Count'] : 1;
+ $columnCount = (int) ($columnAttributes['Count'] ?? 1);
while ($c < $column) {
$this->spreadsheet->getActiveSheet()->getColumnDimension(Coordinate::stringFromColumnIndex($c + 1))->setWidth($defaultWidth);
++$c;
@@ -696,7 +555,7 @@ class Gnumeric extends BaseReader
$row = $rowAttributes['No'];
$rowHeight = (float) $rowAttributes['Unit'];
$hidden = (isset($rowAttributes['Hidden'])) && ((string) $rowAttributes['Hidden'] == '1');
- $rowCount = (isset($rowAttributes['Count'])) ? $rowAttributes['Count'] : 1;
+ $rowCount = (int) ($rowAttributes['Count'] ?? 1);
while ($r < $row) {
++$r;
$this->spreadsheet->getActiveSheet()->getRowDimension($r)->setRowHeight($defaultHeight);
diff --git a/src/PhpSpreadsheet/Reader/Gnumeric/Properties.php b/src/PhpSpreadsheet/Reader/Gnumeric/Properties.php
new file mode 100644
index 00000000..16d9c2e0
--- /dev/null
+++ b/src/PhpSpreadsheet/Reader/Gnumeric/Properties.php
@@ -0,0 +1,167 @@
+spreadsheet = $spreadsheet;
+ }
+
+ private function docPropertiesOld(SimpleXMLElement $gnmXML): void
+ {
+ $docProps = $this->spreadsheet->getProperties();
+ foreach ($gnmXML->Summary->Item as $summaryItem) {
+ $propertyName = $summaryItem->name;
+ $propertyValue = $summaryItem->{'val-string'};
+ switch ($propertyName) {
+ case 'title':
+ $docProps->setTitle(trim($propertyValue));
+
+ break;
+ case 'comments':
+ $docProps->setDescription(trim($propertyValue));
+
+ break;
+ case 'keywords':
+ $docProps->setKeywords(trim($propertyValue));
+
+ break;
+ case 'category':
+ $docProps->setCategory(trim($propertyValue));
+
+ break;
+ case 'manager':
+ $docProps->setManager(trim($propertyValue));
+
+ break;
+ case 'author':
+ $docProps->setCreator(trim($propertyValue));
+ $docProps->setLastModifiedBy(trim($propertyValue));
+
+ break;
+ case 'company':
+ $docProps->setCompany(trim($propertyValue));
+
+ break;
+ }
+ }
+ }
+
+ private function docPropertiesDC(SimpleXMLElement $officePropertyDC): void
+ {
+ $docProps = $this->spreadsheet->getProperties();
+ foreach ($officePropertyDC as $propertyName => $propertyValue) {
+ $propertyValue = trim((string) $propertyValue);
+ switch ($propertyName) {
+ case 'title':
+ $docProps->setTitle($propertyValue);
+
+ break;
+ case 'subject':
+ $docProps->setSubject($propertyValue);
+
+ break;
+ case 'creator':
+ $docProps->setCreator($propertyValue);
+ $docProps->setLastModifiedBy($propertyValue);
+
+ break;
+ case 'date':
+ $creationDate = strtotime($propertyValue);
+ $creationDate = $creationDate === false ? time() : $creationDate;
+ $docProps->setCreated($creationDate);
+ $docProps->setModified($creationDate);
+
+ break;
+ case 'description':
+ $docProps->setDescription($propertyValue);
+
+ break;
+ }
+ }
+ }
+
+ private function docPropertiesMeta(SimpleXMLElement $officePropertyMeta, array $namespacesMeta): void
+ {
+ $docProps = $this->spreadsheet->getProperties();
+ foreach ($officePropertyMeta as $propertyName => $propertyValue) {
+ if ($propertyValue === null) {
+ continue;
+ }
+
+ $attributes = $propertyValue->attributes($namespacesMeta['meta']);
+ $propertyValue = trim((string) $propertyValue);
+ switch ($propertyName) {
+ case 'keyword':
+ $docProps->setKeywords($propertyValue);
+
+ break;
+ case 'initial-creator':
+ $docProps->setCreator($propertyValue);
+ $docProps->setLastModifiedBy($propertyValue);
+
+ break;
+ case 'creation-date':
+ $creationDate = strtotime($propertyValue);
+ $creationDate = $creationDate === false ? time() : $creationDate;
+ $docProps->setCreated($creationDate);
+ $docProps->setModified($creationDate);
+
+ break;
+ case 'user-defined':
+ [, $attrName] = explode(':', $attributes['name']);
+ switch ($attrName) {
+ case 'publisher':
+ $docProps->setCompany($propertyValue);
+
+ break;
+ case 'category':
+ $docProps->setCategory($propertyValue);
+
+ break;
+ case 'manager':
+ $docProps->setManager($propertyValue);
+
+ break;
+ }
+
+ break;
+ }
+ }
+ }
+
+ public function readProperties(SimpleXMLElement $xml, SimpleXMLElement $gnmXML, array $namespacesMeta): void
+ {
+ if (isset($namespacesMeta['office'])) {
+ $officeXML = $xml->children($namespacesMeta['office']);
+ $officeDocXML = $officeXML->{'document-meta'};
+ $officeDocMetaXML = $officeDocXML->meta;
+
+ foreach ($officeDocMetaXML as $officePropertyData) {
+ $officePropertyDC = [];
+ if (isset($namespacesMeta['dc'])) {
+ $officePropertyDC = $officePropertyData->children($namespacesMeta['dc']);
+ }
+ $this->docPropertiesDC($officePropertyDC);
+
+ $officePropertyMeta = [];
+ if (isset($namespacesMeta['meta'])) {
+ $officePropertyMeta = $officePropertyData->children($namespacesMeta['meta']);
+ }
+ $this->docPropertiesMeta($officePropertyMeta, $namespacesMeta);
+ }
+ } elseif (isset($gnmXML->Summary)) {
+ $this->docPropertiesOld($gnmXML);
+ }
+ }
+}
diff --git a/src/PhpSpreadsheet/Reader/Html.php b/src/PhpSpreadsheet/Reader/Html.php
index 73f4591e..f235f9b1 100644
--- a/src/PhpSpreadsheet/Reader/Html.php
+++ b/src/PhpSpreadsheet/Reader/Html.php
@@ -320,7 +320,7 @@ class Html extends BaseReader
{
if ($child->nodeName === 'title') {
$this->processDomElement($child, $sheet, $row, $column, $cellContent);
- $sheet->setTitle($cellContent, true, false);
+ $sheet->setTitle($cellContent, true, true);
$cellContent = '';
} else {
$this->processDomElementSpanEtc($sheet, $row, $column, $cellContent, $child, $attributeArray);
@@ -650,7 +650,7 @@ class Html extends BaseReader
$loaded = false;
}
if ($loaded === false) {
- throw new Exception('Failed to load ' . $pFilename . ' as a DOM Document');
+ throw new Exception('Failed to load ' . $pFilename . ' as a DOM Document', 0, $e ?? null);
}
return $this->loadDocument($dom, $spreadsheet);
@@ -672,7 +672,7 @@ class Html extends BaseReader
$loaded = false;
}
if ($loaded === false) {
- throw new Exception('Failed to load content as a DOM Document');
+ throw new Exception('Failed to load content as a DOM Document', 0, $e ?? null);
}
return $this->loadDocument($dom, $spreadsheet ?? new Spreadsheet());
@@ -910,8 +910,6 @@ class Html extends BaseReader
/**
* Check if has #, so we can get clean hex.
*
- * @param $value
- *
* @return null|string
*/
public function getStyleColor($value)
diff --git a/src/PhpSpreadsheet/Reader/Ods.php b/src/PhpSpreadsheet/Reader/Ods.php
index 4ceac653..1a4d7ca3 100644
--- a/src/PhpSpreadsheet/Reader/Ods.php
+++ b/src/PhpSpreadsheet/Reader/Ods.php
@@ -23,6 +23,7 @@ use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
+use Throwable;
use XMLReader;
use ZipArchive;
@@ -379,9 +380,8 @@ class Ods extends BaseReader
}
$columnID = 'A';
- foreach ($childNode->childNodes as $key => $cellData) {
- // @var \DOMElement $cellData
-
+ /** @var DOMElement $cellData */
+ foreach ($childNode->childNodes as $cellData) {
if ($this->getReadFilter() !== null) {
if (!$this->getReadFilter()->readCell($columnID, $rowID, $worksheetName)) {
++$columnID;
@@ -646,10 +646,83 @@ class Ods extends BaseReader
$this->readDefinedExpressions($spreadsheet, $workbookData, $tableNs);
}
$spreadsheet->setActiveSheetIndex(0);
+
+ if ($zip->locateName('settings.xml') !== false) {
+ $this->processSettings($zip, $spreadsheet);
+ }
// Return
return $spreadsheet;
}
+ private function processSettings(ZipArchive $zip, Spreadsheet $spreadsheet): void
+ {
+ $dom = new DOMDocument('1.01', 'UTF-8');
+ $dom->loadXML(
+ $this->securityScanner->scan($zip->getFromName('settings.xml')),
+ Settings::getLibXmlLoaderOptions()
+ );
+ //$xlinkNs = $dom->lookupNamespaceUri('xlink');
+ $configNs = $dom->lookupNamespaceUri('config');
+ //$oooNs = $dom->lookupNamespaceUri('ooo');
+ $officeNs = $dom->lookupNamespaceUri('office');
+ $settings = $dom->getElementsByTagNameNS($officeNs, 'settings')
+ ->item(0);
+ $this->lookForActiveSheet($settings, $spreadsheet, $configNs);
+ $this->lookForSelectedCells($settings, $spreadsheet, $configNs);
+ }
+
+ private function lookForActiveSheet(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void
+ {
+ /** @var DOMElement $t */
+ foreach ($settings->getElementsByTagNameNS($configNs, 'config-item') as $t) {
+ if ($t->getAttributeNs($configNs, 'name') === 'ActiveTable') {
+ try {
+ $spreadsheet->setActiveSheetIndexByName($t->nodeValue);
+ } catch (Throwable $e) {
+ // do nothing
+ }
+
+ break;
+ }
+ }
+ }
+
+ private function lookForSelectedCells(DOMElement $settings, Spreadsheet $spreadsheet, string $configNs): void
+ {
+ /** @var DOMElement $t */
+ foreach ($settings->getElementsByTagNameNS($configNs, 'config-item-map-named') as $t) {
+ if ($t->getAttributeNs($configNs, 'name') === 'Tables') {
+ foreach ($t->getElementsByTagNameNS($configNs, 'config-item-map-entry') as $ws) {
+ $setRow = $setCol = '';
+ $wsname = $ws->getAttributeNs($configNs, 'name');
+ foreach ($ws->getElementsByTagNameNS($configNs, 'config-item') as $configItem) {
+ $attrName = $configItem->getAttributeNs($configNs, 'name');
+ if ($attrName === 'CursorPositionX') {
+ $setCol = $configItem->nodeValue;
+ }
+ if ($attrName === 'CursorPositionY') {
+ $setRow = $configItem->nodeValue;
+ }
+ }
+ $this->setSelected($spreadsheet, $wsname, $setCol, $setRow);
+ }
+
+ break;
+ }
+ }
+ }
+
+ private function setSelected(Spreadsheet $spreadsheet, string $wsname, string $setCol, string $setRow): void
+ {
+ if (is_numeric($setCol) && is_numeric($setRow)) {
+ try {
+ $spreadsheet->getSheetByName($wsname)->setSelectedCellByColumnAndRow($setCol + 1, $setRow + 1);
+ } catch (Throwable $e) {
+ // do nothing
+ }
+ }
+ }
+
/**
* Recursively scan element.
*
diff --git a/src/PhpSpreadsheet/Reader/Ods/PageSettings.php b/src/PhpSpreadsheet/Reader/Ods/PageSettings.php
index 77341aab..8d24fd0c 100644
--- a/src/PhpSpreadsheet/Reader/Ods/PageSettings.php
+++ b/src/PhpSpreadsheet/Reader/Ods/PageSettings.php
@@ -54,10 +54,10 @@ class PageSettings
$marginBottom = $pageLayoutProperties->getAttributeNS($this->stylesFo, 'margin-bottom');
$header = $styleSet->getElementsByTagNameNS($this->stylesNs, 'header-style')[0];
$headerProperties = $header->getElementsByTagNameNS($this->stylesNs, 'header-footer-properties')[0];
- $marginHeader = $headerProperties->getAttributeNS($this->stylesFo, 'min-height');
+ $marginHeader = isset($headerProperties) ? $headerProperties->getAttributeNS($this->stylesFo, 'min-height') : null;
$footer = $styleSet->getElementsByTagNameNS($this->stylesNs, 'footer-style')[0];
$footerProperties = $footer->getElementsByTagNameNS($this->stylesNs, 'header-footer-properties')[0];
- $marginFooter = $footerProperties->getAttributeNS($this->stylesFo, 'min-height');
+ $marginFooter = isset($footerProperties) ? $footerProperties->getAttributeNS($this->stylesFo, 'min-height') : null;
$this->pageLayoutStyles[$styleName] = (object) [
'orientation' => $styleOrientation ?: PageSetup::ORIENTATION_DEFAULT,
diff --git a/src/PhpSpreadsheet/Reader/Slk.php b/src/PhpSpreadsheet/Reader/Slk.php
index e58ff2f6..c7b6fc82 100644
--- a/src/PhpSpreadsheet/Reader/Slk.php
+++ b/src/PhpSpreadsheet/Reader/Slk.php
@@ -169,7 +169,7 @@ class Slk extends BaseReader
foreach ($rowData as $rowDatum) {
switch ($rowDatum[0]) {
case 'X':
- $columnIndex = substr($rowDatum, 1) - 1;
+ $columnIndex = (int) substr($rowDatum, 1) - 1;
break;
case 'Y':
@@ -251,7 +251,7 @@ class Slk extends BaseReader
}
// Bracketed R references are relative to the current row
if ($rowReference[0] == '[') {
- $rowReference = $row + trim($rowReference, '[]');
+ $rowReference = (int) $row + (int) trim($rowReference, '[]');
}
$columnReference = $cellReference[4][0];
// Empty C reference is the current column
@@ -260,7 +260,7 @@ class Slk extends BaseReader
}
// Bracketed C references are relative to the current column
if ($columnReference[0] == '[') {
- $columnReference = $column + trim($columnReference, '[]');
+ $columnReference = (int) $column + (int) trim($columnReference, '[]');
}
$A1CellReference = Coordinate::stringFromColumnIndex($columnReference) . $rowReference;
@@ -419,14 +419,14 @@ class Slk extends BaseReader
if ($columnWidth > '') {
if ($startCol == $endCol) {
$startCol = Coordinate::stringFromColumnIndex((int) $startCol);
- $spreadsheet->getActiveSheet()->getColumnDimension($startCol)->setWidth($columnWidth);
+ $spreadsheet->getActiveSheet()->getColumnDimension($startCol)->setWidth((float) $columnWidth);
} else {
$startCol = Coordinate::stringFromColumnIndex($startCol);
$endCol = Coordinate::stringFromColumnIndex($endCol);
$spreadsheet->getActiveSheet()->getColumnDimension($startCol)->setWidth((float) $columnWidth);
do {
- $spreadsheet->getActiveSheet()->getColumnDimension(++$startCol)->setWidth($columnWidth);
- } while ($startCol != $endCol);
+ $spreadsheet->getActiveSheet()->getColumnDimension(++$startCol)->setWidth((float) $columnWidth);
+ } while ($startCol !== $endCol);
}
}
}
diff --git a/src/PhpSpreadsheet/Reader/Xls.php b/src/PhpSpreadsheet/Reader/Xls.php
index 023806d6..c389105b 100644
--- a/src/PhpSpreadsheet/Reader/Xls.php
+++ b/src/PhpSpreadsheet/Reader/Xls.php
@@ -224,7 +224,7 @@ class Xls extends BaseReader
/**
* Shared fonts.
*
- * @var array
+ * @var Font[]
*/
private $objFonts;
@@ -374,7 +374,7 @@ class Xls extends BaseReader
*
* @var int
*/
- private $encryptionStartPos = false;
+ private $encryptionStartPos = 0;
/**
* The current RC4 decryption object.
@@ -659,7 +659,7 @@ class Xls extends BaseReader
$this->definedname = [];
$this->sst = [];
$this->drawingGroupData = '';
- $this->xfIndex = '';
+ $this->xfIndex = 0;
$this->mapCellXfIndex = [];
$this->mapCellStyleXfIndex = [];
@@ -801,9 +801,10 @@ class Xls extends BaseReader
}
// treat MSODRAWINGGROUP records, workbook-level Escher
+ $escherWorkbook = null;
if (!$this->readDataOnly && $this->drawingGroupData) {
- $escherWorkbook = new Escher();
- $reader = new Xls\Escher($escherWorkbook);
+ $escher = new Escher();
+ $reader = new Xls\Escher($escher);
$escherWorkbook = $reader->load($this->drawingGroupData);
}
@@ -1133,38 +1134,40 @@ class Xls extends BaseReader
continue 2;
}
- $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection();
- $BSE = $BSECollection[$BSEindex - 1];
- $blipType = $BSE->getBlipType();
+ if ($escherWorkbook) {
+ $BSECollection = $escherWorkbook->getDggContainer()->getBstoreContainer()->getBSECollection();
+ $BSE = $BSECollection[$BSEindex - 1];
+ $blipType = $BSE->getBlipType();
- // need check because some blip types are not supported by Escher reader such as EMF
- if ($blip = $BSE->getBlip()) {
- $ih = imagecreatefromstring($blip->getData());
- $drawing = new MemoryDrawing();
- $drawing->setImageResource($ih);
+ // need check because some blip types are not supported by Escher reader such as EMF
+ if ($blip = $BSE->getBlip()) {
+ $ih = imagecreatefromstring($blip->getData());
+ $drawing = new MemoryDrawing();
+ $drawing->setImageResource($ih);
- // width, height, offsetX, offsetY
- $drawing->setResizeProportional(false);
- $drawing->setWidth($width);
- $drawing->setHeight($height);
- $drawing->setOffsetX($offsetX);
- $drawing->setOffsetY($offsetY);
+ // width, height, offsetX, offsetY
+ $drawing->setResizeProportional(false);
+ $drawing->setWidth($width);
+ $drawing->setHeight($height);
+ $drawing->setOffsetX($offsetX);
+ $drawing->setOffsetY($offsetY);
- switch ($blipType) {
- case BSE::BLIPTYPE_JPEG:
- $drawing->setRenderingFunction(MemoryDrawing::RENDERING_JPEG);
- $drawing->setMimeType(MemoryDrawing::MIMETYPE_JPEG);
+ switch ($blipType) {
+ case BSE::BLIPTYPE_JPEG:
+ $drawing->setRenderingFunction(MemoryDrawing::RENDERING_JPEG);
+ $drawing->setMimeType(MemoryDrawing::MIMETYPE_JPEG);
- break;
- case BSE::BLIPTYPE_PNG:
- $drawing->setRenderingFunction(MemoryDrawing::RENDERING_PNG);
- $drawing->setMimeType(MemoryDrawing::MIMETYPE_PNG);
+ break;
+ case BSE::BLIPTYPE_PNG:
+ $drawing->setRenderingFunction(MemoryDrawing::RENDERING_PNG);
+ $drawing->setMimeType(MemoryDrawing::MIMETYPE_PNG);
- break;
+ break;
+ }
+
+ $drawing->setWorksheet($this->phpSheet);
+ $drawing->setCoordinates($spContainer->getStartCoordinates());
}
-
- $drawing->setWorksheet($this->phpSheet);
- $drawing->setCoordinates($spContainer->getStartCoordinates());
}
break;
@@ -1290,10 +1293,10 @@ class Xls extends BaseReader
}
}
// Named Value
- // TODO Provide support for named values
+ // TODO Provide support for named values
}
}
- $this->data = null;
+ $this->data = '';
return $this->spreadsheet;
}
@@ -1703,7 +1706,8 @@ class Xls extends BaseReader
// max 2048 bytes will probably throw a wobbly.
$row = self::getUInt2d($recordData, 0);
$extension = true;
- $cellAddress = array_pop(array_keys($this->phpSheet->getComments()));
+ $arrayKeys = array_keys($this->phpSheet->getComments());
+ $cellAddress = array_pop($arrayKeys);
}
$cellAddress = str_replace('$', '', $cellAddress);
@@ -2286,8 +2290,8 @@ class Xls extends BaseReader
$rotation = $angle;
} elseif ($angle <= 180) {
$rotation = 90 - $angle;
- } elseif ($angle == 255) {
- $rotation = -165;
+ } elseif ($angle == Alignment::TEXTROTATION_STACK_EXCEL) {
+ $rotation = Alignment::TEXTROTATION_STACK_PHPSPREADSHEET;
}
$objStyle->getAlignment()->setTextRotation($rotation);
@@ -2389,7 +2393,7 @@ class Xls extends BaseReader
break;
case 1:
- $objStyle->getAlignment()->setTextRotation(-165);
+ $objStyle->getAlignment()->setTextRotation(Alignment::TEXTROTATION_STACK_PHPSPREADSHEET);
break;
case 2:
@@ -2741,6 +2745,7 @@ class Xls extends BaseReader
$sheetType = ord($recordData[5]);
// offset: 6; size: var; sheet name
+ $rec_name = null;
if ($this->version == self::XLS_BIFF8) {
$string = self::readUnicodeStringShort(substr($recordData, 6));
$rec_name = $string['value'];
@@ -3017,12 +3022,14 @@ class Xls extends BaseReader
// bit: 3; mask: 0x03; 0 = ordinary; 1 = Rich-Text
$hasRichText = (($optionFlags & 0x08) != 0);
+ $formattingRuns = 0;
if ($hasRichText) {
// number of Rich-Text formatting runs
$formattingRuns = self::getUInt2d($recordData, $pos);
$pos += 2;
}
+ $extendedRunLength = 0;
if ($hasAsian) {
// size of Asian phonetic setting
$extendedRunLength = self::getInt4d($recordData, $pos);
@@ -3033,6 +3040,7 @@ class Xls extends BaseReader
$len = ($isCompressed) ? $numChars : $numChars * 2;
// look up limit position - Check it again to be sure that no error occurs when parsing SST structure
+ $limitpos = null;
foreach ($spliceOffsets as $spliceOffset) {
// it can happen that the string is empty, therefore we need
// <= and not just <
@@ -3097,7 +3105,7 @@ class Xls extends BaseReader
$len = min($charsLeft, $limitpos - $pos);
for ($j = 0; $j < $len; ++$j) {
$retstr .= $recordData[$pos + $j]
- . chr(0);
+ . chr(0);
}
$charsLeft -= $len;
$isCompressed = false;
@@ -4384,6 +4392,8 @@ class Xls extends BaseReader
// offset: 4; size: 2; index to first visible colum
$firstVisibleColumn = self::getUInt2d($recordData, 4);
+ $zoomscaleInPageBreakPreview = 0;
+ $zoomscaleInNormalView = 0;
if ($this->version === self::XLS_BIFF8) {
// offset: 8; size: 2; not used
// offset: 10; size: 2; cached magnification factor in page break preview (in percent); 0 = Default (60%)
@@ -7181,6 +7191,7 @@ class Xls extends BaseReader
{
[$baseCol, $baseRow] = Coordinate::coordinateFromString($baseCell);
$baseCol = Coordinate::columnIndexFromString($baseCol) - 1;
+ $baseRow = (int) $baseRow;
// offset: 0; size: 2; index to row (0... 65535) (or offset (-32768... 32767))
$rowIndex = self::getUInt2d($cellAddressStructure, 0);
@@ -7358,8 +7369,8 @@ class Xls extends BaseReader
*/
private function readBIFF8CellRangeAddressB($subData, $baseCell = 'A1')
{
- [$baseCol, $baseRow] = Coordinate::coordinateFromString($baseCell);
- $baseCol = Coordinate::columnIndexFromString($baseCol) - 1;
+ [$baseCol, $baseRow] = Coordinate::indexesFromString($baseCell);
+ $baseCol = $baseCol - 1;
// TODO: if cell range is just a single cell, should this funciton
// not just return e.g. 'A1' and not 'A1:A1' ?
@@ -7635,6 +7646,8 @@ class Xls extends BaseReader
$size = 9;
break;
+ default:
+ throw new PhpSpreadsheetException('Unsupported BIFF8 constant');
}
return [
diff --git a/src/PhpSpreadsheet/Reader/Xls/Color.php b/src/PhpSpreadsheet/Reader/Xls/Color.php
index c45f88c7..06c2d0b9 100644
--- a/src/PhpSpreadsheet/Reader/Xls/Color.php
+++ b/src/PhpSpreadsheet/Reader/Xls/Color.php
@@ -20,7 +20,7 @@ class Color
if ($color <= 0x07 || $color >= 0x40) {
// special built-in color
return Color\BuiltIn::lookup($color);
- } elseif (isset($palette, $palette[$color - 8])) {
+ } elseif (isset($palette[$color - 8])) {
// palette color, color index 0x08 maps to pallete index 0
return $palette[$color - 8];
}
diff --git a/src/PhpSpreadsheet/Reader/Xls/MD5.php b/src/PhpSpreadsheet/Reader/Xls/MD5.php
index c0417ba6..3e15f641 100644
--- a/src/PhpSpreadsheet/Reader/Xls/MD5.php
+++ b/src/PhpSpreadsheet/Reader/Xls/MD5.php
@@ -5,12 +5,25 @@ namespace PhpOffice\PhpSpreadsheet\Reader\Xls;
class MD5
{
// Context
+
+ /**
+ * @var int
+ */
private $a;
+ /**
+ * @var int
+ */
private $b;
+ /**
+ * @var int
+ */
private $c;
+ /**
+ * @var int
+ */
private $d;
/**
@@ -56,7 +69,7 @@ class MD5
*
* @param string $data Data to add
*/
- public function add($data): void
+ public function add(string $data): void
{
$words = array_values(unpack('V16', $data));
@@ -148,34 +161,34 @@ class MD5
$this->d = ($this->d + $D) & 0xffffffff;
}
- private static function f($X, $Y, $Z)
+ private static function f(int $X, int $Y, int $Z)
{
return ($X & $Y) | ((~$X) & $Z); // X AND Y OR NOT X AND Z
}
- private static function g($X, $Y, $Z)
+ private static function g(int $X, int $Y, int $Z)
{
return ($X & $Z) | ($Y & (~$Z)); // X AND Z OR Y AND NOT Z
}
- private static function h($X, $Y, $Z)
+ private static function h(int $X, int $Y, int $Z)
{
return $X ^ $Y ^ $Z; // X XOR Y XOR Z
}
- private static function i($X, $Y, $Z)
+ private static function i(int $X, int $Y, int $Z)
{
return $Y ^ ($X | (~$Z)); // Y XOR (X OR NOT Z)
}
- private static function step($func, &$A, $B, $C, $D, $M, $s, $t): void
+ private static function step($func, int &$A, int $B, int $C, int $D, int $M, int $s, int $t): void
{
$A = ($A + call_user_func($func, $B, $C, $D) + $M + $t) & 0xffffffff;
$A = self::rotate($A, $s);
$A = ($B + $A) & 0xffffffff;
}
- private static function rotate($decimal, $bits)
+ private static function rotate(int $decimal, int $bits)
{
$binary = str_pad(decbin($decimal), 32, '0', STR_PAD_LEFT);
diff --git a/src/PhpSpreadsheet/Reader/Xlsx.php b/src/PhpSpreadsheet/Reader/Xlsx.php
index 0bc29c61..f734c99f 100644
--- a/src/PhpSpreadsheet/Reader/Xlsx.php
+++ b/src/PhpSpreadsheet/Reader/Xlsx.php
@@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheet\Reader;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
+use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Cell\Hyperlink;
use PhpOffice\PhpSpreadsheet\DefinedName;
use PhpOffice\PhpSpreadsheet\Reader\Security\XmlScanner;
@@ -271,11 +272,11 @@ class Xlsx extends BaseReader
if (!isset($sharedFormulas[(string) $c->f['si']])) {
$sharedFormulas[$instance] = ['master' => $r, 'formula' => $value];
} else {
- $master = Coordinate::coordinateFromString($sharedFormulas[$instance]['master']);
- $current = Coordinate::coordinateFromString($r);
+ $master = Coordinate::indexesFromString($sharedFormulas[$instance]['master']);
+ $current = Coordinate::indexesFromString($r);
$difference = [0, 0];
- $difference[0] = Coordinate::columnIndexFromString($current[0]) - Coordinate::columnIndexFromString($master[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]);
@@ -429,7 +430,7 @@ class Xlsx extends BaseReader
'SimpleXMLElement',
Settings::getLibXmlLoaderOptions()
);
- if (isset($xmlStrings, $xmlStrings->si)) {
+ if (isset($xmlStrings->si)) {
foreach ($xmlStrings->si as $val) {
if (isset($val->t)) {
$sharedStrings[] = StringHelper::controlCharacterOOXML2PHP((string) $val->t);
@@ -488,7 +489,7 @@ class Xlsx extends BaseReader
}
if (!$this->readDataOnly && $xmlStyles) {
foreach ($xmlStyles->cellXfs->xf as $xf) {
- $numFmt = NumberFormat::FORMAT_GENERAL;
+ $numFmt = null;
if ($xf['numFmtId']) {
if (isset($numFmts)) {
@@ -503,19 +504,17 @@ class Xlsx extends BaseReader
// But there's a lot of naughty homebrew xlsx writers that do use "reserved" id values that aren't actually used
// So we make allowance for them rather than lose formatting masks
if (
+ $numFmt === null &&
(int) $xf['numFmtId'] < 164 &&
NumberFormat::builtInFormatCode((int) $xf['numFmtId']) !== ''
) {
$numFmt = NumberFormat::builtInFormatCode((int) $xf['numFmtId']);
}
}
- $quotePrefix = false;
- if (isset($xf['quotePrefix'])) {
- $quotePrefix = (bool) $xf['quotePrefix'];
- }
+ $quotePrefix = (bool) ($xf['quotePrefix'] ?? false);
$style = (object) [
- 'numFmt' => $numFmt,
+ 'numFmt' => $numFmt ?? NumberFormat::FORMAT_GENERAL,
'font' => $xmlStyles->fonts->font[(int) ($xf['fontId'])],
'fill' => $xmlStyles->fills->fill[(int) ($xf['fillId'])],
'border' => $xmlStyles->borders->border[(int) ($xf['borderId'])],
@@ -531,7 +530,7 @@ class Xlsx extends BaseReader
$excel->addCellXf($objStyle);
}
- foreach (isset($xmlStyles->cellStyleXfs->xf) ? $xmlStyles->cellStyleXfs->xf : [] as $xf) {
+ foreach ($xmlStyles->cellStyleXfs->xf ?? [] as $xf) {
$numFmt = NumberFormat::FORMAT_GENERAL;
if ($numFmts && $xf['numFmtId']) {
$tmpNumFmt = self::getArrayItem($numFmts->xpath("sml:numFmt[@numFmtId=$xf[numFmtId]]"));
@@ -542,6 +541,8 @@ class Xlsx extends BaseReader
}
}
+ $quotePrefix = (bool) ($xf['quotePrefix'] ?? false);
+
$cellStyle = (object) [
'numFmt' => $numFmt,
'font' => $xmlStyles->fonts->font[(int) ($xf['fontId'])],
@@ -720,6 +721,10 @@ class Xlsx extends BaseReader
} 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]);
+ }
}
break;
@@ -735,6 +740,10 @@ class Xlsx extends BaseReader
$cell = $docSheet->getCell($r);
// Assign value
if ($cellDataType != '') {
+ // it is possible, that datatype is numeric but with an empty string, which result in an error
+ if ($cellDataType === DataType::TYPE_NUMERIC && $value === '') {
+ $cellDataType = DataType::TYPE_STRING;
+ }
$cell->setValueExplicit($value, $cellDataType);
} else {
$cell->setValue($value);
@@ -870,10 +879,11 @@ class Xlsx extends BaseReader
// Loop through contents
foreach ($commentsFile->commentList->comment as $comment) {
+ $commentModel = $docSheet->getComment((string) $comment['ref']);
if (!empty($comment['authorId'])) {
- $docSheet->getComment((string) $comment['ref'])->setAuthor($authors[(string) $comment['authorId']]);
+ $commentModel->setAuthor($authors[$comment['authorId']]);
}
- $docSheet->getComment((string) $comment['ref'])->setText($this->parseRichText($comment->text));
+ $commentModel->setText($this->parseRichText($comment->text));
}
}
@@ -1071,6 +1081,7 @@ class Xlsx extends BaseReader
}
if ($xmlSheet->drawing && !$this->readDataOnly) {
$unparsedDrawings = [];
+ $fileDrawing = null;
foreach ($xmlSheet->drawing as $drawing) {
$drawingRelId = (string) self::getArrayItem($drawing->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'), 'id');
$fileDrawing = $drawings[$drawingRelId];
@@ -1123,15 +1134,20 @@ class Xlsx extends BaseReader
$objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$objDrawing->setName((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name'));
$objDrawing->setDescription((string) self::getArrayItem($oneCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'descr'));
- $objDrawing->setPath(
- 'zip://' . File::realpath($pFilename) . '#' .
- $images[(string) self::getArrayItem(
- $blip->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'),
- 'embed'
- )],
- false
+ $imageKey = (string) self::getArrayItem(
+ $blip->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'),
+ 'embed'
);
- $objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((string) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1));
+
+ if (isset($images[$imageKey])) {
+ $objDrawing->setPath(
+ 'zip://' . File::realpath($pFilename) . '#' .
+ $images[$imageKey],
+ false
+ );
+ }
+ $objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((int) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1));
+
$objDrawing->setOffsetX(Drawing::EMUToPixels($oneCellAnchor->from->colOff));
$objDrawing->setOffsetY(Drawing::EMUToPixels($oneCellAnchor->from->rowOff));
$objDrawing->setResizeProportional(false);
@@ -1147,7 +1163,7 @@ class Xlsx extends BaseReader
$shadow->setDistance(Drawing::EMUToPixels(self::getArrayItem($outerShdw->attributes(), 'dist')));
$shadow->setDirection(Drawing::angleToDegrees(self::getArrayItem($outerShdw->attributes(), 'dir')));
$shadow->setAlignment((string) self::getArrayItem($outerShdw->attributes(), 'algn'));
- $clr = isset($outerShdw->srgbClr) ? $outerShdw->srgbClr : $outerShdw->prstClr;
+ $clr = $outerShdw->srgbClr ?? $outerShdw->prstClr;
$shadow->getColor()->setRGB(self::getArrayItem($clr->attributes(), 'val'));
$shadow->setAlpha(self::getArrayItem($clr->alpha->attributes(), 'val') / 1000);
}
@@ -1155,13 +1171,27 @@ class Xlsx extends BaseReader
$this->readHyperLinkDrawing($objDrawing, $oneCellAnchor, $hyperlinks);
$objDrawing->setWorksheet($docSheet);
- } else {
- // ? Can charts be positioned with a oneCellAnchor ?
- $coordinates = Coordinate::stringFromColumnIndex(((string) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1);
+ } elseif ($this->includeCharts && $oneCellAnchor->graphicFrame) {
+ // Exported XLSX from Google Sheets positions charts with a oneCellAnchor
+ $coordinates = Coordinate::stringFromColumnIndex(((int) $oneCellAnchor->from->col) + 1) . ($oneCellAnchor->from->row + 1);
$offsetX = Drawing::EMUToPixels($oneCellAnchor->from->colOff);
$offsetY = Drawing::EMUToPixels($oneCellAnchor->from->rowOff);
$width = Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cx'));
$height = Drawing::EMUToPixels(self::getArrayItem($oneCellAnchor->ext->attributes(), 'cy'));
+
+ $graphic = $oneCellAnchor->graphicFrame->children('http://schemas.openxmlformats.org/drawingml/2006/main')->graphic;
+ /** @var SimpleXMLElement $chartRef */
+ $chartRef = $graphic->graphicData->children('http://schemas.openxmlformats.org/drawingml/2006/chart')->chart;
+ $thisChart = (string) $chartRef->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships');
+
+ $chartDetails[$docSheet->getTitle() . '!' . $thisChart] = [
+ 'fromCoordinate' => $coordinates,
+ 'fromOffsetX' => $offsetX,
+ 'fromOffsetY' => $offsetY,
+ 'width' => $width,
+ 'height' => $height,
+ 'worksheetTitle' => $docSheet->getTitle(),
+ ];
}
}
}
@@ -1175,15 +1205,19 @@ class Xlsx extends BaseReader
$objDrawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing();
$objDrawing->setName((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name'));
$objDrawing->setDescription((string) self::getArrayItem($twoCellAnchor->pic->nvPicPr->cNvPr->attributes(), 'descr'));
- $objDrawing->setPath(
- 'zip://' . File::realpath($pFilename) . '#' .
- $images[(string) self::getArrayItem(
- $blip->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'),
- 'embed'
- )],
- false
+ $imageKey = (string) self::getArrayItem(
+ $blip->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'),
+ 'embed'
);
- $objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1));
+ if (isset($images[$imageKey])) {
+ $objDrawing->setPath(
+ 'zip://' . File::realpath($pFilename) . '#' .
+ $images[$imageKey],
+ false
+ );
+ }
+ $objDrawing->setCoordinates(Coordinate::stringFromColumnIndex(((int) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1));
+
$objDrawing->setOffsetX(Drawing::EMUToPixels($twoCellAnchor->from->colOff));
$objDrawing->setOffsetY(Drawing::EMUToPixels($twoCellAnchor->from->rowOff));
$objDrawing->setResizeProportional(false);
@@ -1200,7 +1234,7 @@ class Xlsx extends BaseReader
$shadow->setDistance(Drawing::EMUToPixels(self::getArrayItem($outerShdw->attributes(), 'dist')));
$shadow->setDirection(Drawing::angleToDegrees(self::getArrayItem($outerShdw->attributes(), 'dir')));
$shadow->setAlignment((string) self::getArrayItem($outerShdw->attributes(), 'algn'));
- $clr = isset($outerShdw->srgbClr) ? $outerShdw->srgbClr : $outerShdw->prstClr;
+ $clr = $outerShdw->srgbClr ?? $outerShdw->prstClr;
$shadow->getColor()->setRGB(self::getArrayItem($clr->attributes(), 'val'));
$shadow->setAlpha(self::getArrayItem($clr->alpha->attributes(), 'val') / 1000);
}
@@ -1209,10 +1243,10 @@ class Xlsx extends BaseReader
$objDrawing->setWorksheet($docSheet);
} elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) {
- $fromCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1);
+ $fromCoordinate = Coordinate::stringFromColumnIndex(((int) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1);
$fromOffsetX = Drawing::EMUToPixels($twoCellAnchor->from->colOff);
$fromOffsetY = Drawing::EMUToPixels($twoCellAnchor->from->rowOff);
- $toCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->to->col) + 1) . ($twoCellAnchor->to->row + 1);
+ $toCoordinate = Coordinate::stringFromColumnIndex(((int) $twoCellAnchor->to->col) + 1) . ($twoCellAnchor->to->row + 1);
$toOffsetX = Drawing::EMUToPixels($twoCellAnchor->to->colOff);
$toOffsetY = Drawing::EMUToPixels($twoCellAnchor->to->rowOff);
$graphic = $twoCellAnchor->graphicFrame->children('http://schemas.openxmlformats.org/drawingml/2006/main')->graphic;
@@ -1508,7 +1542,10 @@ class Xlsx extends BaseReader
$excel->getSheetByName($charts[$chartEntryRef]['sheet'])->addChart($objChart);
$objChart->setWorksheet($excel->getSheetByName($charts[$chartEntryRef]['sheet']));
$objChart->setTopLeftPosition($chartDetails[$chartPositionRef]['fromCoordinate'], $chartDetails[$chartPositionRef]['fromOffsetX'], $chartDetails[$chartPositionRef]['fromOffsetY']);
- $objChart->setBottomRightPosition($chartDetails[$chartPositionRef]['toCoordinate'], $chartDetails[$chartPositionRef]['toOffsetX'], $chartDetails[$chartPositionRef]['toOffsetY']);
+ if (array_key_exists('toCoordinate', $chartDetails[$chartPositionRef])) {
+ // For oneCellAnchor positioned charts, toCoordinate is not in the data. Does it need to be calculated?
+ $objChart->setBottomRightPosition($chartDetails[$chartPositionRef]['toCoordinate'], $chartDetails[$chartPositionRef]['toOffsetX'], $chartDetails[$chartPositionRef]['toOffsetY']);
+ }
}
}
}
@@ -1701,7 +1738,7 @@ class Xlsx extends BaseReader
*
* @return RichText
*/
- private function parseRichText($is)
+ private function parseRichText(?SimpleXMLElement $is)
{
$value = new RichText();
@@ -1709,6 +1746,8 @@ class Xlsx extends BaseReader
$value->createText(StringHelper::controlCharacterOOXML2PHP((string) $is->t));
} else {
if (is_object($is->r)) {
+
+ /** @var SimpleXMLElement $run */
foreach ($is->r as $run) {
if (!isset($run->rPr)) {
$value->createText(StringHelper::controlCharacterOOXML2PHP((string) $run->t));
diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php
index c9a230c2..c9fc2f66 100644
--- a/src/PhpSpreadsheet/Reader/Xlsx/Chart.php
+++ b/src/PhpSpreadsheet/Reader/Xlsx/Chart.php
@@ -61,7 +61,7 @@ class Chart
$XaxisLabel = $YaxisLabel = $legend = $title = null;
$dispBlanksAs = $plotVisOnly = null;
-
+ $plotArea = null;
foreach ($chartElementsC as $chartElementKey => $chartElement) {
switch ($chartElementKey) {
case 'chart':
@@ -90,8 +90,22 @@ class Chart
break;
case 'valAx':
- if (isset($chartDetail->title)) {
- $YaxisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta);
+ if (isset($chartDetail->title, $chartDetail->axPos)) {
+ $axisLabel = self::chartTitle($chartDetail->title->children($namespacesChartMeta['c']), $namespacesChartMeta);
+ $axPos = self::getAttribute($chartDetail->axPos, 'val', 'string');
+
+ switch ($axPos) {
+ case 't':
+ case 'b':
+ $XaxisLabel = $axisLabel;
+
+ break;
+ case 'r':
+ case 'l':
+ $YaxisLabel = $axisLabel;
+
+ break;
+ }
}
break;
@@ -328,26 +342,51 @@ class Chart
{
if (isset($seriesDetail->strRef)) {
$seriesSource = (string) $seriesDetail->strRef->f;
- $seriesData = self::chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's');
+ $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker);
- return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
+ if (isset($seriesDetail->strRef->strCache)) {
+ $seriesData = self::chartDataSeriesValues($seriesDetail->strRef->strCache->children($namespacesChartMeta['c']), 's');
+ $seriesValues
+ ->setFormatCode($seriesData['formatCode'])
+ ->setDataValues($seriesData['dataValues']);
+ }
+
+ return $seriesValues;
} elseif (isset($seriesDetail->numRef)) {
$seriesSource = (string) $seriesDetail->numRef->f;
- $seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c']));
+ $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, null, null, null, $marker);
+ if (isset($seriesDetail->numRef->numCache)) {
+ $seriesData = self::chartDataSeriesValues($seriesDetail->numRef->numCache->children($namespacesChartMeta['c']));
+ $seriesValues
+ ->setFormatCode($seriesData['formatCode'])
+ ->setDataValues($seriesData['dataValues']);
+ }
- return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
+ return $seriesValues;
} elseif (isset($seriesDetail->multiLvlStrRef)) {
$seriesSource = (string) $seriesDetail->multiLvlStrRef->f;
- $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's');
- $seriesData['pointCount'] = count($seriesData['dataValues']);
+ $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker);
- return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
+ if (isset($seriesDetail->multiLvlStrRef->multiLvlStrCache)) {
+ $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlStrRef->multiLvlStrCache->children($namespacesChartMeta['c']), 's');
+ $seriesValues
+ ->setFormatCode($seriesData['formatCode'])
+ ->setDataValues($seriesData['dataValues']);
+ }
+
+ return $seriesValues;
} elseif (isset($seriesDetail->multiLvlNumRef)) {
$seriesSource = (string) $seriesDetail->multiLvlNumRef->f;
- $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's');
- $seriesData['pointCount'] = count($seriesData['dataValues']);
+ $seriesValues = new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, null, null, null, $marker);
- return new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, $seriesSource, $seriesData['formatCode'], $seriesData['pointCount'], $seriesData['dataValues'], $marker);
+ if (isset($seriesDetail->multiLvlNumRef->multiLvlNumCache)) {
+ $seriesData = self::chartDataSeriesValuesMultiLevel($seriesDetail->multiLvlNumRef->multiLvlNumCache->children($namespacesChartMeta['c']), 's');
+ $seriesValues
+ ->setFormatCode($seriesData['formatCode'])
+ ->setDataValues($seriesData['dataValues']);
+ }
+
+ return $seriesValues;
}
return null;
@@ -500,7 +539,7 @@ class Chart
{
$plotAttributes = [];
if (isset($chartDetail->dLbls)) {
- if (isset($chartDetail->dLbls->howLegendKey)) {
+ if (isset($chartDetail->dLbls->showLegendKey)) {
$plotAttributes['showLegendKey'] = self::getAttribute($chartDetail->dLbls->showLegendKey, 'val', 'string');
}
if (isset($chartDetail->dLbls->showVal)) {
diff --git a/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php b/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
index 4aa48e17..7f96956f 100644
--- a/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
+++ b/src/PhpSpreadsheet/Reader/Xlsx/ConditionalStyles.php
@@ -2,7 +2,11 @@
namespace PhpOffice\PhpSpreadsheet\Reader\Xlsx;
+use PhpOffice\PhpSpreadsheet\Style\Color;
use PhpOffice\PhpSpreadsheet\Style\Conditional;
+use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar;
+use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension;
+use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormatValueObject;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use SimpleXMLElement;
@@ -25,7 +29,8 @@ class ConditionalStyles
{
$this->setConditionalStyles(
$this->worksheet,
- $this->readConditionalStyles($this->worksheetXml)
+ $this->readConditionalStyles($this->worksheetXml),
+ $this->worksheetXml->extLst
);
}
@@ -36,14 +41,16 @@ class ConditionalStyles
foreach ($conditional->cfRule as $cfRule) {
if (
((string) $cfRule['type'] == Conditional::CONDITION_NONE
- || (string) $cfRule['type'] == Conditional::CONDITION_CELLIS
- || (string) $cfRule['type'] == Conditional::CONDITION_CONTAINSTEXT
- || (string) $cfRule['type'] == Conditional::CONDITION_CONTAINSBLANKS
- || (string) $cfRule['type'] == Conditional::CONDITION_NOTCONTAINSBLANKS
- || (string) $cfRule['type'] == Conditional::CONDITION_EXPRESSION)
+ || (string) $cfRule['type'] == Conditional::CONDITION_CELLIS
+ || (string) $cfRule['type'] == Conditional::CONDITION_CONTAINSTEXT
+ || (string) $cfRule['type'] == Conditional::CONDITION_CONTAINSBLANKS
+ || (string) $cfRule['type'] == Conditional::CONDITION_NOTCONTAINSBLANKS
+ || (string) $cfRule['type'] == Conditional::CONDITION_EXPRESSION)
&& isset($this->dxfs[(int) ($cfRule['dxfId'])])
) {
$conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
+ } elseif ((string) $cfRule['type'] == Conditional::CONDITION_DATABAR) {
+ $conditionals[(string) $conditional['sqref']][(int) ($cfRule['priority'])] = $cfRule;
}
}
}
@@ -51,11 +58,11 @@ class ConditionalStyles
return $conditionals;
}
- private function setConditionalStyles(Worksheet $worksheet, array $conditionals): void
+ private function setConditionalStyles(Worksheet $worksheet, array $conditionals, $xmlExtLst): void
{
foreach ($conditionals as $ref => $cfRules) {
ksort($cfRules);
- $conditionalStyles = $this->readStyleRules($cfRules);
+ $conditionalStyles = $this->readStyleRules($cfRules, $xmlExtLst);
// Extract all cell references in $ref
$cellBlocks = explode(' ', str_replace('$', '', strtoupper($ref)));
@@ -65,8 +72,9 @@ class ConditionalStyles
}
}
- private function readStyleRules($cfRules)
+ private function readStyleRules($cfRules, $extLst)
{
+ $conditionalFormattingRuleExtensions = ConditionalFormattingRuleExtension::parseExtLstXml($extLst);
$conditionalStyles = [];
foreach ($cfRules as $cfRule) {
$objConditional = new Conditional();
@@ -88,10 +96,61 @@ class ConditionalStyles
} else {
$objConditional->addCondition((string) $cfRule->formula);
}
- $objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]);
+
+ if (isset($cfRule->dataBar)) {
+ $objConditional->setDataBar($this->readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions));
+ } else {
+ $objConditional->setStyle(clone $this->dxfs[(int) ($cfRule['dxfId'])]);
+ }
+
$conditionalStyles[] = $objConditional;
}
return $conditionalStyles;
}
+
+ private function readDataBarOfConditionalRule($cfRule, $conditionalFormattingRuleExtensions): ConditionalDataBar
+ {
+ $dataBar = new ConditionalDataBar();
+ //dataBar attribute
+ if (isset($cfRule->dataBar['showValue'])) {
+ $dataBar->setShowValue((bool) $cfRule->dataBar['showValue']);
+ }
+
+ //dataBar children
+ //conditionalFormatValueObjects
+ $cfvoXml = $cfRule->dataBar->cfvo;
+ $cfvoIndex = 0;
+ foreach ((count($cfvoXml) > 1 ? $cfvoXml : [$cfvoXml]) as $cfvo) {
+ if ($cfvoIndex === 0) {
+ $dataBar->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val']));
+ }
+ if ($cfvoIndex === 1) {
+ $dataBar->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo['type'], (string) $cfvo['val']));
+ }
+ ++$cfvoIndex;
+ }
+
+ //color
+ if (isset($cfRule->dataBar->color)) {
+ $dataBar->setColor((string) $cfRule->dataBar->color['rgb']);
+ }
+ //extLst
+ $this->readDataBarExtLstOfConditionalRule($dataBar, $cfRule, $conditionalFormattingRuleExtensions);
+
+ return $dataBar;
+ }
+
+ private function readDataBarExtLstOfConditionalRule(ConditionalDataBar $dataBar, $cfRule, $conditionalFormattingRuleExtensions): void
+ {
+ if (isset($cfRule->extLst)) {
+ $ns = $cfRule->extLst->getNamespaces(true);
+ foreach ((count($cfRule->extLst) > 0 ? $cfRule->extLst->ext : [$cfRule->extLst->ext]) as $ext) {
+ $extId = (string) $ext->children($ns['x14'])->id;
+ if (isset($conditionalFormattingRuleExtensions[$extId]) && (string) $ext['uri'] === '{B025F937-C7B1-47D3-B67F-A62EFF666E3E}') {
+ $dataBar->setConditionalFormattingRuleExt($conditionalFormattingRuleExtensions[$extId]);
+ }
+ }
+ }
+ }
}
diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php b/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php
index 106fd44e..a9afce38 100644
--- a/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php
+++ b/src/PhpSpreadsheet/Reader/Xlsx/Hyperlinks.php
@@ -29,7 +29,9 @@ class Hyperlinks
public function setHyperlinks(SimpleXMLElement $worksheetXml): void
{
foreach ($worksheetXml->hyperlink as $hyperlink) {
- $this->setHyperlink($hyperlink, $this->worksheet);
+ if ($hyperlink !== null) {
+ $this->setHyperlink($hyperlink, $this->worksheet);
+ }
}
}
diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Styles.php b/src/PhpSpreadsheet/Reader/Xlsx/Styles.php
index 43de8787..290e8cb7 100644
--- a/src/PhpSpreadsheet/Reader/Xlsx/Styles.php
+++ b/src/PhpSpreadsheet/Reader/Xlsx/Styles.php
@@ -143,21 +143,21 @@ class Styles extends BaseParserClass
private static function readAlignmentStyle(Alignment $alignment, SimpleXMLElement $alignmentXml): void
{
- $alignment->setHorizontal((string) $alignmentXml->alignment['horizontal']);
- $alignment->setVertical((string) $alignmentXml->alignment['vertical']);
+ $alignment->setHorizontal((string) $alignmentXml['horizontal']);
+ $alignment->setVertical((string) $alignmentXml['vertical']);
$textRotation = 0;
- if ((int) $alignmentXml->alignment['textRotation'] <= 90) {
- $textRotation = (int) $alignmentXml->alignment['textRotation'];
- } elseif ((int) $alignmentXml->alignment['textRotation'] > 90) {
- $textRotation = 90 - (int) $alignmentXml->alignment['textRotation'];
+ if ((int) $alignmentXml['textRotation'] <= 90) {
+ $textRotation = (int) $alignmentXml['textRotation'];
+ } elseif ((int) $alignmentXml['textRotation'] > 90) {
+ $textRotation = 90 - (int) $alignmentXml['textRotation'];
}
$alignment->setTextRotation((int) $textRotation);
- $alignment->setWrapText(self::boolean((string) $alignmentXml->alignment['wrapText']));
- $alignment->setShrinkToFit(self::boolean((string) $alignmentXml->alignment['shrinkToFit']));
- $alignment->setIndent((int) ((string) $alignmentXml->alignment['indent']) > 0 ? (int) ((string) $alignmentXml->alignment['indent']) : 0);
- $alignment->setReadOrder((int) ((string) $alignmentXml->alignment['readingOrder']) > 0 ? (int) ((string) $alignmentXml->alignment['readingOrder']) : 0);
+ $alignment->setWrapText(self::boolean((string) $alignmentXml['wrapText']));
+ $alignment->setShrinkToFit(self::boolean((string) $alignmentXml['shrinkToFit']));
+ $alignment->setIndent((int) ((string) $alignmentXml['indent']) > 0 ? (int) ((string) $alignmentXml['indent']) : 0);
+ $alignment->setReadOrder((int) ((string) $alignmentXml['readingOrder']) > 0 ? (int) ((string) $alignmentXml['readingOrder']) : 0);
}
private function readStyle(Style $docStyle, $style): void
diff --git a/src/PhpSpreadsheet/Reader/Xlsx/Theme.php b/src/PhpSpreadsheet/Reader/Xlsx/Theme.php
index c105f3c1..1f2b863c 100644
--- a/src/PhpSpreadsheet/Reader/Xlsx/Theme.php
+++ b/src/PhpSpreadsheet/Reader/Xlsx/Theme.php
@@ -21,16 +21,16 @@ class Theme
/**
* Colour Map.
*
- * @var array of string
+ * @var string[]
*/
private $colourMap;
/**
* Create a new Theme.
*
- * @param mixed $themeName
- * @param mixed $colourSchemeName
- * @param mixed $colourMap
+ * @param string $themeName
+ * @param string $colourSchemeName
+ * @param string[] $colourMap
*/
public function __construct($themeName, $colourSchemeName, $colourMap)
{
@@ -63,9 +63,9 @@ class Theme
/**
* Get colour Map Value by Position.
*
- * @param mixed $index
+ * @param int $index
*
- * @return string
+ * @return null|string
*/
public function getColourByIndex($index)
{
diff --git a/src/PhpSpreadsheet/Reader/Xml.php b/src/PhpSpreadsheet/Reader/Xml.php
index 11aa1df3..a900ad9b 100644
--- a/src/PhpSpreadsheet/Reader/Xml.php
+++ b/src/PhpSpreadsheet/Reader/Xml.php
@@ -2,6 +2,8 @@
namespace PhpOffice\PhpSpreadsheet\Reader;
+use DateTime;
+use DateTimeZone;
use PhpOffice\PhpSpreadsheet\Cell\AddressHelper;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
@@ -114,7 +116,7 @@ class Xml extends BaseReader
$signature = [
'',
+ 'xmlns:ss="urn:schemas-microsoft-com:office:spreadsheet',
];
// Open file
@@ -191,7 +193,7 @@ class Xml extends BaseReader
$xml_ss = $xml->children($namespaces['ss']);
foreach ($xml_ss->Worksheet as $worksheet) {
- $worksheet_ss = $worksheet->attributes($namespaces['ss']);
+ $worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']);
$worksheetNames[] = (string) $worksheet_ss['Name'];
}
@@ -221,7 +223,7 @@ class Xml extends BaseReader
$worksheetID = 1;
$xml_ss = $xml->children($namespaces['ss']);
foreach ($xml_ss->Worksheet as $worksheet) {
- $worksheet_ss = $worksheet->attributes($namespaces['ss']);
+ $worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']);
$tmpInfo = [];
$tmpInfo['worksheetName'] = '';
@@ -381,13 +383,13 @@ class Xml extends BaseReader
}
if (isset($xml->CustomDocumentProperties)) {
foreach ($xml->CustomDocumentProperties[0] as $propertyName => $propertyValue) {
- $propertyAttributes = $propertyValue->attributes($namespaces['dt']);
+ $propertyAttributes = self::getAttributes($propertyValue, $namespaces['dt']);
$propertyName = preg_replace_callback('/_x([0-9a-f]{4})_/i', ['self', 'hex2str'], $propertyName);
$propertyType = Properties::PROPERTY_TYPE_UNKNOWN;
switch ((string) $propertyAttributes) {
case 'string':
$propertyType = Properties::PROPERTY_TYPE_STRING;
- $propertyValue = trim($propertyValue);
+ $propertyValue = trim((string) $propertyValue);
break;
case 'boolean':
@@ -407,7 +409,7 @@ class Xml extends BaseReader
break;
case 'dateTime.tz':
$propertyType = Properties::PROPERTY_TYPE_DATE;
- $propertyValue = strtotime(trim($propertyValue));
+ $propertyValue = strtotime(trim((string) $propertyValue));
break;
}
@@ -420,8 +422,10 @@ class Xml extends BaseReader
$worksheetID = 0;
$xml_ss = $xml->children($namespaces['ss']);
- foreach ($xml_ss->Worksheet as $worksheet) {
- $worksheet_ss = $worksheet->attributes($namespaces['ss']);
+ /** @var null|SimpleXMLElement $worksheetx */
+ foreach ($xml_ss->Worksheet as $worksheetx) {
+ $worksheet = $worksheetx ?? new SimpleXMLElement('');
+ $worksheet_ss = self::getAttributes($worksheet, $namespaces['ss']);
if (
(isset($this->loadSheetsOnly)) && (isset($worksheet_ss['Name'])) &&
@@ -433,6 +437,7 @@ class Xml extends BaseReader
// Create new Worksheet
$spreadsheet->createSheet();
$spreadsheet->setActiveSheetIndex($worksheetID);
+ $worksheetName = '';
if (isset($worksheet_ss['Name'])) {
$worksheetName = (string) $worksheet_ss['Name'];
// Use false for $updateFormulaCellReferences to prevent adjustment of worksheet references in
@@ -444,7 +449,7 @@ class Xml extends BaseReader
// locally scoped defined names
if (isset($worksheet->Names[0])) {
foreach ($worksheet->Names[0] as $definedName) {
- $definedName_ss = $definedName->attributes($namespaces['ss']);
+ $definedName_ss = self::getAttributes($definedName, $namespaces['ss']);
$name = (string) $definedName_ss['Name'];
$definedValue = (string) $definedName_ss['RefersTo'];
$convertedValue = AddressHelper::convertFormulaToA1($definedValue);
@@ -458,7 +463,7 @@ class Xml extends BaseReader
$columnID = 'A';
if (isset($worksheet->Table->Column)) {
foreach ($worksheet->Table->Column as $columnData) {
- $columnData_ss = $columnData->attributes($namespaces['ss']);
+ $columnData_ss = self::getAttributes($columnData, $namespaces['ss']);
if (isset($columnData_ss['Index'])) {
$columnID = Coordinate::stringFromColumnIndex((int) $columnData_ss['Index']);
}
@@ -475,14 +480,14 @@ class Xml extends BaseReader
$additionalMergedCells = 0;
foreach ($worksheet->Table->Row as $rowData) {
$rowHasData = false;
- $row_ss = $rowData->attributes($namespaces['ss']);
+ $row_ss = self::getAttributes($rowData, $namespaces['ss']);
if (isset($row_ss['Index'])) {
$rowID = (int) $row_ss['Index'];
}
$columnID = 'A';
foreach ($rowData->Cell as $cell) {
- $cell_ss = $cell->attributes($namespaces['ss']);
+ $cell_ss = self::getAttributes($cell, $namespaces['ss']);
if (isset($cell_ss['Index'])) {
$columnID = Coordinate::stringFromColumnIndex((int) $cell_ss['Index']);
}
@@ -524,7 +529,7 @@ class Xml extends BaseReader
$cellData = $cell->Data;
$cellValue = (string) $cellData;
$type = DataType::TYPE_NULL;
- $cellData_ss = $cellData->attributes($namespaces['ss']);
+ $cellData_ss = self::getAttributes($cellData, $namespaces['ss']);
if (isset($cellData_ss['Type'])) {
$cellDataType = $cellData_ss['Type'];
switch ($cellDataType) {
@@ -556,7 +561,8 @@ class Xml extends BaseReader
break;
case 'DateTime':
$type = DataType::TYPE_NUMERIC;
- $cellValue = Date::PHPToExcel(strtotime($cellValue . ' UTC'));
+ $dateTime = new DateTime($cellValue, new DateTimeZone('UTC'));
+ $cellValue = Date::PHPToExcel($dateTime);
break;
case 'Error':
@@ -587,7 +593,7 @@ class Xml extends BaseReader
$author = (string) $commentAttributes->Author;
}
$node = $cell->Comment->Data->asXML();
- $annotation = strip_tags($node);
+ $annotation = strip_tags((string) $node);
$spreadsheet->getActiveSheet()->getComment($columnID . $rowID)->setAuthor($author)->setText($this->parseRichText($annotation));
}
@@ -610,7 +616,7 @@ class Xml extends BaseReader
if ($rowHasData) {
if (isset($row_ss['Height'])) {
$rowHeight = $row_ss['Height'];
- $spreadsheet->getActiveSheet()->getRowDimension($rowID)->setRowHeight($rowHeight);
+ $spreadsheet->getActiveSheet()->getRowDimension($rowID)->setRowHeight((float) $rowHeight);
}
}
@@ -631,7 +637,7 @@ class Xml extends BaseReader
$activeWorksheet = $spreadsheet->setActiveSheetIndex(0);
if (isset($xml->Names[0])) {
foreach ($xml->Names[0] as $definedName) {
- $definedName_ss = $definedName->attributes($namespaces['ss']);
+ $definedName_ss = self::getAttributes($definedName, $namespaces['ss']);
$name = (string) $definedName_ss['Name'];
$definedValue = (string) $definedName_ss['RefersTo'];
$convertedValue = AddressHelper::convertFormulaToA1($definedValue);
@@ -662,10 +668,11 @@ class Xml extends BaseReader
}
foreach ($xml->Styles[0] as $style) {
- $style_ss = $style->attributes($namespaces['ss']);
+ $style_ss = self::getAttributes($style, $namespaces['ss']);
$styleID = (string) $style_ss['ID'];
- $this->styles[$styleID] = (isset($this->styles['Default'])) ? $this->styles['Default'] : [];
- foreach ($style as $styleType => $styleData) {
+ $this->styles[$styleID] = $this->styles['Default'] ?? [];
+ foreach ($style as $styleType => $styleDatax) {
+ $styleData = $styleDatax ?? new SimpleXMLElement('');
$styleAttributes = $styleData->attributes($namespaces['ss']);
switch ($styleType) {
case 'Alignment':
@@ -742,23 +749,21 @@ class Xml extends BaseReader
private static $borderPositions = ['top', 'left', 'bottom', 'right'];
- /**
- * @param $styleID
- */
private function parseStyleBorders($styleID, SimpleXMLElement $styleData, array $namespaces): void
{
$diagonalDirection = '';
$borderPosition = '';
foreach ($styleData->Border as $borderStyle) {
- $borderAttributes = $borderStyle->attributes($namespaces['ss']);
+ $borderAttributes = self::getAttributes($borderStyle, $namespaces['ss']);
$thisBorder = [];
$style = (string) $borderAttributes->Weight;
$style .= strtolower((string) $borderAttributes->LineStyle);
$thisBorder['borderStyle'] = self::$mappings['borderStyle'][$style] ?? Border::BORDER_NONE;
- foreach ($borderAttributes as $borderStyleKey => $borderStyleValue) {
+ foreach ($borderAttributes as $borderStyleKey => $borderStyleValuex) {
+ $borderStyleValue = (string) $borderStyleValuex;
switch ($borderStyleKey) {
case 'Position':
- $borderStyleValue = strtolower((string) $borderStyleValue);
+ $borderStyleValue = strtolower($borderStyleValue);
if (in_array($borderStyleValue, self::$borderPositions)) {
$borderPosition = $borderStyleValue;
} elseif ($borderStyleValue == 'diagonalleft') {
@@ -784,6 +789,11 @@ class Xml extends BaseReader
}
}
+ private static function getAttributes(?SimpleXMLElement $simple, string $node): SimpleXMLElement
+ {
+ return ($simple === null) ? new SimpleXMLElement('') : ($simple->attributes($node) ?? new SimpleXMLElement(''));
+ }
+
private static $underlineStyles = [
Font::UNDERLINE_NONE,
Font::UNDERLINE_DOUBLE,
@@ -809,9 +819,6 @@ class Xml extends BaseReader
}
}
- /**
- * @param $styleID
- */
private function parseStyleFont(string $styleID, SimpleXMLElement $styleAttributes): void
{
foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
@@ -849,12 +856,10 @@ class Xml extends BaseReader
}
}
- /**
- * @param $styleID
- */
private function parseStyleInterior($styleID, SimpleXMLElement $styleAttributes): void
{
- foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValue) {
+ foreach ($styleAttributes as $styleAttributeKey => $styleAttributeValuex) {
+ $styleAttributeValue = (string) $styleAttributeValuex;
switch ($styleAttributeKey) {
case 'Color':
$this->styles[$styleID]['fill']['endColor']['rgb'] = substr($styleAttributeValue, 1);
@@ -874,9 +879,6 @@ class Xml extends BaseReader
}
}
- /**
- * @param $styleID
- */
private function parseStyleNumberFormat($styleID, SimpleXMLElement $styleAttributes): void
{
$fromFormats = ['\-', '\ '];
diff --git a/src/PhpSpreadsheet/ReferenceHelper.php b/src/PhpSpreadsheet/ReferenceHelper.php
index 13f7cf71..d4fced37 100644
--- a/src/PhpSpreadsheet/ReferenceHelper.php
+++ b/src/PhpSpreadsheet/ReferenceHelper.php
@@ -375,17 +375,16 @@ class ReferenceHelper
$allCoordinates = $pSheet->getCoordinates();
// Get coordinate of $pBefore
- [$beforeColumn, $beforeRow] = Coordinate::coordinateFromString($pBefore);
- $beforeColumnIndex = Coordinate::columnIndexFromString($beforeColumn);
+ [$beforeColumn, $beforeRow] = Coordinate::indexesFromString($pBefore);
// Clear cells if we are removing columns or rows
$highestColumn = $pSheet->getHighestColumn();
$highestRow = $pSheet->getHighestRow();
// 1. Clear column strips if we are removing columns
- if ($pNumCols < 0 && $beforeColumnIndex - 2 + $pNumCols > 0) {
+ if ($pNumCols < 0 && $beforeColumn - 2 + $pNumCols > 0) {
for ($i = 1; $i <= $highestRow - 1; ++$i) {
- for ($j = $beforeColumnIndex - 1 + $pNumCols; $j <= $beforeColumnIndex - 2; ++$j) {
+ for ($j = $beforeColumn - 1 + $pNumCols; $j <= $beforeColumn - 2; ++$j) {
$coordinate = Coordinate::stringFromColumnIndex($j + 1) . $i;
$pSheet->removeConditionalStyles($coordinate);
if ($pSheet->cellExists($coordinate)) {
@@ -398,7 +397,7 @@ class ReferenceHelper
// 2. Clear row strips if we are removing rows
if ($pNumRows < 0 && $beforeRow - 1 + $pNumRows > 0) {
- for ($i = $beforeColumnIndex - 1; $i <= Coordinate::columnIndexFromString($highestColumn) - 1; ++$i) {
+ for ($i = $beforeColumn - 1; $i <= Coordinate::columnIndexFromString($highestColumn) - 1; ++$i) {
for ($j = $beforeRow + $pNumRows; $j <= $beforeRow - 1; ++$j) {
$coordinate = Coordinate::stringFromColumnIndex($i + 1) . $j;
$pSheet->removeConditionalStyles($coordinate);
@@ -427,7 +426,7 @@ class ReferenceHelper
$newCoordinate = Coordinate::stringFromColumnIndex($cellIndex + $pNumCols) . ($cell->getRow() + $pNumRows);
// Should the cell be updated? Move value and cellXf index from one cell to another.
- if (($cellIndex >= $beforeColumnIndex) && ($cell->getRow() >= $beforeRow)) {
+ if (($cellIndex >= $beforeColumn) && ($cell->getRow() >= $beforeRow)) {
// Update cell styles
$pSheet->getCell($newCoordinate)->setXfIndex($cell->getXfIndex());
@@ -457,15 +456,15 @@ class ReferenceHelper
$highestColumn = $pSheet->getHighestColumn();
$highestRow = $pSheet->getHighestRow();
- if ($pNumCols > 0 && $beforeColumnIndex - 2 > 0) {
+ if ($pNumCols > 0 && $beforeColumn - 2 > 0) {
for ($i = $beforeRow; $i <= $highestRow - 1; ++$i) {
// Style
- $coordinate = Coordinate::stringFromColumnIndex($beforeColumnIndex - 1) . $i;
+ $coordinate = Coordinate::stringFromColumnIndex($beforeColumn - 1) . $i;
if ($pSheet->cellExists($coordinate)) {
$xfIndex = $pSheet->getCell($coordinate)->getXfIndex();
$conditionalStyles = $pSheet->conditionalStylesExists($coordinate) ?
$pSheet->getConditionalStyles($coordinate) : false;
- for ($j = $beforeColumnIndex; $j <= $beforeColumnIndex - 1 + $pNumCols; ++$j) {
+ for ($j = $beforeColumn; $j <= $beforeColumn - 1 + $pNumCols; ++$j) {
$pSheet->getCellByColumnAndRow($j, $i)->setXfIndex($xfIndex);
if ($conditionalStyles) {
$cloned = [];
@@ -480,7 +479,7 @@ class ReferenceHelper
}
if ($pNumRows > 0 && $beforeRow - 1 > 0) {
- for ($i = $beforeColumnIndex; $i <= Coordinate::columnIndexFromString($highestColumn); ++$i) {
+ for ($i = $beforeColumn; $i <= Coordinate::columnIndexFromString($highestColumn); ++$i) {
// Style
$coordinate = Coordinate::stringFromColumnIndex($i) . ($beforeRow - 1);
if ($pSheet->cellExists($coordinate)) {
@@ -502,28 +501,28 @@ class ReferenceHelper
}
// Update worksheet: column dimensions
- $this->adjustColumnDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
+ $this->adjustColumnDimensions($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: row dimensions
- $this->adjustRowDimensions($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
+ $this->adjustRowDimensions($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: page breaks
- $this->adjustPageBreaks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
+ $this->adjustPageBreaks($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: comments
- $this->adjustComments($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
+ $this->adjustComments($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: hyperlinks
- $this->adjustHyperlinks($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
+ $this->adjustHyperlinks($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: data validations
- $this->adjustDataValidations($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
+ $this->adjustDataValidations($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: merge cells
- $this->adjustMergeCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
+ $this->adjustMergeCells($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: protected cells
- $this->adjustProtectedCells($pSheet, $pBefore, $beforeColumnIndex, $pNumCols, $beforeRow, $pNumRows);
+ $this->adjustProtectedCells($pSheet, $pBefore, $beforeColumn, $pNumCols, $beforeRow, $pNumRows);
// Update worksheet: autofilter
$autoFilter = $pSheet->getAutoFilter();
@@ -608,7 +607,7 @@ class ReferenceHelper
// Update workbook: define names
if (count($pSheet->getParent()->getDefinedNames()) > 0) {
foreach ($pSheet->getParent()->getDefinedNames() as $definedName) {
- if ($definedName->getWorksheet()->getHashCode() === $pSheet->getHashCode()) {
+ if ($definedName->getWorksheet() !== null && $definedName->getWorksheet()->getHashCode() === $pSheet->getHashCode()) {
$definedName->setValue($this->updateCellReference($definedName->getValue(), $pBefore, $pNumCols, $pNumRows));
}
}
@@ -654,7 +653,7 @@ class ReferenceHelper
$toString .= $modified3 . ':' . $modified4;
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
$column = 100000;
- $row = 10000000 + trim($match[3], '$');
+ $row = 10000000 + (int) trim($match[3], '$');
$cellIndex = $column . $row;
$newCellTokens[$cellIndex] = preg_quote($toString, '/');
@@ -705,7 +704,7 @@ class ReferenceHelper
[$column, $row] = Coordinate::coordinateFromString($match[3]);
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
$column = Coordinate::columnIndexFromString(trim($column, '$')) + 100000;
- $row = trim($row, '$') + 10000000;
+ $row = (int) trim($row, '$') + 10000000;
$cellIndex = $column . $row;
$newCellTokens[$cellIndex] = preg_quote($toString, '/');
@@ -731,7 +730,7 @@ class ReferenceHelper
[$column, $row] = Coordinate::coordinateFromString($match[3]);
// Max worksheet size is 1,048,576 rows by 16,384 columns in Excel 2007, so our adjustments need to be at least one digit more
$column = Coordinate::columnIndexFromString(trim($column, '$')) + 100000;
- $row = trim($row, '$') + 10000000;
+ $row = (int) trim($row, '$') + 10000000;
$cellIndex = $row . $column;
$newCellTokens[$cellIndex] = preg_quote($toString, '/');
@@ -1021,7 +1020,7 @@ class ReferenceHelper
// Create new row reference
if ($updateRow) {
- $newRow = $newRow + $pNumRows;
+ $newRow = (int) $newRow + $pNumRows;
}
// Return new reference
diff --git a/src/PhpSpreadsheet/RichText/ITextElement.php b/src/PhpSpreadsheet/RichText/ITextElement.php
index 69954676..39b70c86 100644
--- a/src/PhpSpreadsheet/RichText/ITextElement.php
+++ b/src/PhpSpreadsheet/RichText/ITextElement.php
@@ -14,7 +14,7 @@ interface ITextElement
/**
* Set text.
*
- * @param $text string Text
+ * @param string $text Text
*
* @return ITextElement
*/
diff --git a/src/PhpSpreadsheet/RichText/TextElement.php b/src/PhpSpreadsheet/RichText/TextElement.php
index f8be5d55..26aebc0e 100644
--- a/src/PhpSpreadsheet/RichText/TextElement.php
+++ b/src/PhpSpreadsheet/RichText/TextElement.php
@@ -35,7 +35,7 @@ class TextElement implements ITextElement
/**
* Set text.
*
- * @param $text string Text
+ * @param string $text Text
*
* @return $this
*/
diff --git a/src/PhpSpreadsheet/Settings.php b/src/PhpSpreadsheet/Settings.php
index cfa50573..8fdccbad 100644
--- a/src/PhpSpreadsheet/Settings.php
+++ b/src/PhpSpreadsheet/Settings.php
@@ -118,7 +118,7 @@ class Settings
if (self::$libXmlLoaderOptions === null && defined('LIBXML_DTDLOAD')) {
self::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR);
} elseif (self::$libXmlLoaderOptions === null) {
- self::$libXmlLoaderOptions = true;
+ self::$libXmlLoaderOptions = 0;
}
return self::$libXmlLoaderOptions;
diff --git a/src/PhpSpreadsheet/Shared/Date.php b/src/PhpSpreadsheet/Shared/Date.php
index 180a7159..898dd523 100644
--- a/src/PhpSpreadsheet/Shared/Date.php
+++ b/src/PhpSpreadsheet/Shared/Date.php
@@ -2,9 +2,10 @@
namespace PhpOffice\PhpSpreadsheet\Shared;
+use DateTime;
use DateTimeInterface;
use DateTimeZone;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
@@ -154,26 +155,26 @@ class Date
* if you don't want to treat it as a UTC value
* Use the default (UST) unless you absolutely need a conversion
*
- * @return \DateTime PHP date/time object
+ * @return DateTime PHP date/time object
*/
public static function excelToDateTimeObject($excelTimestamp, $timeZone = null)
{
$timeZone = ($timeZone === null) ? self::getDefaultTimezone() : self::validateTimeZone($timeZone);
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_EXCEL) {
- if ($excelTimestamp < 1.0) {
+ if ($excelTimestamp < 1 && self::$excelCalendar === self::CALENDAR_WINDOWS_1900) {
// Unix timestamp base date
- $baseDate = new \DateTime('1970-01-01', $timeZone);
+ $baseDate = new DateTime('1970-01-01', $timeZone);
} else {
// 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);
+ $baseDate = new DateTime('1904-01-01', $timeZone);
}
}
} else {
- $baseDate = new \DateTime('1899-12-30', $timeZone);
+ $baseDate = new DateTime('1899-12-30', $timeZone);
}
$days = floor($excelTimestamp);
@@ -254,7 +255,7 @@ class Date
*
* @param int $dateValue Unix Timestamp
*
- * @return float MS Excel serialized date/time value
+ * @return false|float MS Excel serialized date/time value
*/
public static function timestampToExcel($dateValue)
{
@@ -262,7 +263,7 @@ class Date
return false;
}
- return self::dateTimeToExcel(new \DateTime('@' . $dateValue));
+ return self::dateTimeToExcel(new DateTime('@' . $dateValue));
}
/**
@@ -303,8 +304,8 @@ class Date
}
// Calculate the Julian Date, then subtract the Excel base date (JD 2415020 = 31-Dec-1899 Giving Excel Date of 0)
- $century = substr($year, 0, 2);
- $decade = substr($year, 2, 2);
+ $century = (int) substr($year, 0, 2);
+ $decade = (int) substr($year, 2, 2);
$excelDate = floor((146097 * $century) / 4) + floor((1461 * $decade) / 4) + floor((153 * $month + 2) / 5) + $day + 1721119 - $myexcelBaseDate + $excel1900isLeapYear;
$excelTime = (($hours * 3600) + ($minutes * 60) + $seconds) / 86400;
@@ -436,14 +437,14 @@ class Date
return false;
}
- $dateValueNew = DateTime::DATEVALUE($dateValue);
+ $dateValueNew = DateTimeExcel\DateValue::funcDateValue($dateValue);
if ($dateValueNew === Functions::VALUE()) {
return false;
}
if (strpos($dateValue, ':') !== false) {
- $timeValue = DateTime::TIMEVALUE($dateValue);
+ $timeValue = DateTimeExcel\TimeValue::funcTimeValue($dateValue);
if ($timeValue === Functions::VALUE()) {
return false;
}
diff --git a/src/PhpSpreadsheet/Shared/Drawing.php b/src/PhpSpreadsheet/Shared/Drawing.php
index f41fb695..ebb87ed1 100644
--- a/src/PhpSpreadsheet/Shared/Drawing.php
+++ b/src/PhpSpreadsheet/Shared/Drawing.php
@@ -15,7 +15,7 @@ class Drawing
*/
public static function pixelsToEMU($pValue)
{
- return round($pValue * 9525);
+ return $pValue * 9525;
}
/**
@@ -28,7 +28,7 @@ class Drawing
public static function EMUToPixels($pValue)
{
if ($pValue != 0) {
- return round($pValue / 9525);
+ return (int) round($pValue / 9525);
}
return 0;
@@ -141,7 +141,7 @@ class Drawing
public static function angleToDegrees($pValue)
{
if ($pValue != 0) {
- return round($pValue / 60000);
+ return (int) round($pValue / 60000);
}
return 0;
@@ -171,6 +171,8 @@ class Drawing
// Process the header
// Structure: http://www.fastgraph.com/help/bmp_header_format.html
+ $width = 0;
+ $height = 0;
if (substr($header, 0, 4) == '424d') {
// Cut it in parts of 2 bytes
$header_parts = str_split($header, 2);
diff --git a/src/PhpSpreadsheet/Shared/File.php b/src/PhpSpreadsheet/Shared/File.php
index 7525df8a..7991ed45 100644
--- a/src/PhpSpreadsheet/Shared/File.php
+++ b/src/PhpSpreadsheet/Shared/File.php
@@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheet\Shared;
use InvalidArgumentException;
+use PhpOffice\PhpSpreadsheet\Exception;
use ZipArchive;
class File
@@ -124,6 +125,16 @@ class File
return realpath(sys_get_temp_dir());
}
+ public static function temporaryFilename(): string
+ {
+ $filename = tempnam(self::sysGetTempDir(), 'phpspreadsheet');
+ if ($filename === false) {
+ throw new Exception('Could not create temporary file');
+ }
+
+ return $filename;
+ }
+
/**
* Assert that given path is an existing file and is readable, otherwise throw exception.
*
diff --git a/src/PhpSpreadsheet/Shared/Font.php b/src/PhpSpreadsheet/Shared/Font.php
index ee1f8aba..00629e69 100644
--- a/src/PhpSpreadsheet/Shared/Font.php
+++ b/src/PhpSpreadsheet/Shared/Font.php
@@ -4,6 +4,7 @@ namespace PhpOffice\PhpSpreadsheet\Shared;
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
+use PhpOffice\PhpSpreadsheet\Style\Alignment;
class Font
{
@@ -231,7 +232,7 @@ class Font
}
// Special case if there are one or more newline characters ("\n")
- if (strpos($cellText, "\n") !== false) {
+ if (strpos($cellText ?? '', "\n") !== false) {
$lineTexts = explode("\n", $cellText);
$lineWidths = [];
foreach ($lineTexts as $lineText) {
@@ -243,6 +244,7 @@ class Font
// Try to get the exact text width in pixels
$approximate = self::$autoSizeMethod == self::AUTOSIZE_METHOD_APPROX;
+ $columnWidth = 0;
if (!$approximate) {
$columnWidthAdjust = ceil(self::getTextWidthPixelsExact('n', $font, 0) * 1.07);
@@ -266,19 +268,13 @@ class Font
$columnWidth = Drawing::pixelsToCellDimension($columnWidth, $defaultFont);
// Return
- return round($columnWidth, 6);
+ return (int) round($columnWidth, 6);
}
/**
* Get GD text width in pixels for a string of text in a certain font at a certain rotation angle.
- *
- * @param string $text
- * @param \PhpOffice\PhpSpreadsheet\Style\Font
- * @param int $rotation
- *
- * @return int
*/
- public static function getTextWidthPixelsExact($text, \PhpOffice\PhpSpreadsheet\Style\Font $font, $rotation = 0)
+ public static function getTextWidthPixelsExact(string $text, \PhpOffice\PhpSpreadsheet\Style\Font $font, int $rotation = 0): int
{
if (!function_exists('imagettfbbox')) {
throw new PhpSpreadsheetException('GD library needs to be enabled');
@@ -342,13 +338,13 @@ class Font
// Calculate approximate rotated column width
if ($rotation !== 0) {
- if ($rotation == -165) {
+ if ($rotation == Alignment::TEXTROTATION_STACK_PHPSPREADSHEET) {
// stacked text
$columnWidth = 4; // approximation
} else {
// rotated text
$columnWidth = $columnWidth * cos(deg2rad($rotation))
- + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation
+ + $fontSize * abs(sin(deg2rad($rotation))) / 5; // approximation
}
}
@@ -413,35 +409,35 @@ class Font
switch ($name) {
case 'Arial':
$fontFile = (
- $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD)
- : ($italic ? self::ARIAL_ITALIC : self::ARIAL)
+ $bold ? ($italic ? self::ARIAL_BOLD_ITALIC : self::ARIAL_BOLD)
+ : ($italic ? self::ARIAL_ITALIC : self::ARIAL)
);
break;
case 'Calibri':
$fontFile = (
- $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD)
- : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI)
+ $bold ? ($italic ? self::CALIBRI_BOLD_ITALIC : self::CALIBRI_BOLD)
+ : ($italic ? self::CALIBRI_ITALIC : self::CALIBRI)
);
break;
case 'Courier New':
$fontFile = (
- $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD)
- : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW)
+ $bold ? ($italic ? self::COURIER_NEW_BOLD_ITALIC : self::COURIER_NEW_BOLD)
+ : ($italic ? self::COURIER_NEW_ITALIC : self::COURIER_NEW)
);
break;
case 'Comic Sans MS':
$fontFile = (
- $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS
+ $bold ? self::COMIC_SANS_MS_BOLD : self::COMIC_SANS_MS
);
break;
case 'Georgia':
$fontFile = (
- $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD)
- : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA)
+ $bold ? ($italic ? self::GEORGIA_BOLD_ITALIC : self::GEORGIA_BOLD)
+ : ($italic ? self::GEORGIA_ITALIC : self::GEORGIA)
);
break;
@@ -451,8 +447,8 @@ class Font
break;
case 'Liberation Sans':
$fontFile = (
- $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD)
- : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS)
+ $bold ? ($italic ? self::LIBERATION_SANS_BOLD_ITALIC : self::LIBERATION_SANS_BOLD)
+ : ($italic ? self::LIBERATION_SANS_ITALIC : self::LIBERATION_SANS)
);
break;
@@ -470,8 +466,8 @@ class Font
break;
case 'Palatino Linotype':
$fontFile = (
- $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD)
- : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE)
+ $bold ? ($italic ? self::PALATINO_LINOTYPE_BOLD_ITALIC : self::PALATINO_LINOTYPE_BOLD)
+ : ($italic ? self::PALATINO_LINOTYPE_ITALIC : self::PALATINO_LINOTYPE)
);
break;
@@ -481,28 +477,28 @@ class Font
break;
case 'Tahoma':
$fontFile = (
- $bold ? self::TAHOMA_BOLD : self::TAHOMA
+ $bold ? self::TAHOMA_BOLD : self::TAHOMA
);
break;
case 'Times New Roman':
$fontFile = (
- $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD)
- : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN)
+ $bold ? ($italic ? self::TIMES_NEW_ROMAN_BOLD_ITALIC : self::TIMES_NEW_ROMAN_BOLD)
+ : ($italic ? self::TIMES_NEW_ROMAN_ITALIC : self::TIMES_NEW_ROMAN)
);
break;
case 'Trebuchet MS':
$fontFile = (
- $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD)
- : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS)
+ $bold ? ($italic ? self::TREBUCHET_MS_BOLD_ITALIC : self::TREBUCHET_MS_BOLD)
+ : ($italic ? self::TREBUCHET_MS_ITALIC : self::TREBUCHET_MS)
);
break;
case 'Verdana':
$fontFile = (
- $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD)
- : ($italic ? self::VERDANA_ITALIC : self::VERDANA)
+ $bold ? ($italic ? self::VERDANA_BOLD_ITALIC : self::VERDANA_BOLD)
+ : ($italic ? self::VERDANA_ITALIC : self::VERDANA)
);
break;
@@ -561,13 +557,13 @@ class Font
// Exact width can be determined
$columnWidth = $pPixels ?
self::$defaultColumnWidths[$font->getName()][$font->getSize()]['px']
- : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width'];
+ : self::$defaultColumnWidths[$font->getName()][$font->getSize()]['width'];
} else {
// We don't have data for this particular font and size, use approximation by
// extrapolating from Calibri 11
$columnWidth = $pPixels ?
self::$defaultColumnWidths['Calibri'][11]['px']
- : self::$defaultColumnWidths['Calibri'][11]['width'];
+ : self::$defaultColumnWidths['Calibri'][11]['width'];
$columnWidth = $columnWidth * $font->getSize() / 11;
// Round pixels to closest integer
diff --git a/src/PhpSpreadsheet/Shared/JAMA/CholeskyDecomposition.php b/src/PhpSpreadsheet/Shared/JAMA/CholeskyDecomposition.php
index 2b241d55..27d02176 100644
--- a/src/PhpSpreadsheet/Shared/JAMA/CholeskyDecomposition.php
+++ b/src/PhpSpreadsheet/Shared/JAMA/CholeskyDecomposition.php
@@ -103,7 +103,7 @@ class CholeskyDecomposition
/**
* Solve A*X = B.
*
- * @param $B Row-equal matrix
+ * @param Matrix $B Row-equal matrix
*
* @return Matrix L * L' * X = B
*/
@@ -111,7 +111,7 @@ class CholeskyDecomposition
{
if ($B->getRowDimension() == $this->m) {
if ($this->isspd) {
- $X = $B->getArrayCopy();
+ $X = $B->getArray();
$nx = $B->getColumnDimension();
for ($k = 0; $k < $this->m; ++$k) {
diff --git a/src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php b/src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php
index 4c67c3a9..5c6ccfd3 100644
--- a/src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php
+++ b/src/PhpSpreadsheet/Shared/JAMA/EigenvalueDecomposition.php
@@ -18,9 +18,9 @@ namespace PhpOffice\PhpSpreadsheet\Shared\JAMA;
* conditioned, or even singular, so the validity of the equation
* A = V*D*inverse(V) depends upon V.cond().
*
- * @author Paul Meagher
+ * @author Paul Meagher
*
- * @version 1.1
+ * @version 1.1
*/
class EigenvalueDecomposition
{
@@ -70,6 +70,11 @@ class EigenvalueDecomposition
private $cdivi;
+ /**
+ * @var array
+ */
+ private $A;
+
/**
* Symmetric Householder reduction to tridiagonal form.
*/
@@ -80,6 +85,7 @@ class EigenvalueDecomposition
// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding
// Fortran subroutine in EISPACK.
$this->d = $this->V[$this->n - 1];
+ $j = 0;
// Householder reduction to tridiagonal form.
for ($i = $this->n - 1; $i > 0; --$i) {
$i_ = $i - 1;
@@ -781,9 +787,9 @@ class EigenvalueDecomposition
/**
* Constructor: Check for symmetry, then construct the eigenvalue decomposition.
*
- * @param mixed $Arg A Square matrix
+ * @param Matrix $Arg A Square matrix
*/
- public function __construct($Arg)
+ public function __construct(Matrix $Arg)
{
$this->A = $Arg->getArray();
$this->n = $Arg->getColumnDimension();
@@ -848,6 +854,7 @@ class EigenvalueDecomposition
*/
public function getD()
{
+ $D = [];
for ($i = 0; $i < $this->n; ++$i) {
$D[$i] = array_fill(0, $this->n, 0.0);
$D[$i][$i] = $this->d[$i];
diff --git a/src/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php b/src/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php
index 4aecff73..ecfe42ba 100644
--- a/src/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php
+++ b/src/PhpSpreadsheet/Shared/JAMA/LUDecomposition.php
@@ -135,6 +135,7 @@ class LUDecomposition
*/
public function getL()
{
+ $L = [];
for ($i = 0; $i < $this->m; ++$i) {
for ($j = 0; $j < $this->n; ++$j) {
if ($i > $j) {
@@ -159,6 +160,7 @@ class LUDecomposition
*/
public function getU()
{
+ $U = [];
for ($i = 0; $i < $this->n; ++$i) {
for ($j = 0; $j < $this->n; ++$j) {
if ($i <= $j) {
@@ -219,7 +221,7 @@ class LUDecomposition
/**
* Count determinants.
*
- * @return array d matrix deterninat
+ * @return float
*/
public function det()
{
@@ -240,11 +242,11 @@ class LUDecomposition
/**
* Solve A*X = B.
*
- * @param mixed $B a Matrix with as many rows as A and any number of columns
+ * @param Matrix $B a Matrix with as many rows as A and any number of columns
*
* @return Matrix X so that L*U*X = B(piv,:)
*/
- public function solve($B)
+ public function solve(Matrix $B)
{
if ($B->getRowDimension() == $this->m) {
if ($this->isNonsingular()) {
diff --git a/src/PhpSpreadsheet/Shared/JAMA/Matrix.php b/src/PhpSpreadsheet/Shared/JAMA/Matrix.php
index a5cb6de0..adf399ac 100644
--- a/src/PhpSpreadsheet/Shared/JAMA/Matrix.php
+++ b/src/PhpSpreadsheet/Shared/JAMA/Matrix.php
@@ -147,7 +147,7 @@ class Matrix
* @param int $i Row position
* @param int $j Column position
*
- * @return mixed Element (int/float/double)
+ * @return float|int
*/
public function get($i = null, $j = null)
{
@@ -323,11 +323,9 @@ class Matrix
*
* @param int $i Row position
* @param int $j Column position
- * @param mixed $c Int/float/double value
- *
- * @return mixed Element (int/float/double)
+ * @param float|int $c value
*/
- public function set($i = null, $j = null, $c = null)
+ public function set($i = null, $j = null, $c = null): void
{
// Optimized set version just has this
$this->A[$i][$j] = $c;
@@ -456,17 +454,6 @@ class Matrix
return $s;
}
- /**
- * uminus.
- *
- * Unary minus matrix -A
- *
- * @return Matrix Unary minus matrix
- */
- public function uminus()
- {
- }
-
/**
* plus.
*
@@ -1164,7 +1151,7 @@ class Matrix
*
* @return Matrix ... Solution if A is square, least squares solution otherwise
*/
- public function solve($B)
+ public function solve(self $B)
{
if ($this->m == $this->n) {
$LU = new LUDecomposition($this);
diff --git a/src/PhpSpreadsheet/Shared/JAMA/QRDecomposition.php b/src/PhpSpreadsheet/Shared/JAMA/QRDecomposition.php
index 3bb8a10e..9b51f413 100644
--- a/src/PhpSpreadsheet/Shared/JAMA/QRDecomposition.php
+++ b/src/PhpSpreadsheet/Shared/JAMA/QRDecomposition.php
@@ -15,9 +15,9 @@ use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalculationException;
* of simultaneous linear equations. This will fail if isFullRank()
* returns false.
*
- * @author Paul Meagher
+ * @author Paul Meagher
*
- * @version 1.1
+ * @version 1.1
*/
class QRDecomposition
{
@@ -54,47 +54,43 @@ class QRDecomposition
/**
* QR Decomposition computed by Householder reflections.
*
- * @param matrix $A Rectangular matrix
+ * @param Matrix $A Rectangular matrix
*/
- public function __construct($A)
+ public function __construct(Matrix $A)
{
- if ($A instanceof Matrix) {
- // Initialize.
- $this->QR = $A->getArray();
- $this->m = $A->getRowDimension();
- $this->n = $A->getColumnDimension();
- // Main loop.
- for ($k = 0; $k < $this->n; ++$k) {
- // Compute 2-norm of k-th column without under/overflow.
- $nrm = 0.0;
- for ($i = $k; $i < $this->m; ++$i) {
- $nrm = hypo($nrm, $this->QR[$i][$k]);
- }
- if ($nrm != 0.0) {
- // Form k-th Householder vector.
- if ($this->QR[$k][$k] < 0) {
- $nrm = -$nrm;
- }
- for ($i = $k; $i < $this->m; ++$i) {
- $this->QR[$i][$k] /= $nrm;
- }
- $this->QR[$k][$k] += 1.0;
- // Apply transformation to remaining columns.
- for ($j = $k + 1; $j < $this->n; ++$j) {
- $s = 0.0;
- for ($i = $k; $i < $this->m; ++$i) {
- $s += $this->QR[$i][$k] * $this->QR[$i][$j];
- }
- $s = -$s / $this->QR[$k][$k];
- for ($i = $k; $i < $this->m; ++$i) {
- $this->QR[$i][$j] += $s * $this->QR[$i][$k];
- }
- }
- }
- $this->Rdiag[$k] = -$nrm;
+ // Initialize.
+ $this->QR = $A->getArray();
+ $this->m = $A->getRowDimension();
+ $this->n = $A->getColumnDimension();
+ // Main loop.
+ for ($k = 0; $k < $this->n; ++$k) {
+ // Compute 2-norm of k-th column without under/overflow.
+ $nrm = 0.0;
+ for ($i = $k; $i < $this->m; ++$i) {
+ $nrm = hypo($nrm, $this->QR[$i][$k]);
}
- } else {
- throw new CalculationException(Matrix::ARGUMENT_TYPE_EXCEPTION);
+ if ($nrm != 0.0) {
+ // Form k-th Householder vector.
+ if ($this->QR[$k][$k] < 0) {
+ $nrm = -$nrm;
+ }
+ for ($i = $k; $i < $this->m; ++$i) {
+ $this->QR[$i][$k] /= $nrm;
+ }
+ $this->QR[$k][$k] += 1.0;
+ // Apply transformation to remaining columns.
+ for ($j = $k + 1; $j < $this->n; ++$j) {
+ $s = 0.0;
+ for ($i = $k; $i < $this->m; ++$i) {
+ $s += $this->QR[$i][$k] * $this->QR[$i][$j];
+ }
+ $s = -$s / $this->QR[$k][$k];
+ for ($i = $k; $i < $this->m; ++$i) {
+ $this->QR[$i][$j] += $s * $this->QR[$i][$k];
+ }
+ }
+ }
+ $this->Rdiag[$k] = -$nrm;
}
}
@@ -205,13 +201,13 @@ class QRDecomposition
*
* @return Matrix matrix that minimizes the two norm of Q*R*X-B
*/
- public function solve($B)
+ public function solve(Matrix $B)
{
if ($B->getRowDimension() == $this->m) {
if ($this->isFullRank()) {
// Copy right hand side
$nx = $B->getColumnDimension();
- $X = $B->getArrayCopy();
+ $X = $B->getArray();
// Compute Y = transpose(Q)*B
for ($k = 0; $k < $this->n; ++$k) {
for ($j = 0; $j < $nx; ++$j) {
diff --git a/src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php b/src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php
index b997fb7c..6c8999d0 100644
--- a/src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php
+++ b/src/PhpSpreadsheet/Shared/JAMA/SingularValueDecomposition.php
@@ -65,7 +65,7 @@ class SingularValueDecomposition
public function __construct($Arg)
{
// Initialize.
- $A = $Arg->getArrayCopy();
+ $A = $Arg->getArray();
$this->m = $Arg->getRowDimension();
$this->n = $Arg->getColumnDimension();
$nu = min($this->m, $this->n);
@@ -476,6 +476,7 @@ class SingularValueDecomposition
*/
public function getS()
{
+ $S = [];
for ($i = 0; $i < $this->n; ++$i) {
for ($j = 0; $j < $this->n; ++$j) {
$S[$i][$j] = 0.0;
diff --git a/src/PhpSpreadsheet/Shared/OLE.php b/src/PhpSpreadsheet/Shared/OLE.php
index d380995c..f65fbca7 100644
--- a/src/PhpSpreadsheet/Shared/OLE.php
+++ b/src/PhpSpreadsheet/Shared/OLE.php
@@ -21,6 +21,7 @@ namespace PhpOffice\PhpSpreadsheet\Shared;
// +----------------------------------------------------------------------+
//
+use PhpOffice\PhpSpreadsheet\Exception;
use PhpOffice\PhpSpreadsheet\Reader\Exception as ReaderException;
use PhpOffice\PhpSpreadsheet\Shared\OLE\ChainedBlockStream;
use PhpOffice\PhpSpreadsheet\Shared\OLE\PPS\Root;
@@ -227,7 +228,8 @@ class OLE
// in OLE_ChainedBlockStream::stream_open().
// Object is removed from self::$instances in OLE_Stream::close().
$GLOBALS['_OLE_INSTANCES'][] = $this;
- $instanceId = end(array_keys($GLOBALS['_OLE_INSTANCES']));
+ $keys = array_keys($GLOBALS['_OLE_INSTANCES']);
+ $instanceId = end($keys);
$path = 'ole-chainedblockstream://oleInstanceId=' . $instanceId;
if ($blockIdOrPps instanceof OLE\PPS) {
@@ -316,7 +318,7 @@ class OLE
break;
default:
- break;
+ throw new Exception('Unsupported PPS type');
}
fseek($fh, 1, SEEK_CUR);
$pps->Type = $type;
@@ -495,7 +497,7 @@ class OLE
*/
public static function localDateToOLE($date)
{
- if (!isset($date)) {
+ if (!$date) {
return "\x00\x00\x00\x00\x00\x00\x00\x00";
}
diff --git a/src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php b/src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php
index cee5cd99..43e4804d 100644
--- a/src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php
+++ b/src/PhpSpreadsheet/Shared/OLE/ChainedBlockStream.php
@@ -9,7 +9,7 @@ class ChainedBlockStream
/**
* The OLE container of the file that is being read.
*
- * @var OLE
+ * @var null|OLE
*/
public $ole;
@@ -42,7 +42,7 @@ class ChainedBlockStream
* ole-chainedblockstream://oleInstanceId=1
* @param string $mode only "r" is supported
* @param int $options mask of STREAM_REPORT_ERRORS and STREAM_USE_PATH
- * @param string &$openedPath absolute path of the opened stream (out parameter)
+ * @param string $openedPath absolute path of the opened stream (out parameter)
*
* @return bool true on success
*/
@@ -112,7 +112,7 @@ class ChainedBlockStream
*
* @param int $count maximum number of bytes to read
*
- * @return string
+ * @return false|string
*/
public function stream_read($count) // @codingStandardsIgnoreLine
{
diff --git a/src/PhpSpreadsheet/Shared/OLE/PPS.php b/src/PhpSpreadsheet/Shared/OLE/PPS.php
index cf764d0b..104b0d6a 100644
--- a/src/PhpSpreadsheet/Shared/OLE/PPS.php
+++ b/src/PhpSpreadsheet/Shared/OLE/PPS.php
@@ -189,7 +189,7 @@ class PPS
. "\x00\x00\x00\x00" // 100
. OLE::localDateToOLE($this->Time1st) // 108
. OLE::localDateToOLE($this->Time2nd) // 116
- . pack('V', isset($this->startBlock) ? $this->startBlock : 0) // 120
+ . pack('V', $this->startBlock ?? 0) // 120
. pack('V', $this->Size) // 124
. pack('V', 0); // 128
@@ -200,7 +200,7 @@ class PPS
* Updates index and pointers to previous, next and children PPS's for this
* PPS. I don't think it'll work with Dir PPS's.
*
- * @param array &$raList Reference to the array of PPS's for the whole OLE
+ * @param array $raList Reference to the array of PPS's for the whole OLE
* container
* @param mixed $to_save
* @param mixed $depth
diff --git a/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php b/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
index 5466d2bc..2fe41055 100644
--- a/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
+++ b/src/PhpSpreadsheet/Shared/OLE/PPS/Root.php
@@ -237,7 +237,7 @@ class Root extends PPS
* Saving big data (PPS's with data bigger than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL).
*
* @param int $iStBlk
- * @param array &$raList Reference to array of PPS's
+ * @param array $raList Reference to array of PPS's
*/
private function saveBigData($iStBlk, &$raList): void
{
@@ -267,7 +267,7 @@ class Root extends PPS
/**
* get small data (PPS's with data smaller than \PhpOffice\PhpSpreadsheet\Shared\OLE::OLE_DATA_SIZE_SMALL).
*
- * @param array &$raList Reference to array of PPS's
+ * @param array $raList Reference to array of PPS's
*
* @return string
*/
diff --git a/src/PhpSpreadsheet/Shared/OLERead.php b/src/PhpSpreadsheet/Shared/OLERead.php
index 7112b090..c4dc572a 100644
--- a/src/PhpSpreadsheet/Shared/OLERead.php
+++ b/src/PhpSpreadsheet/Shared/OLERead.php
@@ -92,10 +92,8 @@ class OLERead
/**
* Read the file.
- *
- * @param $pFilename string Filename
*/
- public function read($pFilename): void
+ public function read(string $pFilename): void
{
File::assertFile($pFilename);
@@ -190,7 +188,7 @@ class OLERead
*
* @param int $stream
*
- * @return string
+ * @return null|string
*/
public function getStream($stream)
{
diff --git a/src/PhpSpreadsheet/Shared/StringHelper.php b/src/PhpSpreadsheet/Shared/StringHelper.php
index 9ae32413..e85ce55d 100644
--- a/src/PhpSpreadsheet/Shared/StringHelper.php
+++ b/src/PhpSpreadsheet/Shared/StringHelper.php
@@ -464,7 +464,7 @@ class StringHelper
*/
public static function countCharacters($value, $enc = 'UTF-8')
{
- return mb_strlen($value, $enc);
+ return mb_strlen($value ?? '', $enc);
}
/**
@@ -556,7 +556,7 @@ class StringHelper
* Identify whether a string contains a fractional numeric value,
* and convert it to a numeric if it is.
*
- * @param string &$operand string value to test
+ * @param string $operand string value to test
*
* @return bool
*/
diff --git a/src/PhpSpreadsheet/Shared/Trend/BestFit.php b/src/PhpSpreadsheet/Shared/Trend/BestFit.php
index c9499722..7df48953 100644
--- a/src/PhpSpreadsheet/Shared/Trend/BestFit.php
+++ b/src/PhpSpreadsheet/Shared/Trend/BestFit.php
@@ -2,7 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Shared\Trend;
-class BestFit
+abstract class BestFit
{
/**
* Indicator flag for a calculation error.
@@ -96,24 +96,18 @@ class BestFit
*
* @param float $xValue X-Value
*
- * @return bool Y-Value
+ * @return float Y-Value
*/
- public function getValueOfYForX($xValue)
- {
- return false;
- }
+ abstract public function getValueOfYForX($xValue);
/**
* Return the X-Value for a specified value of Y.
*
* @param float $yValue Y-Value
*
- * @return bool X-Value
+ * @return float X-Value
*/
- public function getValueOfXForY($yValue)
- {
- return false;
- }
+ abstract public function getValueOfXForY($yValue);
/**
* Return the original set of X-Values.
@@ -130,12 +124,9 @@ class BestFit
*
* @param int $dp Number of places of decimal precision to display
*
- * @return bool
+ * @return string
*/
- public function getEquation($dp = 0)
- {
- return false;
- }
+ abstract public function getEquation($dp = 0);
/**
* Return the Slope of the line.
@@ -348,13 +339,13 @@ class BestFit
$bestFitY = $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue);
$SSres += ($this->yValues[$xKey] - $bestFitY) * ($this->yValues[$xKey] - $bestFitY);
- if ($const) {
+ if ($const === true) {
$SStot += ($this->yValues[$xKey] - $meanY) * ($this->yValues[$xKey] - $meanY);
} else {
$SStot += $this->yValues[$xKey] * $this->yValues[$xKey];
}
$SScov += ($this->xValues[$xKey] - $meanX) * ($this->yValues[$xKey] - $meanY);
- if ($const) {
+ if ($const === true) {
$SSsex += ($this->xValues[$xKey] - $meanX) * ($this->xValues[$xKey] - $meanX);
} else {
$SSsex += $this->xValues[$xKey] * $this->xValues[$xKey];
@@ -362,7 +353,7 @@ class BestFit
}
$this->SSResiduals = $SSres;
- $this->DFResiduals = $this->valueCount - 1 - $const;
+ $this->DFResiduals = $this->valueCount - 1 - ($const === true ? 1 : 0);
if ($this->DFResiduals == 0.0) {
$this->stdevOfResiduals = 0.0;
@@ -395,27 +386,39 @@ class BestFit
}
}
+ private function sumSquares(array $values)
+ {
+ return array_sum(
+ array_map(
+ function ($value) {
+ return $value ** 2;
+ },
+ $values
+ )
+ );
+ }
+
/**
* @param float[] $yValues
* @param float[] $xValues
- * @param bool $const
*/
- protected function leastSquareFit(array $yValues, array $xValues, $const): void
+ protected function leastSquareFit(array $yValues, array $xValues, bool $const): void
{
// calculate sums
- $x_sum = array_sum($xValues);
- $y_sum = array_sum($yValues);
- $meanX = $x_sum / $this->valueCount;
- $meanY = $y_sum / $this->valueCount;
- $mBase = $mDivisor = $xx_sum = $xy_sum = $yy_sum = 0.0;
+ $sumValuesX = array_sum($xValues);
+ $sumValuesY = array_sum($yValues);
+ $meanValueX = $sumValuesX / $this->valueCount;
+ $meanValueY = $sumValuesY / $this->valueCount;
+ $sumSquaresX = $this->sumSquares($xValues);
+ $sumSquaresY = $this->sumSquares($yValues);
+ $mBase = $mDivisor = 0.0;
+ $xy_sum = 0.0;
for ($i = 0; $i < $this->valueCount; ++$i) {
$xy_sum += $xValues[$i] * $yValues[$i];
- $xx_sum += $xValues[$i] * $xValues[$i];
- $yy_sum += $yValues[$i] * $yValues[$i];
- if ($const) {
- $mBase += ($xValues[$i] - $meanX) * ($yValues[$i] - $meanY);
- $mDivisor += ($xValues[$i] - $meanX) * ($xValues[$i] - $meanX);
+ if ($const === true) {
+ $mBase += ($xValues[$i] - $meanValueX) * ($yValues[$i] - $meanValueY);
+ $mDivisor += ($xValues[$i] - $meanValueX) * ($xValues[$i] - $meanValueX);
} else {
$mBase += $xValues[$i] * $yValues[$i];
$mDivisor += $xValues[$i] * $xValues[$i];
@@ -426,13 +429,9 @@ class BestFit
$this->slope = $mBase / $mDivisor;
// calculate intersect
- if ($const) {
- $this->intersect = $meanY - ($this->slope * $meanX);
- } else {
- $this->intersect = 0;
- }
+ $this->intersect = ($const === true) ? $meanValueY - ($this->slope * $meanValueX) : 0.0;
- $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, $meanX, $meanY, $const);
+ $this->calculateGoodnessOfFit($sumValuesX, $sumValuesY, $sumSquaresX, $sumSquaresY, $xy_sum, $meanValueX, $meanValueY, $const);
}
/**
@@ -440,23 +439,22 @@ class BestFit
*
* @param float[] $yValues The set of Y-values for this regression
* @param float[] $xValues The set of X-values for this regression
- * @param bool $const
*/
- public function __construct($yValues, $xValues = [], $const = true)
+ public function __construct($yValues, $xValues = [])
{
// Calculate number of points
- $nY = count($yValues);
- $nX = count($xValues);
+ $yValueCount = count($yValues);
+ $xValueCount = count($xValues);
// Define X Values if necessary
- if ($nX == 0) {
- $xValues = range(1, $nY);
- } elseif ($nY != $nX) {
+ if ($xValueCount === 0) {
+ $xValues = range(1, $yValueCount);
+ } elseif ($yValueCount !== $xValueCount) {
// Ensure both arrays of points are the same size
$this->error = true;
}
- $this->valueCount = $nY;
+ $this->valueCount = $yValueCount;
$this->xValues = $xValues;
$this->yValues = $yValues;
}
diff --git a/src/PhpSpreadsheet/Shared/Trend/ExponentialBestFit.php b/src/PhpSpreadsheet/Shared/Trend/ExponentialBestFit.php
index 82866dee..eb8cd746 100644
--- a/src/PhpSpreadsheet/Shared/Trend/ExponentialBestFit.php
+++ b/src/PhpSpreadsheet/Shared/Trend/ExponentialBestFit.php
@@ -88,20 +88,17 @@ class ExponentialBestFit extends BestFit
*
* @param float[] $yValues The set of Y-values for this regression
* @param float[] $xValues The set of X-values for this regression
- * @param bool $const
*/
- private function exponentialRegression($yValues, $xValues, $const): void
+ private function exponentialRegression(array $yValues, array $xValues, bool $const): void
{
- foreach ($yValues as &$value) {
- if ($value < 0.0) {
- $value = 0 - log(abs($value));
- } elseif ($value > 0.0) {
- $value = log($value);
- }
- }
- unset($value);
+ $adjustedYValues = array_map(
+ function ($value) {
+ return ($value < 0.0) ? 0 - log(abs($value)) : log($value);
+ },
+ $yValues
+ );
- $this->leastSquareFit($yValues, $xValues, $const);
+ $this->leastSquareFit($adjustedYValues, $xValues, $const);
}
/**
@@ -116,7 +113,7 @@ class ExponentialBestFit extends BestFit
parent::__construct($yValues, $xValues);
if (!$this->error) {
- $this->exponentialRegression($yValues, $xValues, $const);
+ $this->exponentialRegression($yValues, $xValues, (bool) $const);
}
}
}
diff --git a/src/PhpSpreadsheet/Shared/Trend/LinearBestFit.php b/src/PhpSpreadsheet/Shared/Trend/LinearBestFit.php
index 26a562c5..65d6b4ff 100644
--- a/src/PhpSpreadsheet/Shared/Trend/LinearBestFit.php
+++ b/src/PhpSpreadsheet/Shared/Trend/LinearBestFit.php
@@ -56,9 +56,8 @@ class LinearBestFit extends BestFit
*
* @param float[] $yValues The set of Y-values for this regression
* @param float[] $xValues The set of X-values for this regression
- * @param bool $const
*/
- private function linearRegression($yValues, $xValues, $const): void
+ private function linearRegression(array $yValues, array $xValues, bool $const): void
{
$this->leastSquareFit($yValues, $xValues, $const);
}
@@ -75,7 +74,7 @@ class LinearBestFit extends BestFit
parent::__construct($yValues, $xValues);
if (!$this->error) {
- $this->linearRegression($yValues, $xValues, $const);
+ $this->linearRegression($yValues, $xValues, (bool) $const);
}
}
}
diff --git a/src/PhpSpreadsheet/Shared/Trend/LogarithmicBestFit.php b/src/PhpSpreadsheet/Shared/Trend/LogarithmicBestFit.php
index c469067d..2366dc63 100644
--- a/src/PhpSpreadsheet/Shared/Trend/LogarithmicBestFit.php
+++ b/src/PhpSpreadsheet/Shared/Trend/LogarithmicBestFit.php
@@ -48,7 +48,7 @@ class LogarithmicBestFit extends BestFit
$slope = $this->getSlope($dp);
$intersect = $this->getIntersect($dp);
- return 'Y = ' . $intersect . ' + ' . $slope . ' * log(X)';
+ return 'Y = ' . $slope . ' * log(' . $intersect . ' * X)';
}
/**
@@ -56,20 +56,17 @@ class LogarithmicBestFit extends BestFit
*
* @param float[] $yValues The set of Y-values for this regression
* @param float[] $xValues The set of X-values for this regression
- * @param bool $const
*/
- private function logarithmicRegression($yValues, $xValues, $const): void
+ private function logarithmicRegression(array $yValues, array $xValues, bool $const): void
{
- foreach ($xValues as &$value) {
- if ($value < 0.0) {
- $value = 0 - log(abs($value));
- } elseif ($value > 0.0) {
- $value = log($value);
- }
- }
- unset($value);
+ $adjustedYValues = array_map(
+ function ($value) {
+ return ($value < 0.0) ? 0 - log(abs($value)) : log($value);
+ },
+ $yValues
+ );
- $this->leastSquareFit($yValues, $xValues, $const);
+ $this->leastSquareFit($adjustedYValues, $xValues, $const);
}
/**
@@ -84,7 +81,7 @@ class LogarithmicBestFit extends BestFit
parent::__construct($yValues, $xValues);
if (!$this->error) {
- $this->logarithmicRegression($yValues, $xValues, $const);
+ $this->logarithmicRegression($yValues, $xValues, (bool) $const);
}
}
}
diff --git a/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php b/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php
index d959eddb..2c8eea5b 100644
--- a/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php
+++ b/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php
@@ -42,6 +42,7 @@ class PolynomialBestFit extends BestFit
{
$retVal = $this->getIntersect();
$slope = $this->getSlope();
+ // @phpstan-ignore-next-line
foreach ($slope as $key => $value) {
if ($value != 0.0) {
$retVal += $value * $xValue ** ($key + 1);
@@ -76,6 +77,7 @@ class PolynomialBestFit extends BestFit
$intersect = $this->getIntersect($dp);
$equation = 'Y = ' . $intersect;
+ // @phpstan-ignore-next-line
foreach ($slope as $key => $value) {
if ($value != 0.0) {
$equation .= ' + ' . $value . ' * X';
@@ -93,7 +95,7 @@ class PolynomialBestFit extends BestFit
*
* @param int $dp Number of places of decimal precision to display
*
- * @return string
+ * @return float
*/
public function getSlope($dp = 0)
{
@@ -103,6 +105,7 @@ class PolynomialBestFit extends BestFit
$coefficients[] = round($coefficient, $dp);
}
+ // @phpstan-ignore-next-line
return $coefficients;
}
@@ -178,9 +181,8 @@ class PolynomialBestFit extends BestFit
* @param int $order Order of Polynomial for this regression
* @param float[] $yValues The set of Y-values for this regression
* @param float[] $xValues The set of X-values for this regression
- * @param bool $const
*/
- public function __construct($order, $yValues, $xValues = [], $const = true)
+ public function __construct($order, $yValues, $xValues = [])
{
parent::__construct($yValues, $xValues);
diff --git a/src/PhpSpreadsheet/Shared/Trend/PowerBestFit.php b/src/PhpSpreadsheet/Shared/Trend/PowerBestFit.php
index c53eab63..cafd0115 100644
--- a/src/PhpSpreadsheet/Shared/Trend/PowerBestFit.php
+++ b/src/PhpSpreadsheet/Shared/Trend/PowerBestFit.php
@@ -72,28 +72,23 @@ class PowerBestFit extends BestFit
*
* @param float[] $yValues The set of Y-values for this regression
* @param float[] $xValues The set of X-values for this regression
- * @param bool $const
*/
- private function powerRegression($yValues, $xValues, $const): void
+ private function powerRegression(array $yValues, array $xValues, bool $const): void
{
- foreach ($xValues as &$value) {
- if ($value < 0.0) {
- $value = 0 - log(abs($value));
- } elseif ($value > 0.0) {
- $value = log($value);
- }
- }
- unset($value);
- foreach ($yValues as &$value) {
- if ($value < 0.0) {
- $value = 0 - log(abs($value));
- } elseif ($value > 0.0) {
- $value = log($value);
- }
- }
- unset($value);
+ $adjustedYValues = array_map(
+ function ($value) {
+ return ($value < 0.0) ? 0 - log(abs($value)) : log($value);
+ },
+ $yValues
+ );
+ $adjustedXValues = array_map(
+ function ($value) {
+ return ($value < 0.0) ? 0 - log(abs($value)) : log($value);
+ },
+ $xValues
+ );
- $this->leastSquareFit($yValues, $xValues, $const);
+ $this->leastSquareFit($adjustedYValues, $adjustedXValues, $const);
}
/**
@@ -108,7 +103,7 @@ class PowerBestFit extends BestFit
parent::__construct($yValues, $xValues);
if (!$this->error) {
- $this->powerRegression($yValues, $xValues, $const);
+ $this->powerRegression($yValues, $xValues, (bool) $const);
}
}
}
diff --git a/src/PhpSpreadsheet/Shared/Trend/Trend.php b/src/PhpSpreadsheet/Shared/Trend/Trend.php
index 1b7b3901..61d1183a 100644
--- a/src/PhpSpreadsheet/Shared/Trend/Trend.php
+++ b/src/PhpSpreadsheet/Shared/Trend/Trend.php
@@ -44,7 +44,7 @@ class Trend
/**
* Cached results for each method when trying to identify which provides the best fit.
*
- * @var bestFit[]
+ * @var BestFit[]
*/
private static $trendCache = [];
@@ -55,10 +55,9 @@ class Trend
$nX = count($xValues);
// Define X Values if necessary
- if ($nX == 0) {
+ if ($nX === 0) {
$xValues = range(1, $nY);
- $nX = $nY;
- } elseif ($nY != $nX) {
+ } elseif ($nY !== $nX) {
// Ensure both arrays of points are the same size
trigger_error('Trend(): Number of elements in coordinate arrays do not match.', E_USER_ERROR);
}
@@ -84,7 +83,7 @@ class Trend
case self::TREND_POLYNOMIAL_6:
if (!isset(self::$trendCache[$key])) {
$order = substr($trendType, -1);
- self::$trendCache[$key] = new PolynomialBestFit($order, $yValues, $xValues, $const);
+ self::$trendCache[$key] = new PolynomialBestFit($order, $yValues, $xValues);
}
return self::$trendCache[$key];
@@ -92,6 +91,8 @@ class Trend
case self::TREND_BEST_FIT_NO_POLY:
// If the request is to determine the best fit regression, then we test each Trend line in turn
// Start by generating an instance of each available Trend method
+ $bestFit = [];
+ $bestFitValue = [];
foreach (self::$trendTypes as $trendMethod) {
$className = '\PhpOffice\PhpSpreadsheet\Shared\Trend\\' . $trendType . 'BestFit';
$bestFit[$trendMethod] = new $className($yValues, $xValues, $const);
@@ -100,7 +101,7 @@ class Trend
if ($trendType != self::TREND_BEST_FIT_NO_POLY) {
foreach (self::$trendTypePolynomialOrders as $trendMethod) {
$order = substr($trendMethod, -1);
- $bestFit[$trendMethod] = new PolynomialBestFit($order, $yValues, $xValues, $const);
+ $bestFit[$trendMethod] = new PolynomialBestFit($order, $yValues, $xValues);
if ($bestFit[$trendMethod]->getError()) {
unset($bestFit[$trendMethod]);
} else {
diff --git a/src/PhpSpreadsheet/Shared/XMLWriter.php b/src/PhpSpreadsheet/Shared/XMLWriter.php
index 4f7a6a06..c35b7820 100644
--- a/src/PhpSpreadsheet/Shared/XMLWriter.php
+++ b/src/PhpSpreadsheet/Shared/XMLWriter.php
@@ -87,6 +87,6 @@ class XMLWriter extends \XMLWriter
$text = implode("\n", $text);
}
- return $this->writeRaw(htmlspecialchars($text));
+ return $this->writeRaw(htmlspecialchars($text ?? ''));
}
}
diff --git a/src/PhpSpreadsheet/Shared/Xls.php b/src/PhpSpreadsheet/Shared/Xls.php
index c9eaf378..26035ec6 100644
--- a/src/PhpSpreadsheet/Shared/Xls.php
+++ b/src/PhpSpreadsheet/Shared/Xls.php
@@ -205,12 +205,11 @@ class Xls
* @param int $width Width in pixels
* @param int $height Height in pixels
*
- * @return array
+ * @return null|array
*/
public static function oneAnchor2twoAnchor($sheet, $coordinates, $offsetX, $offsetY, $width, $height)
{
- [$column, $row] = Coordinate::coordinateFromString($coordinates);
- $col_start = Coordinate::columnIndexFromString($column);
+ [$col_start, $row] = Coordinate::indexesFromString($coordinates);
$row_start = $row - 1;
$x1 = $offsetX;
@@ -246,16 +245,16 @@ class Xls
// Bitmap isn't allowed to start or finish in a hidden cell, i.e. a cell
// with zero height or width.
if (self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_start)) == 0) {
- return;
+ return null;
}
if (self::sizeCol($sheet, Coordinate::stringFromColumnIndex($col_end)) == 0) {
- return;
+ return null;
}
if (self::sizeRow($sheet, $row_start + 1) == 0) {
- return;
+ return null;
}
if (self::sizeRow($sheet, $row_end + 1) == 0) {
- return;
+ return null;
}
// Convert the pixel values to the percentage value expected by Excel
diff --git a/src/PhpSpreadsheet/Spreadsheet.php b/src/PhpSpreadsheet/Spreadsheet.php
index c8e8f72c..fb945399 100644
--- a/src/PhpSpreadsheet/Spreadsheet.php
+++ b/src/PhpSpreadsheet/Spreadsheet.php
@@ -55,7 +55,7 @@ class Spreadsheet
/**
* Calculation Engine.
*
- * @var Calculation
+ * @var null|Calculation
*/
private $calculationEngine;
@@ -69,7 +69,7 @@ class Spreadsheet
/**
* Named ranges.
*
- * @var NamedRange[]
+ * @var DefinedName[]
*/
private $definedNames = [];
@@ -104,21 +104,21 @@ class Spreadsheet
/**
* macrosCode : all macros code as binary data (the vbaProject.bin file, this include form, code, etc.), null if no macro.
*
- * @var string
+ * @var null|string
*/
private $macrosCode;
/**
* macrosCertificate : if macros are signed, contains binary data vbaProjectSignature.bin file, null if not signed.
*
- * @var string
+ * @var null|string
*/
private $macrosCertificate;
/**
* ribbonXMLData : null if workbook is'nt Excel 2007 or not contain a customized UI.
*
- * @var null|string
+ * @var null|array{target: string, data: string}
*/
private $ribbonXMLData;
@@ -298,11 +298,9 @@ class Spreadsheet
/**
* retrieve ribbon XML Data.
*
- * return string|null|array
- *
* @param string $what
*
- * @return string
+ * @return null|array|string
*/
public function getRibbonXMLData($what = 'all') //we need some constants here...
{
@@ -373,7 +371,9 @@ class Spreadsheet
*/
private function getExtensionOnly($path)
{
- return pathinfo($path, PATHINFO_EXTENSION);
+ $extension = pathinfo($path, PATHINFO_EXTENSION);
+
+ return is_array($extension) ? '' : $extension;
}
/**
@@ -453,7 +453,7 @@ class Spreadsheet
*
* @param string $pName Sheet name
*
- * @return Worksheet
+ * @return null|Worksheet
*/
public function getSheetByCodeName($pName)
{
@@ -503,8 +503,8 @@ class Spreadsheet
*/
public function __destruct()
{
- $this->calculationEngine = null;
$this->disconnectWorksheets();
+ $this->calculationEngine = null;
}
/**
@@ -513,19 +513,17 @@ class Spreadsheet
*/
public function disconnectWorksheets(): void
{
- $worksheet = null;
- foreach ($this->workSheetCollection as $k => &$worksheet) {
+ foreach ($this->workSheetCollection as $worksheet) {
$worksheet->disconnectCells();
- $this->workSheetCollection[$k] = null;
+ unset($worksheet);
}
- unset($worksheet);
$this->workSheetCollection = [];
}
/**
* Return the calculation engine for this worksheet.
*
- * @return Calculation
+ * @return null|Calculation
*/
public function getCalculationEngine()
{
@@ -874,7 +872,7 @@ class Spreadsheet
/**
* Get an array of all Named Ranges.
*
- * @return NamedRange[]
+ * @return DefinedName[]
*/
public function getNamedRanges(): array
{
@@ -889,7 +887,7 @@ class Spreadsheet
/**
* Get an array of all Named Formulae.
*
- * @return NamedFormula[]
+ * @return DefinedName[]
*/
public function getNamedFormulae(): array
{
@@ -1122,6 +1120,7 @@ class Spreadsheet
*/
public function __clone()
{
+ // @phpstan-ignore-next-line
foreach ($this as $key => $val) {
if (is_object($val) || (is_array($val))) {
$this->{$key} = unserialize(serialize($val));
@@ -1341,6 +1340,7 @@ class Spreadsheet
// remove cellXfs without references and create mapping so we can update xfIndex
// for all cells and columns
$countNeededCellXfs = 0;
+ $map = [];
foreach ($this->cellXfCollection as $index => $cellXf) {
if ($countReferencesCellXf[$index] > 0 || $index == 0) { // we must never remove the first cellXf
++$countNeededCellXfs;
diff --git a/src/PhpSpreadsheet/Style/Alignment.php b/src/PhpSpreadsheet/Style/Alignment.php
index 04a089fe..e072c524 100644
--- a/src/PhpSpreadsheet/Style/Alignment.php
+++ b/src/PhpSpreadsheet/Style/Alignment.php
@@ -35,21 +35,21 @@ class Alignment extends Supervisor
/**
* Horizontal alignment.
*
- * @var string
+ * @var null|string
*/
protected $horizontal = self::HORIZONTAL_GENERAL;
/**
* Vertical alignment.
*
- * @var string
+ * @var null|string
*/
protected $vertical = self::VERTICAL_BOTTOM;
/**
* Text rotation.
*
- * @var int
+ * @var null|int
*/
protected $textRotation = 0;
@@ -179,7 +179,7 @@ class Alignment extends Supervisor
/**
* Get Horizontal.
*
- * @return string
+ * @return null|string
*/
public function getHorizontal()
{
@@ -216,7 +216,7 @@ class Alignment extends Supervisor
/**
* Get Vertical.
*
- * @return string
+ * @return null|string
*/
public function getVertical()
{
@@ -253,7 +253,7 @@ class Alignment extends Supervisor
/**
* Get TextRotation.
*
- * @return int
+ * @return null|int
*/
public function getTextRotation()
{
@@ -392,7 +392,8 @@ class Alignment extends Supervisor
if (
$this->getHorizontal() != self::HORIZONTAL_GENERAL &&
$this->getHorizontal() != self::HORIZONTAL_LEFT &&
- $this->getHorizontal() != self::HORIZONTAL_RIGHT
+ $this->getHorizontal() != self::HORIZONTAL_RIGHT &&
+ $this->getHorizontal() != self::HORIZONTAL_DISTRIBUTED
) {
$pValue = 0; // indent not supported
}
diff --git a/src/PhpSpreadsheet/Style/Border.php b/src/PhpSpreadsheet/Style/Border.php
index 1d3096f0..a8af9d94 100644
--- a/src/PhpSpreadsheet/Style/Border.php
+++ b/src/PhpSpreadsheet/Style/Border.php
@@ -37,7 +37,7 @@ class Border extends Supervisor
protected $color;
/**
- * @var int
+ * @var null|int
*/
public $colorIndex;
@@ -47,11 +47,8 @@ class Border extends Supervisor
* @param bool $isSupervisor Flag indicating if this is a supervisor or not
* Leave this value at default unless you understand exactly what
* its ramifications are
- * @param bool $isConditional Flag indicating if this is a conditional style or not
- * Leave this value at default unless you understand exactly what
- * its ramifications are
*/
- public function __construct($isSupervisor = false, $isConditional = false)
+ public function __construct($isSupervisor = false)
{
// Supervisor?
parent::__construct($isSupervisor);
@@ -73,17 +70,19 @@ class Border extends Supervisor
*/
public function getSharedComponent()
{
+ /** @var Borders $sharedComponent */
+ $sharedComponent = $this->parent->getSharedComponent();
switch ($this->parentPropertyName) {
case 'bottom':
- return $this->parent->getSharedComponent()->getBottom();
+ return $sharedComponent->getBottom();
case 'diagonal':
- return $this->parent->getSharedComponent()->getDiagonal();
+ return $sharedComponent->getDiagonal();
case 'left':
- return $this->parent->getSharedComponent()->getLeft();
+ return $sharedComponent->getLeft();
case 'right':
- return $this->parent->getSharedComponent()->getRight();
+ return $sharedComponent->getRight();
case 'top':
- return $this->parent->getSharedComponent()->getTop();
+ return $sharedComponent->getTop();
}
throw new PhpSpreadsheetException('Cannot get shared component for a pseudo-border.');
diff --git a/src/PhpSpreadsheet/Style/Borders.php b/src/PhpSpreadsheet/Style/Borders.php
index a1acfdd4..eeb4932a 100644
--- a/src/PhpSpreadsheet/Style/Borders.php
+++ b/src/PhpSpreadsheet/Style/Borders.php
@@ -95,21 +95,18 @@ class Borders extends Supervisor
* @param bool $isSupervisor Flag indicating if this is a supervisor or not
* Leave this value at default unless you understand exactly what
* its ramifications are
- * @param bool $isConditional Flag indicating if this is a conditional style or not
- * Leave this value at default unless you understand exactly what
- * its ramifications are
*/
- public function __construct($isSupervisor = false, $isConditional = false)
+ public function __construct($isSupervisor = false)
{
// Supervisor?
parent::__construct($isSupervisor);
// Initialise values
- $this->left = new Border($isSupervisor, $isConditional);
- $this->right = new Border($isSupervisor, $isConditional);
- $this->top = new Border($isSupervisor, $isConditional);
- $this->bottom = new Border($isSupervisor, $isConditional);
- $this->diagonal = new Border($isSupervisor, $isConditional);
+ $this->left = new Border($isSupervisor);
+ $this->right = new Border($isSupervisor);
+ $this->top = new Border($isSupervisor);
+ $this->bottom = new Border($isSupervisor);
+ $this->diagonal = new Border($isSupervisor);
$this->diagonalDirection = self::DIAGONAL_NONE;
// Specially for supervisor
diff --git a/src/PhpSpreadsheet/Style/Color.php b/src/PhpSpreadsheet/Style/Color.php
index ad598f11..bf5d093f 100644
--- a/src/PhpSpreadsheet/Style/Color.php
+++ b/src/PhpSpreadsheet/Style/Color.php
@@ -71,14 +71,16 @@ class Color extends Supervisor
*/
public function getSharedComponent()
{
+ /** @var Border|Fill $sharedComponent */
+ $sharedComponent = $this->parent->getSharedComponent();
if ($this->parentPropertyName === 'endColor') {
- return $this->parent->getSharedComponent()->getEndColor();
+ return $sharedComponent->getEndColor();
}
if ($this->parentPropertyName === 'startColor') {
- return $this->parent->getSharedComponent()->getStartColor();
+ return $sharedComponent->getStartColor();
}
- return $this->parent->getSharedComponent()->getColor();
+ return $sharedComponent->getColor();
}
/**
@@ -167,7 +169,7 @@ class Color extends Supervisor
return $this->getSharedComponent()->getRGB();
}
- return substr($this->argb, 2);
+ return substr($this->argb ?? '', 2);
}
/**
@@ -200,7 +202,7 @@ class Color extends Supervisor
* @param bool $hex Flag indicating whether the component should be returned as a hex or a
* decimal value
*
- * @return string The extracted colour component
+ * @return int|string The extracted colour component
*/
private static function getColourComponent($RGB, $offset, $hex = true)
{
@@ -216,7 +218,7 @@ class Color extends Supervisor
* @param bool $hex Flag indicating whether the component should be returned as a hex or a
* decimal value
*
- * @return string The red colour component
+ * @return int|string The red colour component
*/
public static function getRed($RGB, $hex = true)
{
@@ -230,7 +232,7 @@ class Color extends Supervisor
* @param bool $hex Flag indicating whether the component should be returned as a hex or a
* decimal value
*
- * @return string The green colour component
+ * @return int|string The green colour component
*/
public static function getGreen($RGB, $hex = true)
{
@@ -244,7 +246,7 @@ class Color extends Supervisor
* @param bool $hex Flag indicating whether the component should be returned as a hex or a
* decimal value
*
- * @return string The blue colour component
+ * @return int|string The blue colour component
*/
public static function getBlue($RGB, $hex = true)
{
@@ -264,8 +266,11 @@ class Color extends Supervisor
$rgba = (strlen($hex) === 8);
$adjustPercentage = max(-1.0, min(1.0, $adjustPercentage));
+ /** @var int $red */
$red = self::getRed($hex, false);
+ /** @var int $green */
$green = self::getGreen($hex, false);
+ /** @var int $blue */
$blue = self::getBlue($hex, false);
if ($adjustPercentage > 0) {
$red += (255 - $red) * $adjustPercentage;
diff --git a/src/PhpSpreadsheet/Style/Conditional.php b/src/PhpSpreadsheet/Style/Conditional.php
index e4fe0acc..b008c9f2 100644
--- a/src/PhpSpreadsheet/Style/Conditional.php
+++ b/src/PhpSpreadsheet/Style/Conditional.php
@@ -3,6 +3,7 @@
namespace PhpOffice\PhpSpreadsheet\Style;
use PhpOffice\PhpSpreadsheet\IComparable;
+use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar;
class Conditional implements IComparable
{
@@ -13,6 +14,7 @@ class Conditional implements IComparable
const CONDITION_EXPRESSION = 'expression';
const CONDITION_CONTAINSBLANKS = 'containsBlanks';
const CONDITION_NOTCONTAINSBLANKS = 'notContainsBlanks';
+ const CONDITION_DATABAR = 'dataBar';
// Operator types
const OPERATOR_NONE = '';
@@ -64,6 +66,11 @@ class Conditional implements IComparable
*/
private $condition = [];
+ /**
+ * @var ConditionalDataBar
+ */
+ private $dataBar;
+
/**
* Style.
*
@@ -241,6 +248,28 @@ class Conditional implements IComparable
return $this;
}
+ /**
+ * get DataBar.
+ *
+ * @return ConditionalDataBar | null
+ */
+ public function getDataBar()
+ {
+ return $this->dataBar;
+ }
+
+ /**
+ * set DataBar.
+ *
+ * @return $this
+ */
+ public function setDataBar(ConditionalDataBar $dataBar)
+ {
+ $this->dataBar = $dataBar;
+
+ return $this;
+ }
+
/**
* Get hash code.
*
diff --git a/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php b/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php
new file mode 100644
index 00000000..54513670
--- /dev/null
+++ b/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBar.php
@@ -0,0 +1,102 @@
+ attribute */
+
+ /** @var null|bool */
+ private $showValue;
+
+ /** children */
+
+ /** @var ConditionalFormatValueObject */
+ private $minimumConditionalFormatValueObject;
+
+ /** @var ConditionalFormatValueObject */
+ private $maximumConditionalFormatValueObject;
+
+ /** @var string */
+ private $color;
+
+ /** */
+
+ /** @var ConditionalFormattingRuleExtension */
+ private $conditionalFormattingRuleExt;
+
+ /**
+ * @return null|bool
+ */
+ public function getShowValue()
+ {
+ return $this->showValue;
+ }
+
+ /**
+ * @param bool $showValue
+ */
+ public function setShowValue($showValue)
+ {
+ $this->showValue = $showValue;
+
+ return $this;
+ }
+
+ /**
+ * @return ConditionalFormatValueObject
+ */
+ public function getMinimumConditionalFormatValueObject()
+ {
+ return $this->minimumConditionalFormatValueObject;
+ }
+
+ public function setMinimumConditionalFormatValueObject(ConditionalFormatValueObject $minimumConditionalFormatValueObject)
+ {
+ $this->minimumConditionalFormatValueObject = $minimumConditionalFormatValueObject;
+
+ return $this;
+ }
+
+ /**
+ * @return ConditionalFormatValueObject
+ */
+ public function getMaximumConditionalFormatValueObject()
+ {
+ return $this->maximumConditionalFormatValueObject;
+ }
+
+ public function setMaximumConditionalFormatValueObject(ConditionalFormatValueObject $maximumConditionalFormatValueObject)
+ {
+ $this->maximumConditionalFormatValueObject = $maximumConditionalFormatValueObject;
+
+ return $this;
+ }
+
+ public function getColor(): string
+ {
+ return $this->color;
+ }
+
+ public function setColor(string $color): self
+ {
+ $this->color = $color;
+
+ return $this;
+ }
+
+ /**
+ * @return ConditionalFormattingRuleExtension
+ */
+ public function getConditionalFormattingRuleExt()
+ {
+ return $this->conditionalFormattingRuleExt;
+ }
+
+ public function setConditionalFormattingRuleExt(ConditionalFormattingRuleExtension $conditionalFormattingRuleExt)
+ {
+ $this->conditionalFormattingRuleExt = $conditionalFormattingRuleExt;
+
+ return $this;
+ }
+}
diff --git a/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php b/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php
new file mode 100644
index 00000000..c709cf3e
--- /dev/null
+++ b/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalDataBarExtension.php
@@ -0,0 +1,290 @@
+ attributes */
+
+ /** @var int */
+ private $minLength;
+
+ /** @var int */
+ private $maxLength;
+
+ /** @var null|bool */
+ private $border;
+
+ /** @var null|bool */
+ private $gradient;
+
+ /** @var string */
+ private $direction;
+
+ /** @var null|bool */
+ private $negativeBarBorderColorSameAsPositive;
+
+ /** @var string */
+ private $axisPosition;
+
+ // children
+
+ /** @var ConditionalFormatValueObject */
+ private $maximumConditionalFormatValueObject;
+
+ /** @var ConditionalFormatValueObject */
+ private $minimumConditionalFormatValueObject;
+
+ /** @var string */
+ private $borderColor;
+
+ /** @var string */
+ private $negativeFillColor;
+
+ /** @var string */
+ private $negativeBorderColor;
+
+ /** @var array */
+ private $axisColor = [
+ 'rgb' => null,
+ 'theme' => null,
+ 'tint' => null,
+ ];
+
+ public function getXmlAttributes()
+ {
+ $ret = [];
+ foreach (['minLength', 'maxLength', 'direction', 'axisPosition'] as $attrKey) {
+ if (null !== $this->{$attrKey}) {
+ $ret[$attrKey] = $this->{$attrKey};
+ }
+ }
+ foreach (['border', 'gradient', 'negativeBarBorderColorSameAsPositive'] as $attrKey) {
+ if (null !== $this->{$attrKey}) {
+ $ret[$attrKey] = $this->{$attrKey} ? '1' : '0';
+ }
+ }
+
+ return $ret;
+ }
+
+ public function getXmlElements()
+ {
+ $ret = [];
+ $elms = ['borderColor', 'negativeFillColor', 'negativeBorderColor'];
+ foreach ($elms as $elmKey) {
+ if (null !== $this->{$elmKey}) {
+ $ret[$elmKey] = ['rgb' => $this->{$elmKey}];
+ }
+ }
+ foreach (array_filter($this->axisColor) as $attrKey => $axisColorAttr) {
+ if (!isset($ret['axisColor'])) {
+ $ret['axisColor'] = [];
+ }
+ $ret['axisColor'][$attrKey] = $axisColorAttr;
+ }
+
+ return $ret;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMinLength()
+ {
+ return $this->minLength;
+ }
+
+ public function setMinLength(int $minLength): self
+ {
+ $this->minLength = $minLength;
+
+ return $this;
+ }
+
+ /**
+ * @return int
+ */
+ public function getMaxLength()
+ {
+ return $this->maxLength;
+ }
+
+ public function setMaxLength(int $maxLength): self
+ {
+ $this->maxLength = $maxLength;
+
+ return $this;
+ }
+
+ /**
+ * @return null|bool
+ */
+ public function getBorder()
+ {
+ return $this->border;
+ }
+
+ public function setBorder(bool $border): self
+ {
+ $this->border = $border;
+
+ return $this;
+ }
+
+ /**
+ * @return null|bool
+ */
+ public function getGradient()
+ {
+ return $this->gradient;
+ }
+
+ public function setGradient(bool $gradient): self
+ {
+ $this->gradient = $gradient;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getDirection()
+ {
+ return $this->direction;
+ }
+
+ public function setDirection(string $direction): self
+ {
+ $this->direction = $direction;
+
+ return $this;
+ }
+
+ /**
+ * @return null|bool
+ */
+ public function getNegativeBarBorderColorSameAsPositive()
+ {
+ return $this->negativeBarBorderColorSameAsPositive;
+ }
+
+ public function setNegativeBarBorderColorSameAsPositive(bool $negativeBarBorderColorSameAsPositive): self
+ {
+ $this->negativeBarBorderColorSameAsPositive = $negativeBarBorderColorSameAsPositive;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getAxisPosition()
+ {
+ return $this->axisPosition;
+ }
+
+ public function setAxisPosition(string $axisPosition): self
+ {
+ $this->axisPosition = $axisPosition;
+
+ return $this;
+ }
+
+ /**
+ * @return ConditionalFormatValueObject
+ */
+ public function getMaximumConditionalFormatValueObject()
+ {
+ return $this->maximumConditionalFormatValueObject;
+ }
+
+ public function setMaximumConditionalFormatValueObject(ConditionalFormatValueObject $maximumConditionalFormatValueObject)
+ {
+ $this->maximumConditionalFormatValueObject = $maximumConditionalFormatValueObject;
+
+ return $this;
+ }
+
+ /**
+ * @return ConditionalFormatValueObject
+ */
+ public function getMinimumConditionalFormatValueObject()
+ {
+ return $this->minimumConditionalFormatValueObject;
+ }
+
+ public function setMinimumConditionalFormatValueObject(ConditionalFormatValueObject $minimumConditionalFormatValueObject)
+ {
+ $this->minimumConditionalFormatValueObject = $minimumConditionalFormatValueObject;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getBorderColor()
+ {
+ return $this->borderColor;
+ }
+
+ public function setBorderColor(string $borderColor): self
+ {
+ $this->borderColor = $borderColor;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getNegativeFillColor()
+ {
+ return $this->negativeFillColor;
+ }
+
+ public function setNegativeFillColor(string $negativeFillColor): self
+ {
+ $this->negativeFillColor = $negativeFillColor;
+
+ return $this;
+ }
+
+ /**
+ * @return string
+ */
+ public function getNegativeBorderColor()
+ {
+ return $this->negativeBorderColor;
+ }
+
+ public function setNegativeBorderColor(string $negativeBorderColor): self
+ {
+ $this->negativeBorderColor = $negativeBorderColor;
+
+ return $this;
+ }
+
+ public function getAxisColor(): array
+ {
+ return $this->axisColor;
+ }
+
+ /**
+ * @param mixed $rgb
+ * @param null|mixed $theme
+ * @param null|mixed $tint
+ */
+ public function setAxisColor($rgb, $theme = null, $tint = null): self
+ {
+ $this->axisColor = [
+ 'rgb' => $rgb,
+ 'theme' => $theme,
+ 'tint' => $tint,
+ ];
+
+ return $this;
+ }
+}
diff --git a/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php b/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
new file mode 100644
index 00000000..107969bf
--- /dev/null
+++ b/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormatValueObject.php
@@ -0,0 +1,78 @@
+type = $type;
+ $this->value = $value;
+ $this->cellFormula = $cellFormula;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getType()
+ {
+ return $this->type;
+ }
+
+ /**
+ * @param mixed $type
+ */
+ public function setType($type)
+ {
+ $this->type = $type;
+
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getValue()
+ {
+ return $this->value;
+ }
+
+ /**
+ * @param mixed $value
+ */
+ public function setValue($value)
+ {
+ $this->value = $value;
+
+ return $this;
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getCellFormula()
+ {
+ return $this->cellFormula;
+ }
+
+ /**
+ * @param mixed $cellFormula
+ */
+ public function setCellFormula($cellFormula)
+ {
+ $this->cellFormula = $cellFormula;
+
+ return $this;
+ }
+}
diff --git a/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php b/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
new file mode 100644
index 00000000..899bbe43
--- /dev/null
+++ b/src/PhpSpreadsheet/Style/ConditionalFormatting/ConditionalFormattingRuleExtension.php
@@ -0,0 +1,195 @@
+ attributes */
+ private $id;
+
+ /** @var string Conditional Formatting Rule */
+ private $cfRule;
+
+ /** children */
+
+ /** @var ConditionalDataBarExtension */
+ private $dataBar;
+
+ /** @var string Sequence of References */
+ private $sqref;
+
+ /**
+ * ConditionalFormattingRuleExtension constructor.
+ */
+ public function __construct($id = null, string $cfRule = self::CONDITION_EXTENSION_DATABAR)
+ {
+ if (null === $id) {
+ $this->id = '{' . $this->generateUuid() . '}';
+ } else {
+ $this->id = $id;
+ }
+ $this->cfRule = $cfRule;
+ }
+
+ private function generateUuid()
+ {
+ $chars = str_split('xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx');
+
+ foreach ($chars as $i => $char) {
+ if ($char === 'x') {
+ $chars[$i] = dechex(random_int(0, 15));
+ } elseif ($char === 'y') {
+ $chars[$i] = dechex(random_int(8, 11));
+ }
+ }
+
+ return implode('', $chars);
+ }
+
+ public static function parseExtLstXml($extLstXml)
+ {
+ $conditionalFormattingRuleExtensions = [];
+ $conditionalFormattingRuleExtensionXml = null;
+ if ($extLstXml instanceof SimpleXMLElement) {
+ foreach ((count($extLstXml) > 0 ? $extLstXml : [$extLstXml]) as $extLst) {
+ //this uri is conditionalFormattings
+ //https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/07d607af-5618-4ca2-b683-6a78dc0d9627
+ if (isset($extLst->ext['uri']) && (string) $extLst->ext['uri'] === '{78C0D931-6437-407d-A8EE-F0AAD7539E65}') {
+ $conditionalFormattingRuleExtensionXml = $extLst->ext;
+ }
+ }
+ if ($conditionalFormattingRuleExtensionXml) {
+ $ns = $conditionalFormattingRuleExtensionXml->getNamespaces(true);
+ $extFormattingsXml = $conditionalFormattingRuleExtensionXml->children($ns['x14']);
+
+ foreach ($extFormattingsXml->children($ns['x14']) as $extFormattingXml) {
+ $extCfRuleXml = $extFormattingXml->cfRule;
+ $extFormattingRuleObj = new self((string) $extCfRuleXml->attributes()->id);
+ $extFormattingRuleObj->setSqref((string) $extFormattingXml->children($ns['xm'])->sqref);
+ $conditionalFormattingRuleExtensions[$extFormattingRuleObj->getId()] = $extFormattingRuleObj;
+
+ $extDataBarObj = new ConditionalDataBarExtension();
+ $extFormattingRuleObj->setDataBarExt($extDataBarObj);
+
+ $dataBarXml = $extCfRuleXml->dataBar;
+ self::parseExtDataBarAttributesFromXml($extDataBarObj, $dataBarXml);
+ self::parseExtDataBarElementChildrenFromXml($extDataBarObj, $dataBarXml, $ns);
+ }
+ }
+ }
+
+ return $conditionalFormattingRuleExtensions;
+ }
+
+ private static function parseExtDataBarAttributesFromXml(ConditionalDataBarExtension $extDataBarObj, SimpleXMLElement $dataBarXml): void
+ {
+ $dataBarAttribute = $dataBarXml->attributes();
+ if ($dataBarAttribute->minLength) {
+ $extDataBarObj->setMinLength((int) $dataBarAttribute->minLength);
+ }
+ if ($dataBarAttribute->maxLength) {
+ $extDataBarObj->setMaxLength((int) $dataBarAttribute->maxLength);
+ }
+ if ($dataBarAttribute->border) {
+ $extDataBarObj->setBorder((bool) (string) $dataBarAttribute->border);
+ }
+ if ($dataBarAttribute->gradient) {
+ $extDataBarObj->setGradient((bool) (string) $dataBarAttribute->gradient);
+ }
+ if ($dataBarAttribute->direction) {
+ $extDataBarObj->setDirection((string) $dataBarAttribute->direction);
+ }
+ if ($dataBarAttribute->negativeBarBorderColorSameAsPositive) {
+ $extDataBarObj->setNegativeBarBorderColorSameAsPositive((bool) (string) $dataBarAttribute->negativeBarBorderColorSameAsPositive);
+ }
+ if ($dataBarAttribute->axisPosition) {
+ $extDataBarObj->setAxisPosition((string) $dataBarAttribute->axisPosition);
+ }
+ }
+
+ private static function parseExtDataBarElementChildrenFromXml(ConditionalDataBarExtension $extDataBarObj, SimpleXMLElement $dataBarXml, $ns): void
+ {
+ if ($dataBarXml->borderColor) {
+ $extDataBarObj->setBorderColor((string) $dataBarXml->borderColor->attributes()['rgb']);
+ }
+ if ($dataBarXml->negativeFillColor) {
+ $extDataBarObj->setNegativeFillColor((string) $dataBarXml->negativeFillColor->attributes()['rgb']);
+ }
+ if ($dataBarXml->negativeBorderColor) {
+ $extDataBarObj->setNegativeBorderColor((string) $dataBarXml->negativeBorderColor->attributes()['rgb']);
+ }
+ if ($dataBarXml->axisColor) {
+ $axisColorAttr = $dataBarXml->axisColor->attributes();
+ $extDataBarObj->setAxisColor((string) $axisColorAttr['rgb'], (string) $axisColorAttr['theme'], (string) $axisColorAttr['tint']);
+ }
+ $cfvoIndex = 0;
+ foreach ($dataBarXml->cfvo as $cfvo) {
+ $f = (string) $cfvo->children($ns['xm'])->f;
+ if ($cfvoIndex === 0) {
+ $extDataBarObj->setMinimumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo->attributes()['type'], null, (empty($f) ? null : $f)));
+ }
+ if ($cfvoIndex === 1) {
+ $extDataBarObj->setMaximumConditionalFormatValueObject(new ConditionalFormatValueObject((string) $cfvo->attributes()['type'], null, (empty($f) ? null : $f)));
+ }
+ ++$cfvoIndex;
+ }
+ }
+
+ /**
+ * @return mixed
+ */
+ public function getId()
+ {
+ return $this->id;
+ }
+
+ /**
+ * @param mixed $id
+ */
+ public function setId($id): self
+ {
+ $this->id = $id;
+
+ return $this;
+ }
+
+ public function getCfRule(): string
+ {
+ return $this->cfRule;
+ }
+
+ public function setCfRule(string $cfRule): self
+ {
+ $this->cfRule = $cfRule;
+
+ return $this;
+ }
+
+ public function getDataBarExt(): ConditionalDataBarExtension
+ {
+ return $this->dataBar;
+ }
+
+ public function setDataBarExt(ConditionalDataBarExtension $dataBar): self
+ {
+ $this->dataBar = $dataBar;
+
+ return $this;
+ }
+
+ public function getSqref(): string
+ {
+ return $this->sqref;
+ }
+
+ public function setSqref(string $sqref): self
+ {
+ $this->sqref = $sqref;
+
+ return $this;
+ }
+}
diff --git a/src/PhpSpreadsheet/Style/Fill.php b/src/PhpSpreadsheet/Style/Fill.php
index 3891bc47..e793f1e7 100644
--- a/src/PhpSpreadsheet/Style/Fill.php
+++ b/src/PhpSpreadsheet/Style/Fill.php
@@ -28,19 +28,19 @@ class Fill extends Supervisor
const FILL_PATTERN_MEDIUMGRAY = 'mediumGray';
/**
- * @var int
+ * @var null|int
*/
public $startcolorIndex;
/**
- * @var int
+ * @var null|int
*/
public $endcolorIndex;
/**
* Fill type.
*
- * @var string
+ * @var null|string
*/
protected $fillType = self::FILL_NONE;
@@ -168,7 +168,7 @@ class Fill extends Supervisor
/**
* Get Fill Type.
*
- * @return string
+ * @return null|string
*/
public function getFillType()
{
diff --git a/src/PhpSpreadsheet/Style/Font.php b/src/PhpSpreadsheet/Style/Font.php
index ad405708..473fe1dc 100644
--- a/src/PhpSpreadsheet/Style/Font.php
+++ b/src/PhpSpreadsheet/Style/Font.php
@@ -14,56 +14,56 @@ class Font extends Supervisor
/**
* Font Name.
*
- * @var string
+ * @var null|string
*/
protected $name = 'Calibri';
/**
* Font Size.
*
- * @var float
+ * @var null|float
*/
protected $size = 11;
/**
* Bold.
*
- * @var bool
+ * @var null|bool
*/
protected $bold = false;
/**
* Italic.
*
- * @var bool
+ * @var null|bool
*/
protected $italic = false;
/**
* Superscript.
*
- * @var bool
+ * @var null|bool
*/
protected $superscript = false;
/**
* Subscript.
*
- * @var bool
+ * @var null|bool
*/
protected $subscript = false;
/**
* Underline.
*
- * @var string
+ * @var null|string
*/
protected $underline = self::UNDERLINE_NONE;
/**
* Strikethrough.
*
- * @var bool
+ * @var null|bool
*/
protected $strikethrough = false;
@@ -75,7 +75,7 @@ class Font extends Supervisor
protected $color;
/**
- * @var int
+ * @var null|int
*/
public $colorIndex;
@@ -199,7 +199,7 @@ class Font extends Supervisor
/**
* Get Name.
*
- * @return string
+ * @return null|string
*/
public function getName()
{
@@ -235,7 +235,7 @@ class Font extends Supervisor
/**
* Get Size.
*
- * @return float
+ * @return null|float
*/
public function getSize()
{
@@ -271,7 +271,7 @@ class Font extends Supervisor
/**
* Get Bold.
*
- * @return bool
+ * @return null|bool
*/
public function getBold()
{
@@ -307,7 +307,7 @@ class Font extends Supervisor
/**
* Get Italic.
*
- * @return bool
+ * @return null|bool
*/
public function getItalic()
{
@@ -343,7 +343,7 @@ class Font extends Supervisor
/**
* Get Superscript.
*
- * @return bool
+ * @return null|bool
*/
public function getSuperscript()
{
@@ -377,7 +377,7 @@ class Font extends Supervisor
/**
* Get Subscript.
*
- * @return bool
+ * @return null|bool
*/
public function getSubscript()
{
@@ -411,7 +411,7 @@ class Font extends Supervisor
/**
* Get Underline.
*
- * @return string
+ * @return null|string
*/
public function getUnderline()
{
@@ -451,7 +451,7 @@ class Font extends Supervisor
/**
* Get Strikethrough.
*
- * @return bool
+ * @return null|bool
*/
public function getStrikethrough()
{
diff --git a/src/PhpSpreadsheet/Style/NumberFormat.php b/src/PhpSpreadsheet/Style/NumberFormat.php
index 0b761bd3..6235d864 100644
--- a/src/PhpSpreadsheet/Style/NumberFormat.php
+++ b/src/PhpSpreadsheet/Style/NumberFormat.php
@@ -2,10 +2,6 @@
namespace PhpOffice\PhpSpreadsheet\Style;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
-
class NumberFormat extends Supervisor
{
// Pre-defined formats
@@ -68,14 +64,14 @@ class NumberFormat extends Supervisor
/**
* Format Code.
*
- * @var string
+ * @var null|string
*/
protected $formatCode = self::FORMAT_GENERAL;
/**
* Built-in format Code.
*
- * @var string
+ * @var false|int
*/
protected $builtInFormatCode = 0;
@@ -154,7 +150,7 @@ class NumberFormat extends Supervisor
/**
* Get Format Code.
*
- * @return string
+ * @return null|string
*/
public function getFormatCode()
{
@@ -194,7 +190,7 @@ class NumberFormat extends Supervisor
/**
* Get Built-In Format Code.
*
- * @return int
+ * @return false|int
*/
public function getBuiltInFormatCode()
{
@@ -389,428 +385,6 @@ class NumberFormat extends Supervisor
);
}
- /**
- * Search/replace values to convert Excel date/time format masks to PHP format masks.
- *
- * @var array
- */
- private static $dateFormatReplacements = [
- // first remove escapes related to non-format characters
- '\\' => '',
- // 12-hour suffix
- 'am/pm' => 'A',
- // 4-digit year
- 'e' => 'Y',
- 'yyyy' => 'Y',
- // 2-digit year
- 'yy' => 'y',
- // first letter of month - no php equivalent
- 'mmmmm' => 'M',
- // full month name
- 'mmmm' => 'F',
- // short month name
- 'mmm' => 'M',
- // mm is minutes if time, but can also be month w/leading zero
- // so we try to identify times be the inclusion of a : separator in the mask
- // It isn't perfect, but the best way I know how
- ':mm' => ':i',
- 'mm:' => 'i:',
- // month leading zero
- 'mm' => 'm',
- // month no leading zero
- 'm' => 'n',
- // full day of week name
- 'dddd' => 'l',
- // short day of week name
- 'ddd' => 'D',
- // days leading zero
- 'dd' => 'd',
- // days no leading zero
- 'd' => 'j',
- // seconds
- 'ss' => 's',
- // fractional seconds - no php equivalent
- '.s' => '',
- ];
-
- /**
- * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock).
- *
- * @var array
- */
- private static $dateFormatReplacements24 = [
- 'hh' => 'H',
- 'h' => 'G',
- ];
-
- /**
- * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock).
- *
- * @var array
- */
- private static $dateFormatReplacements12 = [
- 'hh' => 'h',
- 'h' => 'g',
- ];
-
- private static function setLowercaseCallback($matches)
- {
- return mb_strtolower($matches[0]);
- }
-
- private static function escapeQuotesCallback($matches)
- {
- return '\\' . implode('\\', str_split($matches[1]));
- }
-
- private static function formatAsDate(&$value, &$format): void
- {
- // strip off first part containing e.g. [$-F800] or [$USD-409]
- // general syntax: [$-]
- // language info is in hexadecimal
- // strip off chinese part like [DBNum1][$-804]
- $format = preg_replace('/^(\[[0-9A-Za-z]*\])*(\[\$[A-Z]*-[0-9A-F]*\])/i', '', $format);
-
- // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case;
- // but we don't want to change any quoted strings
- $format = preg_replace_callback('/(?:^|")([^"]*)(?:$|")/', ['self', 'setLowercaseCallback'], $format);
-
- // Only process the non-quoted blocks for date format characters
- $blocks = explode('"', $format);
- foreach ($blocks as $key => &$block) {
- if ($key % 2 == 0) {
- $block = strtr($block, self::$dateFormatReplacements);
- if (!strpos($block, 'A')) {
- // 24-hour time format
- // when [h]:mm format, the [h] should replace to the hours of the value * 24
- if (false !== strpos($block, '[h]')) {
- $hours = (int) ($value * 24);
- $block = str_replace('[h]', $hours, $block);
-
- continue;
- }
- $block = strtr($block, self::$dateFormatReplacements24);
- } else {
- // 12-hour time format
- $block = strtr($block, self::$dateFormatReplacements12);
- }
- }
- }
- $format = implode('"', $blocks);
-
- // escape any quoted characters so that DateTime format() will render them correctly
- $format = preg_replace_callback('/"(.*)"/U', ['self', 'escapeQuotesCallback'], $format);
-
- $dateObj = Date::excelToDateTimeObject($value);
- $value = $dateObj->format($format);
- }
-
- private static function formatAsPercentage(&$value, &$format): void
- {
- if ($format === self::FORMAT_PERCENTAGE) {
- $value = round((100 * $value), 0) . '%';
- } else {
- if (preg_match('/\.[#0]+/', $format, $m)) {
- $s = substr($m[0], 0, 1) . (strlen($m[0]) - 1);
- $format = str_replace($m[0], $s, $format);
- }
- if (preg_match('/^[#0]+/', $format, $m)) {
- $format = str_replace($m[0], strlen($m[0]), $format);
- }
- $format = '%' . str_replace('%', 'f%%', $format);
-
- $value = sprintf($format, 100 * $value);
- }
- }
-
- private static function formatAsFraction(&$value, &$format): void
- {
- $sign = ($value < 0) ? '-' : '';
-
- $integerPart = floor(abs($value));
- $decimalPart = trim(fmod(abs($value), 1), '0.');
- $decimalLength = strlen($decimalPart);
- $decimalDivisor = 10 ** $decimalLength;
-
- $GCD = MathTrig::GCD($decimalPart, $decimalDivisor);
-
- $adjustedDecimalPart = $decimalPart / $GCD;
- $adjustedDecimalDivisor = $decimalDivisor / $GCD;
-
- if ((strpos($format, '0') !== false)) {
- $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
- } elseif ((strpos($format, '#') !== false)) {
- if ($integerPart == 0) {
- $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor";
- } else {
- $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
- }
- } elseif ((substr($format, 0, 3) == '? ?')) {
- if ($integerPart == 0) {
- $integerPart = '';
- }
- $value = "$sign$integerPart $adjustedDecimalPart/$adjustedDecimalDivisor";
- } else {
- $adjustedDecimalPart += $integerPart * $adjustedDecimalDivisor;
- $value = "$sign$adjustedDecimalPart/$adjustedDecimalDivisor";
- }
- }
-
- private static function mergeComplexNumberFormatMasks($numbers, $masks)
- {
- $decimalCount = strlen($numbers[1]);
- $postDecimalMasks = [];
-
- do {
- $tempMask = array_pop($masks);
- $postDecimalMasks[] = $tempMask;
- $decimalCount -= strlen($tempMask);
- } while ($decimalCount > 0);
-
- return [
- implode('.', $masks),
- implode('.', array_reverse($postDecimalMasks)),
- ];
- }
-
- private static function processComplexNumberFormatMask($number, $mask)
- {
- $result = $number;
- $maskingBlockCount = preg_match_all('/0+/', $mask, $maskingBlocks, PREG_OFFSET_CAPTURE);
-
- if ($maskingBlockCount > 1) {
- $maskingBlocks = array_reverse($maskingBlocks[0]);
-
- foreach ($maskingBlocks as $block) {
- $divisor = 1 . $block[0];
- $size = strlen($block[0]);
- $offset = $block[1];
-
- $blockValue = sprintf(
- '%0' . $size . 'd',
- fmod($number, $divisor)
- );
- $number = floor($number / $divisor);
- $mask = substr_replace($mask, $blockValue, $offset, $size);
- }
- if ($number > 0) {
- $mask = substr_replace($mask, $number, $offset, 0);
- }
- $result = $mask;
- }
-
- return $result;
- }
-
- private static function complexNumberFormatMask($number, $mask, $splitOnPoint = true)
- {
- $sign = ($number < 0.0);
- $number = abs($number);
-
- if ($splitOnPoint && strpos($mask, '.') !== false && strpos($number, '.') !== false) {
- $numbers = explode('.', $number);
- $masks = explode('.', $mask);
- if (count($masks) > 2) {
- $masks = self::mergeComplexNumberFormatMasks($numbers, $masks);
- }
- $result1 = self::complexNumberFormatMask($numbers[0], $masks[0], false);
- $result2 = strrev(self::complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), false));
-
- return (($sign) ? '-' : '') . $result1 . '.' . $result2;
- }
-
- $result = self::processComplexNumberFormatMask($number, $mask);
-
- return (($sign) ? '-' : '') . $result;
- }
-
- private static function formatStraightNumericValue($value, $format, array $matches, $useThousands, $number_regex)
- {
- $left = $matches[1];
- $dec = $matches[2];
- $right = $matches[3];
-
- // minimun width of formatted number (including dot)
- $minWidth = strlen($left) + strlen($dec) + strlen($right);
- if ($useThousands) {
- $value = number_format(
- $value,
- strlen($right),
- StringHelper::getDecimalSeparator(),
- StringHelper::getThousandsSeparator()
- );
- $value = preg_replace($number_regex, $value, $format);
- } else {
- if (preg_match('/[0#]E[+-]0/i', $format)) {
- // Scientific format
- $value = sprintf('%5.2E', $value);
- } elseif (preg_match('/0([^\d\.]+)0/', $format) || substr_count($format, '.') > 1) {
- if ($value == (int) $value && substr_count($format, '.') === 1) {
- $value *= 10 ** strlen(explode('.', $format)[1]);
- }
- $value = self::complexNumberFormatMask($value, $format);
- } else {
- $sprintf_pattern = "%0$minWidth." . strlen($right) . 'f';
- $value = sprintf($sprintf_pattern, $value);
- $value = preg_replace($number_regex, $value, $format);
- }
- }
-
- return $value;
- }
-
- private static function formatAsNumber($value, $format)
- {
- // The "_" in this string has already been stripped out,
- // so this test is never true. Furthermore, testing
- // on Excel shows this format uses Euro symbol, not "EUR".
- //if ($format === self::FORMAT_CURRENCY_EUR_SIMPLE) {
- // return 'EUR ' . sprintf('%1.2f', $value);
- //}
-
- // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols
- $format = str_replace(['"', '*'], '', $format);
-
- // Find out if we need thousands separator
- // This is indicated by a comma enclosed by a digit placeholder:
- // #,# or 0,0
- $useThousands = preg_match('/(#,#|0,0)/', $format);
- if ($useThousands) {
- $format = preg_replace('/0,0/', '00', $format);
- $format = preg_replace('/#,#/', '##', $format);
- }
-
- // Scale thousands, millions,...
- // This is indicated by a number of commas after a digit placeholder:
- // #, or 0.0,,
- $scale = 1; // same as no scale
- $matches = [];
- if (preg_match('/(#|0)(,+)/', $format, $matches)) {
- $scale = 1000 ** strlen($matches[2]);
-
- // strip the commas
- $format = preg_replace('/0,+/', '0', $format);
- $format = preg_replace('/#,+/', '#', $format);
- }
-
- if (preg_match('/#?.*\?\/\?/', $format, $m)) {
- if ($value != (int) $value) {
- self::formatAsFraction($value, $format);
- }
- } else {
- // Handle the number itself
-
- // scale number
- $value = $value / $scale;
- // Strip #
- $format = preg_replace('/\\#/', '0', $format);
- // Remove locale code [$-###]
- $format = preg_replace('/\[\$\-.*\]/', '', $format);
-
- $n = '/\\[[^\\]]+\\]/';
- $m = preg_replace($n, '', $format);
- $number_regex = '/(0+)(\\.?)(0*)/';
- if (preg_match($number_regex, $m, $matches)) {
- $value = self::formatStraightNumericValue($value, $format, $matches, $useThousands, $number_regex);
- }
- }
-
- if (preg_match('/\[\$(.*)\]/u', $format, $m)) {
- // Currency or Accounting
- $currencyCode = $m[1];
- [$currencyCode] = explode('-', $currencyCode);
- if ($currencyCode == '') {
- $currencyCode = StringHelper::getCurrencyCode();
- }
- $value = preg_replace('/\[\$([^\]]*)\]/u', $currencyCode, $value);
- }
-
- return $value;
- }
-
- private static function splitFormatCompare($value, $cond, $val, $dfcond, $dfval)
- {
- if (!$cond) {
- $cond = $dfcond;
- $val = $dfval;
- }
- switch ($cond) {
- case '>':
- return $value > $val;
-
- case '<':
- return $value < $val;
-
- case '<=':
- return $value <= $val;
-
- case '<>':
- return $value != $val;
-
- case '=':
- return $value == $val;
- }
-
- return $value >= $val;
- }
-
- private static function splitFormat($sections, $value)
- {
- // Extract the relevant section depending on whether number is positive, negative, or zero?
- // Text not supported yet.
- // Here is how the sections apply to various values in Excel:
- // 1 section: [POSITIVE/NEGATIVE/ZERO/TEXT]
- // 2 sections: [POSITIVE/ZERO/TEXT] [NEGATIVE]
- // 3 sections: [POSITIVE/TEXT] [NEGATIVE] [ZERO]
- // 4 sections: [POSITIVE] [NEGATIVE] [ZERO] [TEXT]
- $cnt = count($sections);
- $color_regex = '/\\[(' . implode('|', Color::NAMED_COLORS) . ')\\]/';
- $cond_regex = '/\\[(>|>=|<|<=|=|<>)([+-]?\\d+([.]\\d+)?)\\]/';
- $colors = ['', '', '', '', ''];
- $condops = ['', '', '', '', ''];
- $condvals = [0, 0, 0, 0, 0];
- for ($idx = 0; $idx < $cnt; ++$idx) {
- if (preg_match($color_regex, $sections[$idx], $matches)) {
- $colors[$idx] = $matches[0];
- $sections[$idx] = preg_replace($color_regex, '', $sections[$idx]);
- }
- if (preg_match($cond_regex, $sections[$idx], $matches)) {
- $condops[$idx] = $matches[1];
- $condvals[$idx] = $matches[2];
- $sections[$idx] = preg_replace($cond_regex, '', $sections[$idx]);
- }
- }
- $color = $colors[0];
- $format = $sections[0];
- $absval = $value;
- switch ($cnt) {
- case 2:
- $absval = abs($value);
- if (!self::splitFormatCompare($value, $condops[0], $condvals[0], '>=', 0)) {
- $color = $colors[1];
- $format = $sections[1];
- }
-
- break;
- case 3:
- case 4:
- $absval = abs($value);
- if (!self::splitFormatCompare($value, $condops[0], $condvals[0], '>', 0)) {
- if (self::splitFormatCompare($value, $condops[1], $condvals[1], '<', 0)) {
- $color = $colors[1];
- $format = $sections[1];
- } else {
- $color = $colors[2];
- $format = $sections[2];
- }
- }
-
- break;
- }
-
- return [$color, $format, $absval];
- }
-
/**
* Convert a value in a pre-defined format to a PHP string.
*
@@ -822,53 +396,7 @@ class NumberFormat extends Supervisor
*/
public static function toFormattedString($value, $format, $callBack = null)
{
- // For now we do not treat strings although section 4 of a format code affects strings
- if (!is_numeric($value)) {
- return $value;
- }
-
- // For 'General' format code, we just pass the value although this is not entirely the way Excel does it,
- // it seems to round numbers to a total of 10 digits.
- if (($format === self::FORMAT_GENERAL) || ($format === self::FORMAT_TEXT)) {
- return $value;
- }
-
- // Convert any other escaped characters to quoted strings, e.g. (\T to "T")
- $format = preg_replace('/(\\\(((.)(?!((AM\/PM)|(A\/P))))|([^ ])))(?=(?:[^"]|"[^"]*")*$)/u', '"${2}"', $format);
-
- // Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal)
- $sections = preg_split('/(;)(?=(?:[^"]|"[^"]*")*$)/u', $format);
-
- [$colors, $format, $value] = self::splitFormat($sections, $value);
-
- // In Excel formats, "_" is used to add spacing,
- // The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space
- $format = preg_replace('/_./', ' ', $format);
-
- // Let's begin inspecting the format and converting the value to a formatted string
-
- // Check for date/time characters (not inside quotes)
- if (preg_match('/(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy](?=(?:[^"]|"[^"]*")*$)/miu', $format, $matches)) {
- // datetime format
- self::formatAsDate($value, $format);
- } else {
- if (substr($format, 0, 1) === '"' && substr($format, -1, 1) === '"') {
- $value = substr($format, 1, -1);
- } elseif (preg_match('/%$/', $format)) {
- // % number format
- self::formatAsPercentage($value, $format);
- } else {
- $value = self::formatAsNumber($value, $format);
- }
- }
-
- // Additional formatting provided by callback function
- if ($callBack !== null) {
- [$writerInstance, $function] = $callBack;
- $value = $writerInstance->$function($value, $colors);
- }
-
- return $value;
+ return NumberFormat\Formatter::toFormattedString($value, $format, $callBack);
}
protected function exportArray1(): array
diff --git a/src/PhpSpreadsheet/Style/NumberFormat/BaseFormatter.php b/src/PhpSpreadsheet/Style/NumberFormat/BaseFormatter.php
new file mode 100644
index 00000000..7988143c
--- /dev/null
+++ b/src/PhpSpreadsheet/Style/NumberFormat/BaseFormatter.php
@@ -0,0 +1,12 @@
+ '',
+ // 12-hour suffix
+ 'am/pm' => 'A',
+ // 4-digit year
+ 'e' => 'Y',
+ 'yyyy' => 'Y',
+ // 2-digit year
+ 'yy' => 'y',
+ // first letter of month - no php equivalent
+ 'mmmmm' => 'M',
+ // full month name
+ 'mmmm' => 'F',
+ // short month name
+ 'mmm' => 'M',
+ // mm is minutes if time, but can also be month w/leading zero
+ // so we try to identify times be the inclusion of a : separator in the mask
+ // It isn't perfect, but the best way I know how
+ ':mm' => ':i',
+ 'mm:' => 'i:',
+ // month leading zero
+ 'mm' => 'm',
+ // month no leading zero
+ 'm' => 'n',
+ // full day of week name
+ 'dddd' => 'l',
+ // short day of week name
+ 'ddd' => 'D',
+ // days leading zero
+ 'dd' => 'd',
+ // days no leading zero
+ 'd' => 'j',
+ // seconds
+ 'ss' => 's',
+ // fractional seconds - no php equivalent
+ '.s' => '',
+ ];
+
+ /**
+ * Search/replace values to convert Excel date/time format masks hours to PHP format masks (24 hr clock).
+ *
+ * @var array
+ */
+ private static $dateFormatReplacements24 = [
+ 'hh' => 'H',
+ 'h' => 'G',
+ ];
+
+ /**
+ * Search/replace values to convert Excel date/time format masks hours to PHP format masks (12 hr clock).
+ *
+ * @var array
+ */
+ private static $dateFormatReplacements12 = [
+ 'hh' => 'h',
+ 'h' => 'g',
+ ];
+
+ public static function format($value, string $format): string
+ {
+ // strip off first part containing e.g. [$-F800] or [$USD-409]
+ // general syntax: [$-]
+ // language info is in hexadecimal
+ // strip off chinese part like [DBNum1][$-804]
+ $format = preg_replace('/^(\[DBNum\d\])*(\[\$[^\]]*\])/i', '', $format);
+
+ // OpenOffice.org uses upper-case number formats, e.g. 'YYYY', convert to lower-case;
+ // but we don't want to change any quoted strings
+ $format = preg_replace_callback('/(?:^|")([^"]*)(?:$|")/', ['self', 'setLowercaseCallback'], $format);
+
+ // Only process the non-quoted blocks for date format characters
+ $blocks = explode('"', $format);
+ foreach ($blocks as $key => &$block) {
+ if ($key % 2 == 0) {
+ $block = strtr($block, self::$dateFormatReplacements);
+ if (!strpos($block, 'A')) {
+ // 24-hour time format
+ // when [h]:mm format, the [h] should replace to the hours of the value * 24
+ if (false !== strpos($block, '[h]')) {
+ $hours = (int) ($value * 24);
+ $block = str_replace('[h]', $hours, $block);
+
+ continue;
+ }
+ $block = strtr($block, self::$dateFormatReplacements24);
+ } else {
+ // 12-hour time format
+ $block = strtr($block, self::$dateFormatReplacements12);
+ }
+ }
+ }
+ $format = implode('"', $blocks);
+
+ // escape any quoted characters so that DateTime format() will render them correctly
+ $format = preg_replace_callback('/"(.*)"/U', ['self', 'escapeQuotesCallback'], $format);
+
+ $dateObj = Date::excelToDateTimeObject($value);
+ // If the colon preceding minute had been quoted, as happens in
+ // Excel 2003 XML formats, m will not have been changed to i above.
+ // Change it now.
+ $format = \preg_replace('/\\\\:m/', ':i', $format);
+
+ return $dateObj->format($format);
+ }
+
+ private static function setLowercaseCallback($matches): string
+ {
+ return mb_strtolower($matches[0]);
+ }
+
+ private static function escapeQuotesCallback($matches): string
+ {
+ return '\\' . implode('\\', str_split($matches[1]));
+ }
+}
diff --git a/src/PhpSpreadsheet/Style/NumberFormat/Formatter.php b/src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
new file mode 100644
index 00000000..ef756d7b
--- /dev/null
+++ b/src/PhpSpreadsheet/Style/NumberFormat/Formatter.php
@@ -0,0 +1,162 @@
+':
+ return $value > $val;
+
+ case '<':
+ return $value < $val;
+
+ case '<=':
+ return $value <= $val;
+
+ case '<>':
+ return $value != $val;
+
+ case '=':
+ return $value == $val;
+ }
+
+ return $value >= $val;
+ }
+
+ private static function splitFormat($sections, $value)
+ {
+ // Extract the relevant section depending on whether number is positive, negative, or zero?
+ // Text not supported yet.
+ // Here is how the sections apply to various values in Excel:
+ // 1 section: [POSITIVE/NEGATIVE/ZERO/TEXT]
+ // 2 sections: [POSITIVE/ZERO/TEXT] [NEGATIVE]
+ // 3 sections: [POSITIVE/TEXT] [NEGATIVE] [ZERO]
+ // 4 sections: [POSITIVE] [NEGATIVE] [ZERO] [TEXT]
+ $cnt = count($sections);
+ $color_regex = '/\\[(' . implode('|', Color::NAMED_COLORS) . ')\\]/mui';
+ $cond_regex = '/\\[(>|>=|<|<=|=|<>)([+-]?\\d+([.]\\d+)?)\\]/';
+ $colors = ['', '', '', '', ''];
+ $condops = ['', '', '', '', ''];
+ $condvals = [0, 0, 0, 0, 0];
+ for ($idx = 0; $idx < $cnt; ++$idx) {
+ if (preg_match($color_regex, $sections[$idx], $matches)) {
+ $colors[$idx] = $matches[0];
+ $sections[$idx] = preg_replace($color_regex, '', $sections[$idx]);
+ }
+ if (preg_match($cond_regex, $sections[$idx], $matches)) {
+ $condops[$idx] = $matches[1];
+ $condvals[$idx] = $matches[2];
+ $sections[$idx] = preg_replace($cond_regex, '', $sections[$idx]);
+ }
+ }
+ $color = $colors[0];
+ $format = $sections[0];
+ $absval = $value;
+ switch ($cnt) {
+ case 2:
+ $absval = abs($value);
+ if (!self::splitFormatCompare($value, $condops[0], $condvals[0], '>=', 0)) {
+ $color = $colors[1];
+ $format = $sections[1];
+ }
+
+ break;
+ case 3:
+ case 4:
+ $absval = abs($value);
+ if (!self::splitFormatCompare($value, $condops[0], $condvals[0], '>', 0)) {
+ if (self::splitFormatCompare($value, $condops[1], $condvals[1], '<', 0)) {
+ $color = $colors[1];
+ $format = $sections[1];
+ } else {
+ $color = $colors[2];
+ $format = $sections[2];
+ }
+ }
+
+ break;
+ }
+
+ return [$color, $format, $absval];
+ }
+
+ /**
+ * Convert a value in a pre-defined format to a PHP string.
+ *
+ * @param mixed $value Value to format
+ * @param string $format Format code, see = NumberFormat::FORMAT_*
+ * @param array $callBack Callback function for additional formatting of string
+ *
+ * @return string Formatted string
+ */
+ public static function toFormattedString($value, $format, $callBack = null)
+ {
+ // For now we do not treat strings although section 4 of a format code affects strings
+ if (!is_numeric($value)) {
+ return $value;
+ }
+
+ // For 'General' format code, we just pass the value although this is not entirely the way Excel does it,
+ // it seems to round numbers to a total of 10 digits.
+ if (($format === NumberFormat::FORMAT_GENERAL) || ($format === NumberFormat::FORMAT_TEXT)) {
+ return $value;
+ }
+
+ $format = preg_replace_callback(
+ '/(["])(?:(?=(\\\\?))\\2.)*?\\1/u',
+ function ($matches) {
+ return str_replace('.', chr(0x00), $matches[0]);
+ },
+ $format
+ );
+
+ // Convert any other escaped characters to quoted strings, e.g. (\T to "T")
+ $format = preg_replace('/(\\\(((.)(?!((AM\/PM)|(A\/P))))|([^ ])))(?=(?:[^"]|"[^"]*")*$)/ui', '"${2}"', $format);
+
+ // Get the sections, there can be up to four sections, separated with a semi-colon (but only if not a quoted literal)
+ $sections = preg_split('/(;)(?=(?:[^"]|"[^"]*")*$)/u', $format);
+
+ [$colors, $format, $value] = self::splitFormat($sections, $value);
+
+ // In Excel formats, "_" is used to add spacing,
+ // The following character indicates the size of the spacing, which we can't do in HTML, so we just use a standard space
+ $format = preg_replace('/_/ui', ' ', $format);
+
+ // Let's begin inspecting the format and converting the value to a formatted string
+
+ // Check for date/time characters (not inside quotes)
+ if (preg_match('/(\[\$[A-Z]*-[0-9A-F]*\])*[hmsdy](?=(?:[^"]|"[^"]*")*$)/miu', $format, $matches)) {
+ // datetime format
+ $value = DateFormatter::format($value, $format);
+ } else {
+ if (substr($format, 0, 1) === '"' && substr($format, -1, 1) === '"' && substr_count($format, '"') === 2) {
+ $value = substr($format, 1, -1);
+ } elseif (preg_match('/[0#, ]%/', $format)) {
+ // % number format
+ $value = PercentageFormatter::format($value, $format);
+ } else {
+ $value = NumberFormatter::format($value, $format);
+ }
+ }
+
+ // Additional formatting provided by callback function
+ if ($callBack !== null) {
+ [$writerInstance, $function] = $callBack;
+ $value = $writerInstance->$function($value, $colors);
+ }
+
+ $value = str_replace(chr(0x00), '.', $value);
+
+ return $value;
+ }
+}
diff --git a/src/PhpSpreadsheet/Style/NumberFormat/FractionFormatter.php b/src/PhpSpreadsheet/Style/NumberFormat/FractionFormatter.php
new file mode 100644
index 00000000..48d927f2
--- /dev/null
+++ b/src/PhpSpreadsheet/Style/NumberFormat/FractionFormatter.php
@@ -0,0 +1,45 @@
+ 0);
+
+ return [
+ implode('.', $masks),
+ implode('.', array_reverse($postDecimalMasks)),
+ ];
+ }
+
+ private static function processComplexNumberFormatMask($number, $mask): string
+ {
+ $result = $number;
+ $maskingBlockCount = preg_match_all('/0+/', $mask, $maskingBlocks, PREG_OFFSET_CAPTURE);
+
+ if ($maskingBlockCount > 1) {
+ $maskingBlocks = array_reverse($maskingBlocks[0]);
+
+ $offset = 0;
+ foreach ($maskingBlocks as $block) {
+ $size = strlen($block[0]);
+ $divisor = 10 ** $size;
+ $offset = $block[1];
+
+ $blockValue = sprintf("%0{$size}d", fmod($number, $divisor));
+ $number = floor($number / $divisor);
+ $mask = substr_replace($mask, $blockValue, $offset, $size);
+ }
+ if ($number > 0) {
+ $mask = substr_replace($mask, $number, $offset, 0);
+ }
+ $result = $mask;
+ }
+
+ return $result;
+ }
+
+ private static function complexNumberFormatMask($number, $mask, $splitOnPoint = true): string
+ {
+ $sign = ($number < 0.0) ? '-' : '';
+ $number = abs($number);
+
+ if ($splitOnPoint && strpos($mask, '.') !== false && strpos($number, '.') !== false) {
+ $numbers = explode('.', $number);
+ $masks = explode('.', $mask);
+ if (count($masks) > 2) {
+ $masks = self::mergeComplexNumberFormatMasks($numbers, $masks);
+ }
+ $integerPart = self::complexNumberFormatMask($numbers[0], $masks[0], false);
+ $decimalPart = strrev(self::complexNumberFormatMask(strrev($numbers[1]), strrev($masks[1]), false));
+
+ return "{$sign}{$integerPart}.{$decimalPart}";
+ }
+
+ $result = self::processComplexNumberFormatMask($number, $mask);
+
+ return "{$sign}{$result}";
+ }
+
+ private static function formatStraightNumericValue($value, $format, array $matches, $useThousands): string
+ {
+ $left = $matches[1];
+ $dec = $matches[2];
+ $right = $matches[3];
+
+ // minimun width of formatted number (including dot)
+ $minWidth = strlen($left) + strlen($dec) + strlen($right);
+ if ($useThousands) {
+ $value = number_format(
+ $value,
+ strlen($right),
+ StringHelper::getDecimalSeparator(),
+ StringHelper::getThousandsSeparator()
+ );
+
+ return preg_replace(self::NUMBER_REGEX, $value, $format);
+ }
+
+ if (preg_match('/[0#]E[+-]0/i', $format)) {
+ // Scientific format
+ return sprintf('%5.2E', $value);
+ } elseif (preg_match('/0([^\d\.]+)0/', $format) || substr_count($format, '.') > 1) {
+ if ($value == (int) $value && substr_count($format, '.') === 1) {
+ $value *= 10 ** strlen(explode('.', $format)[1]);
+ }
+
+ return self::complexNumberFormatMask($value, $format);
+ }
+
+ $sprintf_pattern = "%0$minWidth." . strlen($right) . 'f';
+ $value = sprintf($sprintf_pattern, $value);
+
+ return preg_replace(self::NUMBER_REGEX, $value, $format);
+ }
+
+ public static function format($value, $format): string
+ {
+ // The "_" in this string has already been stripped out,
+ // so this test is never true. Furthermore, testing
+ // on Excel shows this format uses Euro symbol, not "EUR".
+ //if ($format === NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE) {
+ // return 'EUR ' . sprintf('%1.2f', $value);
+ //}
+
+ // Some non-number strings are quoted, so we'll get rid of the quotes, likewise any positional * symbols
+ $format = str_replace(['"', '*'], '', $format);
+
+ // Find out if we need thousands separator
+ // This is indicated by a comma enclosed by a digit placeholder:
+ // #,# or 0,0
+ $useThousands = preg_match('/(#,#|0,0)/', $format);
+ if ($useThousands) {
+ $format = preg_replace('/0,0/', '00', $format);
+ $format = preg_replace('/#,#/', '##', $format);
+ }
+
+ // Scale thousands, millions,...
+ // This is indicated by a number of commas after a digit placeholder:
+ // #, or 0.0,,
+ $scale = 1; // same as no scale
+ $matches = [];
+ if (preg_match('/(#|0)(,+)/', $format, $matches)) {
+ $scale = 1000 ** strlen($matches[2]);
+
+ // strip the commas
+ $format = preg_replace('/0,+/', '0', $format);
+ $format = preg_replace('/#,+/', '#', $format);
+ }
+
+ if (preg_match('/#?.*\?\/\?/', $format, $m)) {
+ if ($value != (int) $value) {
+ $value = FractionFormatter::format($value, $format);
+ }
+ } else {
+ // Handle the number itself
+
+ // scale number
+ $value = $value / $scale;
+ // Strip #
+ $format = preg_replace('/\\#/', '0', $format);
+ // Remove locale code [$-###]
+ $format = preg_replace('/\[\$\-.*\]/', '', $format);
+
+ $n = '/\\[[^\\]]+\\]/';
+ $m = preg_replace($n, '', $format);
+ if (preg_match(self::NUMBER_REGEX, $m, $matches)) {
+ $value = self::formatStraightNumericValue($value, $format, $matches, $useThousands);
+ }
+ }
+
+ if (preg_match('/\[\$(.*)\]/u', $format, $m)) {
+ // Currency or Accounting
+ $currencyCode = $m[1];
+ [$currencyCode] = explode('-', $currencyCode);
+ if ($currencyCode == '') {
+ $currencyCode = StringHelper::getCurrencyCode();
+ }
+ $value = preg_replace('/\[\$([^\]]*)\]/u', $currencyCode, $value);
+ }
+
+ return $value;
+ }
+}
diff --git a/src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php b/src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php
new file mode 100644
index 00000000..cf1731ec
--- /dev/null
+++ b/src/PhpSpreadsheet/Style/NumberFormat/PercentageFormatter.php
@@ -0,0 +1,42 @@
+font = new Font($isSupervisor, $isConditional);
$this->fill = new Fill($isSupervisor, $isConditional);
- $this->borders = new Borders($isSupervisor, $isConditional);
+ $this->borders = new Borders($isSupervisor);
$this->alignment = new Alignment($isSupervisor, $isConditional);
$this->numberFormat = new NumberFormat($isSupervisor, $isConditional);
$this->protection = new Protection($isSupervisor, $isConditional);
@@ -202,18 +202,17 @@ class Style extends Supervisor
// Calculate range outer borders
$rangeStart = Coordinate::coordinateFromString($rangeA);
$rangeEnd = Coordinate::coordinateFromString($rangeB);
+ $rangeStartIndexes = Coordinate::indexesFromString($rangeA);
+ $rangeEndIndexes = Coordinate::indexesFromString($rangeB);
- // Translate column into index
- $rangeStart0 = $rangeStart[0];
- $rangeEnd0 = $rangeEnd[0];
- $rangeStart[0] = Coordinate::columnIndexFromString($rangeStart[0]);
- $rangeEnd[0] = Coordinate::columnIndexFromString($rangeEnd[0]);
+ $columnStart = $rangeStart[0];
+ $columnEnd = $rangeEnd[0];
// Make sure we can loop upwards on rows and columns
- if ($rangeStart[0] > $rangeEnd[0] && $rangeStart[1] > $rangeEnd[1]) {
- $tmp = $rangeStart;
- $rangeStart = $rangeEnd;
- $rangeEnd = $tmp;
+ if ($rangeStartIndexes[0] > $rangeEndIndexes[0] && $rangeStartIndexes[1] > $rangeEndIndexes[1]) {
+ $tmp = $rangeStartIndexes;
+ $rangeStartIndexes = $rangeEndIndexes;
+ $rangeEndIndexes = $tmp;
}
// ADVANCED MODE:
@@ -249,19 +248,19 @@ class Style extends Supervisor
unset($pStyles['borders']['inside']); // not needed any more
}
// width and height characteristics of selection, 1, 2, or 3 (for 3 or more)
- $xMax = min($rangeEnd[0] - $rangeStart[0] + 1, 3);
- $yMax = min($rangeEnd[1] - $rangeStart[1] + 1, 3);
+ $xMax = min($rangeEndIndexes[0] - $rangeStartIndexes[0] + 1, 3);
+ $yMax = min($rangeEndIndexes[1] - $rangeStartIndexes[1] + 1, 3);
// loop through up to 3 x 3 = 9 regions
for ($x = 1; $x <= $xMax; ++$x) {
// start column index for region
$colStart = ($x == 3) ?
- Coordinate::stringFromColumnIndex($rangeEnd[0])
- : Coordinate::stringFromColumnIndex($rangeStart[0] + $x - 1);
+ Coordinate::stringFromColumnIndex($rangeEndIndexes[0])
+ : Coordinate::stringFromColumnIndex($rangeStartIndexes[0] + $x - 1);
// end column index for region
$colEnd = ($x == 1) ?
- Coordinate::stringFromColumnIndex($rangeStart[0])
- : Coordinate::stringFromColumnIndex($rangeEnd[0] - $xMax + $x);
+ Coordinate::stringFromColumnIndex($rangeStartIndexes[0])
+ : Coordinate::stringFromColumnIndex($rangeEndIndexes[0] - $xMax + $x);
for ($y = 1; $y <= $yMax; ++$y) {
// which edges are touching the region
@@ -285,11 +284,11 @@ class Style extends Supervisor
// start row index for region
$rowStart = ($y == 3) ?
- $rangeEnd[1] : $rangeStart[1] + $y - 1;
+ $rangeEndIndexes[1] : $rangeStartIndexes[1] + $y - 1;
// end row index for region
$rowEnd = ($y == 1) ?
- $rangeStart[1] : $rangeEnd[1] - $yMax + $y;
+ $rangeStartIndexes[1] : $rangeEndIndexes[1] - $yMax + $y;
// build range for region
$range = $colStart . $rowStart . ':' . $colEnd . $rowEnd;
@@ -349,52 +348,11 @@ class Style extends Supervisor
}
// First loop through columns, rows, or cells to find out which styles are affected by this operation
- switch ($selectionType) {
- case 'COLUMN':
- $oldXfIndexes = [];
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
- }
- foreach ($this->getActiveSheet()->getColumnIterator($rangeStart0, $rangeEnd0) as $columnIterator) {
- $cellIterator = $columnIterator->getCellIterator();
- $cellIterator->setIterateOnlyExistingCells(true);
- foreach ($cellIterator as $columnCell) {
- $columnCell->getStyle()->applyFromArray($pStyles);
- }
- }
-
- break;
- case 'ROW':
- $oldXfIndexes = [];
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
- if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() == null) {
- $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
- } else {
- $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
- }
- }
- foreach ($this->getActiveSheet()->getRowIterator((int) $rangeStart[1], (int) $rangeEnd[1]) as $rowIterator) {
- $cellIterator = $rowIterator->getCellIterator();
- $cellIterator->setIterateOnlyExistingCells(true);
- foreach ($cellIterator as $rowCell) {
- $rowCell->getStyle()->applyFromArray($pStyles);
- }
- }
-
- break;
- case 'CELL':
- $oldXfIndexes = [];
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
- $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
- }
- }
-
- break;
- }
+ $oldXfIndexes = $this->getOldXfIndexes($selectionType, $rangeStartIndexes, $rangeEndIndexes, $columnStart, $columnEnd, $pStyles);
// clone each of the affected styles, apply the style array, and add the new styles to the workbook
$workbook = $this->getActiveSheet()->getParent();
+ $newXfIndexes = [];
foreach ($oldXfIndexes as $oldXfIndex => $dummy) {
$style = $workbook->getCellXfByIndex($oldXfIndex);
$newStyle = clone $style;
@@ -413,7 +371,7 @@ class Style extends Supervisor
// Loop through columns, rows, or cells again and update the XF index
switch ($selectionType) {
case 'COLUMN':
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ for ($col = $rangeStartIndexes[0]; $col <= $rangeEndIndexes[0]; ++$col) {
$columnDimension = $this->getActiveSheet()->getColumnDimensionByColumn($col);
$oldXfIndex = $columnDimension->getXfIndex();
$columnDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
@@ -421,17 +379,17 @@ class Style extends Supervisor
break;
case 'ROW':
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ for ($row = $rangeStartIndexes[1]; $row <= $rangeEndIndexes[1]; ++$row) {
$rowDimension = $this->getActiveSheet()->getRowDimension($row);
- $oldXfIndex = $rowDimension->getXfIndex() === null ?
- 0 : $rowDimension->getXfIndex(); // row without explicit style should be formatted based on default style
+ // row without explicit style should be formatted based on default style
+ $oldXfIndex = $rowDimension->getXfIndex() ?? 0;
$rowDimension->setXfIndex($newXfIndexes[$oldXfIndex]);
}
break;
case 'CELL':
- for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
- for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ for ($col = $rangeStartIndexes[0]; $col <= $rangeEndIndexes[0]; ++$col) {
+ for ($row = $rangeStartIndexes[1]; $row <= $rangeEndIndexes[1]; ++$row) {
$cell = $this->getActiveSheet()->getCellByColumnAndRow($col, $row);
$oldXfIndex = $cell->getXfIndex();
$cell->setXfIndex($newXfIndexes[$oldXfIndex]);
@@ -468,6 +426,57 @@ class Style extends Supervisor
return $this;
}
+ private function getOldXfIndexes(string $selectionType, array $rangeStart, array $rangeEnd, string $columnStart, string $columnEnd, array $pStyles): array
+ {
+ $oldXfIndexes = [];
+ switch ($selectionType) {
+ case 'COLUMN':
+ for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ $oldXfIndexes[$this->getActiveSheet()->getColumnDimensionByColumn($col)->getXfIndex()] = true;
+ }
+ foreach ($this->getActiveSheet()->getColumnIterator($columnStart, $columnEnd) as $columnIterator) {
+ $cellIterator = $columnIterator->getCellIterator();
+ $cellIterator->setIterateOnlyExistingCells(true);
+ foreach ($cellIterator as $columnCell) {
+ if ($columnCell !== null) {
+ $columnCell->getStyle()->applyFromArray($pStyles);
+ }
+ }
+ }
+
+ break;
+ case 'ROW':
+ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ if ($this->getActiveSheet()->getRowDimension($row)->getXfIndex() === null) {
+ $oldXfIndexes[0] = true; // row without explicit style should be formatted based on default style
+ } else {
+ $oldXfIndexes[$this->getActiveSheet()->getRowDimension($row)->getXfIndex()] = true;
+ }
+ }
+ foreach ($this->getActiveSheet()->getRowIterator((int) $rangeStart[1], (int) $rangeEnd[1]) as $rowIterator) {
+ $cellIterator = $rowIterator->getCellIterator();
+ $cellIterator->setIterateOnlyExistingCells(true);
+ foreach ($cellIterator as $rowCell) {
+ if ($rowCell !== null) {
+ $rowCell->getStyle()->applyFromArray($pStyles);
+ }
+ }
+ }
+
+ break;
+ case 'CELL':
+ for ($col = $rangeStart[0]; $col <= $rangeEnd[0]; ++$col) {
+ for ($row = $rangeStart[1]; $row <= $rangeEnd[1]; ++$row) {
+ $oldXfIndexes[$this->getActiveSheet()->getCellByColumnAndRow($col, $row)->getXfIndex()] = true;
+ }
+ }
+
+ break;
+ }
+
+ return $oldXfIndexes;
+ }
+
/**
* Get Fill.
*
diff --git a/src/PhpSpreadsheet/Worksheet/AutoFilter.php b/src/PhpSpreadsheet/Worksheet/AutoFilter.php
index c2ded195..1a710e40 100644
--- a/src/PhpSpreadsheet/Worksheet/AutoFilter.php
+++ b/src/PhpSpreadsheet/Worksheet/AutoFilter.php
@@ -3,7 +3,7 @@
namespace PhpOffice\PhpSpreadsheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
@@ -14,7 +14,7 @@ class AutoFilter
/**
* Autofilter Worksheet.
*
- * @var Worksheet
+ * @var null|Worksheet
*/
private $workSheet;
@@ -47,7 +47,7 @@ class AutoFilter
/**
* Get AutoFilter Parent Worksheet.
*
- * @return Worksheet
+ * @return null|Worksheet
*/
public function getParent()
{
@@ -472,7 +472,7 @@ class AutoFilter
$val = $maxVal = null;
$ruleValues = [];
- $baseDate = DateTime::DATENOW();
+ $baseDate = DateTimeExcel\Now::funcNow();
// Calculate start/end dates for the required date range based on current date
switch ($dynamicRuleType) {
case AutoFilter\Column\Rule::AUTOFILTER_RULETYPE_DYNAMIC_LASTWEEK:
@@ -595,7 +595,9 @@ class AutoFilter
sort($dataValues);
}
- return array_pop(array_slice($dataValues, 0, $ruleValue));
+ $slice = array_slice($dataValues, 0, $ruleValue);
+
+ return array_pop($slice);
}
/**
@@ -777,6 +779,9 @@ class AutoFilter
case AutoFilter\Column::AUTOFILTER_FILTERTYPE_TOPTENFILTER:
$ruleValues = [];
$dataRowCount = $rangeEnd[1] - $rangeStart[1];
+ $toptenRuleType = null;
+ $ruleValue = 0;
+ $ruleOperator = null;
foreach ($rules as $rule) {
// We should only ever have one Dynamic Filter Rule anyway
$toptenRuleType = $rule->getGrouping();
@@ -786,10 +791,10 @@ class AutoFilter
if ($ruleOperator === AutoFilter\Column\Rule::AUTOFILTER_COLUMN_RULE_TOPTEN_PERCENT) {
$ruleValue = floor($ruleValue * ($dataRowCount / 100));
}
- if ($ruleValue < 1) {
+ if (!is_array($ruleValue) && $ruleValue < 1) {
$ruleValue = 1;
}
- if ($ruleValue > 500) {
+ if (!is_array($ruleValue) && $ruleValue > 500) {
$ruleValue = 500;
}
diff --git a/src/PhpSpreadsheet/Worksheet/AutoFilter/Column.php b/src/PhpSpreadsheet/Worksheet/AutoFilter/Column.php
index 09584a7a..8ec0ca3b 100644
--- a/src/PhpSpreadsheet/Worksheet/AutoFilter/Column.php
+++ b/src/PhpSpreadsheet/Worksheet/AutoFilter/Column.php
@@ -49,7 +49,7 @@ class Column
/**
* Autofilter.
*
- * @var AutoFilter
+ * @var null|AutoFilter
*/
private $parent;
@@ -77,14 +77,14 @@ class Column
/**
* Autofilter Column Rules.
*
- * @var array of Column\Rule
+ * @var Column\Rule[]
*/
private $ruleset = [];
/**
* Autofilter Column Dynamic Attributes.
*
- * @var array of mixed
+ * @var mixed[]
*/
private $attributes = [];
@@ -133,7 +133,7 @@ class Column
/**
* Get this Column's AutoFilter Parent.
*
- * @return AutoFilter
+ * @return null|AutoFilter
*/
public function getParent()
{
@@ -256,7 +256,7 @@ class Column
*
* @param string $pName Attribute Name
*
- * @return string
+ * @return null|string
*/
public function getAttribute($pName)
{
diff --git a/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php b/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
index 1aacb0cb..330a1641 100644
--- a/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
+++ b/src/PhpSpreadsheet/Worksheet/AutoFilter/Column/Rule.php
@@ -217,7 +217,7 @@ class Rule
/**
* Autofilter Rule Value.
*
- * @var string
+ * @var string|string[]
*/
private $value = '';
@@ -276,7 +276,7 @@ class Rule
/**
* Get AutoFilter Rule Value.
*
- * @return string
+ * @return string|string[]
*/
public function getValue()
{
diff --git a/src/PhpSpreadsheet/Worksheet/BaseDrawing.php b/src/PhpSpreadsheet/Worksheet/BaseDrawing.php
index be2f23df..5829671b 100644
--- a/src/PhpSpreadsheet/Worksheet/BaseDrawing.php
+++ b/src/PhpSpreadsheet/Worksheet/BaseDrawing.php
@@ -39,7 +39,7 @@ class BaseDrawing implements IComparable
/**
* Worksheet.
*
- * @var Worksheet
+ * @var null|Worksheet
*/
protected $worksheet;
@@ -190,7 +190,7 @@ class BaseDrawing implements IComparable
/**
* Get Worksheet.
*
- * @return Worksheet
+ * @return null|Worksheet
*/
public function getWorksheet()
{
@@ -330,7 +330,7 @@ class BaseDrawing implements IComparable
// Resize proportional?
if ($this->resizeProportional && $pValue != 0) {
$ratio = $this->height / ($this->width != 0 ? $this->width : 1);
- $this->height = round($ratio * $pValue);
+ $this->height = (int) round($ratio * $pValue);
}
// Set width
@@ -361,7 +361,7 @@ class BaseDrawing implements IComparable
// Resize proportional?
if ($this->resizeProportional && $pValue != 0) {
$ratio = $this->width / ($this->height != 0 ? $this->height : 1);
- $this->width = round($ratio * $pValue);
+ $this->width = (int) round($ratio * $pValue);
}
// Set height
@@ -392,10 +392,10 @@ class BaseDrawing implements IComparable
$yratio = $height / ($this->height != 0 ? $this->height : 1);
if ($this->resizeProportional && !($width == 0 || $height == 0)) {
if (($xratio * $this->height) < $height) {
- $this->height = ceil($xratio * $this->height);
+ $this->height = (int) ceil($xratio * $this->height);
$this->width = $width;
} else {
- $this->width = ceil($yratio * $this->width);
+ $this->width = (int) ceil($yratio * $this->width);
$this->height = $height;
}
} else {
diff --git a/src/PhpSpreadsheet/Worksheet/CellIterator.php b/src/PhpSpreadsheet/Worksheet/CellIterator.php
index 45f76cab..31f6ae65 100644
--- a/src/PhpSpreadsheet/Worksheet/CellIterator.php
+++ b/src/PhpSpreadsheet/Worksheet/CellIterator.php
@@ -25,15 +25,14 @@ abstract class CellIterator implements Iterator
*/
public function __destruct()
{
+ // @phpstan-ignore-next-line
$this->worksheet = null;
}
/**
* Get loop only existing cells.
- *
- * @return bool
*/
- public function getIterateOnlyExistingCells()
+ public function getIterateOnlyExistingCells(): bool
{
return $this->onlyExistingCells;
}
@@ -45,10 +44,8 @@ abstract class CellIterator implements Iterator
/**
* Set the iterator to loop only existing cells.
- *
- * @param bool $value
*/
- public function setIterateOnlyExistingCells($value): void
+ public function setIterateOnlyExistingCells(bool $value): void
{
$this->onlyExistingCells = (bool) $value;
diff --git a/src/PhpSpreadsheet/Worksheet/Column.php b/src/PhpSpreadsheet/Worksheet/Column.php
index 410e8073..8abbabe5 100644
--- a/src/PhpSpreadsheet/Worksheet/Column.php
+++ b/src/PhpSpreadsheet/Worksheet/Column.php
@@ -36,15 +36,14 @@ class Column
*/
public function __destruct()
{
+ // @phpstan-ignore-next-line
$this->parent = null;
}
/**
* Get column index as string eg: 'A'.
- *
- * @return string
*/
- public function getColumnIndex()
+ public function getColumnIndex(): string
{
return $this->columnIndex;
}
diff --git a/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php b/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php
index 714ee7ce..65772114 100644
--- a/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php
+++ b/src/PhpSpreadsheet/Worksheet/ColumnCellIterator.php
@@ -2,6 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Worksheet;
+use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
@@ -17,7 +18,7 @@ class ColumnCellIterator extends CellIterator
/**
* Column index.
*
- * @var string
+ * @var int
*/
private $columnIndex;
@@ -59,7 +60,7 @@ class ColumnCellIterator extends CellIterator
*
* @return $this
*/
- public function resetStart($startRow = 1)
+ public function resetStart(int $startRow = 1)
{
$this->startRow = $startRow;
$this->adjustForExistingOnlyRange();
@@ -77,7 +78,7 @@ class ColumnCellIterator extends CellIterator
*/
public function resetEnd($endRow = null)
{
- $this->endRow = ($endRow) ? $endRow : $this->worksheet->getHighestRow();
+ $this->endRow = $endRow ?: $this->worksheet->getHighestRow();
$this->adjustForExistingOnlyRange();
return $this;
@@ -90,7 +91,7 @@ class ColumnCellIterator extends CellIterator
*
* @return $this
*/
- public function seek($row = 1)
+ public function seek(int $row = 1)
{
if ($this->onlyExistingCells && !($this->worksheet->cellExistsByColumnAndRow($this->columnIndex, $row))) {
throw new PhpSpreadsheetException('In "IterateOnlyExistingCells" mode and Cell does not exist');
@@ -113,20 +114,16 @@ class ColumnCellIterator extends CellIterator
/**
* Return the current cell in this worksheet column.
- *
- * @return \PhpOffice\PhpSpreadsheet\Cell\Cell
*/
- public function current()
+ public function current(): ?Cell
{
return $this->worksheet->getCellByColumnAndRow($this->columnIndex, $this->currentRow);
}
/**
* Return the current iterator key.
- *
- * @return int
*/
- public function key()
+ public function key(): int
{
return $this->currentRow;
}
@@ -161,10 +158,8 @@ class ColumnCellIterator extends CellIterator
/**
* Indicate if more rows exist in the worksheet range of rows that we're iterating.
- *
- * @return bool
*/
- public function valid()
+ public function valid(): bool
{
return $this->currentRow <= $this->endRow && $this->currentRow >= $this->startRow;
}
diff --git a/src/PhpSpreadsheet/Worksheet/ColumnDimension.php b/src/PhpSpreadsheet/Worksheet/ColumnDimension.php
index 4e87a344..12b1efdf 100644
--- a/src/PhpSpreadsheet/Worksheet/ColumnDimension.php
+++ b/src/PhpSpreadsheet/Worksheet/ColumnDimension.php
@@ -43,10 +43,8 @@ class ColumnDimension extends Dimension
/**
* Get column index as string eg: 'A'.
- *
- * @return string
*/
- public function getColumnIndex()
+ public function getColumnIndex(): string
{
return $this->columnIndex;
}
@@ -54,23 +52,19 @@ class ColumnDimension extends Dimension
/**
* Set column index as string eg: 'A'.
*
- * @param string $pValue
- *
* @return $this
*/
- public function setColumnIndex($pValue)
+ public function setColumnIndex(string $index)
{
- $this->columnIndex = $pValue;
+ $this->columnIndex = $index;
return $this;
}
/**
* Get Width.
- *
- * @return float
*/
- public function getWidth()
+ public function getWidth(): float
{
return $this->width;
}
@@ -78,23 +72,19 @@ class ColumnDimension extends Dimension
/**
* Set Width.
*
- * @param float $pValue
- *
* @return $this
*/
- public function setWidth($pValue)
+ public function setWidth(float $width)
{
- $this->width = $pValue;
+ $this->width = $width;
return $this;
}
/**
* Get Auto Size.
- *
- * @return bool
*/
- public function getAutoSize()
+ public function getAutoSize(): bool
{
return $this->autoSize;
}
@@ -102,13 +92,11 @@ class ColumnDimension extends Dimension
/**
* Set Auto Size.
*
- * @param bool $pValue
- *
* @return $this
*/
- public function setAutoSize($pValue)
+ public function setAutoSize(bool $autosizeEnabled)
{
- $this->autoSize = $pValue;
+ $this->autoSize = $autosizeEnabled;
return $this;
}
diff --git a/src/PhpSpreadsheet/Worksheet/ColumnIterator.php b/src/PhpSpreadsheet/Worksheet/ColumnIterator.php
index d0bb20cc..0651a7a4 100644
--- a/src/PhpSpreadsheet/Worksheet/ColumnIterator.php
+++ b/src/PhpSpreadsheet/Worksheet/ColumnIterator.php
@@ -57,6 +57,7 @@ class ColumnIterator implements Iterator
*/
public function __destruct()
{
+ // @phpstan-ignore-next-line
$this->worksheet = null;
}
@@ -67,11 +68,13 @@ class ColumnIterator implements Iterator
*
* @return $this
*/
- public function resetStart($startColumn = 'A')
+ public function resetStart(string $startColumn = 'A')
{
$startColumnIndex = Coordinate::columnIndexFromString($startColumn);
if ($startColumnIndex > Coordinate::columnIndexFromString($this->worksheet->getHighestColumn())) {
- throw new Exception("Start column ({$startColumn}) is beyond highest column ({$this->worksheet->getHighestColumn()})");
+ throw new Exception(
+ "Start column ({$startColumn}) is beyond highest column ({$this->worksheet->getHighestColumn()})"
+ );
}
$this->startColumnIndex = $startColumnIndex;
@@ -92,7 +95,7 @@ class ColumnIterator implements Iterator
*/
public function resetEnd($endColumn = null)
{
- $endColumn = $endColumn ? $endColumn : $this->worksheet->getHighestColumn();
+ $endColumn = $endColumn ?: $this->worksheet->getHighestColumn();
$this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
return $this;
@@ -105,11 +108,13 @@ class ColumnIterator implements Iterator
*
* @return $this
*/
- public function seek($column = 'A')
+ public function seek(string $column = 'A')
{
$column = Coordinate::columnIndexFromString($column);
if (($column < $this->startColumnIndex) || ($column > $this->endColumnIndex)) {
- throw new PhpSpreadsheetException("Column $column is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})");
+ throw new PhpSpreadsheetException(
+ "Column $column is out of range ({$this->startColumnIndex} - {$this->endColumnIndex})"
+ );
}
$this->currentColumnIndex = $column;
@@ -136,10 +141,8 @@ class ColumnIterator implements Iterator
/**
* Return the current iterator key.
- *
- * @return string
*/
- public function key()
+ public function key(): string
{
return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
}
@@ -162,10 +165,8 @@ class ColumnIterator implements Iterator
/**
* Indicate if more columns exist in the worksheet range of columns that we're iterating.
- *
- * @return bool
*/
- public function valid()
+ public function valid(): bool
{
return $this->currentColumnIndex <= $this->endColumnIndex && $this->currentColumnIndex >= $this->startColumnIndex;
}
diff --git a/src/PhpSpreadsheet/Worksheet/Dimension.php b/src/PhpSpreadsheet/Worksheet/Dimension.php
index a27daf09..4b3a0da8 100644
--- a/src/PhpSpreadsheet/Worksheet/Dimension.php
+++ b/src/PhpSpreadsheet/Worksheet/Dimension.php
@@ -47,10 +47,8 @@ abstract class Dimension
/**
* Get Visible.
- *
- * @return bool
*/
- public function getVisible()
+ public function getVisible(): bool
{
return $this->visible;
}
@@ -58,23 +56,19 @@ abstract class Dimension
/**
* Set Visible.
*
- * @param bool $pValue
- *
* @return $this
*/
- public function setVisible($pValue)
+ public function setVisible(bool $visible)
{
- $this->visible = (bool) $pValue;
+ $this->visible = $visible;
return $this;
}
/**
* Get Outline Level.
- *
- * @return int
*/
- public function getOutlineLevel()
+ public function getOutlineLevel(): int
{
return $this->outlineLevel;
}
@@ -83,27 +77,23 @@ abstract class Dimension
* Set Outline Level.
* Value must be between 0 and 7.
*
- * @param int $pValue
- *
* @return $this
*/
- public function setOutlineLevel($pValue)
+ public function setOutlineLevel(int $level)
{
- if ($pValue < 0 || $pValue > 7) {
+ if ($level < 0 || $level > 7) {
throw new PhpSpreadsheetException('Outline level must range between 0 and 7.');
}
- $this->outlineLevel = $pValue;
+ $this->outlineLevel = $level;
return $this;
}
/**
* Get Collapsed.
- *
- * @return bool
*/
- public function getCollapsed()
+ public function getCollapsed(): bool
{
return $this->collapsed;
}
@@ -111,13 +101,11 @@ abstract class Dimension
/**
* Set Collapsed.
*
- * @param bool $pValue
- *
* @return $this
*/
- public function setCollapsed($pValue)
+ public function setCollapsed(bool $collapsed)
{
- $this->collapsed = (bool) $pValue;
+ $this->collapsed = $collapsed;
return $this;
}
@@ -127,7 +115,7 @@ abstract class Dimension
*
* @return int
*/
- public function getXfIndex()
+ public function getXfIndex(): ?int
{
return $this->xfIndex;
}
@@ -135,11 +123,9 @@ abstract class Dimension
/**
* Set index to cellXf.
*
- * @param int $pValue
- *
* @return $this
*/
- public function setXfIndex($pValue)
+ public function setXfIndex(int $pValue)
{
$this->xfIndex = $pValue;
diff --git a/src/PhpSpreadsheet/Worksheet/Drawing/Shadow.php b/src/PhpSpreadsheet/Worksheet/Drawing/Shadow.php
index 01ffed94..0557c83c 100644
--- a/src/PhpSpreadsheet/Worksheet/Drawing/Shadow.php
+++ b/src/PhpSpreadsheet/Worksheet/Drawing/Shadow.php
@@ -52,7 +52,7 @@ class Shadow implements IComparable
/**
* Shadow alignment.
*
- * @var int
+ * @var string
*/
private $alignment;
@@ -184,7 +184,7 @@ class Shadow implements IComparable
/**
* Get Shadow alignment.
*
- * @return int
+ * @return string
*/
public function getAlignment()
{
@@ -194,7 +194,7 @@ class Shadow implements IComparable
/**
* Set Shadow alignment.
*
- * @param int $pValue
+ * @param string $pValue
*
* @return $this
*/
diff --git a/src/PhpSpreadsheet/Worksheet/Iterator.php b/src/PhpSpreadsheet/Worksheet/Iterator.php
index 6cfed37a..134b619a 100644
--- a/src/PhpSpreadsheet/Worksheet/Iterator.php
+++ b/src/PhpSpreadsheet/Worksheet/Iterator.php
@@ -29,14 +29,6 @@ class Iterator implements \Iterator
$this->subject = $subject;
}
- /**
- * Destructor.
- */
- public function __destruct()
- {
- $this->subject = null;
- }
-
/**
* Rewind iterator.
*/
@@ -47,20 +39,16 @@ class Iterator implements \Iterator
/**
* Current Worksheet.
- *
- * @return Worksheet
*/
- public function current()
+ public function current(): Worksheet
{
return $this->subject->getSheet($this->position);
}
/**
* Current key.
- *
- * @return int
*/
- public function key()
+ public function key(): int
{
return $this->position;
}
diff --git a/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php b/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
index fb002114..cde23c96 100644
--- a/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
+++ b/src/PhpSpreadsheet/Worksheet/MemoryDrawing.php
@@ -52,7 +52,6 @@ class MemoryDrawing extends BaseDrawing
public function __construct()
{
// Initialise values
- $this->imageResource = null;
$this->renderingFunction = self::RENDERING_DEFAULT;
$this->mimeType = self::MIMETYPE_DEFAULT;
$this->uniqueName = md5(mt_rand(0, 9999) . time() . mt_rand(0, 9999));
diff --git a/src/PhpSpreadsheet/Worksheet/PageSetup.php b/src/PhpSpreadsheet/Worksheet/PageSetup.php
index d1a22a7b..7f3f71dc 100644
--- a/src/PhpSpreadsheet/Worksheet/PageSetup.php
+++ b/src/PhpSpreadsheet/Worksheet/PageSetup.php
@@ -238,7 +238,7 @@ class PageSetup
/**
* Print area.
*
- * @var string
+ * @var null|string
*/
private $printArea;
diff --git a/src/PhpSpreadsheet/Worksheet/Row.php b/src/PhpSpreadsheet/Worksheet/Row.php
index 4f48a346..01053c39 100644
--- a/src/PhpSpreadsheet/Worksheet/Row.php
+++ b/src/PhpSpreadsheet/Worksheet/Row.php
@@ -36,15 +36,14 @@ class Row
*/
public function __destruct()
{
+ // @phpstan-ignore-next-line
$this->worksheet = null;
}
/**
* Get row index.
- *
- * @return int
*/
- public function getRowIndex()
+ public function getRowIndex(): int
{
return $this->rowIndex;
}
@@ -64,10 +63,8 @@ class Row
/**
* Returns bound worksheet.
- *
- * @return Worksheet
*/
- public function getWorksheet()
+ public function getWorksheet(): Worksheet
{
return $this->worksheet;
}
diff --git a/src/PhpSpreadsheet/Worksheet/RowCellIterator.php b/src/PhpSpreadsheet/Worksheet/RowCellIterator.php
index 9b9d54eb..6a96a826 100644
--- a/src/PhpSpreadsheet/Worksheet/RowCellIterator.php
+++ b/src/PhpSpreadsheet/Worksheet/RowCellIterator.php
@@ -2,6 +2,7 @@
namespace PhpOffice\PhpSpreadsheet\Worksheet;
+use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException;
@@ -59,7 +60,7 @@ class RowCellIterator extends CellIterator
*
* @return $this
*/
- public function resetStart($startColumn = 'A')
+ public function resetStart(string $startColumn = 'A')
{
$this->startColumnIndex = Coordinate::columnIndexFromString($startColumn);
$this->adjustForExistingOnlyRange();
@@ -77,7 +78,7 @@ class RowCellIterator extends CellIterator
*/
public function resetEnd($endColumn = null)
{
- $endColumn = $endColumn ? $endColumn : $this->worksheet->getHighestColumn();
+ $endColumn = $endColumn ?: $this->worksheet->getHighestColumn();
$this->endColumnIndex = Coordinate::columnIndexFromString($endColumn);
$this->adjustForExistingOnlyRange();
@@ -91,7 +92,7 @@ class RowCellIterator extends CellIterator
*
* @return $this
*/
- public function seek($column = 'A')
+ public function seek(string $column = 'A')
{
$columnx = $column;
$column = Coordinate::columnIndexFromString($column);
@@ -116,20 +117,16 @@ class RowCellIterator extends CellIterator
/**
* Return the current cell in this worksheet row.
- *
- * @return \PhpOffice\PhpSpreadsheet\Cell\Cell
*/
- public function current()
+ public function current(): ?Cell
{
return $this->worksheet->getCellByColumnAndRow($this->currentColumnIndex, $this->rowIndex);
}
/**
* Return the current iterator key.
- *
- * @return string
*/
- public function key()
+ public function key(): string
{
return Coordinate::stringFromColumnIndex($this->currentColumnIndex);
}
@@ -166,10 +163,8 @@ class RowCellIterator extends CellIterator
/**
* Return the current iterator position.
- *
- * @return int
*/
- public function getCurrentColumnIndex()
+ public function getCurrentColumnIndex(): int
{
return $this->currentColumnIndex;
}
diff --git a/src/PhpSpreadsheet/Worksheet/RowDimension.php b/src/PhpSpreadsheet/Worksheet/RowDimension.php
index c4a87bdb..d86dd80f 100644
--- a/src/PhpSpreadsheet/Worksheet/RowDimension.php
+++ b/src/PhpSpreadsheet/Worksheet/RowDimension.php
@@ -43,10 +43,8 @@ class RowDimension extends Dimension
/**
* Get Row Index.
- *
- * @return int
*/
- public function getRowIndex()
+ public function getRowIndex(): int
{
return $this->rowIndex;
}
@@ -54,13 +52,11 @@ class RowDimension extends Dimension
/**
* Set Row Index.
*
- * @param int $pValue
- *
* @return $this
*/
- public function setRowIndex($pValue)
+ public function setRowIndex(int $index)
{
- $this->rowIndex = $pValue;
+ $this->rowIndex = $index;
return $this;
}
@@ -78,23 +74,21 @@ class RowDimension extends Dimension
/**
* Set Row Height.
*
- * @param float $pValue
+ * @param float $height
*
* @return $this
*/
- public function setRowHeight($pValue)
+ public function setRowHeight($height)
{
- $this->height = $pValue;
+ $this->height = $height;
return $this;
}
/**
* Get ZeroHeight.
- *
- * @return bool
*/
- public function getZeroHeight()
+ public function getZeroHeight(): bool
{
return $this->zeroHeight;
}
@@ -102,11 +96,9 @@ class RowDimension extends Dimension
/**
* Set ZeroHeight.
*
- * @param bool $pValue
- *
* @return $this
*/
- public function setZeroHeight($pValue)
+ public function setZeroHeight(bool $pValue)
{
$this->zeroHeight = $pValue;
diff --git a/src/PhpSpreadsheet/Worksheet/RowIterator.php b/src/PhpSpreadsheet/Worksheet/RowIterator.php
index 42542533..7d49f1ac 100644
--- a/src/PhpSpreadsheet/Worksheet/RowIterator.php
+++ b/src/PhpSpreadsheet/Worksheet/RowIterator.php
@@ -50,14 +50,6 @@ class RowIterator implements Iterator
$this->resetStart($startRow);
}
- /**
- * Destructor.
- */
- public function __destruct()
- {
- $this->subject = null;
- }
-
/**
* (Re)Set the start row and the current row pointer.
*
@@ -65,10 +57,12 @@ class RowIterator implements Iterator
*
* @return $this
*/
- public function resetStart($startRow = 1)
+ public function resetStart(int $startRow = 1)
{
if ($startRow > $this->subject->getHighestRow()) {
- throw new PhpSpreadsheetException("Start row ({$startRow}) is beyond highest row ({$this->subject->getHighestRow()})");
+ throw new PhpSpreadsheetException(
+ "Start row ({$startRow}) is beyond highest row ({$this->subject->getHighestRow()})"
+ );
}
$this->startRow = $startRow;
@@ -89,7 +83,7 @@ class RowIterator implements Iterator
*/
public function resetEnd($endRow = null)
{
- $this->endRow = ($endRow) ? $endRow : $this->subject->getHighestRow();
+ $this->endRow = $endRow ?: $this->subject->getHighestRow();
return $this;
}
@@ -101,7 +95,7 @@ class RowIterator implements Iterator
*
* @return $this
*/
- public function seek($row = 1)
+ public function seek(int $row = 1)
{
if (($row < $this->startRow) || ($row > $this->endRow)) {
throw new PhpSpreadsheetException("Row $row is out of range ({$this->startRow} - {$this->endRow})");
@@ -131,10 +125,8 @@ class RowIterator implements Iterator
/**
* Return the current iterator key.
- *
- * @return int
*/
- public function key()
+ public function key(): int
{
return $this->position;
}
@@ -157,10 +149,8 @@ class RowIterator implements Iterator
/**
* Indicate if more rows exist in the worksheet range of rows that we're iterating.
- *
- * @return bool
*/
- public function valid()
+ public function valid(): bool
{
return $this->position <= $this->endRow && $this->position >= $this->startRow;
}
diff --git a/src/PhpSpreadsheet/Worksheet/Worksheet.php b/src/PhpSpreadsheet/Worksheet/Worksheet.php
index 19833b71..2ecd210c 100644
--- a/src/PhpSpreadsheet/Worksheet/Worksheet.php
+++ b/src/PhpSpreadsheet/Worksheet/Worksheet.php
@@ -96,16 +96,16 @@ class Worksheet implements IComparable
/**
* Collection of drawings.
*
- * @var BaseDrawing[]
+ * @var ArrayObject
*/
private $drawingCollection;
/**
* Collection of Chart objects.
*
- * @var Chart[]
+ * @var ArrayObject
*/
- private $chartCollection = [];
+ private $chartCollection;
/**
* Worksheet title.
@@ -180,7 +180,7 @@ class Worksheet implements IComparable
/**
* Collection of breaks.
*
- * @var array
+ * @var int[]
*/
private $breaks = [];
@@ -278,9 +278,9 @@ class Worksheet implements IComparable
/**
* Cached highest column.
*
- * @var string
+ * @var int
*/
- private $cachedHighestColumn = 'A';
+ private $cachedHighestColumn = 1;
/**
* Cached highest row.
@@ -313,7 +313,7 @@ class Worksheet implements IComparable
/**
* Tab color.
*
- * @var Color
+ * @var null|Color
*/
private $tabColor;
@@ -383,9 +383,11 @@ class Worksheet implements IComparable
{
if ($this->cellCollection !== null) {
$this->cellCollection->unsetWorksheetCells();
+ // @phpstan-ignore-next-line
$this->cellCollection = null;
}
// detach ourself from the workbook, so that it can then delete this worksheet successfully
+ // @phpstan-ignore-next-line
$this->parent = null;
}
@@ -534,7 +536,7 @@ class Worksheet implements IComparable
/**
* Get collection of drawings.
*
- * @return BaseDrawing[]
+ * @return ArrayObject
*/
public function getDrawingCollection()
{
@@ -544,7 +546,7 @@ class Worksheet implements IComparable
/**
* Get collection of charts.
*
- * @return Chart[]
+ * @return ArrayObject
*/
public function getChartCollection()
{
@@ -728,7 +730,7 @@ class Worksheet implements IComparable
// loop through all cells in the worksheet
foreach ($this->getCoordinates(false) as $coordinate) {
- $cell = $this->getCell($coordinate, false);
+ $cell = $this->getCellOrNull($coordinate);
if ($cell !== null && isset($autoSizes[$this->cellCollection->getCurrentColumn()])) {
//Determine if cell is in merge range
$isMerged = isset($isMergeCell[$this->cellCollection->getCurrentCoordinate()]);
@@ -824,7 +826,7 @@ class Worksheet implements IComparable
/**
* Set title.
*
- * @param string $pValue String containing the dimension of this worksheet
+ * @param string $title String containing the dimension of this worksheet
* @param bool $updateFormulaCellReferences Flag indicating whether cell references in formulae should
* be updated to reflect the new sheet name.
* This should be left as the default true, unless you are
@@ -835,10 +837,10 @@ class Worksheet implements IComparable
*
* @return $this
*/
- public function setTitle($pValue, $updateFormulaCellReferences = true, $validate = true)
+ public function setTitle($title, $updateFormulaCellReferences = true, $validate = true)
{
// Is this a 'rename' or not?
- if ($this->getTitle() == $pValue) {
+ if ($this->getTitle() == $title) {
return $this;
}
@@ -847,37 +849,37 @@ class Worksheet implements IComparable
if ($validate) {
// Syntax check
- self::checkSheetTitle($pValue);
+ self::checkSheetTitle($title);
if ($this->parent) {
// Is there already such sheet name?
- if ($this->parent->sheetNameExists($pValue)) {
+ if ($this->parent->sheetNameExists($title)) {
// Use name, but append with lowest possible integer
- if (Shared\StringHelper::countCharacters($pValue) > 29) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 29);
+ if (Shared\StringHelper::countCharacters($title) > 29) {
+ $title = Shared\StringHelper::substring($title, 0, 29);
}
$i = 1;
- while ($this->parent->sheetNameExists($pValue . ' ' . $i)) {
+ while ($this->parent->sheetNameExists($title . ' ' . $i)) {
++$i;
if ($i == 10) {
- if (Shared\StringHelper::countCharacters($pValue) > 28) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 28);
+ if (Shared\StringHelper::countCharacters($title) > 28) {
+ $title = Shared\StringHelper::substring($title, 0, 28);
}
} elseif ($i == 100) {
- if (Shared\StringHelper::countCharacters($pValue) > 27) {
- $pValue = Shared\StringHelper::substring($pValue, 0, 27);
+ if (Shared\StringHelper::countCharacters($title) > 27) {
+ $title = Shared\StringHelper::substring($title, 0, 27);
}
}
}
- $pValue .= " $i";
+ $title .= " $i";
}
}
}
// Set title
- $this->title = $pValue;
+ $this->title = $title;
$this->dirty = true;
if ($this->parent && $this->parent->getCalculationEngine()) {
@@ -1039,7 +1041,7 @@ class Worksheet implements IComparable
public function getHighestColumn($row = null)
{
if ($row == null) {
- return $this->cachedHighestColumn;
+ return Coordinate::stringFromColumnIndex($this->cachedHighestColumn);
}
return $this->getHighestDataColumn($row);
@@ -1166,50 +1168,94 @@ class Worksheet implements IComparable
/**
* Get cell at a specific coordinate.
*
- * @param string $pCoordinate Coordinate of the cell, eg: 'A1'
- * @param bool $createIfNotExists Flag indicating whether a new cell should be created if it doesn't
- * already exist, or a null should be returned instead
+ * @param string $coordinate Coordinate of the cell, eg: 'A1'
*
- * @return null|Cell Cell that was found/created or null
+ * @return Cell Cell that was found or created
*/
- public function getCell($pCoordinate, $createIfNotExists = true)
+ public function getCell(string $coordinate): Cell
{
- // Uppercase coordinate
- $pCoordinateUpper = strtoupper($pCoordinate);
+ // Shortcut for increased performance for the vast majority of simple cases
+ if ($this->cellCollection->has($coordinate)) {
+ /** @var Cell $cell */
+ $cell = $this->cellCollection->get($coordinate);
- // Check cell collection
- if ($this->cellCollection->has($pCoordinateUpper)) {
- return $this->cellCollection->get($pCoordinateUpper);
+ return $cell;
}
+ /** @var Worksheet $sheet */
+ [$sheet, $finalCoordinate] = $this->getWorksheetAndCoordinate($coordinate);
+ $cell = $sheet->cellCollection->get($finalCoordinate);
+
+ return $cell ?? $sheet->createNewCell($finalCoordinate);
+ }
+
+ /**
+ * Get the correct Worksheet and coordinate from a coordinate that may
+ * contains reference to another sheet or a named range.
+ *
+ * @return array{0: Worksheet, 1: string}
+ */
+ private function getWorksheetAndCoordinate(string $pCoordinate): array
+ {
+ $sheet = null;
+ $finalCoordinate = null;
+
// Worksheet reference?
if (strpos($pCoordinate, '!') !== false) {
$worksheetReference = self::extractSheetTitle($pCoordinate, true);
- return $this->parent->getSheetByName($worksheetReference[0])->getCell(strtoupper($worksheetReference[1]), $createIfNotExists);
- }
+ $sheet = $this->parent->getSheetByName($worksheetReference[0]);
+ $finalCoordinate = strtoupper($worksheetReference[1]);
- // Named range?
- if (
- (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $pCoordinate, $matches)) &&
- (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/i', $pCoordinate, $matches))
+ if (!$sheet) {
+ throw new Exception('Sheet not found for name: ' . $worksheetReference[0]);
+ }
+ } elseif (
+ !preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $pCoordinate) &&
+ preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/i', $pCoordinate)
) {
- $namedRange = DefinedName::resolveName($pCoordinate, $this);
+ // Named range?
+ $namedRange = $this->validateNamedRange($pCoordinate, true);
if ($namedRange !== null) {
- $pCoordinate = $namedRange->getValue();
+ $sheet = $namedRange->getWorksheet();
+ if (!$sheet) {
+ throw new Exception('Sheet not found for named range: ' . $namedRange->getName());
+ }
- return $namedRange->getWorksheet()->getCell($pCoordinate, $createIfNotExists);
+ $cellCoordinate = ltrim(substr($namedRange->getValue(), strrpos($namedRange->getValue(), '!')), '!');
+ $finalCoordinate = str_replace('$', '', $cellCoordinate);
}
}
- if (Coordinate::coordinateIsRange($pCoordinate)) {
- throw new Exception('Cell coordinate can not be a range of cells.');
- } elseif (strpos($pCoordinate, '$') !== false) {
+ if (!$sheet || !$finalCoordinate) {
+ $sheet = $this;
+ $finalCoordinate = strtoupper($pCoordinate);
+ }
+
+ if (Coordinate::coordinateIsRange($finalCoordinate)) {
+ throw new Exception('Cell coordinate string can not be a range of cells.');
+ } elseif (strpos($finalCoordinate, '$') !== false) {
throw new Exception('Cell coordinate must not be absolute.');
}
- // Create new cell object, if required
- return $createIfNotExists ? $this->createNewCell($pCoordinateUpper) : null;
+ return [$sheet, $finalCoordinate];
+ }
+
+ /**
+ * Get an existing cell at a specific coordinate, or null.
+ *
+ * @param string $coordinate Coordinate of the cell, eg: 'A1'
+ *
+ * @return null|Cell Cell that was found or null
+ */
+ private function getCellOrNull($coordinate): ?Cell
+ {
+ // Check cell collection
+ if ($this->cellCollection->has($coordinate)) {
+ return $this->cellCollection->get($coordinate);
+ }
+
+ return null;
}
/**
@@ -1250,11 +1296,12 @@ class Worksheet implements IComparable
// Coordinates
$aCoordinates = Coordinate::coordinateFromString($pCoordinate);
- if (Coordinate::columnIndexFromString($this->cachedHighestColumn) < Coordinate::columnIndexFromString($aCoordinates[0])) {
- $this->cachedHighestColumn = $aCoordinates[0];
+ $aIndexes = Coordinate::indexesFromString($pCoordinate);
+ if ($this->cachedHighestColumn < $aIndexes[0]) {
+ $this->cachedHighestColumn = $aIndexes[0];
}
- if ($aCoordinates[1] > $this->cachedHighestRow) {
- $this->cachedHighestRow = $aCoordinates[1];
+ if ($aIndexes[1] > $this->cachedHighestRow) {
+ $this->cachedHighestRow = $aIndexes[1];
}
// Cell needs appropriate xfIndex from dimensions records
@@ -1276,50 +1323,16 @@ class Worksheet implements IComparable
/**
* Does the cell at a specific coordinate exist?
*
- * @param string $pCoordinate Coordinate of the cell eg: 'A1'
+ * @param string $coordinate Coordinate of the cell eg: 'A1'
*
* @return bool
*/
- public function cellExists($pCoordinate)
+ public function cellExists($coordinate)
{
- // Worksheet reference?
- if (strpos($pCoordinate, '!') !== false) {
- $worksheetReference = self::extractSheetTitle($pCoordinate, true);
+ /** @var Worksheet $sheet */
+ [$sheet, $finalCoordinate] = $this->getWorksheetAndCoordinate($coordinate);
- return $this->parent->getSheetByName($worksheetReference[0])->cellExists(strtoupper($worksheetReference[1]));
- }
-
- // Named range?
- if (
- (!preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $pCoordinate, $matches)) &&
- (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/i', $pCoordinate, $matches))
- ) {
- $namedRange = DefinedName::resolveName($pCoordinate, $this);
- if ($namedRange !== null) {
- $pCoordinate = $namedRange->getValue();
- if ($this->getHashCode() != $namedRange->getWorksheet()->getHashCode()) {
- if (!$namedRange->getLocalOnly()) {
- return $namedRange->getWorksheet()->cellExists($pCoordinate);
- }
-
- throw new Exception('Named range ' . $namedRange->getName() . ' is not accessible from within sheet ' . $this->getTitle());
- }
- } else {
- return false;
- }
- }
-
- // Uppercase coordinate
- $pCoordinate = strtoupper($pCoordinate);
-
- if (Coordinate::coordinateIsRange($pCoordinate)) {
- throw new Exception('Cell coordinate can not be a range of cells.');
- } elseif (strpos($pCoordinate, '$') !== false) {
- throw new Exception('Cell coordinate must not be absolute.');
- }
-
- // Cell exists?
- return $this->cellCollection->has($pCoordinate);
+ return $sheet->cellCollection->has($finalCoordinate);
}
/**
@@ -1341,7 +1354,7 @@ class Worksheet implements IComparable
* @param int $pRow Numeric index of the row
* @param bool $create
*
- * @return RowDimension
+ * @return null|RowDimension
*/
public function getRowDimension($pRow, $create = true)
{
@@ -1367,7 +1380,7 @@ class Worksheet implements IComparable
* @param string $pColumn String index of the column eg: 'A'
* @param bool $create
*
- * @return ColumnDimension
+ * @return null|ColumnDimension
*/
public function getColumnDimension($pColumn, $create = true)
{
@@ -1381,8 +1394,9 @@ class Worksheet implements IComparable
}
$this->columnDimensions[$pColumn] = new ColumnDimension($pColumn);
- if (Coordinate::columnIndexFromString($this->cachedHighestColumn) < Coordinate::columnIndexFromString($pColumn)) {
- $this->cachedHighestColumn = $pColumn;
+ $columnIndex = Coordinate::columnIndexFromString($pColumn);
+ if ($this->cachedHighestColumn < $columnIndex) {
+ $this->cachedHighestColumn = $columnIndex;
}
}
@@ -1394,7 +1408,7 @@ class Worksheet implements IComparable
*
* @param int $columnIndex Numeric column coordinate of the cell
*
- * @return ColumnDimension
+ * @return null|ColumnDimension
*/
public function getColumnDimensionByColumn($columnIndex)
{
@@ -1486,7 +1500,7 @@ class Worksheet implements IComparable
* Set conditional styles.
*
* @param string $pCoordinate eg: 'A1'
- * @param $pValue Conditional[]
+ * @param Conditional[] $pValue
*
* @return $this
*/
@@ -1644,7 +1658,7 @@ class Worksheet implements IComparable
/**
* Get breaks.
*
- * @return array[]
+ * @return int[]
*/
public function getBreaks()
{
@@ -1991,7 +2005,7 @@ class Worksheet implements IComparable
/**
* Get the default position of the right bottom pane.
*
- * @return int
+ * @return null|string
*/
public function getTopLeftCell()
{
@@ -2550,10 +2564,42 @@ class Worksheet implements IComparable
return $returnValue;
}
+ private function validateNamedRange(string $definedName, bool $returnNullIfInvalid = false): ?DefinedName
+ {
+ $namedRange = DefinedName::resolveName($definedName, $this);
+ if ($namedRange === null) {
+ if ($returnNullIfInvalid) {
+ return null;
+ }
+
+ throw new Exception('Named Range ' . $definedName . ' does not exist.');
+ }
+
+ if ($namedRange->isFormula()) {
+ if ($returnNullIfInvalid) {
+ return null;
+ }
+
+ throw new Exception('Defined Named ' . $definedName . ' is a formula, not a range or cell.');
+ }
+
+ if ($namedRange->getLocalOnly() && $this->getHashCode() !== $namedRange->getWorksheet()->getHashCode()) {
+ if ($returnNullIfInvalid) {
+ return null;
+ }
+
+ throw new Exception(
+ 'Named range ' . $definedName . ' is not accessible from within sheet ' . $this->getTitle()
+ );
+ }
+
+ return $namedRange;
+ }
+
/**
* Create array from a range of cells.
*
- * @param string $pNamedRange Name of the Named Range
+ * @param string $definedName The Named Range that should be returned
* @param mixed $nullValue Value returned in the array entry if a cell doesn't exist
* @param bool $calculateFormulas Should formulas be calculated?
* @param bool $formatData Should formatting be applied to cell values?
@@ -2562,17 +2608,14 @@ class Worksheet implements IComparable
*
* @return array
*/
- public function namedRangeToArray($pNamedRange, $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
+ public function namedRangeToArray(string $definedName, $nullValue = null, $calculateFormulas = true, $formatData = true, $returnCellRef = false)
{
- $namedRange = DefinedName::resolveName($pNamedRange, $this);
- if ($namedRange !== null) {
- $pWorkSheet = $namedRange->getWorksheet();
- $pCellRange = $namedRange->getValue();
+ $namedRange = $this->validateNamedRange($definedName);
+ $workSheet = $namedRange->getWorksheet();
+ $cellRange = ltrim(substr($namedRange->getValue(), strrpos($namedRange->getValue(), '!')), '!');
+ $cellRange = str_replace('$', '', $cellRange);
- return $pWorkSheet->rangeToArray($pCellRange, $nullValue, $calculateFormulas, $formatData, $returnCellRef);
- }
-
- throw new Exception('Named Range ' . $pNamedRange . ' does not exist.');
+ return $workSheet->rangeToArray($cellRange, $nullValue, $calculateFormulas, $formatData, $returnCellRef);
}
/**
@@ -2652,9 +2695,9 @@ class Worksheet implements IComparable
// Cache values
if ($highestColumn < 1) {
- $this->cachedHighestColumn = 'A';
+ $this->cachedHighestColumn = 1;
} else {
- $this->cachedHighestColumn = Coordinate::stringFromColumnIndex($highestColumn);
+ $this->cachedHighestColumn = $highestColumn;
}
$this->cachedHighestRow = $highestRow;
@@ -2880,7 +2923,6 @@ class Worksheet implements IComparable
public function resetTabColor()
{
$this->tabColor = null;
- $this->tabColor = null;
return $this;
}
@@ -2910,6 +2952,7 @@ class Worksheet implements IComparable
*/
public function __clone()
{
+ // @phpstan-ignore-next-line
foreach ($this as $key => $val) {
if ($key == 'parent') {
continue;
diff --git a/src/PhpSpreadsheet/Writer/Csv.php b/src/PhpSpreadsheet/Writer/Csv.php
index 74f28636..188a83a8 100644
--- a/src/PhpSpreadsheet/Writer/Csv.php
+++ b/src/PhpSpreadsheet/Writer/Csv.php
@@ -64,6 +64,13 @@ class Csv extends BaseWriter
*/
private $excelCompatibility = false;
+ /**
+ * Output encoding.
+ *
+ * @var string
+ */
+ private $outputEncoding = '';
+
/**
* Create a new CSV.
*
@@ -296,6 +303,30 @@ class Csv extends BaseWriter
return $this;
}
+ /**
+ * Get output encoding.
+ *
+ * @return string
+ */
+ public function getOutputEncoding()
+ {
+ return $this->outputEncoding;
+ }
+
+ /**
+ * Set output encoding.
+ *
+ * @param string $pValue Output encoding
+ *
+ * @return $this
+ */
+ public function setOutputEncoding($pValue)
+ {
+ $this->outputEncoding = $pValue;
+
+ return $this;
+ }
+
private $enclosureRequired = true;
public function setEnclosureRequired(bool $value): self
@@ -347,6 +378,9 @@ class Csv extends BaseWriter
$line .= $this->lineEnding;
// Write to file
+ if ($this->outputEncoding != '') {
+ $line = mb_convert_encoding($line, $this->outputEncoding);
+ }
fwrite($pFileHandle, $line);
}
}
diff --git a/src/PhpSpreadsheet/Writer/Html.php b/src/PhpSpreadsheet/Writer/Html.php
index e9de2ce6..4ee94114 100644
--- a/src/PhpSpreadsheet/Writer/Html.php
+++ b/src/PhpSpreadsheet/Writer/Html.php
@@ -37,7 +37,7 @@ class Html extends BaseWriter
/**
* Sheet index to write.
*
- * @var int
+ * @var null|int
*/
private $sheetIndex = 0;
@@ -453,10 +453,8 @@ class Html extends BaseWriter
// Get worksheet dimension
[$min, $max] = explode(':', $sheet->calculateWorksheetDataDimension());
- [$minCol, $minRow] = Coordinate::coordinateFromString($min);
- $minCol = Coordinate::columnIndexFromString($minCol);
- [$maxCol, $maxRow] = Coordinate::coordinateFromString($max);
- $maxCol = Coordinate::columnIndexFromString($maxCol);
+ [$minCol, $minRow] = Coordinate::indexesFromString($min);
+ [$maxCol, $maxRow] = Coordinate::indexesFromString($max);
[$theadStart, $theadEnd, $tbodyStart] = $this->generateSheetStarts($sheet, $minRow);
@@ -737,7 +735,7 @@ class Html extends BaseWriter
if ($chartCoordinates['cell'] == $coordinates) {
$chartFileName = File::sysGetTempDir() . '/' . uniqid('', true) . '.png';
if (!$chart->render($chartFileName)) {
- return;
+ return '';
}
$html .= PHP_EOL;
@@ -1323,7 +1321,7 @@ class Html extends BaseWriter
[$this, 'formatColor']
);
if ($cellData === $origData) {
- $cellData = htmlspecialchars($cellData);
+ $cellData = htmlspecialchars($cellData ?? '');
}
if ($pSheet->getParent()->getCellXfByIndex($cell->getXfIndex())->getFont()->getSuperscript()) {
$cellData = '' . $cellData . '';
@@ -1703,11 +1701,11 @@ class Html extends BaseWriter
$first = $cells[0];
$last = $cells[1];
- [$fc, $fr] = Coordinate::coordinateFromString($first);
- $fc = Coordinate::columnIndexFromString($fc) - 1;
+ [$fc, $fr] = Coordinate::indexesFromString($first);
+ $fc = $fc - 1;
- [$lc, $lr] = Coordinate::coordinateFromString($last);
- $lc = Coordinate::columnIndexFromString($lc) - 1;
+ [$lc, $lr] = Coordinate::indexesFromString($last);
+ $lc = $lc - 1;
// loop through the individual cells in the individual merge
$r = $fr - 1;
diff --git a/src/PhpSpreadsheet/Writer/Ods.php b/src/PhpSpreadsheet/Writer/Ods.php
index 36f3e9ca..f07ade9a 100644
--- a/src/PhpSpreadsheet/Writer/Ods.php
+++ b/src/PhpSpreadsheet/Writer/Ods.php
@@ -2,7 +2,6 @@
namespace PhpOffice\PhpSpreadsheet\Writer;
-use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Content;
@@ -18,13 +17,6 @@ use ZipStream\ZipStream;
class Ods extends BaseWriter
{
- /**
- * Private writer parts.
- *
- * @var Ods\WriterPart[]
- */
- private $writerParts = [];
-
/**
* Private PhpSpreadsheet.
*
@@ -32,6 +24,41 @@ class Ods extends BaseWriter
*/
private $spreadSheet;
+ /**
+ * @var Content
+ */
+ private $writerPartContent;
+
+ /**
+ * @var Meta
+ */
+ private $writerPartMeta;
+
+ /**
+ * @var MetaInf
+ */
+ private $writerPartMetaInf;
+
+ /**
+ * @var Mimetype
+ */
+ private $writerPartMimetype;
+
+ /**
+ * @var Settings
+ */
+ private $writerPartSettings;
+
+ /**
+ * @var Styles
+ */
+ private $writerPartStyles;
+
+ /**
+ * @var Thumbnails
+ */
+ private $writerPartThumbnails;
+
/**
* Create a new Ods.
*/
@@ -39,35 +66,48 @@ class Ods extends BaseWriter
{
$this->setSpreadsheet($spreadsheet);
- $writerPartsArray = [
- 'content' => Content::class,
- 'meta' => Meta::class,
- 'meta_inf' => MetaInf::class,
- 'mimetype' => Mimetype::class,
- 'settings' => Settings::class,
- 'styles' => Styles::class,
- 'thumbnails' => Thumbnails::class,
- ];
-
- foreach ($writerPartsArray as $writer => $class) {
- $this->writerParts[$writer] = new $class($this);
- }
+ $this->writerPartContent = new Content($this);
+ $this->writerPartMeta = new Meta($this);
+ $this->writerPartMetaInf = new MetaInf($this);
+ $this->writerPartMimetype = new Mimetype($this);
+ $this->writerPartSettings = new Settings($this);
+ $this->writerPartStyles = new Styles($this);
+ $this->writerPartThumbnails = new Thumbnails($this);
}
- /**
- * Get writer part.
- *
- * @param string $pPartName Writer part name
- *
- * @return null|Ods\WriterPart
- */
- public function getWriterPart($pPartName)
+ public function getWriterPartContent(): Content
{
- if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
- return $this->writerParts[strtolower($pPartName)];
- }
+ return $this->writerPartContent;
+ }
- return null;
+ public function getWriterPartMeta(): Meta
+ {
+ return $this->writerPartMeta;
+ }
+
+ public function getWriterPartMetaInf(): MetaInf
+ {
+ return $this->writerPartMetaInf;
+ }
+
+ public function getWriterPartMimetype(): Mimetype
+ {
+ return $this->writerPartMimetype;
+ }
+
+ public function getWriterPartSettings(): Settings
+ {
+ return $this->writerPartSettings;
+ }
+
+ public function getWriterPartStyles(): Styles
+ {
+ return $this->writerPartStyles;
+ }
+
+ public function getWriterPartThumbnails(): Thumbnails
+ {
+ return $this->writerPartThumbnails;
}
/**
@@ -88,13 +128,13 @@ class Ods extends BaseWriter
$zip = $this->createZip();
- $zip->addFile('META-INF/manifest.xml', $this->getWriterPart('meta_inf')->writeManifest());
- $zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPart('thumbnails')->writeThumbnail());
- $zip->addFile('content.xml', $this->getWriterPart('content')->write());
- $zip->addFile('meta.xml', $this->getWriterPart('meta')->write());
- $zip->addFile('mimetype', $this->getWriterPart('mimetype')->write());
- $zip->addFile('settings.xml', $this->getWriterPart('settings')->write());
- $zip->addFile('styles.xml', $this->getWriterPart('styles')->write());
+ $zip->addFile('META-INF/manifest.xml', $this->getWriterPartMetaInf()->write());
+ $zip->addFile('Thumbnails/thumbnail.png', $this->getWriterPartthumbnails()->write());
+ $zip->addFile('content.xml', $this->getWriterPartcontent()->write());
+ $zip->addFile('meta.xml', $this->getWriterPartmeta()->write());
+ $zip->addFile('mimetype', $this->getWriterPartmimetype()->write());
+ $zip->addFile('settings.xml', $this->getWriterPartsettings()->write());
+ $zip->addFile('styles.xml', $this->getWriterPartstyles()->write());
// Close file
try {
diff --git a/src/PhpSpreadsheet/Writer/Ods/Cell/Style.php b/src/PhpSpreadsheet/Writer/Ods/Cell/Style.php
new file mode 100644
index 00000000..f8aae20c
--- /dev/null
+++ b/src/PhpSpreadsheet/Writer/Ods/Cell/Style.php
@@ -0,0 +1,178 @@
+writer = $writer;
+ }
+
+ private function mapHorizontalAlignment(string $horizontalAlignment): string
+ {
+ switch ($horizontalAlignment) {
+ case Alignment::HORIZONTAL_CENTER:
+ case Alignment::HORIZONTAL_CENTER_CONTINUOUS:
+ case Alignment::HORIZONTAL_DISTRIBUTED:
+ return 'center';
+ case Alignment::HORIZONTAL_RIGHT:
+ return 'end';
+ case Alignment::HORIZONTAL_FILL:
+ case Alignment::HORIZONTAL_JUSTIFY:
+ return 'justify';
+ }
+
+ return 'start';
+ }
+
+ private function mapVerticalAlignment(string $verticalAlignment): string
+ {
+ switch ($verticalAlignment) {
+ case Alignment::VERTICAL_TOP:
+ return 'top';
+ case Alignment::VERTICAL_CENTER:
+ return 'middle';
+ case Alignment::VERTICAL_DISTRIBUTED:
+ case Alignment::VERTICAL_JUSTIFY:
+ return 'automatic';
+ }
+
+ return 'bottom';
+ }
+
+ private function writeFillStyle(Fill $fill): void
+ {
+ switch ($fill->getFillType()) {
+ case Fill::FILL_SOLID:
+ $this->writer->writeAttribute('fo:background-color', sprintf(
+ '#%s',
+ strtolower($fill->getStartColor()->getRGB())
+ ));
+
+ break;
+ case Fill::FILL_GRADIENT_LINEAR:
+ case Fill::FILL_GRADIENT_PATH:
+ /// TODO :: To be implemented
+ break;
+ case Fill::FILL_NONE:
+ default:
+ }
+ }
+
+ private function writeCellProperties(CellStyle $style): void
+ {
+ // Align
+ $hAlign = $style->getAlignment()->getHorizontal();
+ $vAlign = $style->getAlignment()->getVertical();
+ $wrap = $style->getAlignment()->getWrapText();
+
+ $this->writer->startElement('style:table-cell-properties');
+ if (!empty($vAlign) || $wrap) {
+ if (!empty($vAlign)) {
+ $vAlign = $this->mapVerticalAlignment($vAlign);
+ $this->writer->writeAttribute('style:vertical-align', $vAlign);
+ }
+ if ($wrap) {
+ $this->writer->writeAttribute('fo:wrap-option', 'wrap');
+ }
+ }
+ $this->writer->writeAttribute('style:rotation-align', 'none');
+
+ // Fill
+ if ($fill = $style->getFill()) {
+ $this->writeFillStyle($fill);
+ }
+
+ $this->writer->endElement();
+
+ if (!empty($hAlign)) {
+ $hAlign = $this->mapHorizontalAlignment($hAlign);
+ $this->writer->startElement('style:paragraph-properties');
+ $this->writer->writeAttribute('fo:text-align', $hAlign);
+ $this->writer->endElement();
+ }
+ }
+
+ protected function mapUnderlineStyle(Font $font): string
+ {
+ switch ($font->getUnderline()) {
+ case Font::UNDERLINE_DOUBLE:
+ case Font::UNDERLINE_DOUBLEACCOUNTING:
+ return'double';
+ case Font::UNDERLINE_SINGLE:
+ case Font::UNDERLINE_SINGLEACCOUNTING:
+ return'single';
+ }
+
+ return 'none';
+ }
+
+ protected function writeTextProperties(CellStyle $style): void
+ {
+ // Font
+ $this->writer->startElement('style:text-properties');
+
+ $font = $style->getFont();
+
+ if ($font->getBold()) {
+ $this->writer->writeAttribute('fo:font-weight', 'bold');
+ $this->writer->writeAttribute('style:font-weight-complex', 'bold');
+ $this->writer->writeAttribute('style:font-weight-asian', 'bold');
+ }
+
+ if ($font->getItalic()) {
+ $this->writer->writeAttribute('fo:font-style', 'italic');
+ }
+
+ if ($color = $font->getColor()) {
+ $this->writer->writeAttribute('fo:color', sprintf('#%s', $color->getRGB()));
+ }
+
+ if ($family = $font->getName()) {
+ $this->writer->writeAttribute('fo:font-family', $family);
+ }
+
+ if ($size = $font->getSize()) {
+ $this->writer->writeAttribute('fo:font-size', sprintf('%.1Fpt', $size));
+ }
+
+ if ($font->getUnderline() && $font->getUnderline() !== Font::UNDERLINE_NONE) {
+ $this->writer->writeAttribute('style:text-underline-style', 'solid');
+ $this->writer->writeAttribute('style:text-underline-width', 'auto');
+ $this->writer->writeAttribute('style:text-underline-color', 'font-color');
+
+ $underline = $this->mapUnderlineStyle($font);
+ $this->writer->writeAttribute('style:text-underline-type', $underline);
+ }
+
+ $this->writer->endElement(); // Close style:text-properties
+ }
+
+ public function write(CellStyle $style): void
+ {
+ $this->writer->startElement('style:style');
+ $this->writer->writeAttribute('style:name', self::CELL_STYLE_PREFIX . $style->getIndex());
+ $this->writer->writeAttribute('style:family', 'table-cell');
+ $this->writer->writeAttribute('style:parent-style-name', 'Default');
+
+ // Alignment, fill colour, etc
+ $this->writeCellProperties($style);
+
+ // style:text-properties
+ $this->writeTextProperties($style);
+
+ // End
+ $this->writer->endElement(); // Close style:style
+ }
+}
diff --git a/src/PhpSpreadsheet/Writer/Ods/Content.php b/src/PhpSpreadsheet/Writer/Ods/Content.php
index 96e66850..e4bd1793 100644
--- a/src/PhpSpreadsheet/Writer/Ods/Content.php
+++ b/src/PhpSpreadsheet/Writer/Ods/Content.php
@@ -7,13 +7,12 @@ use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
-use PhpOffice\PhpSpreadsheet\Style\Fill;
-use PhpOffice\PhpSpreadsheet\Style\Font;
use PhpOffice\PhpSpreadsheet\Worksheet\Row;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Writer\Exception;
use PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Writer\Ods\Cell\Comment;
+use PhpOffice\PhpSpreadsheet\Writer\Ods\Cell\Style;
/**
* @author Alexander Pervakov
@@ -22,7 +21,6 @@ class Content extends WriterPart
{
const NUMBER_COLS_REPEATED_MAX = 1024;
const NUMBER_ROWS_REPEATED_MAX = 1048576;
- const CELL_STYLE_PREFIX = 'ce';
private $formulaConvertor;
@@ -41,7 +39,7 @@ class Content extends WriterPart
*
* @return string XML Output
*/
- public function write()
+ public function write(): string
{
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
@@ -185,7 +183,7 @@ class Content extends WriterPart
// Style XF
$style = $cell->getXfIndex();
if ($style !== null) {
- $objWriter->writeAttribute('table:style-name', self::CELL_STYLE_PREFIX . $style);
+ $objWriter->writeAttribute('table:style-name', Style::CELL_STYLE_PREFIX . $style);
}
switch ($cell->getDataType()) {
@@ -196,7 +194,10 @@ class Content extends WriterPart
break;
case DataType::TYPE_ERROR:
- throw new Exception('Writing of error not implemented yet.');
+ $objWriter->writeAttribute('table:formula', 'of:=#NULL!');
+ $objWriter->writeAttribute('office:value-type', 'string');
+ $objWriter->writeAttribute('office:string-value', '');
+ $objWriter->writeElement('text:p', '#NULL!');
break;
case DataType::TYPE_FORMULA:
@@ -217,10 +218,6 @@ class Content extends WriterPart
$objWriter->writeAttribute('office:value', $formulaValue);
$objWriter->writeElement('text:p', $formulaValue);
- break;
- case DataType::TYPE_INLINE:
- throw new Exception('Writing of inline not implemented yet.');
-
break;
case DataType::TYPE_NUMERIC:
$objWriter->writeAttribute('office:value-type', 'float');
@@ -228,6 +225,8 @@ class Content extends WriterPart
$objWriter->writeElement('text:p', $cell->getValue());
break;
+ case DataType::TYPE_INLINE:
+ // break intentionally omitted
case DataType::TYPE_STRING:
$objWriter->writeAttribute('office:value-type', 'string');
$objWriter->writeElement('text:p', $cell->getValue());
@@ -274,89 +273,9 @@ class Content extends WriterPart
*/
private function writeXfStyles(XMLWriter $writer, Spreadsheet $spreadsheet): void
{
+ $styleWriter = new Style($writer);
foreach ($spreadsheet->getCellXfCollection() as $style) {
- $writer->startElement('style:style');
- $writer->writeAttribute('style:name', self::CELL_STYLE_PREFIX . $style->getIndex());
- $writer->writeAttribute('style:family', 'table-cell');
- $writer->writeAttribute('style:parent-style-name', 'Default');
-
- // style:text-properties
-
- // Font
- $writer->startElement('style:text-properties');
-
- $font = $style->getFont();
-
- if ($font->getBold()) {
- $writer->writeAttribute('fo:font-weight', 'bold');
- $writer->writeAttribute('style:font-weight-complex', 'bold');
- $writer->writeAttribute('style:font-weight-asian', 'bold');
- }
-
- if ($font->getItalic()) {
- $writer->writeAttribute('fo:font-style', 'italic');
- }
-
- if ($color = $font->getColor()) {
- $writer->writeAttribute('fo:color', sprintf('#%s', $color->getRGB()));
- }
-
- if ($family = $font->getName()) {
- $writer->writeAttribute('fo:font-family', $family);
- }
-
- if ($size = $font->getSize()) {
- $writer->writeAttribute('fo:font-size', sprintf('%.1Fpt', $size));
- }
-
- if ($font->getUnderline() && $font->getUnderline() != Font::UNDERLINE_NONE) {
- $writer->writeAttribute('style:text-underline-style', 'solid');
- $writer->writeAttribute('style:text-underline-width', 'auto');
- $writer->writeAttribute('style:text-underline-color', 'font-color');
-
- switch ($font->getUnderline()) {
- case Font::UNDERLINE_DOUBLE:
- $writer->writeAttribute('style:text-underline-type', 'double');
-
- break;
- case Font::UNDERLINE_SINGLE:
- $writer->writeAttribute('style:text-underline-type', 'single');
-
- break;
- }
- }
-
- $writer->endElement(); // Close style:text-properties
-
- // style:table-cell-properties
-
- $writer->startElement('style:table-cell-properties');
- $writer->writeAttribute('style:rotation-align', 'none');
-
- // Fill
- if ($fill = $style->getFill()) {
- switch ($fill->getFillType()) {
- case Fill::FILL_SOLID:
- $writer->writeAttribute('fo:background-color', sprintf(
- '#%s',
- strtolower($fill->getStartColor()->getRGB())
- ));
-
- break;
- case Fill::FILL_GRADIENT_LINEAR:
- case Fill::FILL_GRADIENT_PATH:
- /// TODO :: To be implemented
- break;
- case Fill::FILL_NONE:
- default:
- }
- }
-
- $writer->endElement(); // Close style:table-cell-properties
-
- // End
-
- $writer->endElement(); // Close style:style
+ $styleWriter->write($style);
}
}
@@ -374,7 +293,7 @@ class Content extends WriterPart
$start = Coordinate::coordinateFromString($startCell);
$end = Coordinate::coordinateFromString($endCell);
$columnSpan = Coordinate::columnIndexFromString($end[0]) - Coordinate::columnIndexFromString($start[0]) + 1;
- $rowSpan = $end[1] - $start[1] + 1;
+ $rowSpan = ((int) $end[1]) - ((int) $start[1]) + 1;
$objWriter->writeAttribute('table:number-columns-spanned', $columnSpan);
$objWriter->writeAttribute('table:number-rows-spanned', $rowSpan);
diff --git a/src/PhpSpreadsheet/Writer/Ods/Meta.php b/src/PhpSpreadsheet/Writer/Ods/Meta.php
index 365221f7..cd3054c0 100644
--- a/src/PhpSpreadsheet/Writer/Ods/Meta.php
+++ b/src/PhpSpreadsheet/Writer/Ods/Meta.php
@@ -3,22 +3,17 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
-use PhpOffice\PhpSpreadsheet\Spreadsheet;
class Meta extends WriterPart
{
/**
* Write meta.xml to XML format.
*
- * @param Spreadsheet $spreadsheet
- *
* @return string XML Output
*/
- public function write(?Spreadsheet $spreadsheet = null)
+ public function write(): string
{
- if (!$spreadsheet) {
- $spreadsheet = $this->getParentWriter()->getSpreadsheet();
- }
+ $spreadsheet = $this->getParentWriter()->getSpreadsheet();
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
diff --git a/src/PhpSpreadsheet/Writer/Ods/MetaInf.php b/src/PhpSpreadsheet/Writer/Ods/MetaInf.php
index c9085cf8..f3f0d5fc 100644
--- a/src/PhpSpreadsheet/Writer/Ods/MetaInf.php
+++ b/src/PhpSpreadsheet/Writer/Ods/MetaInf.php
@@ -11,7 +11,7 @@ class MetaInf extends WriterPart
*
* @return string XML Output
*/
- public function writeManifest()
+ public function write(): string
{
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
diff --git a/src/PhpSpreadsheet/Writer/Ods/Mimetype.php b/src/PhpSpreadsheet/Writer/Ods/Mimetype.php
index 4aac3685..e109e6e7 100644
--- a/src/PhpSpreadsheet/Writer/Ods/Mimetype.php
+++ b/src/PhpSpreadsheet/Writer/Ods/Mimetype.php
@@ -2,18 +2,14 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
-use PhpOffice\PhpSpreadsheet\Spreadsheet;
-
class Mimetype extends WriterPart
{
/**
* Write mimetype to plain text format.
*
- * @param Spreadsheet $spreadsheet
- *
* @return string XML Output
*/
- public function write(?Spreadsheet $spreadsheet = null)
+ public function write(): string
{
return 'application/vnd.oasis.opendocument.spreadsheet';
}
diff --git a/src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php b/src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
index 9edc5c64..ae1c4217 100644
--- a/src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
+++ b/src/PhpSpreadsheet/Writer/Ods/NamedExpressions.php
@@ -23,11 +23,13 @@ class NamedExpressions
$this->formulaConvertor = $formulaConvertor;
}
- public function write(): void
+ public function write(): string
{
$this->objWriter->startElement('table:named-expressions');
$this->writeExpressions();
$this->objWriter->endElement();
+
+ return '';
}
private function writeExpressions(): void
diff --git a/src/PhpSpreadsheet/Writer/Ods/Settings.php b/src/PhpSpreadsheet/Writer/Ods/Settings.php
index d458e8c2..047bd410 100644
--- a/src/PhpSpreadsheet/Writer/Ods/Settings.php
+++ b/src/PhpSpreadsheet/Writer/Ods/Settings.php
@@ -2,21 +2,18 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
+use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
-use PhpOffice\PhpSpreadsheet\Spreadsheet;
class Settings extends WriterPart
{
/**
* Write settings.xml to XML format.
*
- * @param Spreadsheet $spreadsheet
- *
* @return string XML Output
*/
- public function write(?Spreadsheet $spreadsheet = null)
+ public function write(): string
{
- $objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
$objWriter = new XMLWriter(XMLWriter::STORAGE_DISK, $this->getParentWriter()->getDiskCachingDirectory());
} else {
@@ -39,13 +36,52 @@ class Settings extends WriterPart
$objWriter->writeAttribute('config:name', 'ooo:view-settings');
$objWriter->startElement('config:config-item-map-indexed');
$objWriter->writeAttribute('config:name', 'Views');
- $objWriter->endElement();
- $objWriter->endElement();
+ $objWriter->startElement('config:config-item-map-entry');
+ $spreadsheet = $this->getParentWriter()->getSpreadsheet();
+
+ $objWriter->startElement('config:config-item');
+ $objWriter->writeAttribute('config:name', 'ViewId');
+ $objWriter->writeAttribute('config:type', 'string');
+ $objWriter->text('view1');
+ $objWriter->endElement(); // ViewId
+ $objWriter->startElement('config:config-item-map-named');
+ $objWriter->writeAttribute('config:name', 'Tables');
+ foreach ($spreadsheet->getWorksheetIterator() as $ws) {
+ $objWriter->startElement('config:config-item-map-entry');
+ $objWriter->writeAttribute('config:name', $ws->getTitle());
+ $selected = $ws->getSelectedCells();
+ if (preg_match('/^([a-z]+)([0-9]+)/i', $selected, $matches) === 1) {
+ $colSel = Coordinate::columnIndexFromString($matches[1]) - 1;
+ $rowSel = (int) $matches[2] - 1;
+ $objWriter->startElement('config:config-item');
+ $objWriter->writeAttribute('config:name', 'CursorPositionX');
+ $objWriter->writeAttribute('config:type', 'int');
+ $objWriter->text($colSel);
+ $objWriter->endElement();
+ $objWriter->startElement('config:config-item');
+ $objWriter->writeAttribute('config:name', 'CursorPositionY');
+ $objWriter->writeAttribute('config:type', 'int');
+ $objWriter->text($rowSel);
+ $objWriter->endElement();
+ }
+ $objWriter->endElement(); // config:config-item-map-entry
+ }
+ $objWriter->endElement(); // config:config-item-map-named
+ $wstitle = $spreadsheet->getActiveSheet()->getTitle();
+ $objWriter->startElement('config:config-item');
+ $objWriter->writeAttribute('config:name', 'ActiveTable');
+ $objWriter->writeAttribute('config:type', 'string');
+ $objWriter->text($wstitle);
+ $objWriter->endElement(); // config:config-item ActiveTable
+
+ $objWriter->endElement(); // config:config-item-map-entry
+ $objWriter->endElement(); // config:config-item-map-indexed Views
+ $objWriter->endElement(); // config:config-item-set ooo:view-settings
$objWriter->startElement('config:config-item-set');
$objWriter->writeAttribute('config:name', 'ooo:configuration-settings');
- $objWriter->endElement();
- $objWriter->endElement();
- $objWriter->endElement();
+ $objWriter->endElement(); // config:config-item-set ooo:configuration-settings
+ $objWriter->endElement(); // office:settings
+ $objWriter->endElement(); // office:document-settings
return $objWriter->getData();
}
diff --git a/src/PhpSpreadsheet/Writer/Ods/Styles.php b/src/PhpSpreadsheet/Writer/Ods/Styles.php
index 7ba7eba7..448b1eff 100644
--- a/src/PhpSpreadsheet/Writer/Ods/Styles.php
+++ b/src/PhpSpreadsheet/Writer/Ods/Styles.php
@@ -3,18 +3,15 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
-use PhpOffice\PhpSpreadsheet\Spreadsheet;
class Styles extends WriterPart
{
/**
* Write styles.xml to XML format.
*
- * @param Spreadsheet $spreadsheet
- *
* @return string XML Output
*/
- public function write(?Spreadsheet $spreadsheet = null)
+ public function write(): string
{
$objWriter = null;
if ($this->getParentWriter()->getUseDiskCaching()) {
diff --git a/src/PhpSpreadsheet/Writer/Ods/Thumbnails.php b/src/PhpSpreadsheet/Writer/Ods/Thumbnails.php
index dfab0654..db9579d0 100644
--- a/src/PhpSpreadsheet/Writer/Ods/Thumbnails.php
+++ b/src/PhpSpreadsheet/Writer/Ods/Thumbnails.php
@@ -2,18 +2,14 @@
namespace PhpOffice\PhpSpreadsheet\Writer\Ods;
-use PhpOffice\PhpSpreadsheet\Spreadsheet;
-
class Thumbnails extends WriterPart
{
/**
* Write Thumbnails/thumbnail.png to PNG format.
*
- * @param Spreadsheet $spreadsheet
- *
* @return string XML Output
*/
- public function writeThumbnail(?Spreadsheet $spreadsheet = null)
+ public function write(): string
{
return '';
}
diff --git a/src/PhpSpreadsheet/Writer/Ods/WriterPart.php b/src/PhpSpreadsheet/Writer/Ods/WriterPart.php
index 1982c450..17d5d169 100644
--- a/src/PhpSpreadsheet/Writer/Ods/WriterPart.php
+++ b/src/PhpSpreadsheet/Writer/Ods/WriterPart.php
@@ -30,4 +30,6 @@ abstract class WriterPart
{
$this->parentWriter = $writer;
}
+
+ abstract public function write(): string;
}
diff --git a/src/PhpSpreadsheet/Writer/Pdf.php b/src/PhpSpreadsheet/Writer/Pdf.php
index 87220458..36f3966d 100644
--- a/src/PhpSpreadsheet/Writer/Pdf.php
+++ b/src/PhpSpreadsheet/Writer/Pdf.php
@@ -165,7 +165,7 @@ abstract class Pdf extends Html
/**
* Set Paper Size.
*
- * @param string $pValue Paper size see PageSetup::PAPERSIZE_*
+ * @param int $pValue Paper size see PageSetup::PAPERSIZE_*
*
* @return self
*/
diff --git a/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php b/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php
index 9ae2ccee..87e8eeb5 100644
--- a/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php
+++ b/src/PhpSpreadsheet/Writer/Pdf/Dompdf.php
@@ -59,7 +59,7 @@ class Dompdf extends Pdf
// Create PDF
$pdf = $this->createExternalWriterInstance();
- $pdf->setPaper(strtolower($paperSize), $orientation);
+ $pdf->setPaper($paperSize, $orientation);
$pdf->loadHtml($this->generateHTMLAll());
$pdf->render();
diff --git a/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php b/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php
index 75e0010d..56ac6930 100644
--- a/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php
+++ b/src/PhpSpreadsheet/Writer/Pdf/Mpdf.php
@@ -64,7 +64,7 @@ class Mpdf extends Pdf
$config = ['tempDir' => $this->tempDir . '/mpdf'];
$pdf = $this->createExternalWriterInstance($config);
$ortmp = $orientation;
- $pdf->_setPageSize(strtoupper($paperSize), $ortmp);
+ $pdf->_setPageSize($paperSize, $ortmp);
$pdf->DefOrientation = $orientation;
$pdf->AddPageByArray([
'orientation' => $orientation,
diff --git a/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php b/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php
index 7530b1ef..56e917e3 100644
--- a/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php
+++ b/src/PhpSpreadsheet/Writer/Pdf/Tcpdf.php
@@ -24,7 +24,7 @@ class Tcpdf extends Pdf
*
* @param string $orientation Page orientation
* @param string $unit Unit measure
- * @param string $paperSize Paper size
+ * @param array|string $paperSize Paper size
*
* @return \TCPDF implementation
*/
diff --git a/src/PhpSpreadsheet/Writer/Xls.php b/src/PhpSpreadsheet/Writer/Xls.php
index c7c2e7d6..a1b477bf 100644
--- a/src/PhpSpreadsheet/Writer/Xls.php
+++ b/src/PhpSpreadsheet/Writer/Xls.php
@@ -23,6 +23,9 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
+use PhpOffice\PhpSpreadsheet\Writer\Xls\Parser;
+use PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook;
+use PhpOffice\PhpSpreadsheet\Writer\Xls\Worksheet;
class Xls extends BaseWriter
{
@@ -64,7 +67,7 @@ class Xls extends BaseWriter
/**
* Formula parser.
*
- * @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Parser
+ * @var Parser
*/
private $parser;
@@ -78,24 +81,24 @@ class Xls extends BaseWriter
/**
* Basic OLE object summary information.
*
- * @var array
+ * @var string
*/
private $summaryInformation;
/**
* Extended OLE object document summary information.
*
- * @var array
+ * @var string
*/
private $documentSummaryInformation;
/**
- * @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook
+ * @var Workbook
*/
private $writerWorkbook;
/**
- * @var \PhpOffice\PhpSpreadsheet\Writer\Xls\Worksheet[]
+ * @var Worksheet[]
*/
private $writerWorksheets;
@@ -388,7 +391,7 @@ class Xls extends BaseWriter
}
}
- private function processMemoryDrawing(BstoreContainer &$bstoreContainer, BaseDrawing $drawing, string $renderingFunctionx): void
+ private function processMemoryDrawing(BstoreContainer &$bstoreContainer, MemoryDrawing $drawing, string $renderingFunctionx): void
{
switch ($renderingFunctionx) {
case MemoryDrawing::RENDERING_JPEG:
@@ -418,8 +421,9 @@ class Xls extends BaseWriter
$bstoreContainer->addBSE($BSE);
}
- private function processDrawing(BstoreContainer &$bstoreContainer, BaseDrawing $drawing): void
+ private function processDrawing(BstoreContainer &$bstoreContainer, Drawing $drawing): void
{
+ $blipType = null;
$blipData = '';
$filename = $drawing->getPath();
@@ -723,6 +727,7 @@ class Xls extends BaseWriter
} elseif ($dataProp['type']['data'] == 0x1E) { // null-terminated string prepended by dword string length
// Null-terminated string
$dataProp['data']['data'] .= chr(0);
+ // @phpstan-ignore-next-line
++$dataProp['data']['length'];
// Complete the string with null string for being a %4
$dataProp['data']['length'] = $dataProp['data']['length'] + ((4 - $dataProp['data']['length'] % 4) == 4 ? 0 : (4 - $dataProp['data']['length'] % 4));
@@ -740,6 +745,7 @@ class Xls extends BaseWriter
} else {
$dataSection_Content .= $dataProp['data']['data'];
+ // @phpstan-ignore-next-line
$dataSection_Content_Offset += 4 + $dataProp['data']['length'];
}
}
diff --git a/src/PhpSpreadsheet/Writer/Xls/BIFFwriter.php b/src/PhpSpreadsheet/Writer/Xls/BIFFwriter.php
index 84e27d0d..4a7e0656 100644
--- a/src/PhpSpreadsheet/Writer/Xls/BIFFwriter.php
+++ b/src/PhpSpreadsheet/Writer/Xls/BIFFwriter.php
@@ -49,7 +49,7 @@ class BIFFwriter
/**
* The string containing the data of the BIFF stream.
*
- * @var string
+ * @var null|string
*/
public $_data;
diff --git a/src/PhpSpreadsheet/Writer/Xls/Escher.php b/src/PhpSpreadsheet/Writer/Xls/Escher.php
index 1ee2e904..e42139b3 100644
--- a/src/PhpSpreadsheet/Writer/Xls/Escher.php
+++ b/src/PhpSpreadsheet/Writer/Xls/Escher.php
@@ -420,8 +420,8 @@ class Escher
$recType = 0xF010;
// start coordinates
- [$column, $row] = Coordinate::coordinateFromString($this->object->getStartCoordinates());
- $c1 = Coordinate::columnIndexFromString($column) - 1;
+ [$column, $row] = Coordinate::indexesFromString($this->object->getStartCoordinates());
+ $c1 = $column - 1;
$r1 = $row - 1;
// start offsetX
@@ -431,8 +431,8 @@ class Escher
$startOffsetY = $this->object->getStartOffsetY();
// end coordinates
- [$column, $row] = Coordinate::coordinateFromString($this->object->getEndCoordinates());
- $c2 = Coordinate::columnIndexFromString($column) - 1;
+ [$column, $row] = Coordinate::indexesFromString($this->object->getEndCoordinates());
+ $c2 = $column - 1;
$r2 = $row - 1;
// end offsetX
diff --git a/src/PhpSpreadsheet/Writer/Xls/Font.php b/src/PhpSpreadsheet/Writer/Xls/Font.php
index 9cb31ead..1266cf24 100644
--- a/src/PhpSpreadsheet/Writer/Xls/Font.php
+++ b/src/PhpSpreadsheet/Writer/Xls/Font.php
@@ -119,7 +119,7 @@ class Font
/**
* Map of BIFF2-BIFF8 codes for underline styles.
*
- * @var array of int
+ * @var int[]
*/
private static $mapUnderline = [
\PhpOffice\PhpSpreadsheet\Style\Font::UNDERLINE_NONE => 0x00,
diff --git a/src/PhpSpreadsheet/Writer/Xls/Parser.php b/src/PhpSpreadsheet/Writer/Xls/Parser.php
index f89957a4..d49459b3 100644
--- a/src/PhpSpreadsheet/Writer/Xls/Parser.php
+++ b/src/PhpSpreadsheet/Writer/Xls/Parser.php
@@ -527,11 +527,11 @@ class Parser
} elseif (preg_match('/^' . Calculation::CALCULATION_REGEXP_DEFINEDNAME . '$/mui', $token) && $this->spreadsheet->getDefinedName($token) !== null) {
return $this->convertDefinedName($token);
// commented so argument number can be processed correctly. See toReversePolish().
- /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/", $token))
- {
- return($this->convertFunction($token, $this->_func_args));
- }*/
- // if it's an argument, ignore the token (the argument remains)
+ /*elseif (preg_match("/[A-Z0-9\xc0-\xdc\.]+/", $token))
+ {
+ return($this->convertFunction($token, $this->_func_args));
+ }*/
+ // if it's an argument, ignore the token (the argument remains)
} elseif ($token == 'arg') {
return '';
}
@@ -597,10 +597,9 @@ class Parser
if ($args >= 0) {
return pack('Cv', $this->ptg['ptgFuncV'], $this->functions[$token][0]);
}
+
// Variable number of args eg. SUM($i, $j, $k, ..).
- if ($args == -1) {
- return pack('CCv', $this->ptg['ptgFuncVarV'], $num_args, $this->functions[$token][0]);
- }
+ return pack('CCv', $this->ptg['ptgFuncVarV'], $num_args, $this->functions[$token][0]);
}
/**
@@ -747,7 +746,7 @@ class Parser
return pack('C', 0xFF);
}
- private function convertDefinedName(string $name): void
+ private function convertDefinedName(string $name): string
{
if (strlen($name) > 255) {
throw new WriterException('Defined Name is too long');
@@ -764,7 +763,8 @@ class Parser
$ptgRef = pack('Cvxx', $this->ptg['ptgName'], $nameReference);
throw new WriterException('Cannot yet write formulae with defined names to Xls');
-// return $ptgRef;
+
+ return $ptgRef;
}
/**
@@ -851,10 +851,10 @@ class Parser
* called by the addWorksheet() method of the
* \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook class.
*
- * @see \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook::addWorksheet()
- *
* @param string $name The name of the worksheet being added
* @param int $index The index of the worksheet being added
+ *
+ * @see \PhpOffice\PhpSpreadsheet\Writer\Xls\Workbook::addWorksheet()
*/
public function setExtSheet($name, $index): void
{
@@ -968,6 +968,7 @@ class Parser
*/
private function advance()
{
+ $token = '';
$i = $this->currentCharacter;
$formula_length = strlen($this->formula);
// eat up white spaces
@@ -1229,9 +1230,9 @@ class Parser
* This function just introduces a ptgParen element in the tree, so that Excel
* doesn't get confused when working with a parenthesized formula afterwards.
*
- * @see fact()
- *
* @return array The parsed ptg'd tree
+ *
+ * @see fact()
*/
private function parenthesizedExpression()
{
@@ -1473,6 +1474,7 @@ class Parser
} else {
$left_tree = '';
}
+
// add it's left subtree and return.
return $left_tree . $this->convertFunction($tree['value'], $tree['right']);
}
diff --git a/src/PhpSpreadsheet/Writer/Xls/Workbook.php b/src/PhpSpreadsheet/Writer/Xls/Workbook.php
index f752bce6..a917185d 100644
--- a/src/PhpSpreadsheet/Writer/Xls/Workbook.php
+++ b/src/PhpSpreadsheet/Writer/Xls/Workbook.php
@@ -551,8 +551,8 @@ class Workbook extends BIFFwriter
$newRange = '';
if (empty($worksheet)) {
if (($offset === 0) || ($definedRange[$offset - 1] !== ':')) {
- // We need a worksheet
- $worksheet = $pDefinedName->getWorksheet()->getTitle();
+ // We should have a worksheet
+ $worksheet = $pDefinedName->getWorksheet() ? $pDefinedName->getWorksheet()->getTitle() : null;
}
} else {
$worksheet = str_replace("''", "'", trim($worksheet, "'"));
@@ -678,13 +678,13 @@ class Workbook extends BIFFwriter
$formulaData = '';
for ($j = 0; $j < $countPrintArea; ++$j) {
$printAreaRect = $printArea[$j]; // e.g. A3:J6
- $printAreaRect[0] = Coordinate::coordinateFromString($printAreaRect[0]);
- $printAreaRect[1] = Coordinate::coordinateFromString($printAreaRect[1]);
+ $printAreaRect[0] = Coordinate::indexesFromString($printAreaRect[0]);
+ $printAreaRect[1] = Coordinate::indexesFromString($printAreaRect[1]);
$print_rowmin = $printAreaRect[0][1] - 1;
$print_rowmax = $printAreaRect[1][1] - 1;
- $print_colmin = Coordinate::columnIndexFromString($printAreaRect[0][0]) - 1;
- $print_colmax = Coordinate::columnIndexFromString($printAreaRect[1][0]) - 1;
+ $print_colmin = $printAreaRect[0][0] - 1;
+ $print_colmax = $printAreaRect[1][0] - 1;
// construct formula data manually because parser does not recognize absolute 3d cell references
$formulaData .= pack('Cvvvvv', 0x3B, $i, $print_rowmin, $print_rowmax, $print_colmin, $print_colmax);
@@ -756,8 +756,8 @@ class Workbook extends BIFFwriter
* Write a short NAME record.
*
* @param string $name
- * @param string $sheetIndex 1-based sheet index the defined name applies to. 0 = global
- * @param integer[][] $rangeBounds range boundaries
+ * @param int $sheetIndex 1-based sheet index the defined name applies to. 0 = global
+ * @param int[][] $rangeBounds range boundaries
* @param bool $isHidden
*
* @return string Complete binary record data
@@ -839,10 +839,9 @@ class Workbook extends BIFFwriter
/**
* Writes Excel BIFF BOUNDSHEET record.
*
- * @param Worksheet $sheet Worksheet name
* @param int $offset Location of worksheet BOF
*/
- private function writeBoundSheet($sheet, $offset): void
+ private function writeBoundSheet(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $sheet, $offset): void
{
$sheetname = $sheet->getTitle();
$record = 0x0085; // Record identifier
diff --git a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php
index a793128a..7051ab2d 100644
--- a/src/PhpSpreadsheet/Writer/Xls/Worksheet.php
+++ b/src/PhpSpreadsheet/Writer/Xls/Worksheet.php
@@ -95,7 +95,7 @@ class Worksheet extends BIFFwriter
/**
* Whether to use outline.
*
- * @var int
+ * @var bool
*/
private $outlineOn;
@@ -217,8 +217,8 @@ class Worksheet extends BIFFwriter
*
* @param int $str_total Total number of strings
* @param int $str_unique Total number of unique strings
- * @param array &$str_table String Table
- * @param array &$colors Colour Table
+ * @param array $str_table String Table
+ * @param array $colors Colour Table
* @param Parser $parser The formula parser created for the Workbook
* @param bool $preCalculateFormulas Flag indicating whether formulas should be calculated or just written
* @param \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $phpSheet The worksheet to write
@@ -244,10 +244,10 @@ class Worksheet extends BIFFwriter
$this->printHeaders = 0;
- $this->outlineStyle = 0;
- $this->outlineBelow = 1;
- $this->outlineRight = 1;
- $this->outlineOn = 1;
+ $this->outlineStyle = false;
+ $this->outlineBelow = true;
+ $this->outlineRight = true;
+ $this->outlineOn = true;
$this->fontHashIndex = [];
@@ -512,7 +512,7 @@ class Worksheet extends BIFFwriter
// Hyperlinks
foreach ($phpSheet->getHyperLinkCollection() as $coordinate => $hyperlink) {
- [$column, $row] = Coordinate::coordinateFromString($coordinate);
+ [$column, $row] = Coordinate::indexesFromString($coordinate);
$url = $hyperlink->getUrl();
@@ -526,7 +526,7 @@ class Worksheet extends BIFFwriter
$url = 'external:' . $url;
}
- $this->writeUrl($row - 1, Coordinate::columnIndexFromString($column) - 1, $url);
+ $this->writeUrl($row - 1, $column - 1, $url);
}
$this->writeDataValidity();
@@ -587,22 +587,20 @@ class Worksheet extends BIFFwriter
$lastCell = $explodes[1];
}
- $firstCellCoordinates = Coordinate::coordinateFromString($firstCell); // e.g. [0, 1]
- $lastCellCoordinates = Coordinate::coordinateFromString($lastCell); // e.g. [1, 6]
+ $firstCellCoordinates = Coordinate::indexesFromString($firstCell); // e.g. [0, 1]
+ $lastCellCoordinates = Coordinate::indexesFromString($lastCell); // e.g. [1, 6]
- return pack('vvvv', $firstCellCoordinates[1] - 1, $lastCellCoordinates[1] - 1, Coordinate::columnIndexFromString($firstCellCoordinates[0]) - 1, Coordinate::columnIndexFromString($lastCellCoordinates[0]) - 1);
+ return pack('vvvv', $firstCellCoordinates[1] - 1, $lastCellCoordinates[1] - 1, $firstCellCoordinates[0] - 1, $lastCellCoordinates[0] - 1);
}
/**
- * Retrieves data from memory in one chunk, or from disk in $buffer
+ * Retrieves data from memory in one chunk, or from disk
* sized chunks.
*
* @return string The data
*/
public function getData()
{
- $buffer = 4096;
-
// Return data stored in memory
if (isset($this->_data)) {
$tmp = $this->_data;
@@ -612,7 +610,7 @@ class Worksheet extends BIFFwriter
}
// No data to return
- return false;
+ return '';
}
/**
@@ -640,11 +638,6 @@ class Worksheet extends BIFFwriter
$this->outlineBelow = $symbols_below;
$this->outlineRight = $symbols_right;
$this->outlineStyle = $auto_style;
-
- // Ensure this is a boolean vale for Window2
- if ($this->outlineOn) {
- $this->outlineOn = 1;
- }
}
/**
@@ -926,20 +919,14 @@ class Worksheet extends BIFFwriter
* The hyperlink can be to a http, ftp, mail, internal sheet (not yet), or external
* directory url.
*
- * Returns 0 : normal termination
- * -2 : row or column out of range
- * -3 : long string truncated to 255 chars
- *
* @param int $row Row
* @param int $col Column
* @param string $url URL string
- *
- * @return int
*/
- private function writeUrl($row, $col, $url)
+ private function writeUrl($row, $col, $url): void
{
// Add start row and col to arg list
- return $this->writeUrlRange($row, $col, $row, $col, $url);
+ $this->writeUrlRange($row, $col, $row, $col, $url);
}
/**
@@ -954,21 +941,19 @@ class Worksheet extends BIFFwriter
* @param int $col2 End column
* @param string $url URL string
*
- * @return int
- *
* @see writeUrl()
*/
- public function writeUrlRange($row1, $col1, $row2, $col2, $url)
+ private function writeUrlRange($row1, $col1, $row2, $col2, $url): void
{
// Check for internal/external sheet links or default to web link
if (preg_match('[^internal:]', $url)) {
- return $this->writeUrlInternal($row1, $col1, $row2, $col2, $url);
+ $this->writeUrlInternal($row1, $col1, $row2, $col2, $url);
}
if (preg_match('[^external:]', $url)) {
- return $this->writeUrlExternal($row1, $col1, $row2, $col2, $url);
+ $this->writeUrlExternal($row1, $col1, $row2, $col2, $url);
}
- return $this->writeUrlWeb($row1, $col1, $row2, $col2, $url);
+ $this->writeUrlWeb($row1, $col1, $row2, $col2, $url);
}
/**
@@ -982,14 +967,11 @@ class Worksheet extends BIFFwriter
* @param int $col2 End column
* @param string $url URL string
*
- * @return int
- *
* @see writeUrl()
*/
- public function writeUrlWeb($row1, $col1, $row2, $col2, $url)
+ public function writeUrlWeb($row1, $col1, $row2, $col2, $url): void
{
$record = 0x01B8; // Record identifier
- $length = 0x00000; // Bytes to follow
// Pack the undocumented parts of the hyperlink stream
$unknown1 = pack('H*', 'D0C9EA79F9BACE118C8200AA004BA90B02000000');
@@ -1014,8 +996,6 @@ class Worksheet extends BIFFwriter
// Write the packed data
$this->append($header . $data . $unknown1 . $options . $unknown2 . $url_len . $url);
-
- return 0;
}
/**
@@ -1027,14 +1007,11 @@ class Worksheet extends BIFFwriter
* @param int $col2 End column
* @param string $url URL string
*
- * @return int
- *
* @see writeUrl()
*/
- public function writeUrlInternal($row1, $col1, $row2, $col2, $url)
+ private function writeUrlInternal($row1, $col1, $row2, $col2, $url): void
{
$record = 0x01B8; // Record identifier
- $length = 0x00000; // Bytes to follow
// Strip URL type
$url = preg_replace('/^internal:/', '', $url);
@@ -1063,8 +1040,6 @@ class Worksheet extends BIFFwriter
// Write the packed data
$this->append($header . $data . $unknown1 . $options . $url_len . $url);
-
- return 0;
}
/**
@@ -1080,16 +1055,14 @@ class Worksheet extends BIFFwriter
* @param int $col2 End column
* @param string $url URL string
*
- * @return int
- *
* @see writeUrl()
*/
- public function writeUrlExternal($row1, $col1, $row2, $col2, $url)
+ private function writeUrlExternal($row1, $col1, $row2, $col2, $url): void
{
// Network drives are different. We will handle them separately
// MS/Novell network drives and shares start with \\
if (preg_match('[^external:\\\\]', $url)) {
- return; //($this->writeUrlExternal_net($row1, $col1, $row2, $col2, $url, $str, $format));
+ return;
}
$record = 0x01B8; // Record identifier
@@ -1165,8 +1138,6 @@ class Worksheet extends BIFFwriter
// Write the packed data
$this->append($header . $data);
-
- return 0;
}
/**
@@ -1344,32 +1315,13 @@ class Worksheet extends BIFFwriter
*/
private function writeColinfo($col_array): void
{
- if (isset($col_array[0])) {
- $colFirst = $col_array[0];
- }
- if (isset($col_array[1])) {
- $colLast = $col_array[1];
- }
- if (isset($col_array[2])) {
- $coldx = $col_array[2];
- } else {
- $coldx = 8.43;
- }
- if (isset($col_array[3])) {
- $xfIndex = $col_array[3];
- } else {
- $xfIndex = 15;
- }
- if (isset($col_array[4])) {
- $grbit = $col_array[4];
- } else {
- $grbit = 0;
- }
- if (isset($col_array[5])) {
- $level = $col_array[5];
- } else {
- $level = 0;
- }
+ $colFirst = $col_array[0] ?? null;
+ $colLast = $col_array[1] ?? null;
+ $coldx = $col_array[2] ?? 8.43;
+ $xfIndex = $col_array[3] ?? 15;
+ $grbit = $col_array[4] ?? 0;
+ $level = $col_array[5] ?? 0;
+
$record = 0x007D; // Record identifier
$length = 0x000C; // Number of bytes to follow
@@ -1425,13 +1377,6 @@ class Worksheet extends BIFFwriter
$irefAct = 0; // Active cell ref
$cref = 1; // Number of refs
- if (!isset($rwLast)) {
- $rwLast = $rwFirst; // Last row in reference
- }
- if (!isset($colLast)) {
- $colLast = $colFirst; // Last col in reference
- }
-
// Swap last row/col for first row/col as necessary
if ($rwFirst > $rwLast) {
[$rwFirst, $rwLast] = [$rwLast, $rwFirst];
@@ -1481,10 +1426,10 @@ class Worksheet extends BIFFwriter
// extract the row and column indexes
$range = Coordinate::splitRange($mergeCell);
[$first, $last] = $range[0];
- [$firstColumn, $firstRow] = Coordinate::coordinateFromString($first);
- [$lastColumn, $lastRow] = Coordinate::coordinateFromString($last);
+ [$firstColumn, $firstRow] = Coordinate::indexesFromString($first);
+ [$lastColumn, $lastRow] = Coordinate::indexesFromString($last);
- $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, Coordinate::columnIndexFromString($firstColumn) - 1, Coordinate::columnIndexFromString($lastColumn) - 1);
+ $recordData .= pack('vvvv', $firstRow - 1, $lastRow - 1, $firstColumn - 1, $lastColumn - 1);
// flush record if we have reached limit for number of merged cells, or reached final merged cell
if ($j == $maxCountMergeCellsPerRecord || $i == $countMergeCells) {
@@ -1627,76 +1572,37 @@ class Worksheet extends BIFFwriter
*/
private function writePanes(): void
{
- $panes = [];
- if ($this->phpSheet->getFreezePane()) {
- [$column, $row] = Coordinate::coordinateFromString($this->phpSheet->getFreezePane());
- $panes[0] = Coordinate::columnIndexFromString($column) - 1;
- $panes[1] = $row - 1;
-
- [$leftMostColumn, $topRow] = Coordinate::coordinateFromString($this->phpSheet->getTopLeftCell());
- //Coordinates are zero-based in xls files
- $panes[2] = $topRow - 1;
- $panes[3] = Coordinate::columnIndexFromString($leftMostColumn) - 1;
- } else {
+ if (!$this->phpSheet->getFreezePane()) {
// thaw panes
return;
}
- $x = $panes[0] ?? null;
- $y = $panes[1] ?? null;
- $rwTop = $panes[2] ?? null;
- $colLeft = $panes[3] ?? null;
- if (count($panes) > 4) { // if Active pane was received
- $pnnAct = $panes[4];
- } else {
- $pnnAct = null;
- }
+ [$column, $row] = Coordinate::indexesFromString($this->phpSheet->getFreezePane());
+ $x = $column - 1;
+ $y = $row - 1;
+
+ [$leftMostColumn, $topRow] = Coordinate::indexesFromString($this->phpSheet->getTopLeftCell());
+ //Coordinates are zero-based in xls files
+ $rwTop = $topRow - 1;
+ $colLeft = $leftMostColumn - 1;
+
$record = 0x0041; // Record identifier
$length = 0x000A; // Number of bytes to follow
- // Code specific to frozen or thawed panes.
- if ($this->phpSheet->getFreezePane()) {
- // Set default values for $rwTop and $colLeft
- if (!isset($rwTop)) {
- $rwTop = $y;
- }
- if (!isset($colLeft)) {
- $colLeft = $x;
- }
- } else {
- // Set default values for $rwTop and $colLeft
- if (!isset($rwTop)) {
- $rwTop = 0;
- }
- if (!isset($colLeft)) {
- $colLeft = 0;
- }
-
- // Convert Excel's row and column units to the internal units.
- // The default row height is 12.75
- // The default column width is 8.43
- // The following slope and intersection values were interpolated.
- //
- $y = 20 * $y + 255;
- $x = 113.879 * $x + 390;
- }
-
// Determine which pane should be active. There is also the undocumented
// option to override this should it be necessary: may be removed later.
- //
- if (!isset($pnnAct)) {
- if ($x != 0 && $y != 0) {
- $pnnAct = 0; // Bottom right
- }
- if ($x != 0 && $y == 0) {
- $pnnAct = 1; // Top right
- }
- if ($x == 0 && $y != 0) {
- $pnnAct = 2; // Bottom left
- }
- if ($x == 0 && $y == 0) {
- $pnnAct = 3; // Top left
- }
+ $pnnAct = null;
+ if ($x != 0 && $y != 0) {
+ $pnnAct = 0; // Bottom right
+ }
+ if ($x != 0 && $y == 0) {
+ $pnnAct = 1; // Top right
+ }
+ if ($x == 0 && $y != 0) {
+ $pnnAct = 2; // Bottom left
+ }
+ if ($x == 0 && $y == 0) {
+ $pnnAct = 3; // Top left
}
$this->activePane = $pnnAct; // Used in writeSelection
@@ -1715,9 +1621,7 @@ class Worksheet extends BIFFwriter
$length = 0x0022; // Number of bytes to follow
$iPaperSize = $this->phpSheet->getPageSetup()->getPaperSize(); // Paper size
-
- $iScale = $this->phpSheet->getPageSetup()->getScale() ?
- $this->phpSheet->getPageSetup()->getScale() : 100; // Print scaling factor
+ $iScale = $this->phpSheet->getPageSetup()->getScale() ?: 100; // Print scaling factor
$iPageStart = 0x01; // Starting page number
$iFitWidth = (int) $this->phpSheet->getPageSetup()->getFitToWidth(); // Fit to number of pages wide
@@ -2976,9 +2880,9 @@ class Worksheet extends BIFFwriter
private function writeCFRule(Conditional $conditional): void
{
$record = 0x01B1; // Record identifier
+ $type = null; // Type of the CF
+ $operatorType = null; // Comparison operator
- // $type : Type of the CF
- // $operatorType : Comparison operator
if ($conditional->getConditionType() == Conditional::CONDITION_EXPRESSION) {
$type = 0x02;
$operatorType = 0x00;
@@ -3143,6 +3047,11 @@ class Worksheet extends BIFFwriter
// Text direction
$flags |= (1 == 0 ? 0x80000000 : 0);
+ $dataBlockFont = null;
+ $dataBlockAlign = null;
+ $dataBlockBorder = null;
+ $dataBlockFill = null;
+
// Data Blocks
if ($bFormatFont == 1) {
// Font Name
@@ -4400,15 +4309,6 @@ class Worksheet extends BIFFwriter
$dataBlockFill = pack('v', $blockFillPatternStyle);
$dataBlockFill .= pack('v', $colorIdxFg | ($colorIdxBg << 7));
}
- if ($bFormatProt == 1) {
- $dataBlockProtection = 0;
- if ($conditional->getStyle()->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED) {
- $dataBlockProtection = 1;
- }
- if ($conditional->getStyle()->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED) {
- $dataBlockProtection = 1 << 1;
- }
- }
$data = pack('CCvvVv', $type, $operatorType, $szValue1, $szValue2, $flags, 0x0000);
if ($bFormatFont == 1) { // Block Formatting : OK
@@ -4424,7 +4324,7 @@ class Worksheet extends BIFFwriter
$data .= $dataBlockFill;
}
if ($bFormatProt == 1) {
- $data .= $dataBlockProtection;
+ $data .= $this->getDataBlockProtection($conditional);
}
if ($operand1 !== null) {
$data .= $operand1;
@@ -4459,10 +4359,7 @@ class Worksheet extends BIFFwriter
$arrConditional[] = $conditional->getHashCode();
}
// Cells
- $arrCoord = Coordinate::coordinateFromString($cellCoordinate);
- if (!is_numeric($arrCoord[0])) {
- $arrCoord[0] = Coordinate::columnIndexFromString($arrCoord[0]);
- }
+ $arrCoord = Coordinate::indexesFromString($cellCoordinate);
if ($numColumnMin === null || ($numColumnMin > $arrCoord[0])) {
$numColumnMin = $arrCoord[0];
}
@@ -4488,4 +4385,17 @@ class Worksheet extends BIFFwriter
$data .= $cellRange;
$this->append($header . $data);
}
+
+ private function getDataBlockProtection(Conditional $conditional): int
+ {
+ $dataBlockProtection = 0;
+ if ($conditional->getStyle()->getProtection()->getLocked() == Protection::PROTECTION_PROTECTED) {
+ $dataBlockProtection = 1;
+ }
+ if ($conditional->getStyle()->getProtection()->getHidden() == Protection::PROTECTION_PROTECTED) {
+ $dataBlockProtection = 1 << 1;
+ }
+
+ return $dataBlockProtection;
+ }
}
diff --git a/src/PhpSpreadsheet/Writer/Xls/Xf.php b/src/PhpSpreadsheet/Writer/Xls/Xf.php
index 3e8169b3..6f1d1cb2 100644
--- a/src/PhpSpreadsheet/Writer/Xls/Xf.php
+++ b/src/PhpSpreadsheet/Writer/Xls/Xf.php
@@ -115,6 +115,21 @@ class Xf
*/
private $rightBorderColor;
+ /**
+ * @var int
+ */
+ private $diag;
+
+ /**
+ * @var int
+ */
+ private $diagColor;
+
+ /**
+ * @var Style
+ */
+ private $style;
+
/**
* Constructor.
*
@@ -132,14 +147,14 @@ class Xf
$this->foregroundColor = 0x40;
$this->backgroundColor = 0x41;
- $this->_diag = 0;
+ $this->diag = 0;
$this->bottomBorderColor = 0x40;
$this->topBorderColor = 0x40;
$this->leftBorderColor = 0x40;
$this->rightBorderColor = 0x40;
- $this->_diag_color = 0x40;
- $this->_style = $style;
+ $this->diagColor = 0x40;
+ $this->style = $style;
}
/**
@@ -153,39 +168,39 @@ class Xf
if ($this->isStyleXf) {
$style = 0xFFF5;
} else {
- $style = self::mapLocked($this->_style->getProtection()->getLocked());
- $style |= self::mapHidden($this->_style->getProtection()->getHidden()) << 1;
+ $style = self::mapLocked($this->style->getProtection()->getLocked());
+ $style |= self::mapHidden($this->style->getProtection()->getHidden()) << 1;
}
// Flags to indicate if attributes have been set.
$atr_num = ($this->numberFormatIndex != 0) ? 1 : 0;
$atr_fnt = ($this->fontIndex != 0) ? 1 : 0;
- $atr_alc = ((int) $this->_style->getAlignment()->getWrapText()) ? 1 : 0;
- $atr_bdr = (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) ||
- self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) ||
- self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) ||
- self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle())) ? 1 : 0;
- $atr_pat = (($this->foregroundColor != 0x40) ||
- ($this->backgroundColor != 0x41) ||
- self::mapFillType($this->_style->getFill()->getFillType())) ? 1 : 0;
- $atr_prot = self::mapLocked($this->_style->getProtection()->getLocked())
- | self::mapHidden($this->_style->getProtection()->getHidden());
+ $atr_alc = ((int) $this->style->getAlignment()->getWrapText()) ? 1 : 0;
+ $atr_bdr = (self::mapBorderStyle($this->style->getBorders()->getBottom()->getBorderStyle()) ||
+ self::mapBorderStyle($this->style->getBorders()->getTop()->getBorderStyle()) ||
+ self::mapBorderStyle($this->style->getBorders()->getLeft()->getBorderStyle()) ||
+ self::mapBorderStyle($this->style->getBorders()->getRight()->getBorderStyle())) ? 1 : 0;
+ $atr_pat = ($this->foregroundColor != 0x40) ? 1 : 0;
+ $atr_pat = ($this->backgroundColor != 0x41) ? 1 : $atr_pat;
+ $atr_pat = self::mapFillType($this->style->getFill()->getFillType()) ? 1 : $atr_pat;
+ $atr_prot = self::mapLocked($this->style->getProtection()->getLocked())
+ | self::mapHidden($this->style->getProtection()->getHidden());
// Zero the default border colour if the border has not been set.
- if (self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) == 0) {
+ if (self::mapBorderStyle($this->style->getBorders()->getBottom()->getBorderStyle()) == 0) {
$this->bottomBorderColor = 0;
}
- if (self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) == 0) {
+ if (self::mapBorderStyle($this->style->getBorders()->getTop()->getBorderStyle()) == 0) {
$this->topBorderColor = 0;
}
- if (self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) == 0) {
+ if (self::mapBorderStyle($this->style->getBorders()->getRight()->getBorderStyle()) == 0) {
$this->rightBorderColor = 0;
}
- if (self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()) == 0) {
+ if (self::mapBorderStyle($this->style->getBorders()->getLeft()->getBorderStyle()) == 0) {
$this->leftBorderColor = 0;
}
- if (self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) == 0) {
- $this->_diag_color = 0;
+ if (self::mapBorderStyle($this->style->getBorders()->getDiagonal()->getBorderStyle()) == 0) {
+ $this->diagColor = 0;
}
$record = 0x00E0; // Record identifier
@@ -194,9 +209,9 @@ class Xf
$ifnt = $this->fontIndex; // Index to FONT record
$ifmt = $this->numberFormatIndex; // Index to FORMAT record
- $align = $this->mapHAlign($this->_style->getAlignment()->getHorizontal()); // Alignment
- $align |= (int) $this->_style->getAlignment()->getWrapText() << 3;
- $align |= self::mapVAlign($this->_style->getAlignment()->getVertical()) << 4;
+ $align = $this->mapHAlign($this->style->getAlignment()->getHorizontal()); // Alignment
+ $align |= (int) $this->style->getAlignment()->getWrapText() << 3;
+ $align |= self::mapVAlign($this->style->getAlignment()->getVertical()) << 4;
$align |= $this->textJustLast << 7;
$used_attrib = $atr_num << 2;
@@ -209,35 +224,35 @@ class Xf
$icv = $this->foregroundColor; // fg and bg pattern colors
$icv |= $this->backgroundColor << 7;
- $border1 = self::mapBorderStyle($this->_style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color
- $border1 |= self::mapBorderStyle($this->_style->getBorders()->getRight()->getBorderStyle()) << 4;
- $border1 |= self::mapBorderStyle($this->_style->getBorders()->getTop()->getBorderStyle()) << 8;
- $border1 |= self::mapBorderStyle($this->_style->getBorders()->getBottom()->getBorderStyle()) << 12;
+ $border1 = self::mapBorderStyle($this->style->getBorders()->getLeft()->getBorderStyle()); // Border line style and color
+ $border1 |= self::mapBorderStyle($this->style->getBorders()->getRight()->getBorderStyle()) << 4;
+ $border1 |= self::mapBorderStyle($this->style->getBorders()->getTop()->getBorderStyle()) << 8;
+ $border1 |= self::mapBorderStyle($this->style->getBorders()->getBottom()->getBorderStyle()) << 12;
$border1 |= $this->leftBorderColor << 16;
$border1 |= $this->rightBorderColor << 23;
- $diagonalDirection = $this->_style->getBorders()->getDiagonalDirection();
+ $diagonalDirection = $this->style->getBorders()->getDiagonalDirection();
$diag_tl_to_rb = $diagonalDirection == Borders::DIAGONAL_BOTH
- || $diagonalDirection == Borders::DIAGONAL_DOWN;
+ || $diagonalDirection == Borders::DIAGONAL_DOWN;
$diag_tr_to_lb = $diagonalDirection == Borders::DIAGONAL_BOTH
- || $diagonalDirection == Borders::DIAGONAL_UP;
+ || $diagonalDirection == Borders::DIAGONAL_UP;
$border1 |= $diag_tl_to_rb << 30;
$border1 |= $diag_tr_to_lb << 31;
$border2 = $this->topBorderColor; // Border color
$border2 |= $this->bottomBorderColor << 7;
- $border2 |= $this->_diag_color << 14;
- $border2 |= self::mapBorderStyle($this->_style->getBorders()->getDiagonal()->getBorderStyle()) << 21;
- $border2 |= self::mapFillType($this->_style->getFill()->getFillType()) << 26;
+ $border2 |= $this->diagColor << 14;
+ $border2 |= self::mapBorderStyle($this->style->getBorders()->getDiagonal()->getBorderStyle()) << 21;
+ $border2 |= self::mapFillType($this->style->getFill()->getFillType()) << 26;
$header = pack('vv', $record, $length);
//BIFF8 options: identation, shrinkToFit and text direction
- $biff8_options = $this->_style->getAlignment()->getIndent();
- $biff8_options |= (int) $this->_style->getAlignment()->getShrinkToFit() << 4;
+ $biff8_options = $this->style->getAlignment()->getIndent();
+ $biff8_options |= (int) $this->style->getAlignment()->getShrinkToFit() << 4;
$data = pack('vvvC', $ifnt, $ifmt, $style, $align);
- $data .= pack('CCC', self::mapTextRotation($this->_style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib);
+ $data .= pack('CCC', self::mapTextRotation($this->style->getAlignment()->getTextRotation()), $biff8_options, $used_attrib);
$data .= pack('VVv', $border1, $border2, $icv);
return $header . $data;
@@ -300,7 +315,7 @@ class Xf
*/
public function setDiagColor($colorIndex): void
{
- $this->_diag_color = $colorIndex;
+ $this->diagColor = $colorIndex;
}
/**
@@ -347,7 +362,7 @@ class Xf
/**
* Map of BIFF2-BIFF8 codes for border styles.
*
- * @var array of int
+ * @var int[]
*/
private static $mapBorderStyles = [
Border::BORDER_NONE => 0x00,
@@ -375,17 +390,13 @@ class Xf
*/
private static function mapBorderStyle($borderStyle)
{
- if (isset(self::$mapBorderStyles[$borderStyle])) {
- return self::$mapBorderStyles[$borderStyle];
- }
-
- return 0x00;
+ return self::$mapBorderStyles[$borderStyle] ?? 0;
}
/**
* Map of BIFF2-BIFF8 codes for fill types.
*
- * @var array of int
+ * @var int[]
*/
private static $mapFillTypes = [
Fill::FILL_NONE => 0x00,
@@ -420,17 +431,13 @@ class Xf
*/
private static function mapFillType($fillType)
{
- if (isset(self::$mapFillTypes[$fillType])) {
- return self::$mapFillTypes[$fillType];
- }
-
- return 0x00;
+ return self::$mapFillTypes[$fillType] ?? 0;
}
/**
* Map of BIFF2-BIFF8 codes for horizontal alignment.
*
- * @var array of int
+ * @var int[]
*/
private static $mapHAlignments = [
Alignment::HORIZONTAL_GENERAL => 0,
@@ -451,17 +458,13 @@ class Xf
*/
private function mapHAlign($hAlign)
{
- if (isset(self::$mapHAlignments[$hAlign])) {
- return self::$mapHAlignments[$hAlign];
- }
-
- return 0;
+ return self::$mapHAlignments[$hAlign] ?? 0;
}
/**
* Map of BIFF2-BIFF8 codes for vertical alignment.
*
- * @var array of int
+ * @var int[]
*/
private static $mapVAlignments = [
Alignment::VERTICAL_TOP => 0,
@@ -479,11 +482,7 @@ class Xf
*/
private static function mapVAlign($vAlign)
{
- if (isset(self::$mapVAlignments[$vAlign])) {
- return self::$mapVAlignments[$vAlign];
- }
-
- return 2;
+ return self::$mapVAlignments[$vAlign] ?? 2;
}
/**
@@ -497,15 +496,22 @@ class Xf
{
if ($textRotation >= 0) {
return $textRotation;
- } elseif ($textRotation == -165) {
- return 255;
- } elseif ($textRotation < 0) {
- return 90 - $textRotation;
}
+ if ($textRotation == Alignment::TEXTROTATION_STACK_PHPSPREADSHEET) {
+ return Alignment::TEXTROTATION_STACK_EXCEL;
+ }
+
+ return 90 - $textRotation;
}
+ private const LOCK_ARRAY = [
+ Protection::PROTECTION_INHERIT => 1,
+ Protection::PROTECTION_PROTECTED => 1,
+ Protection::PROTECTION_UNPROTECTED => 0,
+ ];
+
/**
- * Map locked.
+ * Map locked values.
*
* @param string $locked
*
@@ -513,18 +519,15 @@ class Xf
*/
private static function mapLocked($locked)
{
- switch ($locked) {
- case Protection::PROTECTION_INHERIT:
- return 1;
- case Protection::PROTECTION_PROTECTED:
- return 1;
- case Protection::PROTECTION_UNPROTECTED:
- return 0;
- default:
- return 1;
- }
+ return array_key_exists($locked, self::LOCK_ARRAY) ? self::LOCK_ARRAY[$locked] : 1;
}
+ private const HIDDEN_ARRAY = [
+ Protection::PROTECTION_INHERIT => 0,
+ Protection::PROTECTION_PROTECTED => 1,
+ Protection::PROTECTION_UNPROTECTED => 0,
+ ];
+
/**
* Map hidden.
*
@@ -534,15 +537,6 @@ class Xf
*/
private static function mapHidden($hidden)
{
- switch ($hidden) {
- case Protection::PROTECTION_INHERIT:
- return 0;
- case Protection::PROTECTION_PROTECTED:
- return 1;
- case Protection::PROTECTION_UNPROTECTED:
- return 0;
- default:
- return 0;
- }
+ return array_key_exists($hidden, self::HIDDEN_ARRAY) ? self::HIDDEN_ARRAY[$hidden] : 0;
}
}
diff --git a/src/PhpSpreadsheet/Writer/Xlsx.php b/src/PhpSpreadsheet/Writer/Xlsx.php
index d71541c8..27ceb559 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx.php
@@ -5,8 +5,13 @@ namespace PhpOffice\PhpSpreadsheet\Writer;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\HashTable;
-use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Style\Borders;
+use PhpOffice\PhpSpreadsheet\Style\Conditional;
+use PhpOffice\PhpSpreadsheet\Style\Fill;
+use PhpOffice\PhpSpreadsheet\Style\Font;
+use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
+use PhpOffice\PhpSpreadsheet\Worksheet\BaseDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing as WorksheetDrawing;
use PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing;
use PhpOffice\PhpSpreadsheet\Writer\Exception as WriterException;
@@ -37,13 +42,6 @@ class Xlsx extends BaseWriter
*/
private $office2003compatibility = false;
- /**
- * Private writer parts.
- *
- * @var Xlsx\WriterPart[]
- */
- private $writerParts = [];
-
/**
* Private Spreadsheet.
*
@@ -61,49 +59,49 @@ class Xlsx extends BaseWriter
/**
* Private unique Conditional HashTable.
*
- * @var HashTable
+ * @var HashTable
*/
private $stylesConditionalHashTable;
/**
* Private unique Style HashTable.
*
- * @var HashTable
+ * @var HashTable<\PhpOffice\PhpSpreadsheet\Style\Style>
*/
private $styleHashTable;
/**
* Private unique Fill HashTable.
*
- * @var HashTable
+ * @var HashTable
*/
private $fillHashTable;
/**
* Private unique \PhpOffice\PhpSpreadsheet\Style\Font HashTable.
*
- * @var HashTable
+ * @var HashTable
*/
private $fontHashTable;
/**
* Private unique Borders HashTable.
*
- * @var HashTable
+ * @var HashTable
*/
private $bordersHashTable;
/**
* Private unique NumberFormat HashTable.
*
- * @var HashTable
+ * @var HashTable
*/
private $numFmtHashTable;
/**
* Private unique \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable.
*
- * @var HashTable
+ * @var HashTable
*/
private $drawingHashTable;
@@ -114,6 +112,71 @@ class Xlsx extends BaseWriter
*/
private $zip;
+ /**
+ * @var Chart
+ */
+ private $writerPartChart;
+
+ /**
+ * @var Comments
+ */
+ private $writerPartComments;
+
+ /**
+ * @var ContentTypes
+ */
+ private $writerPartContentTypes;
+
+ /**
+ * @var DocProps
+ */
+ private $writerPartDocProps;
+
+ /**
+ * @var Drawing
+ */
+ private $writerPartDrawing;
+
+ /**
+ * @var Rels
+ */
+ private $writerPartRels;
+
+ /**
+ * @var RelsRibbon
+ */
+ private $writerPartRelsRibbon;
+
+ /**
+ * @var RelsVBA
+ */
+ private $writerPartRelsVBA;
+
+ /**
+ * @var StringTable
+ */
+ private $writerPartStringTable;
+
+ /**
+ * @var Style
+ */
+ private $writerPartStyle;
+
+ /**
+ * @var Theme
+ */
+ private $writerPartTheme;
+
+ /**
+ * @var Workbook
+ */
+ private $writerPartWorkbook;
+
+ /**
+ * @var Worksheet
+ */
+ private $writerPartWorksheet;
+
/**
* Create a new Xlsx Writer.
*/
@@ -122,53 +185,100 @@ class Xlsx extends BaseWriter
// Assign PhpSpreadsheet
$this->setSpreadsheet($spreadsheet);
- $writerPartsArray = [
- 'stringtable' => StringTable::class,
- 'contenttypes' => ContentTypes::class,
- 'docprops' => DocProps::class,
- 'rels' => Rels::class,
- 'theme' => Theme::class,
- 'style' => Style::class,
- 'workbook' => Workbook::class,
- 'worksheet' => Worksheet::class,
- 'drawing' => Drawing::class,
- 'comments' => Comments::class,
- 'chart' => Chart::class,
- 'relsvba' => RelsVBA::class,
- 'relsribbonobjects' => RelsRibbon::class,
- ];
-
- // Initialise writer parts
- // and Assign their parent IWriters
- foreach ($writerPartsArray as $writer => $class) {
- $this->writerParts[$writer] = new $class($this);
- }
-
- $hashTablesArray = ['stylesConditionalHashTable', 'fillHashTable', 'fontHashTable',
- 'bordersHashTable', 'numFmtHashTable', 'drawingHashTable',
- 'styleHashTable',
- ];
+ $this->writerPartChart = new Chart($this);
+ $this->writerPartComments = new Comments($this);
+ $this->writerPartContentTypes = new ContentTypes($this);
+ $this->writerPartDocProps = new DocProps($this);
+ $this->writerPartDrawing = new Drawing($this);
+ $this->writerPartRels = new Rels($this);
+ $this->writerPartRelsRibbon = new RelsRibbon($this);
+ $this->writerPartRelsVBA = new RelsVBA($this);
+ $this->writerPartStringTable = new StringTable($this);
+ $this->writerPartStyle = new Style($this);
+ $this->writerPartTheme = new Theme($this);
+ $this->writerPartWorkbook = new Workbook($this);
+ $this->writerPartWorksheet = new Worksheet($this);
// Set HashTable variables
- foreach ($hashTablesArray as $tableName) {
- $this->$tableName = new HashTable();
- }
+ // @phpstan-ignore-next-line
+ $this->bordersHashTable = new HashTable();
+ // @phpstan-ignore-next-line
+ $this->drawingHashTable = new HashTable();
+ // @phpstan-ignore-next-line
+ $this->fillHashTable = new HashTable();
+ // @phpstan-ignore-next-line
+ $this->fontHashTable = new HashTable();
+ // @phpstan-ignore-next-line
+ $this->numFmtHashTable = new HashTable();
+ // @phpstan-ignore-next-line
+ $this->styleHashTable = new HashTable();
+ // @phpstan-ignore-next-line
+ $this->stylesConditionalHashTable = new HashTable();
}
- /**
- * Get writer part.
- *
- * @param string $pPartName Writer part name
- *
- * @return \PhpOffice\PhpSpreadsheet\Writer\Xlsx\WriterPart
- */
- public function getWriterPart($pPartName)
+ public function getWriterPartChart(): Chart
{
- if ($pPartName != '' && isset($this->writerParts[strtolower($pPartName)])) {
- return $this->writerParts[strtolower($pPartName)];
- }
+ return $this->writerPartChart;
+ }
- return null;
+ public function getWriterPartComments(): Comments
+ {
+ return $this->writerPartComments;
+ }
+
+ public function getWriterPartContentTypes(): ContentTypes
+ {
+ return $this->writerPartContentTypes;
+ }
+
+ public function getWriterPartDocProps(): DocProps
+ {
+ return $this->writerPartDocProps;
+ }
+
+ public function getWriterPartDrawing(): Drawing
+ {
+ return $this->writerPartDrawing;
+ }
+
+ public function getWriterPartRels(): Rels
+ {
+ return $this->writerPartRels;
+ }
+
+ public function getWriterPartRelsRibbon(): RelsRibbon
+ {
+ return $this->writerPartRelsRibbon;
+ }
+
+ public function getWriterPartRelsVBA(): RelsVBA
+ {
+ return $this->writerPartRelsVBA;
+ }
+
+ public function getWriterPartStringTable(): StringTable
+ {
+ return $this->writerPartStringTable;
+ }
+
+ public function getWriterPartStyle(): Style
+ {
+ return $this->writerPartStyle;
+ }
+
+ public function getWriterPartTheme(): Theme
+ {
+ return $this->writerPartTheme;
+ }
+
+ public function getWriterPartWorkbook(): Workbook
+ {
+ return $this->writerPartWorkbook;
+ }
+
+ public function getWriterPartWorksheet(): Worksheet
+ {
+ return $this->writerPartWorksheet;
}
/**
@@ -182,8 +292,6 @@ class Xlsx extends BaseWriter
$this->pathNames = [];
$this->spreadSheet->garbageCollect();
- $this->openFileHandle($pFilename);
-
$saveDebugLog = Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog();
Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false);
$saveDateReturnType = Functions::getReturnDateType();
@@ -192,91 +300,86 @@ class Xlsx extends BaseWriter
// Create string lookup table
$this->stringTable = [];
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
- $this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable);
+ $this->stringTable = $this->getWriterPartStringTable()->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable);
}
// Create styles dictionaries
- $this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet));
- $this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet));
- $this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet));
- $this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet));
- $this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet));
- $this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet));
+ $this->styleHashTable->addFromSource($this->getWriterPartStyle()->allStyles($this->spreadSheet));
+ $this->stylesConditionalHashTable->addFromSource($this->getWriterPartStyle()->allConditionalStyles($this->spreadSheet));
+ $this->fillHashTable->addFromSource($this->getWriterPartStyle()->allFills($this->spreadSheet));
+ $this->fontHashTable->addFromSource($this->getWriterPartStyle()->allFonts($this->spreadSheet));
+ $this->bordersHashTable->addFromSource($this->getWriterPartStyle()->allBorders($this->spreadSheet));
+ $this->numFmtHashTable->addFromSource($this->getWriterPartStyle()->allNumberFormats($this->spreadSheet));
// Create drawing dictionary
- $this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet));
-
- $options = new Archive();
- $options->setEnableZip64(false);
- $options->setOutputStream($this->fileHandle);
-
- $this->zip = new ZipStream(null, $options);
+ $this->drawingHashTable->addFromSource($this->getWriterPartDrawing()->allDrawings($this->spreadSheet));
+ $zipContent = [];
// Add [Content_Types].xml to ZIP file
- $this->addZipFile('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts));
+ $zipContent['[Content_Types].xml'] = $this->getWriterPartContentTypes()->writeContentTypes($this->spreadSheet, $this->includeCharts);
//if hasMacros, add the vbaProject.bin file, Certificate file(if exists)
if ($this->spreadSheet->hasMacros()) {
$macrosCode = $this->spreadSheet->getMacrosCode();
if ($macrosCode !== null) {
// we have the code ?
- $this->addZipFile('xl/vbaProject.bin', $macrosCode); //allways in 'xl', allways named vbaProject.bin
+ $zipContent['xl/vbaProject.bin'] = $macrosCode; //allways in 'xl', allways named vbaProject.bin
if ($this->spreadSheet->hasMacrosCertificate()) {
//signed macros ?
// Yes : add the certificate file and the related rels file
- $this->addZipFile('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate());
- $this->addZipFile('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet));
+ $zipContent['xl/vbaProjectSignature.bin'] = $this->spreadSheet->getMacrosCertificate();
+ $zipContent['xl/_rels/vbaProject.bin.rels'] = $this->getWriterPartRelsVBA()->writeVBARelationships($this->spreadSheet);
}
}
}
//a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels)
if ($this->spreadSheet->hasRibbon()) {
$tmpRibbonTarget = $this->spreadSheet->getRibbonXMLData('target');
- $this->addZipFile($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data'));
+ $zipContent[$tmpRibbonTarget] = $this->spreadSheet->getRibbonXMLData('data');
if ($this->spreadSheet->hasRibbonBinObjects()) {
$tmpRootPath = dirname($tmpRibbonTarget) . '/';
$ribbonBinObjects = $this->spreadSheet->getRibbonBinObjects('data'); //the files to write
foreach ($ribbonBinObjects as $aPath => $aContent) {
- $this->addZipFile($tmpRootPath . $aPath, $aContent);
+ $zipContent[$tmpRootPath . $aPath] = $aContent;
}
//the rels for files
- $this->addZipFile($tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet));
+ $zipContent[$tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels'] = $this->getWriterPartRelsRibbon()->writeRibbonRelationships($this->spreadSheet);
}
}
// Add relationships to ZIP file
- $this->addZipFile('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet));
- $this->addZipFile('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet));
+ $zipContent['_rels/.rels'] = $this->getWriterPartRels()->writeRelationships($this->spreadSheet);
+ $zipContent['xl/_rels/workbook.xml.rels'] = $this->getWriterPartRels()->writeWorkbookRelationships($this->spreadSheet);
// Add document properties to ZIP file
- $this->addZipFile('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet));
- $this->addZipFile('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet));
- $customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet);
+ $zipContent['docProps/app.xml'] = $this->getWriterPartDocProps()->writeDocPropsApp($this->spreadSheet);
+ $zipContent['docProps/core.xml'] = $this->getWriterPartDocProps()->writeDocPropsCore($this->spreadSheet);
+ $customPropertiesPart = $this->getWriterPartDocProps()->writeDocPropsCustom($this->spreadSheet);
if ($customPropertiesPart !== null) {
- $this->addZipFile('docProps/custom.xml', $customPropertiesPart);
+ $zipContent['docProps/custom.xml'] = $customPropertiesPart;
}
// Add theme to ZIP file
- $this->addZipFile('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet));
+ $zipContent['xl/theme/theme1.xml'] = $this->getWriterPartTheme()->writeTheme($this->spreadSheet);
// Add string table to ZIP file
- $this->addZipFile('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable));
+ $zipContent['xl/sharedStrings.xml'] = $this->getWriterPartStringTable()->writeStringTable($this->stringTable);
// Add styles to ZIP file
- $this->addZipFile('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet));
+ $zipContent['xl/styles.xml'] = $this->getWriterPartStyle()->writeStyles($this->spreadSheet);
// Add workbook to ZIP file
- $this->addZipFile('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas));
+ $zipContent['xl/workbook.xml'] = $this->getWriterPartWorkbook()->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas);
$chartCount = 0;
// Add worksheets
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
- $this->addZipFile('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts));
+ $zipContent['xl/worksheets/sheet' . ($i + 1) . '.xml'] = $this->getWriterPartWorksheet()->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts);
if ($this->includeCharts) {
$charts = $this->spreadSheet->getSheet($i)->getChartCollection();
if (count($charts) > 0) {
foreach ($charts as $chart) {
- $this->addZipFile('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas));
+ $zipContent['xl/charts/chart' . ($chartCount + 1) . '.xml'] = $this->getWriterPartChart()->writeChart($chart, $this->preCalculateFormulas);
++$chartCount;
}
}
@@ -287,19 +390,19 @@ class Xlsx extends BaseWriter
// Add worksheet relationships (drawings, ...)
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
// Add relationships
- $this->addZipFile('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts));
+ $zipContent['xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels'] = $this->getWriterPartRels()->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts);
// Add unparsedLoadedData
$sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName();
$unparsedLoadedData = $this->spreadSheet->getUnparsedLoadedData();
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'])) {
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'] as $ctrlProp) {
- $this->addZipFile($ctrlProp['filePath'], $ctrlProp['content']);
+ $zipContent[$ctrlProp['filePath']] = $ctrlProp['content'];
}
}
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) {
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) {
- $this->addZipFile($ctrlProp['filePath'], $ctrlProp['content']);
+ $zipContent[$ctrlProp['filePath']] = $ctrlProp['content'];
}
}
@@ -312,13 +415,13 @@ class Xlsx extends BaseWriter
// Add drawing and image relationship parts
if (($drawingCount > 0) || ($chartCount > 0)) {
// Drawing relationships
- $this->addZipFile('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts));
+ $zipContent['xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels'] = $this->getWriterPartRels()->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts);
// Drawings
- $this->addZipFile('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
+ $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = $this->getWriterPartDrawing()->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts);
} elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) {
// Drawings
- $this->addZipFile('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
+ $zipContent['xl/drawings/drawing' . ($i + 1) . '.xml'] = $this->getWriterPartDrawing()->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts);
}
// Add unparsed drawings
@@ -327,7 +430,7 @@ class Xlsx extends BaseWriter
$drawingFile = array_search($relId, $unparsedLoadedData['sheets'][$sheetCodeName]['drawingOriginalIds']);
if ($drawingFile !== false) {
$drawingFile = ltrim($drawingFile, '.');
- $this->addZipFile('xl' . $drawingFile, $drawingXml);
+ $zipContent['xl' . $drawingFile] = $drawingXml;
}
}
}
@@ -335,30 +438,30 @@ class Xlsx extends BaseWriter
// Add comment relationship parts
if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) {
// VML Comments
- $this->addZipFile('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i)));
+ $zipContent['xl/drawings/vmlDrawing' . ($i + 1) . '.vml'] = $this->getWriterPartComments()->writeVMLComments($this->spreadSheet->getSheet($i));
// Comments
- $this->addZipFile('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i)));
+ $zipContent['xl/comments' . ($i + 1) . '.xml'] = $this->getWriterPartComments()->writeComments($this->spreadSheet->getSheet($i));
}
// Add unparsed relationship parts
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['vmlDrawings'])) {
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['vmlDrawings'] as $vmlDrawing) {
- $this->addZipFile($vmlDrawing['filePath'], $vmlDrawing['content']);
+ $zipContent[$vmlDrawing['filePath']] = $vmlDrawing['content'];
}
}
// Add header/footer relationship parts
if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
// VML Drawings
- $this->addZipFile('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i)));
+ $zipContent['xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml'] = $this->getWriterPartDrawing()->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i));
// VML Drawing relationships
- $this->addZipFile('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i)));
+ $zipContent['xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels'] = $this->getWriterPartRels()->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i));
// Media
foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {
- $this->addZipFile('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath()));
+ $zipContent['xl/media/' . $image->getIndexedFilename()] = file_get_contents($image->getPath());
}
}
}
@@ -381,7 +484,7 @@ class Xlsx extends BaseWriter
$imageContents = file_get_contents($imagePath);
}
- $this->addZipFile('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
+ $zipContent['xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename())] = $imageContents;
} elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof MemoryDrawing) {
ob_start();
call_user_func(
@@ -391,13 +494,23 @@ class Xlsx extends BaseWriter
$imageContents = ob_get_contents();
ob_end_clean();
- $this->addZipFile('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
+ $zipContent['xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename())] = $imageContents;
}
}
Functions::setReturnDateType($saveDateReturnType);
Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
+ $this->openFileHandle($pFilename);
+
+ $options = new Archive();
+ $options->setEnableZip64(false);
+ $options->setOutputStream($this->fileHandle);
+
+ $this->zip = new ZipStream(null, $options);
+
+ $this->addZipFiles($zipContent);
+
// Close file
try {
$this->zip->finish();
@@ -445,7 +558,7 @@ class Xlsx extends BaseWriter
/**
* Get Style HashTable.
*
- * @return HashTable
+ * @return HashTable<\PhpOffice\PhpSpreadsheet\Style\Style>
*/
public function getStyleHashTable()
{
@@ -455,7 +568,7 @@ class Xlsx extends BaseWriter
/**
* Get Conditional HashTable.
*
- * @return HashTable
+ * @return HashTable
*/
public function getStylesConditionalHashTable()
{
@@ -465,7 +578,7 @@ class Xlsx extends BaseWriter
/**
* Get Fill HashTable.
*
- * @return HashTable
+ * @return HashTable
*/
public function getFillHashTable()
{
@@ -475,7 +588,7 @@ class Xlsx extends BaseWriter
/**
* Get \PhpOffice\PhpSpreadsheet\Style\Font HashTable.
*
- * @return HashTable
+ * @return HashTable
*/
public function getFontHashTable()
{
@@ -485,7 +598,7 @@ class Xlsx extends BaseWriter
/**
* Get Borders HashTable.
*
- * @return HashTable
+ * @return HashTable
*/
public function getBordersHashTable()
{
@@ -495,7 +608,7 @@ class Xlsx extends BaseWriter
/**
* Get NumberFormat HashTable.
*
- * @return HashTable
+ * @return HashTable
*/
public function getNumFmtHashTable()
{
@@ -505,7 +618,7 @@ class Xlsx extends BaseWriter
/**
* Get \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\BaseDrawing HashTable.
*
- * @return HashTable
+ * @return HashTable
*/
public function getDrawingHashTable()
{
@@ -545,4 +658,11 @@ class Xlsx extends BaseWriter
$this->zip->addFile($path, $content);
}
}
+
+ private function addZipFiles(array $zipContent): void
+ {
+ foreach ($zipContent as $path => $content) {
+ $this->addZipFile($path, $content);
+ }
+ }
}
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php
index 583b262c..eefae529 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/Chart.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/Chart.php
@@ -129,7 +129,7 @@ class Chart extends WriterPart
if ((is_array($caption)) && (count($caption) > 0)) {
$caption = $caption[0];
}
- $this->getParentWriter()->getWriterPart('stringtable')->writeRichTextForCharts($objWriter, $caption, 'a');
+ $this->getParentWriter()->getWriterPartstringtable()->writeRichTextForCharts($objWriter, $caption, 'a');
$objWriter->endElement();
$objWriter->endElement();
@@ -219,10 +219,12 @@ class Chart extends WriterPart
$chartTypes = self::getChartType($plotArea);
$catIsMultiLevelSeries = $valIsMultiLevelSeries = false;
$plotGroupingType = '';
+ $chartType = null;
foreach ($chartTypes as $chartType) {
$objWriter->startElement('c:' . $chartType);
$groupCount = $plotArea->getPlotGroupCount();
+ $plotGroup = null;
for ($i = 0; $i < $groupCount; ++$i) {
$plotGroup = $plotArea->getPlotGroupByIndex($i);
$groupType = $plotGroup->getPlotType();
@@ -244,7 +246,7 @@ class Chart extends WriterPart
$this->writeDataLabels($objWriter, $layout);
- if ($chartType === DataSeries::TYPE_LINECHART) {
+ if ($chartType === DataSeries::TYPE_LINECHART && $plotGroup) {
// Line only, Line3D can't be smoothed
$objWriter->startElement('c:smooth');
$objWriter->writeAttribute('val', (int) $plotGroup->getSmoothLine());
@@ -1038,9 +1040,9 @@ class Chart extends WriterPart
* @param DataSeries $plotGroup
* @param string $groupType Type of plot for dataseries
* @param XMLWriter $objWriter XML Writer
- * @param bool &$catIsMultiLevelSeries Is category a multi-series category
- * @param bool &$valIsMultiLevelSeries Is value set a multi-series set
- * @param string &$plotGroupingType Type of grouping for multi-series values
+ * @param bool $catIsMultiLevelSeries Is category a multi-series category
+ * @param bool $valIsMultiLevelSeries Is value set a multi-series set
+ * @param string $plotGroupingType Type of grouping for multi-series values
*/
private function writePlotGroup($plotGroup, $groupType, $objWriter, &$catIsMultiLevelSeries, &$valIsMultiLevelSeries, &$plotGroupingType): void
{
@@ -1079,6 +1081,7 @@ class Chart extends WriterPart
}
}
+ $plotSeriesIdx = 0;
foreach ($plotSeriesOrder as $plotSeriesIdx => $plotSeriesRef) {
$objWriter->startElement('c:ser');
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Comments.php b/src/PhpSpreadsheet/Writer/Xlsx/Comments.php
index 73c4308b..51f4248c 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/Comments.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/Comments.php
@@ -79,7 +79,7 @@ class Comments extends WriterPart
// text
$objWriter->startElement('text');
- $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $pComment->getText());
+ $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $pComment->getText());
$objWriter->endElement();
$objWriter->endElement();
@@ -165,8 +165,7 @@ class Comments extends WriterPart
private function writeVMLComment(XMLWriter $objWriter, $pCellReference, Comment $pComment): void
{
// Metadata
- [$column, $row] = Coordinate::coordinateFromString($pCellReference);
- $column = Coordinate::columnIndexFromString($column);
+ [$column, $row] = Coordinate::indexesFromString($pCellReference);
$id = 1024 + $column + $row;
$id = substr($id, 0, 4);
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php b/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php
index 8c3da827..4c0929db 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/DefinedNames.php
@@ -69,58 +69,13 @@ class DefinedNames
$this->objWriter->startElement('definedName');
$this->objWriter->writeAttribute('name', $pDefinedName->getName());
if ($pDefinedName->getLocalOnly() && $pDefinedName->getScope() !== null) {
- $this->objWriter->writeAttribute('localSheetId', $pDefinedName->getScope()->getParent()->getIndex($pDefinedName->getScope()));
+ $this->objWriter->writeAttribute(
+ 'localSheetId',
+ $pDefinedName->getScope()->getParent()->getIndex($pDefinedName->getScope())
+ );
}
- $definedRange = $pDefinedName->getValue();
- $splitCount = preg_match_all(
- '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
- $definedRange,
- $splitRanges,
- PREG_OFFSET_CAPTURE
- );
-
- $lengths = array_map('strlen', array_column($splitRanges[0], 0));
- $offsets = array_column($splitRanges[0], 1);
-
- $worksheets = $splitRanges[2];
- $columns = $splitRanges[6];
- $rows = $splitRanges[7];
-
- while ($splitCount > 0) {
- --$splitCount;
- $length = $lengths[$splitCount];
- $offset = $offsets[$splitCount];
- $worksheet = $worksheets[$splitCount][0];
- $column = $columns[$splitCount][0];
- $row = $rows[$splitCount][0];
-
- $newRange = '';
- if (empty($worksheet)) {
- if (($offset === 0) || ($definedRange[$offset - 1] !== ':')) {
- // We should have a worksheet
- $worksheet = $pDefinedName->getWorksheet()->getTitle();
- }
- } else {
- $worksheet = str_replace("''", "'", trim($worksheet, "'"));
- }
- if (!empty($worksheet)) {
- $newRange = "'" . str_replace("'", "''", $worksheet) . "'!";
- }
-
- if (!empty($column)) {
- $newRange .= $column;
- }
- if (!empty($row)) {
- $newRange .= $row;
- }
-
- $definedRange = substr($definedRange, 0, $offset) . $newRange . substr($definedRange, $offset + $length);
- }
-
- if (substr($definedRange, 0, 1) === '=') {
- $definedRange = substr($definedRange, 1);
- }
+ $definedRange = $this->getDefinedRange($pDefinedName);
$this->objWriter->writeRawData($definedRange);
@@ -144,7 +99,7 @@ class DefinedNames
$range = Coordinate::splitRange($autoFilterRange);
$range = $range[0];
// Strip any worksheet ref so we can make the cell ref absolute
- [$ws, $range[0]] = Worksheet::extractSheetTitle($range[0], true);
+ [, $range[0]] = Worksheet::extractSheetTitle($range[0], true);
$range[0] = Coordinate::absoluteCoordinate($range[0]);
$range[1] = Coordinate::absoluteCoordinate($range[1]);
@@ -220,4 +175,54 @@ class DefinedNames
$this->objWriter->endElement();
}
}
+
+ private function getDefinedRange(DefinedName $pDefinedName): string
+ {
+ $definedRange = $pDefinedName->getValue();
+ $splitCount = preg_match_all(
+ '/' . Calculation::CALCULATION_REGEXP_CELLREF_RELATIVE . '/mui',
+ $definedRange,
+ $splitRanges,
+ PREG_OFFSET_CAPTURE
+ );
+
+ $lengths = array_map('strlen', array_column($splitRanges[0], 0));
+ $offsets = array_column($splitRanges[0], 1);
+
+ $worksheets = $splitRanges[2];
+ $columns = $splitRanges[6];
+ $rows = $splitRanges[7];
+
+ while ($splitCount > 0) {
+ --$splitCount;
+ $length = $lengths[$splitCount];
+ $offset = $offsets[$splitCount];
+ $worksheet = $worksheets[$splitCount][0];
+ $column = $columns[$splitCount][0];
+ $row = $rows[$splitCount][0];
+
+ $newRange = '';
+ if (empty($worksheet)) {
+ if (($offset === 0) || ($definedRange[$offset - 1] !== ':')) {
+ // We should have a worksheet
+ $worksheet = $pDefinedName->getWorksheet() ? $pDefinedName->getWorksheet()->getTitle() : null;
+ }
+ } else {
+ $worksheet = str_replace("''", "'", trim($worksheet, "'"));
+ }
+
+ if (!empty($worksheet)) {
+ $newRange = "'" . str_replace("'", "''", $worksheet) . "'!";
+ }
+ $newRange = "{$newRange}{$column}{$row}";
+
+ $definedRange = substr($definedRange, 0, $offset) . $newRange . substr($definedRange, $offset + $length);
+ }
+
+ if (substr($definedRange, 0, 1) === '=') {
+ $definedRange = substr($definedRange, 1);
+ }
+
+ return $definedRange;
+ }
}
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/DocProps.php b/src/PhpSpreadsheet/Writer/Xlsx/DocProps.php
index bcbc2379..6332a34d 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/DocProps.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/DocProps.php
@@ -170,13 +170,13 @@ class DocProps extends WriterPart
/**
* Write docProps/custom.xml to XML format.
*
- * @return string XML Output
+ * @return null|string XML Output
*/
public function writeDocPropsCustom(Spreadsheet $spreadsheet)
{
$customPropertyList = $spreadsheet->getProperties()->getCustomProperties();
if (empty($customPropertyList)) {
- return;
+ return null;
}
// Create XML writer
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php b/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
index 1713b982..a4b09d39 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php
@@ -84,22 +84,22 @@ class Drawing extends WriterPart
public function writeChart(XMLWriter $objWriter, \PhpOffice\PhpSpreadsheet\Chart\Chart $pChart, $pRelationId = -1): void
{
$tl = $pChart->getTopLeftPosition();
- $tl['colRow'] = Coordinate::coordinateFromString($tl['cell']);
+ $tlColRow = Coordinate::indexesFromString($tl['cell']);
$br = $pChart->getBottomRightPosition();
- $br['colRow'] = Coordinate::coordinateFromString($br['cell']);
+ $brColRow = Coordinate::indexesFromString($br['cell']);
$objWriter->startElement('xdr:twoCellAnchor');
$objWriter->startElement('xdr:from');
- $objWriter->writeElement('xdr:col', Coordinate::columnIndexFromString($tl['colRow'][0]) - 1);
+ $objWriter->writeElement('xdr:col', $tlColRow[0] - 1);
$objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['xOffset']));
- $objWriter->writeElement('xdr:row', $tl['colRow'][1] - 1);
+ $objWriter->writeElement('xdr:row', $tlColRow[1] - 1);
$objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($tl['yOffset']));
$objWriter->endElement();
$objWriter->startElement('xdr:to');
- $objWriter->writeElement('xdr:col', Coordinate::columnIndexFromString($br['colRow'][0]) - 1);
+ $objWriter->writeElement('xdr:col', $brColRow[0] - 1);
$objWriter->writeElement('xdr:colOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['xOffset']));
- $objWriter->writeElement('xdr:row', $br['colRow'][1] - 1);
+ $objWriter->writeElement('xdr:row', $brColRow[1] - 1);
$objWriter->writeElement('xdr:rowOff', \PhpOffice\PhpSpreadsheet\Shared\Drawing::pixelsToEMU($br['yOffset']));
$objWriter->endElement();
@@ -158,8 +158,7 @@ class Drawing extends WriterPart
// xdr:oneCellAnchor
$objWriter->startElement('xdr:oneCellAnchor');
// Image location
- $aCoordinates = Coordinate::coordinateFromString($pDrawing->getCoordinates());
- $aCoordinates[0] = Coordinate::columnIndexFromString($aCoordinates[0]);
+ $aCoordinates = Coordinate::indexesFromString($pDrawing->getCoordinates());
// xdr:from
$objWriter->startElement('xdr:from');
@@ -433,7 +432,7 @@ class Drawing extends WriterPart
{
// Calculate object id
preg_match('{(\d+)}', md5($pReference), $m);
- $id = 1500 + (substr($m[1], 0, 2) * 1);
+ $id = 1500 + ((int) substr($m[1], 0, 2) * 1);
// Calculate offset
$width = $pImage->getWidth();
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php
index 79841404..a67d3ef8 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/Rels.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/Rels.php
@@ -291,7 +291,7 @@ class Rels extends WriterPart
/**
* Write drawing relationships to XML format.
*
- * @param int &$chartRef Chart ID
+ * @param int $chartRef Chart ID
* @param bool $includeCharts Flag indicating if we should write charts
*
* @return string XML Output
@@ -425,9 +425,7 @@ class Rels extends WriterPart
}
/**
- * @param $objWriter
* @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing
- * @param $i
*
* @return int
*/
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Theme.php b/src/PhpSpreadsheet/Writer/Xlsx/Theme.php
index 3a47be7f..99177292 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/Theme.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/Theme.php
@@ -10,7 +10,7 @@ class Theme extends WriterPart
/**
* Map of Major fonts to write.
*
- * @var array of string
+ * @var string[]
*/
private static $majorFonts = [
'Jpan' => 'MS Pゴシック',
@@ -48,7 +48,7 @@ class Theme extends WriterPart
/**
* Map of Minor fonts to write.
*
- * @var array of string
+ * @var string[]
*/
private static $minorFonts = [
'Jpan' => 'MS Pゴシック',
@@ -86,7 +86,7 @@ class Theme extends WriterPart
/**
* Map of core colours.
*
- * @var array of string
+ * @var string[]
*/
private static $colourScheme = [
'dk2' => '1F497D',
@@ -784,13 +784,9 @@ class Theme extends WriterPart
/**
* Write fonts to XML format.
*
- * @param XMLWriter $objWriter
- * @param string $latinFont
- * @param array of string $fontSet
- *
- * @return string XML Output
+ * @param string[] $fontSet
*/
- private function writeFonts($objWriter, $latinFont, $fontSet)
+ private function writeFonts(XMLWriter $objWriter, string $latinFont, array $fontSet): void
{
// a:latin
$objWriter->startElement('a:latin');
@@ -817,12 +813,8 @@ class Theme extends WriterPart
/**
* Write colour scheme to XML format.
- *
- * @param XMLWriter $objWriter
- *
- * @return string XML Output
*/
- private function writeColourScheme($objWriter)
+ private function writeColourScheme(XMLWriter $objWriter): void
{
foreach (self::$colourScheme as $colourName => $colourValue) {
$objWriter->startElement('a:' . $colourName);
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
index 8faa7ae2..3978eb6f 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php
@@ -8,6 +8,8 @@ use PhpOffice\PhpSpreadsheet\RichText\RichText;
use PhpOffice\PhpSpreadsheet\Shared\StringHelper;
use PhpOffice\PhpSpreadsheet\Shared\XMLWriter;
use PhpOffice\PhpSpreadsheet\Style\Conditional;
+use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalDataBar;
+use PhpOffice\PhpSpreadsheet\Style\ConditionalFormatting\ConditionalFormattingRuleExtension;
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column;
use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column\Rule;
use PhpOffice\PhpSpreadsheet\Worksheet\SheetView;
@@ -44,6 +46,7 @@ class Worksheet extends WriterPart
$objWriter->writeAttribute('xmlns:xdr', 'http://schemas.openxmlformats.org/drawingml/2006/spreadsheetDrawing');
$objWriter->writeAttribute('xmlns:x14', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/main');
+ $objWriter->writeAttribute('xmlns:xm', 'http://schemas.microsoft.com/office/excel/2006/main');
$objWriter->writeAttribute('xmlns:mc', 'http://schemas.openxmlformats.org/markup-compatibility/2006');
$objWriter->writeAttribute('mc:Ignorable', 'x14ac');
$objWriter->writeAttribute('xmlns:x14ac', 'http://schemas.microsoft.com/office/spreadsheetml/2009/9/ac');
@@ -114,6 +117,10 @@ class Worksheet extends WriterPart
// AlternateContent
$this->writeAlternateContent($objWriter, $pSheet);
+ // ConditionalFormattingRuleExtensionList
+ // (Must be inserted last. Not insert last, an Excel parse error will occur)
+ $this->writeExtLst($objWriter, $pSheet);
+
$objWriter->endElement();
// Return
@@ -503,6 +510,94 @@ class Worksheet extends WriterPart
}
}
+ private static function writeExtConditionalFormattingElements(XMLWriter $objWriter, ConditionalFormattingRuleExtension $ruleExtension): void
+ {
+ $prefix = 'x14';
+ $objWriter->startElementNs($prefix, 'conditionalFormatting', null);
+
+ $objWriter->startElementNs($prefix, 'cfRule', null);
+ $objWriter->writeAttribute('type', $ruleExtension->getCfRule());
+ $objWriter->writeAttribute('id', $ruleExtension->getId());
+ $objWriter->startElementNs($prefix, 'dataBar', null);
+ $dataBar = $ruleExtension->getDataBarExt();
+ foreach ($dataBar->getXmlAttributes() as $attrKey => $val) {
+ $objWriter->writeAttribute($attrKey, $val);
+ }
+ $minCfvo = $dataBar->getMinimumConditionalFormatValueObject();
+ if ($minCfvo) {
+ $objWriter->startElementNs($prefix, 'cfvo', null);
+ $objWriter->writeAttribute('type', $minCfvo->getType());
+ if ($minCfvo->getCellFormula()) {
+ $objWriter->writeElement('xm:f', $minCfvo->getCellFormula());
+ }
+ $objWriter->endElement(); //end cfvo
+ }
+
+ $maxCfvo = $dataBar->getMaximumConditionalFormatValueObject();
+ if ($maxCfvo) {
+ $objWriter->startElementNs($prefix, 'cfvo', null);
+ $objWriter->writeAttribute('type', $maxCfvo->getType());
+ if ($maxCfvo->getCellFormula()) {
+ $objWriter->writeElement('xm:f', $maxCfvo->getCellFormula());
+ }
+ $objWriter->endElement(); //end cfvo
+ }
+
+ foreach ($dataBar->getXmlElements() as $elmKey => $elmAttr) {
+ $objWriter->startElementNs($prefix, $elmKey, null);
+ foreach ($elmAttr as $attrKey => $attrVal) {
+ $objWriter->writeAttribute($attrKey, $attrVal);
+ }
+ $objWriter->endElement(); //end elmKey
+ }
+ $objWriter->endElement(); //end dataBar
+ $objWriter->endElement(); //end cfRule
+ $objWriter->writeElement('xm:sqref', $ruleExtension->getSqref());
+ $objWriter->endElement(); //end conditionalFormatting
+ }
+
+ private static function writeDataBarElements(XMLWriter $objWriter, $dataBar): void
+ {
+ /** @var ConditionalDataBar $dataBar */
+ if ($dataBar) {
+ $objWriter->startElement('dataBar');
+ self::writeAttributeIf($objWriter, null !== $dataBar->getShowValue(), 'showValue', $dataBar->getShowValue() ? '1' : '0');
+
+ $minCfvo = $dataBar->getMinimumConditionalFormatValueObject();
+ if ($minCfvo) {
+ $objWriter->startElement('cfvo');
+ self::writeAttributeIf($objWriter, $minCfvo->getType(), 'type', (string) $minCfvo->getType());
+ self::writeAttributeIf($objWriter, $minCfvo->getValue(), 'val', (string) $minCfvo->getValue());
+ $objWriter->endElement();
+ }
+ $maxCfvo = $dataBar->getMaximumConditionalFormatValueObject();
+ if ($maxCfvo) {
+ $objWriter->startElement('cfvo');
+ self::writeAttributeIf($objWriter, $maxCfvo->getType(), 'type', (string) $maxCfvo->getType());
+ self::writeAttributeIf($objWriter, $maxCfvo->getValue(), 'val', (string) $maxCfvo->getValue());
+ $objWriter->endElement();
+ }
+ if ($dataBar->getColor()) {
+ $objWriter->startElement('color');
+ $objWriter->writeAttribute('rgb', $dataBar->getColor());
+ $objWriter->endElement();
+ }
+ $objWriter->endElement(); // end dataBar
+
+ if ($dataBar->getConditionalFormattingRuleExt()) {
+ $objWriter->startElement('extLst');
+ $extension = $dataBar->getConditionalFormattingRuleExt();
+ $objWriter->startElement('ext');
+ $objWriter->writeAttribute('uri', '{B025F937-C7B1-47D3-B67F-A62EFF666E3E}');
+ $objWriter->startElementNs('x14', 'id', null);
+ $objWriter->text($extension->getId());
+ $objWriter->endElement();
+ $objWriter->endElement();
+ $objWriter->endElement(); //end extLst
+ }
+ }
+ }
+
/**
* Write ConditionalFormatting.
*
@@ -529,7 +624,12 @@ class Worksheet extends WriterPart
// cfRule
$objWriter->startElement('cfRule');
$objWriter->writeAttribute('type', $conditional->getConditionType());
- $objWriter->writeAttribute('dxfId', $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode()));
+ self::writeAttributeIf(
+ $objWriter,
+ ($conditional->getConditionType() != Conditional::CONDITION_DATABAR),
+ 'dxfId',
+ $this->getParentWriter()->getStylesConditionalHashTable()->getIndexForHashCode($conditional->getHashCode())
+ );
$objWriter->writeAttribute('priority', $id++);
self::writeAttributeif(
@@ -548,7 +648,10 @@ class Worksheet extends WriterPart
self::writeOtherCondElements($objWriter, $conditional, $cellCoordinate);
}
- $objWriter->endElement();
+ //
+ self::writeDataBarElements($objWriter, $conditional->getDataBar());
+
+ $objWriter->endElement(); //end cfRule
$objWriter->endElement();
}
@@ -981,7 +1084,7 @@ class Worksheet extends WriterPart
private function writeSheetData(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, array $pStringTable): void
{
// Flipped stringtable, for faster index searching
- $aFlippedStringTable = $this->getParentWriter()->getWriterPart('stringtable')->flipStringTable($pStringTable);
+ $aFlippedStringTable = $this->getParentWriter()->getWriterPartstringtable()->flipStringTable($pStringTable);
// sheetData
$objWriter->startElement('sheetData');
@@ -1066,7 +1169,7 @@ class Worksheet extends WriterPart
$objWriter->writeElement('t', StringHelper::controlCharacterPHP2OOXML(htmlspecialchars($cellValue)));
} elseif ($cellValue instanceof RichText) {
$objWriter->startElement('is');
- $this->getParentWriter()->getWriterPart('stringtable')->writeRichText($objWriter, $cellValue);
+ $this->getParentWriter()->getWriterPartstringtable()->writeRichText($objWriter, $cellValue);
$objWriter->endElement();
}
}
@@ -1279,4 +1382,38 @@ class Worksheet extends WriterPart
$objWriter->writeRaw($alternateContent);
}
}
+
+ /**
+ * write
+ * only implementation conditionalFormattings.
+ *
+ * @url https://docs.microsoft.com/en-us/openspecs/office_standards/ms-xlsx/07d607af-5618-4ca2-b683-6a78dc0d9627
+ */
+ private function writeExtLst(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet): void
+ {
+ $conditionalFormattingRuleExtList = [];
+ foreach ($pSheet->getConditionalStylesCollection() as $cellCoordinate => $conditionalStyles) {
+ /** @var Conditional $conditional */
+ foreach ($conditionalStyles as $conditional) {
+ $dataBar = $conditional->getDataBar();
+ if ($dataBar && $dataBar->getConditionalFormattingRuleExt()) {
+ $conditionalFormattingRuleExtList[] = $dataBar->getConditionalFormattingRuleExt();
+ }
+ }
+ }
+
+ if (count($conditionalFormattingRuleExtList) > 0) {
+ $conditionalFormattingRuleExtNsPrefix = 'x14';
+ $objWriter->startElement('extLst');
+ $objWriter->startElement('ext');
+ $objWriter->writeAttribute('uri', '{78C0D931-6437-407d-A8EE-F0AAD7539E65}');
+ $objWriter->startElementNs($conditionalFormattingRuleExtNsPrefix, 'conditionalFormattings', null);
+ foreach ($conditionalFormattingRuleExtList as $extension) {
+ self::writeExtConditionalFormattingElements($objWriter, $extension);
+ }
+ $objWriter->endElement(); //end conditionalFormattings
+ $objWriter->endElement(); //end ext
+ $objWriter->endElement(); //end extLst
+ }
+ }
}
diff --git a/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php b/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php
index 8f7c07e8..c88ef245 100644
--- a/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php
+++ b/src/PhpSpreadsheet/Writer/Xlsx/Xlfn.php
@@ -10,6 +10,7 @@ class Xlfn
. '|beta[.]inv'
. '|binom[.]dist'
. '|binom[.]inv'
+ . '|ceiling[.]precise'
. '|chisq[.]dist'
. '|chisq[.]dist[.]rt'
. '|chisq[.]inv'
@@ -27,6 +28,7 @@ class Xlfn
. '|f[.]inv'
. '|f[.]inv[.]rt'
. '|f[.]test'
+ . '|floor[.]precise'
. '|gamma[.]dist'
. '|gamma[.]inv'
. '|gammaln[.]precise'
@@ -138,6 +140,11 @@ class Xlfn
. '|unique'
. '|xlookup'
. '|xmatch'
+ . '|arraytotext'
+ . '|call'
+ . '|let'
+ . '|register[.]id'
+ . '|valuetotext'
. ')(?=\\s*[(])/i';
/**
diff --git a/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php b/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php
index 8e339207..433d2be5 100644
--- a/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php
@@ -4,13 +4,20 @@ namespace PhpOffice\PhpSpreadsheetTests\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class CalculationTest extends TestCase
{
+ /**
+ * @var string
+ */
private $compatibilityMode;
+ /**
+ * @var string
+ */
private $locale;
protected function setUp(): void
@@ -46,7 +53,7 @@ class CalculationTest extends TestCase
self::assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible');
}
- public function providerBinaryComparisonOperation()
+ public function providerBinaryComparisonOperation(): array
{
return require 'tests/data/CalculationBinaryComparisonOperation.php';
}
@@ -63,7 +70,7 @@ class CalculationTest extends TestCase
self::assertIsCallable($functionCall);
}
- public function providerGetFunctions()
+ public function providerGetFunctions(): array
{
return Calculation::getInstance()->getFunctions();
}
@@ -88,7 +95,7 @@ class CalculationTest extends TestCase
self::assertTrue($calculation->setLocale($locale));
}
- public function providerCanLoadAllSupportedLocales()
+ public function providerCanLoadAllSupportedLocales(): array
{
return [
['bg'],
@@ -117,11 +124,13 @@ class CalculationTest extends TestCase
$calculation = Calculation::getInstance();
$tree = $calculation->parseFormula('=_xlfn.ISFORMULA(A1)');
+ self::assertIsArray($tree);
self::assertCount(3, $tree);
$function = $tree[2];
self::assertEquals('Function', $function['type']);
$tree = $calculation->parseFormula('=_xlfn.STDEV.S(A1:B2)');
+ self::assertIsArray($tree);
self::assertCount(5, $tree);
$function = $tree[4];
self::assertEquals('Function', $function['type']);
@@ -159,6 +168,14 @@ class CalculationTest extends TestCase
$cell->getStyle()->setQuotePrefix(true);
self::assertEquals("=cmd|'/C calc'!A0", $cell->getCalculatedValue());
+
+ $cell2 = $workSheet->getCell('A2');
+ $cell2->setValueExplicit('ABC', DataType::TYPE_FORMULA);
+ self::assertEquals('ABC', $cell2->getCalculatedValue());
+
+ $cell3 = $workSheet->getCell('A3');
+ $cell3->setValueExplicit('=', DataType::TYPE_FORMULA);
+ self::assertEquals('', $cell3->getCalculatedValue());
}
public function testCellWithDdeExpresion(): void
@@ -196,6 +213,7 @@ class CalculationTest extends TestCase
// Very simple formula
$formula = '=IF(A1="please +",B1)';
$tokens = $calculation->parseFormula($formula);
+ self::assertIsArray($tokens);
$foundEqualAssociatedToStoreKey = false;
$foundConditionalOnB1 = false;
@@ -225,6 +243,7 @@ class CalculationTest extends TestCase
// Internal operation
$formula = '=IF(A1="please +",SUM(B1:B3))+IF(A2="please *",PRODUCT(C1:C3), C1)';
$tokens = $calculation->parseFormula($formula);
+ self::assertIsArray($tokens);
$plusGotTagged = false;
$productFunctionCorrectlyTagged = false;
@@ -254,6 +273,7 @@ class CalculationTest extends TestCase
$formula = '=IF(A1="please +",SUM(B1:B3),1+IF(NOT(A2="please *"),C2-C1,PRODUCT(C1:C3)))';
$tokens = $calculation->parseFormula($formula);
+ self::assertIsArray($tokens);
$plusCorrectlyTagged = false;
$productFunctionCorrectlyTagged = false;
@@ -298,6 +318,8 @@ class CalculationTest extends TestCase
$formula = '=IF(A1="flag",IF(A2<10, 0) + IF(A3<10000, 0))';
$tokens = $calculation->parseFormula($formula);
+ self::assertIsArray($tokens);
+
$properlyTaggedPlus = false;
foreach ($tokens as $token) {
$isPlus = $token['value'] === '+';
@@ -310,8 +332,8 @@ class CalculationTest extends TestCase
}
/**
- * @param $expectedResult
- * @param $dataArray
+ * @param mixed $expectedResult
+ * @param mixed $dataArray
* @param string $formula
* @param string $cellCoordinates where to put the formula
* @param string[] $shouldBeSetInCacheCells coordinates of cells that must
@@ -358,7 +380,7 @@ class CalculationTest extends TestCase
self::assertEquals($expectedResult, $calculated);
}
- public function dataProviderBranchPruningFullExecution()
+ public function dataProviderBranchPruningFullExecution(): array
{
return require 'tests/data/Calculation/Calculation.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/DefinedNameConfusedForCellTest.php b/tests/PhpSpreadsheetTests/Calculation/DefinedNameConfusedForCellTest.php
index 76886c23..6f97f9c8 100644
--- a/tests/PhpSpreadsheetTests/Calculation/DefinedNameConfusedForCellTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/DefinedNameConfusedForCellTest.php
@@ -2,20 +2,23 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation;
+use PhpOffice\PhpSpreadsheet\IOFactory;
+use PhpOffice\PhpSpreadsheet\NamedRange;
use PhpOffice\PhpSpreadsheet\Shared\File;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class DefinedNameConfusedForCellTest extends TestCase
{
public function testDefinedName(): void
{
- $obj = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
+ $obj = new Spreadsheet();
$sheet0 = $obj->setActiveSheetIndex(0);
$sheet0->setCellValue('A1', 2);
- $obj->addNamedRange(new \PhpOffice\PhpSpreadsheet\NamedRange('A1A', $sheet0, 'A1'));
+ $obj->addNamedRange(new NamedRange('A1A', $sheet0, 'A1'));
$sheet0->setCellValue('B1', '=2*A1A');
- $writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($obj, 'Xlsx');
- $filename = tempnam(File::sysGetTempDir(), 'phpspreadsheet-test');
+ $writer = IOFactory::createWriter($obj, 'Xlsx');
+ $filename = File::temporaryFilename();
$writer->save($filename);
self::assertTrue(true);
unlink($filename);
diff --git a/tests/PhpSpreadsheetTests/Calculation/Engine/RangeTest.php b/tests/PhpSpreadsheetTests/Calculation/Engine/RangeTest.php
index 4f1ff397..c27d16af 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Engine/RangeTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Engine/RangeTest.php
@@ -9,7 +9,10 @@ use PHPUnit\Framework\TestCase;
class RangeTest extends TestCase
{
- protected $spreadSheet;
+ /**
+ * @var Spreadsheet
+ */
+ private $spreadSheet;
protected function setUp(): void
{
@@ -40,7 +43,7 @@ class RangeTest extends TestCase
self::assertSame($expectedResult, $actualRresult);
}
- public function providerRangeEvaluation()
+ public function providerRangeEvaluation(): array
{
return[
['=SUM(A1:B3,A1:C2)', 48],
@@ -88,7 +91,7 @@ class RangeTest extends TestCase
self::assertSame($expectedResult, $sumRresult);
}
- public function providerNamedRangeEvaluation()
+ public function providerNamedRangeEvaluation(): array
{
return[
['$A$1:$B$3', '$A$1:$C$2', '=SUM(GROUP1,GROUP2)', 48],
@@ -123,7 +126,7 @@ class RangeTest extends TestCase
self::assertSame($expectedResult, $sumRresult);
}
- public function providerUTF8NamedRangeEvaluation()
+ public function providerUTF8NamedRangeEvaluation(): array
{
return[
[['Γειά', 'σου', 'Κόσμε'], ['$A$1', '$B$1:$B$2', '$C$1:$C$3'], '=SUM(Γειά,σου,Κόσμε)', 26],
@@ -151,7 +154,7 @@ class RangeTest extends TestCase
self::assertSame($expectedCount, $actualCount);
}
- public function providerCompositeNamedRangeEvaluation()
+ public function providerCompositeNamedRangeEvaluation(): array
{
return[
// Calculation engine doesn't yet handle union ranges with overlap
diff --git a/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php b/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php
deleted file mode 100644
index e80ef35b..00000000
--- a/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php
+++ /dev/null
@@ -1,628 +0,0 @@
- 0.999999 && $frac < 1.000001) {
- $result = $expectedResult;
- }
- }
- }
- self::assertEquals($expectedResult, $result, $message);
- }
-
- public function providerXIRR()
- {
- return require 'tests/data/Calculation/Financial/XIRR.php';
- }
-
- /**
- * @dataProvider providerXNPV
- *
- * @param mixed $expectedResult
- * @param mixed $message
- */
- public function testXNPV($expectedResult, $message, ...$args): void
- {
- $result = Financial::XNPV(...$args);
- if (is_numeric($result) && is_numeric($expectedResult)) {
- if ($expectedResult != 0) {
- $frac = $result / $expectedResult;
- if ($frac > 0.999999 && $frac < 1.000001) {
- $result = $expectedResult;
- }
- }
- }
- self::assertEquals($expectedResult, $result, $message);
- }
-
- public function providerXNPV()
- {
- return require 'tests/data/Calculation/Financial/XNPV.php';
- }
-
- /**
- * @dataProvider providerPDURATION
- *
- * @param mixed $expectedResult
- */
- public function testPDURATION($expectedResult, array $args): void
- {
- $result = Financial::PDURATION(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
- }
-
- public function providerPDURATION()
- {
- return require 'tests/data/Calculation/Financial/PDURATION.php';
- }
-
- /**
- * @dataProvider providerRRI
- *
- * @param mixed $expectedResult
- */
- public function testRRI($expectedResult, array $args): void
- {
- $result = Financial::RRI(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
- }
-
- public function providerRRI()
- {
- return require 'tests/data/Calculation/Financial/RRI.php';
- }
-
- /**
- * @dataProvider providerSLN
- *
- * @param mixed $expectedResult
- */
- public function testSLN($expectedResult, array $args): void
- {
- $result = Financial::SLN(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
- }
-
- public function providerSLN()
- {
- return require 'tests/data/Calculation/Financial/SLN.php';
- }
-
- /**
- * @dataProvider providerSYD
- *
- * @param mixed $expectedResult
- */
- public function testSYD($expectedResult, array $args): void
- {
- $result = Financial::SYD(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
- }
-
- public function providerSYD()
- {
- return require 'tests/data/Calculation/Financial/SYD.php';
- }
-}
diff --git a/tests/PhpSpreadsheetTests/Calculation/FormulaAsStringTest.php b/tests/PhpSpreadsheetTests/Calculation/FormulaAsStringTest.php
index 9afe5570..27c746b4 100644
--- a/tests/PhpSpreadsheetTests/Calculation/FormulaAsStringTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/FormulaAsStringTest.php
@@ -39,7 +39,7 @@ class FormulaAsStringTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerFunctionsAsString()
+ public function providerFunctionsAsString(): array
{
return require 'tests/data/Calculation/FunctionsAsString.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DAverageTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DAverageTest.php
new file mode 100644
index 00000000..2d8fb9f9
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DAverageTest.php
@@ -0,0 +1,110 @@
+database1(),
+ 'Yield',
+ [
+ ['Tree', 'Height'],
+ ['=Apple', '>10'],
+ ],
+ ],
+ [
+ 13,
+ $this->database1(),
+ 3,
+ $this->database1(),
+ ],
+ [
+ 268333.333333333333,
+ $this->database2(),
+ 'Sales',
+ [
+ ['Quarter', 'Sales Rep.'],
+ ['>1', 'Tina'],
+ ],
+ ],
+ [
+ 372500,
+ $this->database2(),
+ 'Sales',
+ [
+ ['Quarter', 'Area'],
+ ['1', 'South'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountATest.php
new file mode 100644
index 00000000..2f7cad14
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountATest.php
@@ -0,0 +1,103 @@
+database1(),
+ 'Profit',
+ [
+ ['Tree', 'Height', 'Height'],
+ ['=Apple', '>10', '<16'],
+ ],
+ ],
+ [
+ 2,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['Science', 'Male'],
+ ],
+ ],
+ [
+ 1,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['Math', 'Female'],
+ ],
+ ],
+ [
+ 3,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Score'],
+ ['English', '>60%'],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountTest.php
new file mode 100644
index 00000000..3f9d9966
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DCountTest.php
@@ -0,0 +1,136 @@
+database1(),
+ 'Age',
+ [
+ ['Tree', 'Height', 'Height'],
+ ['=Apple', '>10', '<16'],
+ ],
+ ],
+ [
+ 1,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['Science', 'Male'],
+ ],
+ ],
+ [
+ 1,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['Math', 'Female'],
+ ],
+ ],
+ [
+ 3,
+ $this->database2(),
+ null,
+ [
+ ['Subject', 'Score'],
+ ['English', '>63%'],
+ ],
+ ],
+ [
+ 3,
+ $this->database3(),
+ 'Value',
+ [
+ ['Status'],
+ [true],
+ ],
+ ],
+ [
+ 5,
+ $this->database3(),
+ 'Value',
+ [
+ ['Status'],
+ ['<>true'],
+ ],
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DGetTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DGetTest.php
new file mode 100644
index 00000000..7853e0b6
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DGetTest.php
@@ -0,0 +1,115 @@
+database1(),
+ 'Yield',
+ [
+ ['Tree'],
+ ['=Apple'],
+ ['=Pear'],
+ ],
+ ],
+ [
+ 10,
+ $this->database1(),
+ 'Yield',
+ [
+ ['Tree', 'Height', 'Height'],
+ ['=Apple', '>10', '<16'],
+ ['=Pear', '>12', null],
+ ],
+ ],
+ [
+ 188000,
+ $this->database2(),
+ 'Sales',
+ [
+ ['Sales Rep.', 'Quarter'],
+ ['Tina', 4],
+ ],
+ ],
+ [
+ Functions::NAN(),
+ $this->database2(),
+ 'Sales',
+ [
+ ['Area', 'Quarter'],
+ ['South', 4],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMaxTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMaxTest.php
new file mode 100644
index 00000000..94ac0425
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMaxTest.php
@@ -0,0 +1,105 @@
+database1(),
+ 'Profit',
+ [
+ ['Tree', 'Height', 'Height'],
+ ['=Apple', '>10', '<16'],
+ ['=Pear', null, null],
+ ],
+ ],
+ [
+ 340000,
+ $this->database2(),
+ 'Sales',
+ [
+ ['Quarter', 'Area'],
+ [2, 'North'],
+ ],
+ ],
+ [
+ 460000,
+ $this->database2(),
+ 'Sales',
+ [
+ ['Sales Rep.', 'Quarter'],
+ ['Carol', '>1'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMinTest.php
new file mode 100644
index 00000000..a02ad2e1
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DMinTest.php
@@ -0,0 +1,101 @@
+database1(),
+ 'Profit',
+ [
+ ['Tree', 'Height', 'Height'],
+ ['=Apple', '>10', '<16'],
+ ['=Pear', '>12', null],
+ ],
+ ],
+ [
+ 0.48,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Age'],
+ ['Science', '>8'],
+ ],
+ ],
+ [
+ 0.55,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['Math', 'Male'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DProductTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DProductTest.php
new file mode 100644
index 00000000..14962558
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DProductTest.php
@@ -0,0 +1,102 @@
+database1(),
+ 'Yield',
+ [
+ ['Tree', 'Height', 'Height'],
+ ['=Apple', '>10', '<16'],
+ ['=Pear', null, null],
+ ],
+ ],
+ [
+ 36,
+ $this->database2(),
+ 'Score',
+ [
+ ['Name', 'Date'],
+ ['Gary', '05-Jan-2017'],
+ ],
+ ],
+ [
+ 8,
+ $this->database2(),
+ 'Score',
+ [
+ ['Test', 'Date'],
+ ['Test1', '<05-Jan-2017'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevPTest.php
new file mode 100644
index 00000000..669a694b
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevPTest.php
@@ -0,0 +1,101 @@
+database1(),
+ 'Yield',
+ [
+ ['Tree'],
+ ['=Apple'],
+ ['=Pear'],
+ ],
+ ],
+ [
+ 0.085244745684,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['English', 'Male'],
+ ],
+ ],
+ [
+ 0.160623784042,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Age'],
+ ['Math', '>8'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevTest.php
new file mode 100644
index 00000000..a7975a11
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DStDevTest.php
@@ -0,0 +1,101 @@
+database1(),
+ 'Yield',
+ [
+ ['Tree'],
+ ['=Apple'],
+ ['=Pear'],
+ ],
+ ],
+ [
+ 0.104403065089,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['English', 'Male'],
+ ],
+ ],
+ [
+ 0.196723155729,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Age'],
+ ['Math', '>8'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DSumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DSumTest.php
new file mode 100644
index 00000000..55edffe0
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DSumTest.php
@@ -0,0 +1,123 @@
+database1(),
+ 'Profit',
+ [
+ ['Tree'],
+ ['=Apple'],
+ ],
+ ],
+ [
+ 248,
+ $this->database1(),
+ 'Profit',
+ [
+ ['Tree', 'Height', 'Height'],
+ ['=Apple', '>10', '<16'],
+ ['=Pear', null, null],
+ ],
+ ],
+ [
+ 1210000,
+ $this->database2(),
+ 'Sales',
+ [
+ ['Quarter', 'Area'],
+ ['>2', 'North'],
+ ],
+ ],
+ [
+ 710000,
+ $this->database2(),
+ 'Sales',
+ [
+ ['Quarter', 'Sales Rep.'],
+ ['3', 'C*'],
+ ],
+ ],
+ [
+ 705000,
+ $this->database2(),
+ 'Sales',
+ [
+ ['Quarter', 'Sales Rep.'],
+ ['3', '<>C*'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarPTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarPTest.php
new file mode 100644
index 00000000..60612db5
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarPTest.php
@@ -0,0 +1,101 @@
+database1(),
+ 'Yield',
+ [
+ ['Tree'],
+ ['=Apple'],
+ ['=Pear'],
+ ],
+ ],
+ [
+ 0.025622222222,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['Math', 'Male'],
+ ],
+ ],
+ [
+ 0.011622222222,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Age'],
+ ['Science', '>8'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarTest.php
new file mode 100644
index 00000000..0015b7fb
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Database/DVarTest.php
@@ -0,0 +1,101 @@
+database1(),
+ 'Yield',
+ [
+ ['Tree'],
+ ['=Apple'],
+ ['=Pear'],
+ ],
+ ],
+ [
+ 0.038433333333,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Gender'],
+ ['Math', 'Male'],
+ ],
+ ],
+ [
+ 0.017433333333,
+ $this->database2(),
+ 'Score',
+ [
+ ['Subject', 'Age'],
+ ['Science', '>8'],
+ ],
+ ],
+ [
+ null,
+ $this->database1(),
+ null,
+ $this->database1(),
+ ],
+ ];
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php
new file mode 100644
index 00000000..414670c4
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/AllSetupTeardown.php
@@ -0,0 +1,85 @@
+compatibilityMode = Functions::getCompatibilityMode();
+ $this->excelCalendar = Date::getExcelCalendar();
+ $this->returnDateType = Functions::getReturnDateType();
+ $this->spreadsheet = new Spreadsheet();
+ $this->sheet = $this->spreadsheet->getActiveSheet();
+ }
+
+ protected function tearDown(): void
+ {
+ Date::setExcelCalendar($this->excelCalendar);
+ Functions::setCompatibilityMode($this->compatibilityMode);
+ Functions::setReturnDateType($this->returnDateType);
+ $this->spreadsheet->disconnectWorksheets();
+ }
+
+ protected static function setMac1904(): void
+ {
+ Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
+ }
+
+ protected static function setUnixReturn(): void
+ {
+ Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP);
+ }
+
+ protected static function setObjectReturn(): void
+ {
+ Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT);
+ }
+
+ protected static function setOpenOffice(): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ }
+
+ /**
+ * @param mixed $expectedResult
+ */
+ protected function mightHaveException($expectedResult): void
+ {
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcException::class);
+ }
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php
index db8e29a1..3aa9446d 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateDifTest.php
@@ -2,35 +2,23 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class DateDifTest extends TestCase
+class DateDifTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerDATEDIF
*
* @param mixed $expectedResult
- * @param $startDate
- * @param $endDate
- * @param $unit
*/
- public function testDATEDIF($expectedResult, $startDate, $endDate, $unit): void
+ public function testDATEDIF($expectedResult, string $formula): void
{
- $result = DateTime::DATEDIF($startDate, $endDate, $unit);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ $sheet->getCell('A1')->setValue("=DATEDIF($formula)");
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerDATEDIF()
+ public function providerDATEDIF(): array
{
return require 'tests/data/Calculation/DateTime/DATEDIF.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php
index 48f7cfd7..d790777b 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateTest.php
@@ -2,53 +2,42 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Datefunc;
-class DateTest extends TestCase
+class DateTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerDATE
*
* @param mixed $expectedResult
- * @param $year
- * @param $month
- * @param $day
*/
- public function testDATE($expectedResult, $year, $month, $day): void
+ public function testDATE($expectedResult, string $formula): void
{
- $result = DateTime::DATE($year, $month, $day);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ $sheet->getCell('A1')->setValue("=DATE($formula)");
+ self::assertEquals($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerDATE()
+ public function providerDATE(): array
{
return require 'tests/data/Calculation/DateTime/DATE.php';
}
public function testDATEtoUnixTimestamp(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP);
+ self::setUnixReturn();
- $result = DateTime::DATE(2012, 1, 31);
+ $result = Datefunc::funcDate(2012, 1, 31); // 32-bit safe
self::assertEquals(1327968000, $result);
- self::assertEqualsWithDelta(1327968000, $result, 1E-8);
}
public function testDATEtoDateTimeObject(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT);
+ self::setObjectReturn();
- $result = DateTime::DATE(2012, 1, 31);
+ $result = Datefunc::funcDate(2012, 1, 31);
// Must return an object...
self::assertIsObject($result);
// ... of the correct type
@@ -59,17 +48,12 @@ class DateTest extends TestCase
public function testDATEwith1904Calendar(): void
{
- Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
+ self::setMac1904();
- $result = DateTime::DATE(1918, 11, 11);
+ $result = Datefunc::funcDate(1918, 11, 11);
self::assertEquals($result, 5428);
- }
- public function testDATEwith1904CalendarError(): void
- {
- Date::setExcelCalendar(Date::CALENDAR_MAC_1904);
-
- $result = DateTime::DATE(1901, 1, 31);
+ $result = Datefunc::funcDate(1901, 1, 31);
self::assertEquals($result, '#NUM!');
}
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php
index 51e4f7c0..2d422e0a 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DateValueTest.php
@@ -2,52 +2,60 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
+use DateTimeImmutable;
use DateTimeInterface;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\DateValue;
-class DateValueTest extends TestCase
+class DateValueTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerDATEVALUE
*
* @param mixed $expectedResult
- * @param $dateValue
*/
- public function testDATEVALUE($expectedResult, $dateValue): void
+ public function testDATEVALUE($expectedResult, string $dateValue): void
{
- $result = DateTime::DATEVALUE($dateValue);
+ $this->sheet->getCell('B1')->setValue('1954-07-20');
+ // Loop to avoid extraordinarily rare edge case where first calculation
+ // and second do not take place on same day.
+ $row = 0;
+ do {
+ ++$row;
+ $dtStart = new DateTimeImmutable();
+ $startDay = $dtStart->format('d');
+ if (is_string($expectedResult)) {
+ $replYMD = str_replace('Y', date('Y'), $expectedResult);
+ if ($replYMD !== $expectedResult) {
+ $expectedResult = DateValue::funcDateValue($replYMD);
+ }
+ }
+ $this->sheet->getCell("A$row")->setValue("=DATEVALUE($dateValue)");
+ $result = $this->sheet->getCell("A$row")->getCalculatedValue();
+ $dtEnd = new DateTimeImmutable();
+ $endDay = $dtEnd->format('d');
+ } while ($startDay !== $endDay);
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerDATEVALUE()
+ public function providerDATEVALUE(): array
{
return require 'tests/data/Calculation/DateTime/DATEVALUE.php';
}
public function testDATEVALUEtoUnixTimestamp(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP);
+ self::setUnixReturn();
- $result = DateTime::DATEVALUE('2012-1-31');
+ $result = DateValue::funcDateValue('2012-1-31');
self::assertEquals(1327968000, $result);
self::assertEqualsWithDelta(1327968000, $result, 1E-8);
}
public function testDATEVALUEtoDateTimeObject(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT);
+ self::setObjectReturn();
- $result = DateTime::DATEVALUE('2012-1-31');
+ $result = DateValue::funcDateValue('2012-1-31');
// Must return an object...
self::assertIsObject($result);
// ... of the correct type
@@ -55,4 +63,13 @@ class DateValueTest extends TestCase
// ... with the correct value
self::assertEquals($result->format('d-M-Y'), '31-Jan-2012');
}
+
+ public function testDATEVALUEwith1904Calendar(): void
+ {
+ self::setMac1904();
+ self::assertEquals(5428, DateValue::funcDateValue('1918-11-11'));
+ self::assertEquals(0, DateValue::funcDateValue('1904-01-01'));
+ self::assertEquals('#VALUE!', DateValue::funcDateValue('1903-12-31'));
+ self::assertEquals('#VALUE!', DateValue::funcDateValue('1900-02-29'));
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php
index 482e068d..dc8adf11 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DayTest.php
@@ -2,56 +2,43 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class DayTest extends TestCase
+class DayTest extends AllSetupTeardown
{
- private $compatibilityMode;
-
- private $returnDateType;
-
- private $excelCalendar;
-
- protected function setUp(): void
- {
- $this->compatibilityMode = Functions::getCompatibilityMode();
- $this->returnDateType = Functions::getReturnDateType();
- $this->excelCalendar = Date::getExcelCalendar();
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
- protected function tearDown(): void
- {
- Functions::setCompatibilityMode($this->compatibilityMode);
- Functions::setReturnDateType($this->returnDateType);
- Date::setExcelCalendar($this->excelCalendar);
- }
-
/**
* @dataProvider providerDAY
*
* @param mixed $expectedResultExcel
- * @param mixed $expectedResultOpenOffice
- * @param $dateTimeValue
*/
- public function testDAY($expectedResultExcel, $expectedResultOpenOffice, $dateTimeValue): void
+ public function testDAY($expectedResultExcel, string $dateTimeValue): void
{
- $resultExcel = DateTime::DAYOFMONTH($dateTimeValue);
- self::assertEqualsWithDelta($expectedResultExcel, $resultExcel, 1E-8);
-
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
-
- $resultOpenOffice = DateTime::DAYOFMONTH($dateTimeValue);
- self::assertEqualsWithDelta($expectedResultOpenOffice, $resultOpenOffice, 1E-8);
+ $this->mightHaveException($expectedResultExcel);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ $sheet->getCell('A1')->setValue("=DAY($dateTimeValue)");
+ self::assertSame($expectedResultExcel, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerDAY()
+ public function providerDAY(): array
{
return require 'tests/data/Calculation/DateTime/DAY.php';
}
+
+ /**
+ * @dataProvider providerDAYOpenOffice
+ *
+ * @param mixed $expectedResultOpenOffice
+ */
+ public function testDAYOpenOffice($expectedResultOpenOffice, string $dateTimeValue): void
+ {
+ self::setOpenOffice();
+ $this->mightHaveException($expectedResultOpenOffice);
+ $sheet = $this->sheet;
+ $sheet->getCell('A2')->setValue("=DAY($dateTimeValue)");
+ self::assertSame($expectedResultOpenOffice, $sheet->getCell('A2')->getCalculatedValue());
+ }
+
+ public function providerDAYOpenOffice(): array
+ {
+ return require 'tests/data/Calculation/DateTime/DAYOpenOffice.php';
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php
index 47449e0d..bd3a0283 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/Days360Test.php
@@ -2,35 +2,24 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class Days360Test extends TestCase
+class Days360Test extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerDAYS360
*
* @param mixed $expectedResult
- * @param $startDate
- * @param $endDate
- * @param $method
*/
- public function testDAYS360($expectedResult, $startDate, $endDate, $method): void
+ public function testDAYS360($expectedResult, string $formula): void
{
- $result = DateTime::DAYS360($startDate, $endDate, $method);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('2000-02-29');
+ $sheet->getCell('C1')->setValue('2000-03-31');
+ $sheet->getCell('A1')->setValue("=DAYS360($formula)");
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerDAYS360()
+ public function providerDAYS360(): array
{
return require 'tests/data/Calculation/DateTime/DAYS360.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php
index fe31dfcc..8c65622a 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/DaysTest.php
@@ -2,35 +2,44 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
+use DateTime;
+use DateTimeImmutable;
+use Exception;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Days;
-class DaysTest extends TestCase
+class DaysTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerDAYS
*
* @param mixed $expectedResult
- * @param $endDate
- * @param $startDate
*/
- public function testDAYS($expectedResult, $endDate, $startDate): void
+ public function testDAYS($expectedResult, string $formula): void
{
- $result = DateTime::DAYS($endDate, $startDate);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ $sheet->getCell('C1')->setValue('1954-11-30');
+ $sheet->getCell('A1')->setValue("=DAYS($formula)");
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerDAYS()
+ public function providerDAYS(): array
{
return require 'tests/data/Calculation/DateTime/DAYS.php';
}
+
+ public function testObject(): void
+ {
+ $obj1 = new DateTime('2000-3-31');
+ $obj2 = new DateTimeImmutable('2000-2-29');
+ self::assertSame(31, Days::funcDays($obj1, $obj2));
+ }
+
+ public function testNonDateObject(): void
+ {
+ $obj1 = new Exception();
+ $obj2 = new DateTimeImmutable('2000-2-29');
+ self::assertSame('#VALUE!', Days::funcDays($obj1, $obj2));
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php
index a887ba5b..efb34d0d 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EDateTest.php
@@ -2,52 +2,43 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\EDate;
-class EDateTest extends TestCase
+class EDateTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerEDATE
*
* @param mixed $expectedResult
- * @param $dateValue
- * @param $adjustmentMonths
*/
- public function testEDATE($expectedResult, $dateValue, $adjustmentMonths): void
+ public function testEDATE($expectedResult, string $formula): void
{
- $result = DateTime::EDATE($dateValue, $adjustmentMonths);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=EDATE($formula)");
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ self::assertEquals($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerEDATE()
+ public function providerEDATE(): array
{
return require 'tests/data/Calculation/DateTime/EDATE.php';
}
public function testEDATEtoUnixTimestamp(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP);
+ self::setUnixReturn();
- $result = DateTime::EDATE('2012-1-26', -1);
+ $result = EDate::funcEDate('2012-1-26', -1);
self::assertEquals(1324857600, $result);
self::assertEqualsWithDelta(1324857600, $result, 1E-8);
}
public function testEDATEtoDateTimeObject(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT);
+ self::setObjectReturn();
- $result = DateTime::EDATE('2012-1-26', -1);
+ $result = EDate::funcEDate('2012-1-26', -1);
// Must return an object...
self::assertIsObject($result);
// ... of the correct type
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php
index f9c54039..6db76f58 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/EoMonthTest.php
@@ -2,57 +2,47 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\EoMonth;
-class EoMonthTest extends TestCase
+class EoMonthTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerEOMONTH
*
* @param mixed $expectedResult
- * @param $dateValue
- * @param $adjustmentMonths
*/
- public function testEOMONTH($expectedResult, $dateValue, $adjustmentMonths): void
+ public function testEOMONTH($expectedResult, string $formula): void
{
- $result = DateTime::EOMONTH($dateValue, $adjustmentMonths);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=EOMONTH($formula)");
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ self::assertEquals($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerEOMONTH()
+ public function providerEOMONTH(): array
{
return require 'tests/data/Calculation/DateTime/EOMONTH.php';
}
public function testEOMONTHtoUnixTimestamp(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP);
+ self::setUnixReturn();
- $result = DateTime::EOMONTH('2012-1-26', -1);
+ $result = EoMonth::funcEomonth('2012-1-26', -1);
self::assertEquals(1325289600, $result);
- self::assertEqualsWithDelta(1325289600, $result, 1E-8);
}
public function testEOMONTHtoDateTimeObject(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT);
+ self::setObjectReturn();
- $result = DateTime::EOMONTH('2012-1-26', -1);
+ $result = EoMonth::funcEomonth('2012-1-26', -1);
// Must return an object...
self::assertIsObject($result);
// ... of the correct type
self::assertTrue(is_a($result, 'DateTimeInterface'));
// ... with the correct value
- self::assertEquals($result->format('d-M-Y'), '31-Dec-2011');
+ self::assertSame($result->format('d-M-Y'), '31-Dec-2011');
}
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php
index 2d0cd5d1..93afbb5d 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/HourTest.php
@@ -2,33 +2,23 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class HourTest extends TestCase
+class HourTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerHOUR
*
* @param mixed $expectedResult
- * @param $dateTimeValue
*/
- public function testHOUR($expectedResult, $dateTimeValue): void
+ public function testHOUR($expectedResult, string $dateTimeValue): void
{
- $result = DateTime::HOUROFDAY($dateTimeValue);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=HOUR($dateTimeValue)");
+ $sheet->getCell('B1')->setValue('1954-11-23 2:23:46');
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerHOUR()
+ public function providerHOUR(): array
{
return require 'tests/data/Calculation/DateTime/HOUR.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php
index 1ef0080a..6be2e1af 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/IsoWeekNumTest.php
@@ -2,34 +2,46 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class IsoWeekNumTest extends TestCase
+class IsoWeekNumTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerISOWEEKNUM
*
* @param mixed $expectedResult
- * @param mixed $dateValue
+ * @param string $dateValue
*/
public function testISOWEEKNUM($expectedResult, $dateValue): void
{
- $result = DateTime::ISOWEEKNUM($dateValue);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=ISOWEEKNUM($dateValue)");
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerISOWEEKNUM()
+ public function providerISOWEEKNUM(): array
{
return require 'tests/data/Calculation/DateTime/ISOWEEKNUM.php';
}
+
+ /**
+ * @dataProvider providerISOWEEKNUM1904
+ *
+ * @param mixed $expectedResult
+ * @param string $dateValue
+ */
+ public function testISOWEEKNUM1904($expectedResult, $dateValue): void
+ {
+ $this->mightHaveException($expectedResult);
+ self::setMac1904();
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=ISOWEEKNUM($dateValue)");
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
+ }
+
+ public function providerISOWEEKNUM1904(): array
+ {
+ return require 'tests/data/Calculation/DateTime/ISOWEEKNUM1904.php';
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php
index 8472c6de..57d7a77e 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MinuteTest.php
@@ -2,33 +2,23 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class MinuteTest extends TestCase
+class MinuteTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerMINUTE
*
* @param mixed $expectedResult
- * @param $dateTimeValue
*/
- public function testMINUTE($expectedResult, $dateTimeValue): void
+ public function testMINUTE($expectedResult, string $dateTimeValue): void
{
- $result = DateTime::MINUTE($dateTimeValue);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=MINUTE($dateTimeValue)");
+ $sheet->getCell('B1')->setValue('1954-11-23 2:23:46');
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerMINUTE()
+ public function providerMINUTE(): array
{
return require 'tests/data/Calculation/DateTime/MINUTE.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php
index 62513702..ed09a993 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MonthTest.php
@@ -2,33 +2,23 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class MonthTest extends TestCase
+class MonthTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerMONTH
*
* @param mixed $expectedResult
- * @param $dateTimeValue
*/
- public function testMONTH($expectedResult, $dateTimeValue): void
+ public function testMONTH($expectedResult, string $dateTimeValue): void
{
- $result = DateTime::MONTHOFYEAR($dateTimeValue);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=MONTH($dateTimeValue)");
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerMONTH()
+ public function providerMONTH(): array
{
return require 'tests/data/Calculation/DateTime/MONTH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php
new file mode 100644
index 00000000..d14f7d7d
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/MovedFunctionsTest.php
@@ -0,0 +1,63 @@
+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/DateTime/NetworkDaysTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php
index e366c44e..b121f7bf 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NetworkDaysTest.php
@@ -2,32 +2,50 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class NetworkDaysTest extends TestCase
+class NetworkDaysTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerNETWORKDAYS
*
* @param mixed $expectedResult
+ * @param mixed $arg1
+ * @param mixed $arg2
*/
- public function testNETWORKDAYS($expectedResult, ...$args): void
+ public function testNETWORKDAYS($expectedResult, $arg1 = 'omitted', $arg2 = 'omitted', ?array $arg3 = null): void
{
- $result = DateTime::NETWORKDAYS(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($arg1 !== null) {
+ $sheet->getCell('A1')->setValue($arg1);
+ }
+ if ($arg2 !== null) {
+ $sheet->getCell('A2')->setValue($arg2);
+ }
+ $dateArray = [];
+ if (is_array($arg3)) {
+ if (array_key_exists(0, $arg3) && is_array($arg3[0])) {
+ $dateArray = $arg3[0];
+ } else {
+ $dateArray = $arg3;
+ }
+ }
+ $dateIndex = 0;
+ foreach ($dateArray as $date) {
+ ++$dateIndex;
+ $sheet->getCell("C$dateIndex")->setValue($date);
+ }
+ $arrayArg = $dateIndex ? ", C1:C$dateIndex" : '';
+ if ($arg1 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=NETWORKDAYS()');
+ } elseif ($arg2 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=NETWORKDAYS(A1)');
+ } else {
+ $sheet->getCell('B1')->setValue("=NETWORKDAYS(A1, A2$arrayArg)");
+ }
+ self::assertEquals($expectedResult, $sheet->getCell('B1')->getCalculatedValue());
}
- public function providerNETWORKDAYS()
+ public function providerNETWORKDAYS(): array
{
return require 'tests/data/Calculation/DateTime/NETWORKDAYS.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NowTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NowTest.php
new file mode 100644
index 00000000..e0f68c24
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/NowTest.php
@@ -0,0 +1,34 @@
+sheet;
+ // Loop to avoid rare edge case where first calculation
+ // and second do not take place in same second.
+ do {
+ $dtStart = new DateTimeImmutable();
+ $startSecond = $dtStart->format('s');
+ $sheet->setCellValue('A1', '=NOW()');
+ $dtEnd = new DateTimeImmutable();
+ $endSecond = $dtEnd->format('s');
+ } while ($startSecond !== $endSecond);
+ $sheet->setCellValue('B1', '=YEAR(A1)');
+ $sheet->setCellValue('C1', '=MONTH(A1)');
+ $sheet->setCellValue('D1', '=DAY(A1)');
+ $sheet->setCellValue('E1', '=HOUR(A1)');
+ $sheet->setCellValue('F1', '=MINUTE(A1)');
+ $sheet->setCellValue('G1', '=SECOND(A1)');
+ self::assertEquals($dtStart->format('Y'), $sheet->getCell('B1')->getCalculatedValue());
+ self::assertEquals($dtStart->format('m'), $sheet->getCell('C1')->getCalculatedValue());
+ self::assertEquals($dtStart->format('d'), $sheet->getCell('D1')->getCalculatedValue());
+ self::assertEquals($dtStart->format('H'), $sheet->getCell('E1')->getCalculatedValue());
+ self::assertEquals($dtStart->format('i'), $sheet->getCell('F1')->getCalculatedValue());
+ self::assertEquals($dtStart->format('s'), $sheet->getCell('G1')->getCalculatedValue());
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php
index bc2b0752..6c264a57 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/SecondTest.php
@@ -2,33 +2,23 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class SecondTest extends TestCase
+class SecondTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerSECOND
*
* @param mixed $expectedResult
- * @param $dateTimeValue
*/
- public function testSECOND($expectedResult, $dateTimeValue): void
+ public function testSECOND($expectedResult, string $dateTimeValue): void
{
- $result = DateTime::SECOND($dateTimeValue);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=SECOND($dateTimeValue)");
+ $sheet->getCell('B1')->setValue('1954-11-23 2:23:46');
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerSECOND()
+ public function providerSECOND(): array
{
return require 'tests/data/Calculation/DateTime/SECOND.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php
index 344061d4..d6910024 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeTest.php
@@ -2,49 +2,44 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\Time;
-class TimeTest extends TestCase
+class TimeTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerTIME
*
* @param mixed $expectedResult
*/
- public function testTIME($expectedResult, ...$args): void
+ public function testTIME($expectedResult, string $formula): void
{
- $result = DateTime::TIME(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('15');
+ $sheet->getCell('B2')->setValue('32');
+ $sheet->getCell('B3')->setValue('50');
+ $sheet->getCell('A1')->setValue("=TIME($formula)");
+ self::assertEqualsWithDelta($expectedResult, $sheet->getCell('A1')->getCalculatedValue(), 1E-8);
}
- public function providerTIME()
+ public function providerTIME(): array
{
return require 'tests/data/Calculation/DateTime/TIME.php';
}
public function testTIMEtoUnixTimestamp(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC);
+ self::setUnixReturn();
- $result = DateTime::TIME(7, 30, 20);
+ $result = Time::funcTime(7, 30, 20);
self::assertEqualsWithDelta(27020, $result, 1E-8);
}
public function testTIMEtoDateTimeObject(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT);
+ self::setObjectReturn();
- $result = DateTime::TIME(7, 30, 20);
+ $result = Time::funcTime(7, 30, 20);
// Must return an object...
self::assertIsObject($result);
// ... of the correct type
@@ -52,4 +47,17 @@ class TimeTest extends TestCase
// ... with the correct value
self::assertEquals($result->format('H:i:s'), '07:30:20');
}
+
+ public function testTIME1904(): void
+ {
+ self::setMac1904();
+ $result = Time::funcTime(0, 0, 0);
+ self::assertEquals(0, $result);
+ }
+
+ public function testTIME1900(): void
+ {
+ $result = Time::funcTime(0, 0, 0);
+ self::assertEquals(0, $result);
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php
index 04b8c058..ac4d3dbd 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TimeValueTest.php
@@ -2,51 +2,45 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\TimeValue;
-class TimeValueTest extends TestCase
+class TimeValueTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerTIMEVALUE
*
* @param mixed $expectedResult
- * @param $timeValue
+ * @param mixed $timeValue
*/
public function testTIMEVALUE($expectedResult, $timeValue): void
{
- $result = DateTime::TIMEVALUE($timeValue);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('03:45:52');
+ $sheet->getCell('A1')->setValue("=TIMEVALUE($timeValue)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerTIMEVALUE()
+ public function providerTIMEVALUE(): array
{
return require 'tests/data/Calculation/DateTime/TIMEVALUE.php';
}
public function testTIMEVALUEtoUnixTimestamp(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_UNIX_TIMESTAMP);
+ self::setUnixReturn();
- $result = DateTime::TIMEVALUE('7:30:20');
+ $result = TimeValue::funcTimeValue('7:30:20');
self::assertEquals(23420, $result);
self::assertEqualsWithDelta(23420, $result, 1E-8);
}
public function testTIMEVALUEtoDateTimeObject(): void
{
- Functions::setReturnDateType(Functions::RETURNDATE_PHP_DATETIME_OBJECT);
+ self::setObjectReturn();
- $result = DateTime::TIMEVALUE('7:30:20');
+ $result = TimeValue::funcTimeValue('7:30:20');
// Must return an object...
self::assertIsObject($result);
// ... of the correct type
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TodayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TodayTest.php
new file mode 100644
index 00000000..6ce82bfd
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/TodayTest.php
@@ -0,0 +1,34 @@
+sheet;
+ // Loop to avoid rare edge case where first calculation
+ // and second do not take place in same second.
+ do {
+ $dtStart = new DateTimeImmutable();
+ $startSecond = $dtStart->format('s');
+ $sheet->setCellValue('A1', '=TODAY()');
+ $dtEnd = new DateTimeImmutable();
+ $endSecond = $dtEnd->format('s');
+ } while ($startSecond !== $endSecond);
+ $sheet->setCellValue('B1', '=YEAR(A1)');
+ $sheet->setCellValue('C1', '=MONTH(A1)');
+ $sheet->setCellValue('D1', '=DAY(A1)');
+ $sheet->setCellValue('E1', '=HOUR(A1)');
+ $sheet->setCellValue('F1', '=MINUTE(A1)');
+ $sheet->setCellValue('G1', '=SECOND(A1)');
+ self::assertSame((int) $dtStart->format('Y'), $sheet->getCell('B1')->getCalculatedValue());
+ self::assertSame((int) $dtStart->format('m'), $sheet->getCell('C1')->getCalculatedValue());
+ self::assertSame((int) $dtStart->format('d'), $sheet->getCell('D1')->getCalculatedValue());
+ self::assertSame(0, $sheet->getCell('E1')->getCalculatedValue());
+ self::assertSame(0, $sheet->getCell('F1')->getCalculatedValue());
+ self::assertSame(0, $sheet->getCell('G1')->getCalculatedValue());
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php
index c5b89e01..c95ce9cc 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekDayTest.php
@@ -2,33 +2,34 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
+use PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\WeekDay;
-class WeekDayTest extends TestCase
+class WeekDayTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerWEEKDAY
*
* @param mixed $expectedResult
*/
- public function testWEEKDAY($expectedResult, ...$args): void
+ public function testWEEKDAY($expectedResult, string $formula): void
{
- $result = DateTime::WEEKDAY(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ $sheet->getCell('A1')->setValue("=WEEKDAY($formula)");
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerWEEKDAY()
+ public function providerWEEKDAY(): array
{
return require 'tests/data/Calculation/DateTime/WEEKDAY.php';
}
+
+ public function testWEEKDAYwith1904Calendar(): void
+ {
+ self::setMac1904();
+ self::assertEquals(7, WeekDay::funcWeekDay('1904-01-02'));
+ self::assertEquals(6, WeekDay::funcWeekDay('1904-01-01'));
+ self::assertEquals(6, WeekDay::funcWeekDay(null));
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php
index 9d8e1eb2..cf8ac65b 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WeekNumTest.php
@@ -2,33 +2,44 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class WeekNumTest extends TestCase
+class WeekNumTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerWEEKNUM
*
* @param mixed $expectedResult
*/
- public function testWEEKNUM($expectedResult, ...$args): void
+ public function testWEEKNUM($expectedResult, string $formula): void
{
- $result = DateTime::WEEKNUM(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ $sheet->getCell('A1')->setValue("=WEEKNUM($formula)");
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerWEEKNUM()
+ public function providerWEEKNUM(): array
{
return require 'tests/data/Calculation/DateTime/WEEKNUM.php';
}
+
+ /**
+ * @dataProvider providerWEEKNUM1904
+ *
+ * @param mixed $expectedResult
+ */
+ public function testWEEKNUM1904($expectedResult, string $formula): void
+ {
+ $this->mightHaveException($expectedResult);
+ self::setMac1904();
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ $sheet->getCell('A1')->setValue("=WEEKNUM($formula)");
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
+ }
+
+ public function providerWEEKNUM1904(): array
+ {
+ return require 'tests/data/Calculation/DateTime/WEEKNUM1904.php';
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php
index 4784e463..80829699 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/WorkDayTest.php
@@ -2,32 +2,50 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class WorkDayTest extends TestCase
+class WorkDayTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerWORKDAY
*
* @param mixed $expectedResult
+ * @param mixed $arg1
+ * @param mixed $arg2
*/
- public function testWORKDAY($expectedResult, ...$args): void
+ public function testWORKDAY($expectedResult, $arg1 = 'omitted', $arg2 = 'omitted', ?array $arg3 = null): void
{
- $result = DateTime::WORKDAY(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($arg1 !== null) {
+ $sheet->getCell('A1')->setValue($arg1);
+ }
+ if ($arg2 !== null) {
+ $sheet->getCell('A2')->setValue($arg2);
+ }
+ $dateArray = [];
+ if (is_array($arg3)) {
+ if (array_key_exists(0, $arg3) && is_array($arg3[0])) {
+ $dateArray = $arg3[0];
+ } else {
+ $dateArray = $arg3;
+ }
+ }
+ $dateIndex = 0;
+ foreach ($dateArray as $date) {
+ ++$dateIndex;
+ $sheet->getCell("C$dateIndex")->setValue($date);
+ }
+ $arrayArg = $dateIndex ? ", C1:C$dateIndex" : '';
+ if ($arg1 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=WORKDAY()');
+ } elseif ($arg2 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=WORKDAY(A1)');
+ } else {
+ $sheet->getCell('B1')->setValue("=WORKDAY(A1, A2$arrayArg)");
+ }
+ self::assertEquals($expectedResult, $sheet->getCell('B1')->getCalculatedValue());
}
- public function providerWORKDAY()
+ public function providerWORKDAY(): array
{
return require 'tests/data/Calculation/DateTime/WORKDAY.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php
index 05f11310..e16ce697 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearFracTest.php
@@ -2,32 +2,42 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class YearFracTest extends TestCase
+class YearFracTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerYEARFRAC
*
* @param mixed $expectedResult
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @param mixed $arg3
*/
- public function testYEARFRAC($expectedResult, ...$args): void
+ public function testYEARFRAC($expectedResult, $arg1 = 'omitted', $arg2 = 'omitted', $arg3 = 'omitted'): void
{
- $result = DateTime::YEARFRAC(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($arg1 !== null) {
+ $sheet->getCell('A1')->setValue($arg1);
+ }
+ if ($arg2 !== null) {
+ $sheet->getCell('A2')->setValue($arg2);
+ }
+ if ($arg3 !== null) {
+ $sheet->getCell('A3')->setValue($arg3);
+ }
+ if ($arg1 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=YEARFRAC()');
+ } elseif ($arg2 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=YEARFRAC(A1)');
+ } elseif ($arg3 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=YEARFRAC(A1, A2)');
+ } else {
+ $sheet->getCell('B1')->setValue('=YEARFRAC(A1, A2, A3)');
+ }
+ self::assertEqualswithDelta($expectedResult, $sheet->getCell('B1')->getCalculatedValue(), 1E-6);
}
- public function providerYEARFRAC()
+ public function providerYEARFRAC(): array
{
return require 'tests/data/Calculation/DateTime/YEARFRAC.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php
index bbdaf92a..74b3bed0 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/DateTime/YearTest.php
@@ -2,33 +2,23 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Shared\Date;
-use PHPUnit\Framework\TestCase;
-
-class YearTest extends TestCase
+class YearTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
- Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900);
- }
-
/**
* @dataProvider providerYEAR
*
* @param mixed $expectedResult
- * @param $dateTimeValue
*/
- public function testYEAR($expectedResult, $dateTimeValue): void
+ public function testYEAR($expectedResult, string $dateTimeValue): void
{
- $result = DateTime::YEAR($dateTimeValue);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=YEAR($dateTimeValue)");
+ $sheet->getCell('B1')->setValue('1954-11-23');
+ self::assertSame($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerYEAR()
+ public function providerYEAR(): array
{
return require 'tests/data/Calculation/DateTime/YEAR.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php
index 8fff98af..d24a0208 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselITest.php
@@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase;
class BesselITest extends TestCase
{
- const BESSEL_PRECISION = 1E-8;
+ const BESSEL_PRECISION = 1E-9;
protected function setUp(): void
{
@@ -26,7 +26,7 @@ class BesselITest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION);
}
- public function providerBESSELI()
+ public function providerBESSELI(): array
{
return require 'tests/data/Calculation/Engineering/BESSELI.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php
index d10f028f..325a0d64 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselJTest.php
@@ -26,7 +26,7 @@ class BesselJTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION);
}
- public function providerBESSEJ()
+ public function providerBESSEJ(): array
{
return require 'tests/data/Calculation/Engineering/BESSELJ.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php
index 27123a26..51725d38 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselKTest.php
@@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase;
class BesselKTest extends TestCase
{
- const BESSEL_PRECISION = 1E-8;
+ const BESSEL_PRECISION = 1E-12;
protected function setUp(): void
{
@@ -26,7 +26,7 @@ class BesselKTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION);
}
- public function providerBESSELK()
+ public function providerBESSELK(): array
{
return require 'tests/data/Calculation/Engineering/BESSELK.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php
index ab55f0ac..1e8d863f 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BesselYTest.php
@@ -8,7 +8,7 @@ use PHPUnit\Framework\TestCase;
class BesselYTest extends TestCase
{
- const BESSEL_PRECISION = 1E-8;
+ const BESSEL_PRECISION = 1E-12;
protected function setUp(): void
{
@@ -26,7 +26,7 @@ class BesselYTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::BESSEL_PRECISION);
}
- public function providerBESSELY()
+ public function providerBESSELY(): array
{
return require 'tests/data/Calculation/Engineering/BESSELY.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2DecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2DecTest.php
index faba3de8..c0923d1a 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2DecTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2DecTest.php
@@ -2,30 +2,92 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Bin2DecTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerBIN2DEC
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testBIN2DEC($expectedResult, ...$args): void
+ public function testBin2Dec($expectedResult, $formula): void
{
- $result = Engineering::BINTODEC(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=BIN2DEC($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBIN2DEC()
+ public function providerBIN2DEC(): array
{
return require 'tests/data/Calculation/Engineering/BIN2DEC.php';
}
+
+ /**
+ * @dataProvider providerBIN2DEC
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testBIN2DECOds($expectedResult, $formula): void
+ {
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=BIN2DEC($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testBIN2DECFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=BIN2DEC(101.1)');
+ self::assertEquals(5, $sheet->getCell($cell)->getCalculatedValue(), 'Gnumeric');
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=BIN2DEC(101.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue(), 'Ods');
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=BIN2DEC(101.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue(), 'Excel');
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2HexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2HexTest.php
index 2a16d5ac..c95c375d 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2HexTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2HexTest.php
@@ -2,30 +2,92 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Bin2HexTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerBIN2HEX
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testBIN2HEX($expectedResult, ...$args): void
+ public function testBin2Hex($expectedResult, $formula): void
{
- $result = Engineering::BINTOHEX(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=BIN2HEX($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBIN2HEX()
+ public function providerBIN2HEX(): array
{
return require 'tests/data/Calculation/Engineering/BIN2HEX.php';
}
+
+ /**
+ * @dataProvider providerBIN2HEX
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testBIN2HEXOds($expectedResult, $formula): void
+ {
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=BIN2HEX($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testBIN2HEXFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=BIN2HEX(101.1)');
+ self::assertEquals(5, $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=BIN2HEX(101.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=BIN2HEX(101.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2OctTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2OctTest.php
index 78db6a6e..ee54063c 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2OctTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Bin2OctTest.php
@@ -2,30 +2,92 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Bin2OctTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerBIN2OCT
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testBIN2OCT($expectedResult, ...$args): void
+ public function testBin2Oct($expectedResult, $formula): void
{
- $result = Engineering::BINTOOCT(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=BIN2OCT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBIN2OCT()
+ public function providerBIN2OCT(): array
{
return require 'tests/data/Calculation/Engineering/BIN2OCT.php';
}
+
+ /**
+ * @dataProvider providerBIN2OCT
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testBIN2OCTOds($expectedResult, $formula): void
+ {
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=BIN2OCT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testBIN2OCTFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=BIN2OCT(101.1)');
+ self::assertEquals(5, $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=BIN2OCT(101.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=BIN2OCT(101.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitAndTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitAndTest.php
index e73efccc..23682908 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitAndTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitAndTest.php
@@ -2,30 +2,31 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class BitAndTest extends TestCase
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerBITAND
*
* @param mixed $expectedResult
- * @param mixed[] $args
*/
- public function testBITAND($expectedResult, array $args): void
+ public function testBITAND($expectedResult, string $formula): void
{
- $result = Engineering::BITAND(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 24);
+ $sheet->getCell('A1')->setValue("=BITAND($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBITAND()
+ public function providerBITAND(): array
{
return require 'tests/data/Calculation/Engineering/BITAND.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitLShiftTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitLShiftTest.php
index 61aa89b4..ee408497 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitLShiftTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitLShiftTest.php
@@ -2,30 +2,31 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class BitLShiftTest extends TestCase
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerBITLSHIFT
*
* @param mixed $expectedResult
- * @param mixed[] $args
*/
- public function testBITLSHIFT($expectedResult, array $args): void
+ public function testBITLSHIFT($expectedResult, string $formula): void
{
- $result = Engineering::BITLSHIFT(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 8);
+ $sheet->getCell('A1')->setValue("=BITLSHIFT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBITLSHIFT()
+ public function providerBITLSHIFT(): array
{
return require 'tests/data/Calculation/Engineering/BITLSHIFT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitOrTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitOrTest.php
index 857c7466..3cc1f4bc 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitOrTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitOrTest.php
@@ -2,30 +2,31 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class BitOrTest extends TestCase
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerBITOR
*
* @param mixed $expectedResult
- * @param mixed[] $args
*/
- public function testBITOR($expectedResult, array $args): void
+ public function testBITOR($expectedResult, string $formula): void
{
- $result = Engineering::BITOR(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 8);
+ $sheet->getCell('A1')->setValue("=BITOR($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBITOR()
+ public function providerBITOR(): array
{
return require 'tests/data/Calculation/Engineering/BITOR.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitRShiftTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitRShiftTest.php
index 26b13d07..f58d6149 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitRShiftTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitRShiftTest.php
@@ -2,30 +2,31 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class BitRShiftTest extends TestCase
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerBITRSHIFT
*
* @param mixed $expectedResult
- * @param mixed[] $args
*/
- public function testBITRSHIFT($expectedResult, array $args): void
+ public function testBITRSHIFT($expectedResult, string $formula): void
{
- $result = Engineering::BITRSHIFT(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 8);
+ $sheet->getCell('A1')->setValue("=BITRSHIFT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBITRSHIFT()
+ public function providerBITRSHIFT(): array
{
return require 'tests/data/Calculation/Engineering/BITRSHIFT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitXorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitXorTest.php
index 4415f6da..4fa302af 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitXorTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/BitXorTest.php
@@ -2,30 +2,31 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class BitXorTest extends TestCase
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerBITXOR
*
* @param mixed $expectedResult
- * @param mixed[] $args
*/
- public function testBITXOR($expectedResult, array $args): void
+ public function testBITXOR($expectedResult, string $formula): void
{
- $result = Engineering::BITXOR(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 8);
+ $sheet->getCell('A1')->setValue("=BITXOR($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBITXOR()
+ public function providerBITXOR(): array
{
return require 'tests/data/Calculation/Engineering/BITXOR.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php
index 4b857e2d..f60315dc 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ComplexTest.php
@@ -24,7 +24,7 @@ class ComplexTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerCOMPLEX()
+ public function providerCOMPLEX(): array
{
return require 'tests/data/Calculation/Engineering/COMPLEX.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php
index 7a18067f..87198edb 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ConvertUoMTest.php
@@ -37,6 +37,12 @@ class ConvertUoMTest extends TestCase
self::assertIsArray($result);
}
+ public function testGetBinaryConversionMultipliers(): void
+ {
+ $result = Engineering::getBinaryConversionMultipliers();
+ self::assertIsArray($result);
+ }
+
/**
* @dataProvider providerCONVERTUOM
*
@@ -48,7 +54,7 @@ class ConvertUoMTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerCONVERTUOM()
+ public function providerCONVERTUOM(): array
{
return require 'tests/data/Calculation/Engineering/CONVERTUOM.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2BinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2BinTest.php
index 3626ac6b..dfed3478 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2BinTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2BinTest.php
@@ -2,30 +2,92 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Dec2BinTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerDEC2BIN
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testDEC2BIN($expectedResult, ...$args): void
+ public function testDEC2BIN($expectedResult, $formula): void
{
- $result = Engineering::DECTOBIN(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 5);
+ $sheet->getCell('A1')->setValue("=DEC2BIN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerDEC2BIN()
+ public function providerDEC2BIN(): array
{
return require 'tests/data/Calculation/Engineering/DEC2BIN.php';
}
+
+ /**
+ * @dataProvider providerDEC2BIN
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testDEC2BINOds($expectedResult, $formula): void
+ {
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 5);
+ $sheet->getCell('A1')->setValue("=DEC2BIN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testDEC2BINFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=DEC2BIN(5.1)');
+ self::assertEquals(101, $sheet->getCell($cell)->getCalculatedValue(), 'Gnumeric');
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=DEC2BIN(5.1)');
+ self::assertEquals(101, $sheet->getCell($cell)->getCalculatedValue(), 'Ods');
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=DEC2BIN(5.1)');
+ self::assertEquals(101, $sheet->getCell($cell)->getCalculatedValue(), 'Excel');
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2HexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2HexTest.php
index d191f620..ebe49464 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2HexTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2HexTest.php
@@ -3,29 +3,99 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Dec2HexTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerDEC2HEX
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testDEC2HEX($expectedResult, ...$args): void
+ public function testDEC2HEX($expectedResult, $formula): void
{
- $result = Engineering::DECTOHEX(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 17);
+ $sheet->getCell('A1')->setValue("=DEC2HEX($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerDEC2HEX()
+ public function providerDEC2HEX(): array
{
return require 'tests/data/Calculation/Engineering/DEC2HEX.php';
}
+
+ /**
+ * @dataProvider providerDEC2HEX
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testDEC2HEXOds($expectedResult, $formula): void
+ {
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 17);
+ $sheet->getCell('A1')->setValue("=DEC2HEX($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testDEC2HEXFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=DEC2HEX(17.1)');
+ self::assertEquals(11, $sheet->getCell($cell)->getCalculatedValue(), 'Gnumeric');
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=DEC2HEX(17.1)');
+ self::assertEquals(11, $sheet->getCell($cell)->getCalculatedValue(), 'Ods');
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=DEC2HEX(17.1)');
+ self::assertEquals(11, $sheet->getCell($cell)->getCalculatedValue(), 'Excel');
+ }
+
+ public function test32bitHex(): void
+ {
+ self::assertEquals('A2DE246000', Engineering\ConvertDecimal::hex32bit(-400000000000, 'DE246000', true));
+ self::assertEquals('7FFFFFFFFF', Engineering\ConvertDecimal::hex32bit(549755813887, 'FFFFFFFF', true));
+ self::assertEquals('FFFFFFFFFF', Engineering\ConvertDecimal::hex32bit(-1, 'FFFFFFFF', true));
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2OctTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2OctTest.php
index 61eb3dbb..093f17bc 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2OctTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Dec2OctTest.php
@@ -2,30 +2,92 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Dec2OctTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerDEC2OCT
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testDEC2OCT($expectedResult, ...$args): void
+ public function testDEC2OCT($expectedResult, $formula): void
{
- $result = Engineering::DECTOOCT(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 17);
+ $sheet->getCell('A1')->setValue("=DEC2OCT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerDEC2OCT()
+ public function providerDEC2OCT(): array
{
return require 'tests/data/Calculation/Engineering/DEC2OCT.php';
}
+
+ /**
+ * @dataProvider providerDEC2OCT
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testDEC2OCTOds($expectedResult, $formula): void
+ {
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 17);
+ $sheet->getCell('A1')->setValue("=DEC2OCT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testDEC2OCTFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=DEC2OCT(17.1)');
+ self::assertEquals(21, $sheet->getCell($cell)->getCalculatedValue(), 'Gnumeric');
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=DEC2OCT(17.1)');
+ self::assertEquals(21, $sheet->getCell($cell)->getCalculatedValue(), 'Ods');
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=DEC2OCT(17.1)');
+ self::assertEquals(21, $sheet->getCell($cell)->getCalculatedValue(), 'Excel');
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php
index a93d2ea6..749b33c2 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/DeltaTest.php
@@ -24,7 +24,7 @@ class DeltaTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerDELTA()
+ public function providerDELTA(): array
{
return require 'tests/data/Calculation/Engineering/DELTA.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php
index 09bf448e..45d5b4c8 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfCTest.php
@@ -27,7 +27,7 @@ class ErfCTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION);
}
- public function providerERFC()
+ public function providerERFC(): array
{
return require 'tests/data/Calculation/Engineering/ERFC.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php
index eb26ae98..952b2560 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfPreciseTest.php
@@ -27,7 +27,7 @@ class ErfPreciseTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION);
}
- public function providerERFPRECISE()
+ public function providerERFPRECISE(): array
{
return require 'tests/data/Calculation/Engineering/ERFPRECISE.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php
index 8201edbc..9866024f 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ErfTest.php
@@ -27,7 +27,7 @@ class ErfTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::ERF_PRECISION);
}
- public function providerERF()
+ public function providerERF(): array
{
return require 'tests/data/Calculation/Engineering/ERF.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php
index 370c1a82..07e3a48c 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/GeStepTest.php
@@ -24,7 +24,7 @@ class GeStepTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerGESTEP()
+ public function providerGESTEP(): array
{
return require 'tests/data/Calculation/Engineering/GESTEP.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2BinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2BinTest.php
index 44d8908d..ad76716c 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2BinTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2BinTest.php
@@ -2,30 +2,95 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Hex2BinTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerHEX2BIN
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testHEX2BIN($expectedResult, ...$args): void
+ public function testHEX2BIN($expectedResult, $formula): void
{
- $result = Engineering::HEXTOBIN(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 'B');
+ $sheet->getCell('A1')->setValue("=HEX2BIN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerHEX2BIN()
+ public function providerHEX2BIN(): array
{
return require 'tests/data/Calculation/Engineering/HEX2BIN.php';
}
+
+ /**
+ * @dataProvider providerHEX2BIN
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testHEX2BINOds($expectedResult, $formula): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 'B');
+ $sheet->getCell('A1')->setValue("=HEX2BIN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testHEX2BINFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=HEX2BIN(10.1)');
+ self::assertEquals('10000', $sheet->getCell($cell)->getCalculatedValue());
+ $cell = 'F21';
+ $sheet->setCellValue($cell, '=HEX2BIN("A.1")');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=HEX2BIN(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=HEX2BIN(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2DecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2DecTest.php
index b388b2b7..806ba44d 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2DecTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2DecTest.php
@@ -2,30 +2,95 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Hex2DecTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerHEX2DEC
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testHEX2DEC($expectedResult, ...$args): void
+ public function testHEX2DEC($expectedResult, $formula): void
{
- $result = Engineering::HEXTODEC(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 'B');
+ $sheet->getCell('A1')->setValue("=HEX2DEC($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerHEX2DEC()
+ public function providerHEX2DEC(): array
{
return require 'tests/data/Calculation/Engineering/HEX2DEC.php';
}
+
+ /**
+ * @dataProvider providerHEX2DEC
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testHEX2DECOds($expectedResult, $formula): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 'B');
+ $sheet->getCell('A1')->setValue("=HEX2DEC($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testHEX2DECFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=HEX2DEC(10.1)');
+ self::assertEquals(16, $sheet->getCell($cell)->getCalculatedValue());
+ $cell = 'F21';
+ $sheet->setCellValue($cell, '=HEX2DEC("A.1")');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=HEX2DEC(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=HEX2DEC(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue(), 'Excel');
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2OctTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2OctTest.php
index bc0a5cb7..41f1a8f7 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2OctTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Hex2OctTest.php
@@ -2,30 +2,92 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Hex2OctTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerHEX2OCT
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testHEX2OCT($expectedResult, ...$args): void
+ public function testHEX2OCT($expectedResult, $formula): void
{
- $result = Engineering::HEXTOOCT(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 'B');
+ $sheet->getCell('A1')->setValue("=HEX2OCT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerHEX2OCT()
+ public function providerHEX2OCT(): array
{
return require 'tests/data/Calculation/Engineering/HEX2OCT.php';
}
+
+ /**
+ * @dataProvider providerHEX2OCT
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testHEX2OCTOds($expectedResult, $formula): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 'B');
+ $sheet->getCell('A1')->setValue("=HEX2OCT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testHEX2OCTFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=HEX2OCT(10.1)');
+ self::assertEquals(20, $sheet->getCell($cell)->getCalculatedValue());
+ $cell = 'F21';
+ $sheet->setCellValue($cell, '=HEX2OCT("A.1")');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=HEX2OCT(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=HEX2OCT(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue(), 'Excel');
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php
index 1f1ee9dd..367cfb33 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImAbsTest.php
@@ -27,7 +27,7 @@ class ImAbsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION);
}
- public function providerIMABS()
+ public function providerIMABS(): array
{
return require 'tests/data/Calculation/Engineering/IMABS.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php
index 6f1a6485..9ff8209f 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImArgumentTest.php
@@ -27,7 +27,7 @@ class ImArgumentTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION);
}
- public function providerIMARGUMENT()
+ public function providerIMARGUMENT(): array
{
return require 'tests/data/Calculation/Engineering/IMARGUMENT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php
index bc3a3918..d952f5df 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImConjugateTest.php
@@ -14,7 +14,7 @@ class ImConjugateTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImConjugateTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMCONJUGATE
*
@@ -42,7 +37,7 @@ class ImConjugateTest extends TestCase
);
}
- public function providerIMCONJUGATE()
+ public function providerIMCONJUGATE(): array
{
return require 'tests/data/Calculation/Engineering/IMCONJUGATE.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php
index 693f0bab..b6cb8dc2 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCosTest.php
@@ -14,7 +14,7 @@ class ImCosTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImCosTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMCOS
*
@@ -42,7 +37,7 @@ class ImCosTest extends TestCase
);
}
- public function providerIMCOS()
+ public function providerIMCOS(): array
{
return require 'tests/data/Calculation/Engineering/IMCOS.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php
index ae035fef..0d544084 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCoshTest.php
@@ -14,7 +14,7 @@ class ImCoshTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImCoshTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMCOSH
*
@@ -42,7 +37,7 @@ class ImCoshTest extends TestCase
);
}
- public function providerIMCOSH()
+ public function providerIMCOSH(): array
{
return require 'tests/data/Calculation/Engineering/IMCOSH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php
index 8b888b3f..69bd02ff 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCotTest.php
@@ -14,7 +14,7 @@ class ImCotTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImCotTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMCOT
*
@@ -42,7 +37,7 @@ class ImCotTest extends TestCase
);
}
- public function providerIMCOT()
+ public function providerIMCOT(): array
{
return require 'tests/data/Calculation/Engineering/IMCOT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php
index 5a08c0b6..51843f89 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCscTest.php
@@ -14,7 +14,7 @@ class ImCscTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImCscTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMCSC
*
@@ -42,7 +37,7 @@ class ImCscTest extends TestCase
);
}
- public function providerIMCSC()
+ public function providerIMCSC(): array
{
return require 'tests/data/Calculation/Engineering/IMCSC.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php
index a95a4eaf..d2d7511d 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImCschTest.php
@@ -14,7 +14,7 @@ class ImCschTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImCschTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMCSCH
*
@@ -42,7 +37,7 @@ class ImCschTest extends TestCase
);
}
- public function providerIMCSCH()
+ public function providerIMCSCH(): array
{
return require 'tests/data/Calculation/Engineering/IMCSCH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php
index 2bc91619..652f5ca2 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImDivTest.php
@@ -14,7 +14,7 @@ class ImDivTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImDivTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMDIV
*
@@ -41,7 +36,7 @@ class ImDivTest extends TestCase
);
}
- public function providerIMDIV()
+ public function providerIMDIV(): array
{
return require 'tests/data/Calculation/Engineering/IMDIV.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php
index 7debbc9c..d7be573f 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImExpTest.php
@@ -14,7 +14,7 @@ class ImExpTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImExpTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMEXP
*
@@ -42,7 +37,7 @@ class ImExpTest extends TestCase
);
}
- public function providerIMEXP()
+ public function providerIMEXP(): array
{
return require 'tests/data/Calculation/Engineering/IMEXP.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php
index 3e270975..4566607b 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLnTest.php
@@ -14,7 +14,7 @@ class ImLnTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImLnTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMLN
*
@@ -42,7 +37,7 @@ class ImLnTest extends TestCase
);
}
- public function providerIMLN()
+ public function providerIMLN(): array
{
return require 'tests/data/Calculation/Engineering/IMLN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php
index 2a4db7fb..0d818686 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog10Test.php
@@ -14,7 +14,7 @@ class ImLog10Test extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImLog10Test extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMLOG10
*
@@ -42,7 +37,7 @@ class ImLog10Test extends TestCase
);
}
- public function providerIMLOG10()
+ public function providerIMLOG10(): array
{
return require 'tests/data/Calculation/Engineering/IMLOG10.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php
index 53b302dd..02583448 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImLog2Test.php
@@ -14,7 +14,7 @@ class ImLog2Test extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImLog2Test extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMLOG2
*
@@ -42,7 +37,7 @@ class ImLog2Test extends TestCase
);
}
- public function providerIMLOG2()
+ public function providerIMLOG2(): array
{
return require 'tests/data/Calculation/Engineering/IMLOG2.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php
index 41e52878..18e92791 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImPowerTest.php
@@ -14,7 +14,7 @@ class ImPowerTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImPowerTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMPOWER
*
@@ -41,7 +36,7 @@ class ImPowerTest extends TestCase
);
}
- public function providerIMPOWER()
+ public function providerIMPOWER(): array
{
return require 'tests/data/Calculation/Engineering/IMPOWER.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php
index 43495739..845d436f 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImProductTest.php
@@ -14,7 +14,7 @@ class ImProductTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImProductTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMPRODUCT
*
@@ -41,7 +36,7 @@ class ImProductTest extends TestCase
);
}
- public function providerIMPRODUCT()
+ public function providerIMPRODUCT(): array
{
return require 'tests/data/Calculation/Engineering/IMPRODUCT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php
index 08d2feb1..790487c1 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImRealTest.php
@@ -27,7 +27,7 @@ class ImRealTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION);
}
- public function providerIMREAL()
+ public function providerIMREAL(): array
{
return require 'tests/data/Calculation/Engineering/IMREAL.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php
index e785d3ac..b750796d 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSecTest.php
@@ -14,7 +14,7 @@ class ImSecTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImSecTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMSEC
*
@@ -42,7 +37,7 @@ class ImSecTest extends TestCase
);
}
- public function providerIMSEC()
+ public function providerIMSEC(): array
{
return require 'tests/data/Calculation/Engineering/IMSEC.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php
index 22cb6fae..c6477c1c 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSechTest.php
@@ -14,7 +14,7 @@ class ImSechTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImSechTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMSECH
*
@@ -42,7 +37,7 @@ class ImSechTest extends TestCase
);
}
- public function providerIMSECH()
+ public function providerIMSECH(): array
{
return require 'tests/data/Calculation/Engineering/IMSECH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php
index dd797a35..df8cb020 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinTest.php
@@ -14,7 +14,7 @@ class ImSinTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImSinTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMSIN
*
@@ -42,7 +37,7 @@ class ImSinTest extends TestCase
);
}
- public function providerIMSIN()
+ public function providerIMSIN(): array
{
return require 'tests/data/Calculation/Engineering/IMSIN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php
index 4174d1c0..f8dbafb9 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSinhTest.php
@@ -14,7 +14,7 @@ class ImSinhTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImSinhTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMSINH
*
@@ -42,7 +37,7 @@ class ImSinhTest extends TestCase
);
}
- public function providerIMSINH()
+ public function providerIMSINH(): array
{
return require 'tests/data/Calculation/Engineering/IMSINH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php
index 091b11c5..0d536f94 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSqrtTest.php
@@ -14,7 +14,7 @@ class ImSqrtTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImSqrtTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMSQRT
*
@@ -42,7 +37,7 @@ class ImSqrtTest extends TestCase
);
}
- public function providerIMSQRT()
+ public function providerIMSQRT(): array
{
return require 'tests/data/Calculation/Engineering/IMSQRT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php
index 79286120..edb413d5 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSubTest.php
@@ -14,7 +14,7 @@ class ImSubTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImSubTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMSUB
*
@@ -41,7 +36,7 @@ class ImSubTest extends TestCase
);
}
- public function providerIMSUB()
+ public function providerIMSUB(): array
{
return require 'tests/data/Calculation/Engineering/IMSUB.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php
index 8abc3638..0620c684 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImSumTest.php
@@ -14,7 +14,7 @@ class ImSumTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImSumTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMSUM
*
@@ -41,7 +36,7 @@ class ImSumTest extends TestCase
);
}
- public function providerIMSUM()
+ public function providerIMSUM(): array
{
return require 'tests/data/Calculation/Engineering/IMSUM.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php
index 57b23815..f1e4037e 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImTanTest.php
@@ -14,7 +14,7 @@ class ImTanTest extends TestCase
/**
* @var ComplexAssert
*/
- protected $complexAssert;
+ private $complexAssert;
protected function setUp(): void
{
@@ -22,11 +22,6 @@ class ImTanTest extends TestCase
$this->complexAssert = new ComplexAssert();
}
- protected function tearDown(): void
- {
- $this->complexAssert = null;
- }
-
/**
* @dataProvider providerIMTAN
*
@@ -42,7 +37,7 @@ class ImTanTest extends TestCase
);
}
- public function providerIMTAN()
+ public function providerIMTAN(): array
{
return require 'tests/data/Calculation/Engineering/IMTAN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php
index 6ad72287..1c976b05 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/ImaginaryTest.php
@@ -27,7 +27,7 @@ class ImaginaryTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, self::COMPLEX_PRECISION);
}
- public function providerIMAGINARY()
+ public function providerIMAGINARY(): array
{
return require 'tests/data/Calculation/Engineering/IMAGINARY.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/MovedBitwiseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/MovedBitwiseTest.php
new file mode 100644
index 00000000..457db0d3
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/MovedBitwiseTest.php
@@ -0,0 +1,24 @@
+compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerOCT2BIN
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testOCT2BIN($expectedResult, ...$args): void
+ public function testOCT2BIN($expectedResult, $formula): void
{
- $result = Engineering::OCTTOBIN(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=OCT2BIN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerOCT2BIN()
+ public function providerOCT2BIN(): array
{
return require 'tests/data/Calculation/Engineering/OCT2BIN.php';
}
+
+ /**
+ * @dataProvider providerOCT2BIN
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testOCT2BINOds($expectedResult, $formula): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=OCT2BIN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testOCT2BINFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=HEX2BIN(10.1)');
+ self::assertEquals('10000', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=OCT2BIN(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=OCT2BIN(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2DecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2DecTest.php
index 87e213ef..2c354046 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2DecTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2DecTest.php
@@ -2,30 +2,92 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Oct2DecTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerOCT2DEC
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testOCT2DEC($expectedResult, ...$args): void
+ public function testOCT2DEC($expectedResult, $formula): void
{
- $result = Engineering::OCTTODEC(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=OCT2DEC($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerOCT2DEC()
+ public function providerOCT2DEC(): array
{
return require 'tests/data/Calculation/Engineering/OCT2DEC.php';
}
+
+ /**
+ * @dataProvider providerOCT2DEC
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testOCT2DECOds($expectedResult, $formula): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=OCT2DEC($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testOCT2DECFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=OCT2DEC(10.1)');
+ self::assertEquals(8, $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=OCT2DEC(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=OCT2DEC(10.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2HexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2HexTest.php
index e2d75a78..3f721a48 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2HexTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Engineering/Oct2HexTest.php
@@ -2,30 +2,92 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\Engineering;
-use PhpOffice\PhpSpreadsheet\Calculation\Engineering;
+use PhpOffice\PhpSpreadsheet\Calculation\Exception as CalcExp;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
+use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PHPUnit\Framework\TestCase;
class Oct2HexTest extends TestCase
{
+ /**
+ * @var string
+ */
+ private $compatibilityMode;
+
protected function setUp(): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->compatibilityMode = Functions::getCompatibilityMode();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
}
/**
* @dataProvider providerOCT2HEX
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testOCT2HEX($expectedResult, ...$args): void
+ public function testOCT2HEX($expectedResult, $formula): void
{
- $result = Engineering::OCTTOHEX(...$args);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=OCT2HEX($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerOCT2HEX()
+ public function providerOCT2HEX(): array
{
return require 'tests/data/Calculation/Engineering/OCT2HEX.php';
}
+
+ /**
+ * @dataProvider providerOCT2HEX
+ *
+ * @param mixed $expectedResult
+ * @param mixed $formula
+ */
+ public function testOCT2HEXOds($expectedResult, $formula): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcExp::class);
+ }
+ if ($formula === 'true') {
+ $expectedResult = 1;
+ } elseif ($formula === 'false') {
+ $expectedResult = 0;
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->setCellValue('A2', 101);
+ $sheet->getCell('A1')->setValue("=OCT2HEX($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function testOCT2HEXFrac(): void
+ {
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ $cell = 'G1';
+ $sheet->setCellValue($cell, '=OCT2HEX(20.1)');
+ self::assertEquals(10, $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ $cell = 'O1';
+ $sheet->setCellValue($cell, '=OCT2HEX(20.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $cell = 'E1';
+ $sheet->setCellValue($cell, '=OCT2HEX(20.1)');
+ self::assertEquals('#NUM!', $sheet->getCell($cell)->getCalculatedValue());
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintMTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintMTest.php
index 597db5c2..fbc7a61c 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintMTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintMTest.php
@@ -21,10 +21,10 @@ class AccrintMTest extends TestCase
public function testACCRINTM($expectedResult, ...$args): void
{
$result = Financial::ACCRINTM(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerACCRINTM()
+ public function providerACCRINTM(): array
{
return require 'tests/data/Calculation/Financial/ACCRINTM.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintTest.php
index edb79230..74444061 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AccrintTest.php
@@ -21,10 +21,10 @@ class AccrintTest extends TestCase
public function testACCRINT($expectedResult, ...$args): void
{
$result = Financial::ACCRINT(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerACCRINT()
+ public function providerACCRINT(): array
{
return require 'tests/data/Calculation/Financial/ACCRINT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorDegRcTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorDegRcTest.php
new file mode 100644
index 00000000..6f69e7fb
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/AmorDegRcTest.php
@@ -0,0 +1,31 @@
+ 0.999999 && $frac < 1.000001) {
+ $result = $expectedResult;
+ }
+ }
+ }
+ self::assertEquals($expectedResult, $result, $message);
+ }
+
+ public function providerXNPV(): array
+ {
+ return require 'tests/data/Calculation/Financial/XNPV.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/XirrTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/XirrTest.php
new file mode 100644
index 00000000..a6677f3f
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/XirrTest.php
@@ -0,0 +1,40 @@
+ 0.999999 && $frac < 1.000001) {
+ $result = $expectedResult;
+ }
+ }
+ }
+ self::assertEquals($expectedResult, $result, $message);
+ }
+
+ public function providerXIRR(): array
+ {
+ return require 'tests/data/Calculation/Financial/XIRR.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/YieldDiscTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/YieldDiscTest.php
new file mode 100644
index 00000000..1c966d87
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Financial/YieldDiscTest.php
@@ -0,0 +1,31 @@
+getMockBuilder(Cell::class)
+ ->onlyMethods(['getColumn'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cell->method('getColumn')
+ ->willReturn('D');
+
+ $result = LookupRef::COLUMN(null, $cell);
+ self::assertSame(4, $result);
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php
index a7908241..e14023cd 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/ColumnsTest.php
@@ -24,7 +24,7 @@ class ColumnsTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerCOLUMNS()
+ public function providerCOLUMNS(): array
{
return require 'tests/data/Calculation/LookupRef/COLUMNS.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php
index 767b6de8..7484c47b 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/HLookupTest.php
@@ -24,7 +24,7 @@ class HLookupTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerHLOOKUP()
+ public function providerHLOOKUP(): array
{
return require 'tests/data/Calculation/LookupRef/HLOOKUP.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php
index 8ff66931..4de661ed 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndexTest.php
@@ -21,10 +21,11 @@ class IndexTest extends TestCase
public function testINDEX($expectedResult, ...$args): void
{
$result = LookupRef::INDEX(...$args);
+// var_dump($result);
self::assertEquals($expectedResult, $result);
}
- public function providerINDEX()
+ public function providerINDEX(): array
{
return require 'tests/data/Calculation/LookupRef/INDEX.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndirectTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndirectTest.php
new file mode 100644
index 00000000..b11fce68
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/IndirectTest.php
@@ -0,0 +1,55 @@
+getMockBuilder(Calculation::class)
+// ->setMethods(['getInstance', 'extractCellRange'])
+// ->disableOriginalConstructor()
+// ->getMock();
+// $calculation->method('getInstance')
+// ->willReturn($calculation);
+// $calculation->method('extractCellRange')
+// ->willReturn([]);
+//
+// $worksheet = $this->getMockBuilder(Cell::class)
+// ->setMethods(['getParent'])
+// ->disableOriginalConstructor()
+// ->getMock();
+//
+// $cell = $this->getMockBuilder(Cell::class)
+// ->setMethods(['getWorksheet'])
+// ->disableOriginalConstructor()
+// ->getMock();
+// $cell->method('getWorksheet')
+// ->willReturn($worksheet);
+
+ $result = LookupRef::INDIRECT($cellReference);
+ self::assertSame($expectedResult, $result);
+ }
+
+ public function providerINDIRECT(): array
+ {
+ return require 'tests/data/Calculation/LookupRef/INDIRECT.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php
index d1b36e4a..73dffd3d 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/LookupTest.php
@@ -24,7 +24,7 @@ class LookupTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerLOOKUP()
+ public function providerLOOKUP(): array
{
return require 'tests/data/Calculation/LookupRef/LOOKUP.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php
index e020d3ba..ba2dce29 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/MatchTest.php
@@ -24,7 +24,7 @@ class MatchTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerMATCH()
+ public function providerMATCH(): array
{
return require 'tests/data/Calculation/LookupRef/MATCH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/OffsetTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/OffsetTest.php
new file mode 100644
index 00000000..31a9703a
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/OffsetTest.php
@@ -0,0 +1,32 @@
+getMockBuilder(Cell::class)
+ ->onlyMethods(['getRow'])
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cell->method('getRow')
+ ->willReturn(3);
+
+ $result = LookupRef::ROW(null, $cell);
+ self::assertSame(3, $result);
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php
index 62a06626..ec9b33d9 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/RowsTest.php
@@ -24,7 +24,7 @@ class RowsTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerROWS()
+ public function providerROWS(): array
{
return require 'tests/data/Calculation/LookupRef/ROWS.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/TransposeTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/TransposeTest.php
new file mode 100644
index 00000000..7654f1bd
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/LookupRef/TransposeTest.php
@@ -0,0 +1,32 @@
+sheet;
+ $this->mightHaveException($expectedResult);
+ $this->setCell('A1', $number);
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=ABS()');
+ } else {
+ $sheet->getCell('B1')->setValue('=ABS(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertSame($expectedResult, $result);
+ }
+
+ public function providerAbs(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/ABS.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php
new file mode 100644
index 00000000..c6372ddb
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcosTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A2')->setValue(0.5);
+ $sheet->getCell('A1')->setValue("=ACOS($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerAcos(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/ACOS.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php
new file mode 100644
index 00000000..557da135
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcoshTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A2')->setValue('1.5');
+ $sheet->getCell('A1')->setValue("=ACOSH($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerAcosh(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/ACOSH.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php
index d81c3b9d..d94d4dec 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcotTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class AcotTest extends TestCase
+class AcotTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerACOT
*
@@ -21,11 +12,18 @@ class AcotTest extends TestCase
*/
public function testACOT($expectedResult, $number): void
{
- $result = MathTrig::ACOT($number);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5);
+ $sheet->getCell('A1')->setValue("=ACOT($number)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerACOT()
+ public function providerACOT(): array
{
return require 'tests/data/Calculation/MathTrig/ACOT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php
index 0a3864cc..a065b496 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AcothTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class AcothTest extends TestCase
+class AcothTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerACOTH
*
@@ -21,11 +12,18 @@ class AcothTest extends TestCase
*/
public function testACOTH($expectedResult, $number): void
{
- $result = MathTrig::ACOTH($number);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -10);
+ $sheet->getCell('A1')->setValue("=ACOTH($number)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerACOTH()
+ public function providerACOTH(): array
{
return require 'tests/data/Calculation/MathTrig/ACOTH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AllSetupTeardown.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AllSetupTeardown.php
new file mode 100644
index 00000000..a8630727
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AllSetupTeardown.php
@@ -0,0 +1,75 @@
+compatibilityMode = Functions::getCompatibilityMode();
+ $this->spreadsheet = new Spreadsheet();
+ $this->sheet = $this->spreadsheet->getActiveSheet();
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
+ $this->spreadsheet->disconnectWorksheets();
+ }
+
+ protected static function setOpenOffice(): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE);
+ }
+
+ protected static function setGnumeric(): void
+ {
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_GNUMERIC);
+ }
+
+ /**
+ * @param mixed $expectedResult
+ */
+ protected function mightHaveException($expectedResult): void
+ {
+ if ($expectedResult === 'exception') {
+ $this->expectException(CalcException::class);
+ }
+ }
+
+ /**
+ * @param mixed $value
+ */
+ protected function setCell(string $cell, $value): void
+ {
+ if ($value !== null) {
+ if (is_string($value) && is_numeric($value)) {
+ $this->sheet->getCell($cell)->setValueExplicit($value, DataType::TYPE_STRING);
+ } else {
+ $this->sheet->getCell($cell)->setValue($value);
+ }
+ }
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php
index 7b3a5e15..c9dbbcce 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ArabicTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class ArabicTest extends TestCase
+class ArabicTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerARABIC
*
@@ -21,11 +12,15 @@ class ArabicTest extends TestCase
*/
public function testARABIC($expectedResult, $romanNumeral): void
{
- $result = MathTrig::ARABIC($romanNumeral);
- self::assertEquals($expectedResult, $result);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue($romanNumeral);
+ $sheet->getCell('B1')->setValue('=ARABIC(A1)');
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertSame($expectedResult, $result);
}
- public function providerARABIC()
+ public function providerARABIC(): array
{
return require 'tests/data/Calculation/MathTrig/ARABIC.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php
new file mode 100644
index 00000000..b3612d01
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A2')->setValue(0.5);
+ $sheet->getCell('A1')->setValue("=ASIN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerAsin(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/ASIN.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php
new file mode 100644
index 00000000..e8f21142
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AsinhTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A2')->setValue(0.5);
+ $sheet->getCell('A1')->setValue("=ASINH($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerAsinh(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/ASINH.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php
index 4edec4cb..a22d6ad3 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Atan2Test.php
@@ -2,31 +2,25 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class Atan2Test extends TestCase
+class Atan2Test extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerATAN2
*
* @param mixed $expectedResult
- * @param mixed $x
- * @param mixed $y
*/
- public function testATAN2($expectedResult, $x, $y): void
+ public function testATAN2($expectedResult, string $formula): void
{
- $result = MathTrig::ATAN2($x, $y);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A2')->setValue(5);
+ $sheet->getCell('A3')->setValue(6);
+ $sheet->getCell('A1')->setValue("=ATAN2($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerATAN2()
+ public function providerATAN2(): array
{
return require 'tests/data/Calculation/MathTrig/ATAN2.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php
new file mode 100644
index 00000000..69f4ed53
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A2')->setValue(5);
+ $sheet->getCell('A1')->setValue("=ATAN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerAtan(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/ATAN.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php
new file mode 100644
index 00000000..20a3e9c0
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/AtanhTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A2')->setValue(0.8);
+ $sheet->getCell('A1')->setValue("=ATANH($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerAtanh(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/ATANH.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php
index 72b52559..8bf0f4b2 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/BaseTest.php
@@ -2,29 +2,43 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class BaseTest extends TestCase
+class BaseTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerBASE
*
* @param mixed $expectedResult
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @param mixed $arg3
*/
- public function testBASE($expectedResult, ...$args): void
+ public function testBASE($expectedResult, $arg1 = 'omitted', $arg2 = 'omitted', $arg3 = 'omitted'): void
{
- $result = MathTrig::BASE(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($arg1 !== null) {
+ $sheet->getCell('A1')->setValue($arg1);
+ }
+ if ($arg2 !== null) {
+ $sheet->getCell('A2')->setValue($arg2);
+ }
+ if ($arg3 !== null) {
+ $sheet->getCell('A3')->setValue($arg3);
+ }
+ if ($arg1 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=BASE()');
+ } elseif ($arg2 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=BASE(A1)');
+ } elseif ($arg3 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=BASE(A1, A2)');
+ } else {
+ $sheet->getCell('B1')->setValue('=BASE(A1, A2, A3)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerBASE()
+ public function providerBASE(): array
{
return require 'tests/data/Calculation/MathTrig/BASE.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingMathTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingMathTest.php
new file mode 100644
index 00000000..f4039458
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingMathTest.php
@@ -0,0 +1,30 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=CEILING.MATH($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ }
+
+ public function providerCEILINGMATH(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/CEILINGMATH.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingPreciseTest.php
new file mode 100644
index 00000000..c859646b
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingPreciseTest.php
@@ -0,0 +1,30 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=CEILING.PRECISE($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ }
+
+ public function providerFLOORPRECISE(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/CEILINGPRECISE.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php
index b60d7c30..d65ac6e9 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CeilingTest.php
@@ -2,30 +2,56 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class CeilingTest extends TestCase
+class CeilingTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerCEILING
*
* @param mixed $expectedResult
+ * @param string $formula
*/
- public function testCEILING($expectedResult, ...$args): void
+ public function testCEILING($expectedResult, $formula): void
{
- $result = MathTrig::CEILING(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=CEILING($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerCEILING()
+ public function providerCEILING(): array
{
return require 'tests/data/Calculation/MathTrig/CEILING.php';
}
+
+ public function testCEILINGGnumeric1Arg(): void
+ {
+ self::setGnumeric();
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue('=CEILING(5.1)');
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta(6, $result, 1E-12);
+ }
+
+ public function testCELINGOpenOffice1Arg(): void
+ {
+ self::setOpenOffice();
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue('=CEILING(5.1)');
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta(6, $result, 1E-12);
+ }
+
+ public function testCEILINGExcel1Arg(): void
+ {
+ $this->mightHaveException('exception');
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue('=CEILING(5.1)');
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta(6, $result, 1E-12);
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php
new file mode 100644
index 00000000..45ad8b29
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinATest.php
@@ -0,0 +1,33 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($numObjs !== null) {
+ $sheet->getCell('A1')->setValue($numObjs);
+ }
+ if ($numInSet !== null) {
+ $sheet->getCell('A2')->setValue($numInSet);
+ }
+ $sheet->getCell('B1')->setValue('=COMBINA(A1,A2)');
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function providerCOMBINA(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/COMBINA.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php
index d9156339..408b60fe 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CombinTest.php
@@ -2,29 +2,31 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class CombinTest extends TestCase
+class CombinTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerCOMBIN
*
* @param mixed $expectedResult
+ * @param mixed $numObjs
+ * @param mixed $numInSet
*/
- public function testCOMBIN($expectedResult, ...$args): void
+ public function testCOMBIN($expectedResult, $numObjs, $numInSet): void
{
- $result = MathTrig::COMBIN(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($numObjs !== null) {
+ $sheet->getCell('A1')->setValue($numObjs);
+ }
+ if ($numInSet !== null) {
+ $sheet->getCell('A2')->setValue($numInSet);
+ }
+ $sheet->getCell('B1')->setValue('=COMBIN(A1,A2)');
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
}
- public function providerCOMBIN()
+ public function providerCOMBIN(): array
{
return require 'tests/data/Calculation/MathTrig/COMBIN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php
new file mode 100644
index 00000000..5bb3427e
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CosTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 2);
+ $sheet->getCell('A1')->setValue("=COS($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerCos(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/COS.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php
new file mode 100644
index 00000000..c408338f
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CoshTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 2);
+ $sheet->getCell('A1')->setValue("=COSH($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerCosh(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/COSH.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php
index 3fee6901..d096d0da 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CotTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class CotTest extends TestCase
+class CotTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerCOT
*
@@ -21,11 +12,18 @@ class CotTest extends TestCase
*/
public function testCOT($expectedResult, $angle): void
{
- $result = MathTrig::COT($angle);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=COT($angle)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerCOT()
+ public function providerCOT(): array
{
return require 'tests/data/Calculation/MathTrig/COT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php
index e3db23d5..11949c43 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CothTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class CothTest extends TestCase
+class CothTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerCOTH
*
@@ -21,11 +12,18 @@ class CothTest extends TestCase
*/
public function testCOTH($expectedResult, $angle): void
{
- $result = MathTrig::COTH($angle);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=COTH($angle)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerCOTH()
+ public function providerCOTH(): array
{
return require 'tests/data/Calculation/MathTrig/COTH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php
index 675ebf57..ea5a74bf 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CscTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class CscTest extends TestCase
+class CscTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerCSC
*
@@ -21,11 +12,18 @@ class CscTest extends TestCase
*/
public function testCSC($expectedResult, $angle): void
{
- $result = MathTrig::CSC($angle);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=CSC($angle)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerCSC()
+ public function providerCSC(): array
{
return require 'tests/data/Calculation/MathTrig/CSC.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php
index c630be2f..071f7497 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/CschTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class CschTest extends TestCase
+class CschTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerCSCH
*
@@ -21,11 +12,18 @@ class CschTest extends TestCase
*/
public function testCSCH($expectedResult, $angle): void
{
- $result = MathTrig::CSCH($angle);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=CSCH($angle)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerCSCH()
+ public function providerCSCH(): array
{
return require 'tests/data/Calculation/MathTrig/CSCH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php
new file mode 100644
index 00000000..10eb3b10
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/DegreesTest.php
@@ -0,0 +1,31 @@
+sheet;
+ $this->mightHaveException($expectedResult);
+ $this->setCell('A1', $number);
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=DEGREES()');
+ } else {
+ $sheet->getCell('B1')->setValue('=DEGREES(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
+ }
+
+ public function providerDegrees(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/DEGREES.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php
index 96c0b046..12bca051 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/EvenTest.php
@@ -2,30 +2,24 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class EvenTest extends TestCase
+class EvenTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerEVEN
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $value
*/
public function testEVEN($expectedResult, $value): void
{
- $result = MathTrig::EVEN($value);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=EVEN($value)");
+ $sheet->getCell('A2')->setValue(3.7);
+ self::assertEquals($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerEVEN()
+ public function providerEVEN(): array
{
return require 'tests/data/Calculation/MathTrig/EVEN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php
new file mode 100644
index 00000000..70e7c650
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ExpTest.php
@@ -0,0 +1,33 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($number !== null) {
+ $sheet->getCell('A1')->setValue($number);
+ }
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=EXP()');
+ } else {
+ $sheet->getCell('B1')->setValue('=EXP(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ }
+
+ public function providerEXP(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/EXP.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php
index f0b6b146..70f06f11 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactDoubleTest.php
@@ -2,30 +2,25 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class FactDoubleTest extends TestCase
+class FactDoubleTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerFACTDOUBLE
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $value
*/
public function testFACTDOUBLE($expectedResult, $value): void
{
- $result = MathTrig::FACTDOUBLE($value);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue($value);
+ $sheet->getCell('B1')->setValue('=FACTDOUBLE(A1)');
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
}
- public function providerFACTDOUBLE()
+ public function providerFACTDOUBLE(): array
{
return require 'tests/data/Calculation/MathTrig/FACTDOUBLE.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php
index f6092896..379b382c 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FactTest.php
@@ -2,31 +2,60 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class FactTest extends TestCase
+class FactTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerFACT
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $arg1
*/
- public function testFACT($expectedResult, $value): void
+ public function testFACT($expectedResult, $arg1): void
{
- $result = MathTrig::FACT($value);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($arg1 !== null) {
+ $sheet->getCell('A1')->setValue($arg1);
+ }
+ if ($arg1 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=FACT()');
+ } else {
+ $sheet->getCell('B1')->setValue('=FACT(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
}
- public function providerFACT()
+ public function providerFACT(): array
{
return require 'tests/data/Calculation/MathTrig/FACT.php';
}
+
+ /**
+ * @dataProvider providerFACTGnumeric
+ *
+ * @param mixed $expectedResult
+ * @param mixed $arg1
+ */
+ public function testFACTGnumeric($expectedResult, $arg1): void
+ {
+ $this->mightHaveException($expectedResult);
+ self::setGnumeric();
+ $sheet = $this->sheet;
+ if ($arg1 !== null) {
+ $sheet->getCell('A1')->setValue($arg1);
+ }
+ if ($arg1 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=FACT()');
+ } else {
+ $sheet->getCell('B1')->setValue('=FACT(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function providerFACTGnumeric(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/FACTGNUMERIC.php';
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorMathTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorMathTest.php
index d7d51b59..ecf4c73a 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorMathTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorMathTest.php
@@ -2,29 +2,28 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class FloorMathTest extends TestCase
+class FloorMathTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerFLOORMATH
*
* @param mixed $expectedResult
+ * @param string $formula
*/
- public function testFLOORMATH($expectedResult, ...$args): void
+ public function testFLOORMATH($expectedResult, $formula): void
{
- $result = MathTrig::FLOORMATH(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=FLOOR.MATH($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerFLOORMATH()
+ public function providerFLOORMATH(): array
{
return require 'tests/data/Calculation/MathTrig/FLOORMATH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorPreciseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorPreciseTest.php
index ae5a3199..22dd72ad 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorPreciseTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorPreciseTest.php
@@ -2,29 +2,28 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class FloorPreciseTest extends TestCase
+class FloorPreciseTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerFLOORPRECISE
*
* @param mixed $expectedResult
+ * @param string $formula
*/
- public function testFLOOR($expectedResult, ...$args): void
+ public function testFLOORPRECISE($expectedResult, $formula): void
{
- $result = MathTrig::FLOORPRECISE(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=FLOOR.PRECISE($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerFLOORPRECISE()
+ public function providerFLOORPRECISE(): array
{
return require 'tests/data/Calculation/MathTrig/FLOORPRECISE.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php
index e66d97ae..b981b26a 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/FloorTest.php
@@ -2,30 +2,56 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class FloorTest extends TestCase
+class FloorTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerFLOOR
*
* @param mixed $expectedResult
+ * @param string $formula
*/
- public function testFLOOR($expectedResult, ...$args): void
+ public function testFLOOR($expectedResult, $formula): void
{
- $result = MathTrig::FLOOR(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=FLOOR($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerFLOOR()
+ public function providerFLOOR(): array
{
return require 'tests/data/Calculation/MathTrig/FLOOR.php';
}
+
+ public function testFLOORGnumeric1Arg(): void
+ {
+ self::setGnumeric();
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue('=FLOOR(5.1)');
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta(5, $result, 1E-12);
+ }
+
+ public function testFLOOROpenOffice1Arg(): void
+ {
+ self::setOpenOffice();
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue('=FLOOR(5.1)');
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta(5, $result, 1E-12);
+ }
+
+ public function testFLOORExcel1Arg(): void
+ {
+ $this->mightHaveException('exception');
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue('=FLOOR(5.1)');
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta(5, $result, 1E-12);
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/GcdTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/GcdTest.php
index ce1aec3f..aaa641d7 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/GcdTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/GcdTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class GcdTest extends TestCase
+class GcdTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerGCD
*
@@ -20,11 +11,25 @@ class GcdTest extends TestCase
*/
public function testGCD($expectedResult, ...$args): void
{
- $result = MathTrig::GCD(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $row = 0;
+ foreach ($args as $arg) {
+ ++$row;
+ if ($arg !== null) {
+ $sheet->getCell("A$row")->setValue($arg);
+ }
+ }
+ if ($row < 1) {
+ $sheet->getCell('B1')->setValue('=GCD()');
+ } else {
+ $sheet->getCell('B1')->setValue("=GCD(A1:A$row)");
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerGCD()
+ public function providerGCD(): array
{
return require 'tests/data/Calculation/MathTrig/GCD.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php
index f400a7fe..29abbf41 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/IntTest.php
@@ -2,30 +2,28 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class IntTest extends TestCase
+class IntTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerINT
*
* @param mixed $expectedResult
- * @param $value
+ * @param string $formula
*/
- public function testINT($expectedResult, $value): void
+ public function testINT($expectedResult, $formula): void
{
- $result = MathTrig::INT($value);
- self::assertEquals($expectedResult, $result);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=INT($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerINT()
+ public function providerINT(): array
{
return require 'tests/data/Calculation/MathTrig/INT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LcmTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LcmTest.php
index 57b4a67f..5d0ebb58 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LcmTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LcmTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class LcmTest extends TestCase
+class LcmTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerLCM
*
@@ -20,11 +11,18 @@ class LcmTest extends TestCase
*/
public function testLCM($expectedResult, ...$args): void
{
- $result = MathTrig::LCM(...$args);
+ $sheet = $this->sheet;
+ $row = 0;
+ foreach ($args as $arg) {
+ ++$row;
+ $sheet->getCell("A$row")->setValue($arg);
+ }
+ $sheet->getCell('B1')->setValue("=LCM(A1:A$row)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerLCM()
+ public function providerLCM(): array
{
return require 'tests/data/Calculation/MathTrig/LCM.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LnTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LnTest.php
new file mode 100644
index 00000000..3fe35a3c
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LnTest.php
@@ -0,0 +1,33 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($number !== null) {
+ $sheet->getCell('A1')->setValue($number);
+ }
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=LN()');
+ } else {
+ $sheet->getCell('B1')->setValue('=LN(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerLN(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/LN.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Log10Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Log10Test.php
new file mode 100644
index 00000000..61cade1d
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/Log10Test.php
@@ -0,0 +1,33 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($number !== null) {
+ $sheet->getCell('A1')->setValue($number);
+ }
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=LOG10()');
+ } else {
+ $sheet->getCell('B1')->setValue('=LOG10(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerLN(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/LOG10.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LogTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LogTest.php
index 184d83e6..8c45a840 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LogTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/LogTest.php
@@ -2,29 +2,37 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class LogTest extends TestCase
+class LogTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerLOG
*
* @param mixed $expectedResult
+ * @param mixed $number
+ * @param mixed $base
*/
- public function testLOG($expectedResult, ...$args): void
+ public function testLOG($expectedResult, $number = 'omitted', $base = 'omitted'): void
{
- $result = MathTrig::logBase(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($number !== null) {
+ $sheet->getCell('A1')->setValue($number);
+ }
+ if ($base !== null) {
+ $sheet->getCell('A2')->setValue($base);
+ }
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=LOG()');
+ } elseif ($base === 'omitted') {
+ $sheet->getCell('B1')->setValue('=LOG(A1)');
+ } else {
+ $sheet->getCell('B1')->setValue('=LOG(A1,A2)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerLOG()
+ public function providerLOG(): array
{
return require 'tests/data/Calculation/MathTrig/LOG.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MInverseTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MInverseTest.php
index a500c3f6..b629d466 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MInverseTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MInverseTest.php
@@ -2,30 +2,31 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-class MInverseTest extends TestCase
+class MInverseTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerMINVERSE
*
* @param mixed $expectedResult
*/
- public function testMINVERSE($expectedResult, ...$args): void
+ public function testMINVERSE($expectedResult, array $args): void
{
- $result = MathTrig::MINVERSE(...$args);
+ $result = MathTrig\MatrixFunctions::inverse($args);
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerMINVERSE()
+ public function providerMINVERSE(): array
{
return require 'tests/data/Calculation/MathTrig/MINVERSE.php';
}
+
+ public function testOnSpreadsheet(): void
+ {
+ // very limited ability to test this in the absence of dynamic arrays
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue('=MINVERSE({1,2,3})'); // not square
+ self::assertSame('#VALUE!', $sheet->getCell('A1')->getCalculatedValue());
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MMultTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MMultTest.php
index 66fa80db..e27922c2 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MMultTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MMultTest.php
@@ -2,17 +2,10 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-class MMultTest extends TestCase
+class MMultTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerMMULT
*
@@ -20,12 +13,31 @@ class MMultTest extends TestCase
*/
public function testMMULT($expectedResult, ...$args): void
{
- $result = MathTrig::MMULT(...$args);
+ $result = MathTrig\MatrixFunctions::multiply(...$args);
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerMMULT()
+ public function providerMMULT(): array
{
return require 'tests/data/Calculation/MathTrig/MMULT.php';
}
+
+ public function testOnSpreadsheet(): void
+ {
+ // very limited ability to test this in the absence of dynamic arrays
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue('=MMULT({1,2,3}, {1,2,3})'); // incompatible dimensions
+ self::assertSame('#VALUE!', $sheet->getCell('A1')->getCalculatedValue());
+
+ $sheet->getCell('A11')->setValue('=MMULT({1, 2, 3, 4}, {5; 6; 7; 8})');
+ self::assertEquals(70, $sheet->getCell('A11')->getCalculatedValue());
+ $sheet->getCell('A2')->setValue(1);
+ $sheet->getCell('B2')->setValue(2);
+ $sheet->getCell('C2')->setValue(3);
+ $sheet->getCell('D2')->setValue(4);
+ $sheet->getCell('D3')->setValue(5);
+ $sheet->getCell('D4')->setValue(6);
+ $sheet->getCell('A12')->setValue('=MMULT(A2:C2,D2:D4)');
+ self::assertEquals(32, $sheet->getCell('A12')->getCalculatedValue());
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php
index 32c9c355..e7aa0f41 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MRoundTest.php
@@ -2,29 +2,28 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class MRoundTest extends TestCase
+class MRoundTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerMROUND
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testMROUND($expectedResult, ...$args): void
+ public function testMROUND($expectedResult, $formula): void
{
- $result = MathTrig::MROUND(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=MROUND($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerMROUND()
+ public function providerMROUND(): array
{
return require 'tests/data/Calculation/MathTrig/MROUND.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MUnitTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MUnitTest.php
new file mode 100644
index 00000000..1035dac7
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MUnitTest.php
@@ -0,0 +1,23 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if (is_array($matrix)) {
+ $sheet->fromArray($matrix, null, 'A1', true);
+ $maxCol = $sheet->getHighestColumn();
+ $maxRow = $sheet->getHighestRow();
+ $sheet->getCell('Z1')->setValue("=MDETERM(A1:$maxCol$maxRow)");
+ } else {
+ $sheet->getCell('Z1')->setValue("=MDETERM($matrix)");
+ }
+ $result = $sheet->getCell('Z1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerMDETERM()
+ public function providerMDETERM(): array
{
return require 'tests/data/Calculation/MathTrig/MDETERM.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php
index 930708f5..ff35657f 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ModTest.php
@@ -2,29 +2,37 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class ModTest extends TestCase
+class ModTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerMOD
*
* @param mixed $expectedResult
+ * @param mixed $dividend
+ * @param mixed $divisor
*/
- public function testMOD($expectedResult, ...$args): void
+ public function testMOD($expectedResult, $dividend = 'omitted', $divisor = 'omitted'): void
{
- $result = MathTrig::MOD(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($dividend !== null) {
+ $sheet->getCell('A1')->setValue($dividend);
+ }
+ if ($divisor !== null) {
+ $sheet->getCell('A2')->setValue($divisor);
+ }
+ if ($dividend === 'omitted') {
+ $sheet->getCell('B1')->setValue('=MOD()');
+ } elseif ($divisor === 'omitted') {
+ $sheet->getCell('B1')->setValue('=MOD(A1)');
+ } else {
+ $sheet->getCell('B1')->setValue('=MOD(A1,A2)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerMOD()
+ public function providerMOD(): array
{
return require 'tests/data/Calculation/MathTrig/MOD.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MovedFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MovedFunctionsTest.php
new file mode 100644
index 00000000..2cca8f36
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MovedFunctionsTest.php
@@ -0,0 +1,111 @@
+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/MathTrig/MultinomialTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MultinomialTest.php
index 93735ba9..3fea7651 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MultinomialTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/MultinomialTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class MultinomialTest extends TestCase
+class MultinomialTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerMULTINOMIAL
*
@@ -20,11 +11,23 @@ class MultinomialTest extends TestCase
*/
public function testMULTINOMIAL($expectedResult, ...$args): void
{
- $result = MathTrig::MULTINOMIAL(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $row = 0;
+ $excelArg = '';
+ foreach ($args as $arg) {
+ ++$row;
+ $excelArg = "A1:A$row";
+ if ($arg !== null) {
+ $sheet->getCell("A$row")->setValue($arg);
+ }
+ }
+ $sheet->getCell('B1')->setValue("=MULTINOMIAL($excelArg)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerMULTINOMIAL()
+ public function providerMULTINOMIAL(): array
{
return require 'tests/data/Calculation/MathTrig/MULTINOMIAL.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php
index 6c5758c6..37042743 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/OddTest.php
@@ -2,30 +2,24 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class OddTest extends TestCase
+class OddTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerODD
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $value
*/
public function testODD($expectedResult, $value): void
{
- $result = MathTrig::ODD($value);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->getCell('A1')->setValue("=ODD($value)");
+ $sheet->getCell('A2')->setValue(3.7);
+ self::assertEquals($expectedResult, $sheet->getCell('A1')->getCalculatedValue());
}
- public function providerODD()
+ public function providerODD(): array
{
return require 'tests/data/Calculation/MathTrig/ODD.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php
index 6749b14a..4d6ba7e2 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/PowerTest.php
@@ -2,29 +2,37 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class PowerTest extends TestCase
+class PowerTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerPOWER
*
* @param mixed $expectedResult
+ * @param mixed $base
+ * @param mixed $exponent
*/
- public function testPOWER($expectedResult, ...$args): void
+ public function testPOWER($expectedResult, $base = 'omitted', $exponent = 'omitted'): void
{
- $result = MathTrig::POWER(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($base !== null) {
+ $sheet->getCell('A1')->setValue($base);
+ }
+ if ($exponent !== null) {
+ $sheet->getCell('A2')->setValue($exponent);
+ }
+ if ($base === 'omitted') {
+ $sheet->getCell('B1')->setValue('=POWER()');
+ } elseif ($exponent === 'omitted') {
+ $sheet->getCell('B1')->setValue('=POWER(A1)');
+ } else {
+ $sheet->getCell('B1')->setValue('=POWER(A1,A2)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerPOWER()
+ public function providerPOWER(): array
{
return require 'tests/data/Calculation/MathTrig/POWER.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ProductTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ProductTest.php
index 251b783b..4e63ae91 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ProductTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/ProductTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class ProductTest extends TestCase
+class ProductTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerPRODUCT
*
@@ -20,11 +11,18 @@ class ProductTest extends TestCase
*/
public function testPRODUCT($expectedResult, ...$args): void
{
- $result = MathTrig::PRODUCT(...$args);
+ $sheet = $this->sheet;
+ $row = 0;
+ foreach ($args as $arg) {
+ ++$row;
+ $sheet->getCell("A$row")->setValue($arg);
+ }
+ $sheet->getCell('B1')->setValue("=PRODUCT(A1:A$row)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerPRODUCT()
+ public function providerPRODUCT(): array
{
return require 'tests/data/Calculation/MathTrig/PRODUCT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php
index 4232729a..c8cd13b7 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/QuotientTest.php
@@ -2,29 +2,37 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class QuotientTest extends TestCase
+class QuotientTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerQUOTIENT
*
* @param mixed $expectedResult
+ * @param mixed $arg1
+ * @param mixed $arg2
*/
- public function testQUOTIENT($expectedResult, ...$args): void
+ public function testQUOTIENT($expectedResult, $arg1 = 'omitted', $arg2 = 'omitted'): void
{
- $result = MathTrig::QUOTIENT(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($arg1 !== null) {
+ $sheet->getCell('A1')->setValue($arg1);
+ }
+ if ($arg2 !== null) {
+ $sheet->getCell('A2')->setValue($arg2);
+ }
+ if ($arg1 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=QUOTIENT()');
+ } elseif ($arg2 === 'omitted') {
+ $sheet->getCell('B1')->setValue('=QUOTIENT(A1)');
+ } else {
+ $sheet->getCell('B1')->setValue('=QUOTIENT(A1, A2)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertSame($expectedResult, $result);
}
- public function providerQUOTIENT()
+ public function providerQUOTIENT(): array
{
return require 'tests/data/Calculation/MathTrig/QUOTIENT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php
new file mode 100644
index 00000000..03cceaac
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RadiansTest.php
@@ -0,0 +1,31 @@
+sheet;
+ $this->mightHaveException($expectedResult);
+ $this->setCell('A1', $number);
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=RADIANS()');
+ } else {
+ $sheet->getCell('B1')->setValue('=RADIANS(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
+ }
+
+ public function providerRADIANS(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/RADIANS.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandBetweenTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandBetweenTest.php
new file mode 100644
index 00000000..2e1ba676
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandBetweenTest.php
@@ -0,0 +1,46 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $lower = (int) $min;
+ $upper = (int) $max;
+ if ($min !== null) {
+ $sheet->getCell('A1')->setValue($min);
+ }
+ if ($max !== null) {
+ $sheet->getCell('A2')->setValue($max);
+ }
+ if ($min === 'omitted') {
+ $sheet->getCell('B1')->setValue('=RANDBETWEEN()');
+ } elseif ($max === 'omitted') {
+ $sheet->getCell('B1')->setValue('=RANDBETWEEN(A1)');
+ } else {
+ $sheet->getCell('B1')->setValue('=RANDBETWEEN(A1,A2)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ if (is_numeric($expectedResult)) {
+ self::assertGreaterThanOrEqual($lower, $result);
+ self::assertLessThanOrEqual($upper, $result);
+ } else {
+ self::assertSame($expectedResult, $result);
+ }
+ }
+
+ public function providerRANDBETWEEN(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/RANDBETWEEN.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandTest.php
new file mode 100644
index 00000000..e5e2e107
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RandTest.php
@@ -0,0 +1,24 @@
+sheet;
+ $sheet->getCell('B1')->setValue('=RAND()');
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertGreaterThanOrEqual(0, $result);
+ self::assertLessThanOrEqual(1, $result);
+ }
+
+ public function testRandException(): void
+ {
+ $this->mightHaveException('exception');
+ $sheet = $this->sheet;
+ $sheet->getCell('B1')->setValue('=RAND(A1)');
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEquals(0, $result);
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php
index c74daa32..417656c0 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RomanTest.php
@@ -2,29 +2,25 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class RomanTest extends TestCase
+class RomanTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerROMAN
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testROMAN($expectedResult, ...$args): void
+ public function testROMAN($expectedResult, $formula): void
{
- $result = MathTrig::ROMAN(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A3', 49);
+ $sheet->getCell('A1')->setValue("=ROMAN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEquals($expectedResult, $result);
}
- public function providerROMAN()
+ public function providerROMAN(): array
{
return require 'tests/data/Calculation/MathTrig/ROMAN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php
index 2fc211f3..97058102 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundDownTest.php
@@ -2,29 +2,28 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class RoundDownTest extends TestCase
+class RoundDownTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
- * @dataProvider providerROUNDDOWN
+ * @dataProvider providerRoundDown
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testROUNDDOWN($expectedResult, ...$args): void
+ public function testRoundDown($expectedResult, $formula): void
{
- $result = MathTrig::ROUNDDOWN(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=ROUNDDOWN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerROUNDDOWN()
+ public function providerRoundDown(): array
{
return require 'tests/data/Calculation/MathTrig/ROUNDDOWN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php
new file mode 100644
index 00000000..960f4740
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundTest.php
@@ -0,0 +1,30 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=ROUND($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ }
+
+ public function providerRound(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/ROUND.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php
index 825fe419..f9ba44e0 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/RoundUpTest.php
@@ -2,29 +2,28 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class RoundUpTest extends TestCase
+class RoundUpTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
- * @dataProvider providerROUNDUP
+ * @dataProvider providerRoundUp
*
* @param mixed $expectedResult
+ * @param mixed $formula
*/
- public function testROUNDUP($expectedResult, ...$args): void
+ public function testRoundUp($expectedResult, $formula): void
{
- $result = MathTrig::ROUNDUP(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=ROUNDUP($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerROUNDUP()
+ public function providerRoundUp(): array
{
return require 'tests/data/Calculation/MathTrig/ROUNDUP.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php
index ad4b196c..ad52cee2 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SecTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class SecTest extends TestCase
+class SecTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSEC
*
@@ -21,11 +12,18 @@ class SecTest extends TestCase
*/
public function testSEC($expectedResult, $angle): void
{
- $result = MathTrig::SEC($angle);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=SEC($angle)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerSEC()
+ public function providerSEC(): array
{
return require 'tests/data/Calculation/MathTrig/SEC.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php
index b9488bda..7dabf291 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SechTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class SechTest extends TestCase
+class SechTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSECH
*
@@ -21,11 +12,18 @@ class SechTest extends TestCase
*/
public function testSECH($expectedResult, $angle): void
{
- $result = MathTrig::SECH($angle);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=SECH($angle)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-9);
}
- public function providerSECH()
+ public function providerSECH(): array
{
return require 'tests/data/Calculation/MathTrig/SECH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SeriesSumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SeriesSumTest.php
index 689336a3..9070f60b 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SeriesSumTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SeriesSumTest.php
@@ -3,28 +3,43 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-class SeriesSumTest extends TestCase
+class SeriesSumTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSERIESSUM
*
* @param mixed $expectedResult
+ * @param mixed $arg1
+ * @param mixed $arg2
+ * @param mixed $arg3
*/
- public function testSERIESSUM($expectedResult, ...$args): void
+ public function testSERIESSUM($expectedResult, $arg1, $arg2, $arg3, ...$args): void
{
- $result = MathTrig::SERIESSUM(...$args);
+ $sheet = $this->sheet;
+ if ($arg1 !== null) {
+ $sheet->getCell('C1')->setValue($arg1);
+ }
+ if ($arg2 !== null) {
+ $sheet->getCell('C2')->setValue($arg2);
+ }
+ if ($arg3 !== null) {
+ $sheet->getCell('C3')->setValue($arg3);
+ }
+ $row = 0;
+ $aArgs = Functions::flattenArray($args);
+ foreach ($aArgs as $arg) {
+ ++$row;
+ if ($arg !== null) {
+ $sheet->getCell("A$row")->setValue($arg);
+ }
+ }
+ $sheet->getCell('B1')->setValue("=SERIESSUM(C1, C2, C3, A1:A$row)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSERIESSUM()
+ public function providerSERIESSUM(): array
{
return require 'tests/data/Calculation/MathTrig/SERIESSUM.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php
index 68f5acb9..fd1a3e6c 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SignTest.php
@@ -2,30 +2,27 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class SignTest extends TestCase
+class SignTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSIGN
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $value
*/
public function testSIGN($expectedResult, $value): void
{
- $result = MathTrig::SIGN($value);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 0);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->getCell('A1')->setValue("=SIGN($value)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
}
- public function providerSIGN()
+ public function providerSIGN(): array
{
return require 'tests/data/Calculation/MathTrig/SIGN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php
new file mode 100644
index 00000000..c2d0afe5
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 2);
+ $sheet->getCell('A1')->setValue("=SIN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerSin(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/SIN.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php
new file mode 100644
index 00000000..bb680f08
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SinhTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 2);
+ $sheet->getCell('A1')->setValue("=SINH($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerCosh(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/SINH.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php
index bb4bba4b..1a879056 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtPiTest.php
@@ -2,30 +2,31 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class SqrtPiTest extends TestCase
+class SqrtPiTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSQRTPI
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $number
*/
- public function testSQRTPI($expectedResult, $value): void
+ public function testSQRTPI($expectedResult, $number): void
{
- $result = MathTrig::SQRTPI($value);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ if ($number !== null) {
+ $sheet->getCell('A1')->setValue($number);
+ }
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=SQRTPI()');
+ } else {
+ $sheet->getCell('B1')->setValue('=SQRTPI(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSQRTPI()
+ public function providerSQRTPI(): array
{
return require 'tests/data/Calculation/MathTrig/SQRTPI.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php
new file mode 100644
index 00000000..8ce557bd
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SqrtTest.php
@@ -0,0 +1,31 @@
+sheet;
+ $this->mightHaveException($expectedResult);
+ $this->setCell('A1', $number);
+ if ($number === 'omitted') {
+ $sheet->getCell('B1')->setValue('=SQRT()');
+ } else {
+ $sheet->getCell('B1')->setValue('=SQRT(A1)');
+ }
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerSqrt(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/SQRT.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SubTotalTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SubTotalTest.php
index 14865673..fde1d16e 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SubTotalTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SubTotalTest.php
@@ -2,197 +2,127 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PhpOffice\PhpSpreadsheet\Cell\Cell;
-use PhpOffice\PhpSpreadsheet\Worksheet\ColumnDimension;
-use PhpOffice\PhpSpreadsheet\Worksheet\RowDimension;
-use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
-use PHPUnit\Framework\TestCase;
-
-class SubTotalTest extends TestCase
+class SubTotalTest extends AllSetupTeardown
{
- protected function setUp(): void
+ /**
+ * @dataProvider providerSUBTOTAL
+ *
+ * @param mixed $expectedResult
+ * @param mixed $type expect an integer
+ */
+ public function testSubtotal($expectedResult, $type): void
{
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->fromArray([[0], [1], [1], [2], [3], [5], [8], [13], [21], [34], [55], [89]], null, 'A1', true);
+ $maxCol = $sheet->getHighestColumn();
+ $maxRow = $sheet->getHighestRow();
+ $sheet->getCell('D2')->setValue("=SUBTOTAL($type, A1:$maxCol$maxRow)");
+ $result = $sheet->getCell('D2')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ }
+
+ public function providerSUBTOTAL(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/SUBTOTAL.php';
}
/**
* @dataProvider providerSUBTOTAL
*
* @param mixed $expectedResult
+ * @param mixed $type expect an integer
*/
- public function testSUBTOTAL($expectedResult, ...$args): void
+ public function testSubtotalColumnHidden($expectedResult, $type): void
{
- $cell = $this->getMockBuilder(Cell::class)
- ->setMethods(['getValue', 'isFormula'])
- ->disableOriginalConstructor()
- ->getMock();
- $cell->method('getValue')
- ->willReturn(null);
- $cell->method('getValue')
- ->willReturn(false);
- $worksheet = $this->getMockBuilder(Worksheet::class)
- ->setMethods(['cellExists', 'getCell'])
- ->disableOriginalConstructor()
- ->getMock();
- $worksheet->method('cellExists')
- ->willReturn(true);
- $worksheet->method('getCell')
- ->willReturn($cell);
- $cellReference = $this->getMockBuilder(Cell::class)
- ->setMethods(['getWorksheet'])
- ->disableOriginalConstructor()
- ->getMock();
- $cellReference->method('getWorksheet')
- ->willReturn($worksheet);
-
- array_push($args, $cellReference);
- $result = MathTrig::SUBTOTAL(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
- }
-
- public function providerSUBTOTAL()
- {
- return require 'tests/data/Calculation/MathTrig/SUBTOTAL.php';
- }
-
- protected function rowVisibility()
- {
- $data = [1 => false, 2 => true, 3 => false, 4 => true, 5 => false, 6 => false, 7 => false, 8 => true, 9 => false, 10 => true, 11 => true];
- foreach ($data as $k => $v) {
- yield $k => $v;
+ // Hidden columns don't affect calculation, only hidden rows
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->fromArray([0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89], null, 'A1', true);
+ $maxCol = $sheet->getHighestColumn();
+ $maxRow = $sheet->getHighestRow();
+ $hiddenColumns = [
+ 'A' => false,
+ 'B' => true,
+ 'C' => false,
+ 'D' => true,
+ 'E' => false,
+ 'F' => false,
+ 'G' => false,
+ 'H' => true,
+ 'I' => false,
+ 'J' => true,
+ 'K' => true,
+ 'L' => false,
+ ];
+ foreach ($hiddenColumns as $col => $hidden) {
+ $sheet->getColumnDimension($col)->setVisible($hidden);
}
+ $sheet->getCell('D2')->setValue("=SUBTOTAL($type, A1:$maxCol$maxRow)");
+ $result = $sheet->getCell('D2')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
/**
- * @dataProvider providerHiddenSUBTOTAL
+ * @dataProvider providerSUBTOTALHIDDEN
*
* @param mixed $expectedResult
+ * @param mixed $type expect an integer
*/
- public function testHiddenSUBTOTAL($expectedResult, ...$args): void
+ public function testSubtotalRowHidden($expectedResult, $type): void
{
- $visibilityGenerator = $this->rowVisibility();
-
- $rowDimension = $this->getMockBuilder(RowDimension::class)
- ->setMethods(['getVisible'])
- ->disableOriginalConstructor()
- ->getMock();
- $rowDimension->method('getVisible')
- ->willReturnCallback(function () use ($visibilityGenerator) {
- $result = $visibilityGenerator->current();
- $visibilityGenerator->next();
-
- return $result;
- });
- $columnDimension = $this->getMockBuilder(ColumnDimension::class)
- ->setMethods(['getVisible'])
- ->disableOriginalConstructor()
- ->getMock();
- $columnDimension->method('getVisible')
- ->willReturn(true);
- $cell = $this->getMockBuilder(Cell::class)
- ->setMethods(['getValue', 'isFormula'])
- ->disableOriginalConstructor()
- ->getMock();
- $cell->method('getValue')
- ->willReturn('');
- $cell->method('getValue')
- ->willReturn(false);
- $worksheet = $this->getMockBuilder(Worksheet::class)
- ->setMethods(['cellExists', 'getCell', 'getRowDimension', 'getColumnDimension'])
- ->disableOriginalConstructor()
- ->getMock();
- $worksheet->method('cellExists')
- ->willReturn(true);
- $worksheet->method('getCell')
- ->willReturn($cell);
- $worksheet->method('getRowDimension')
- ->willReturn($rowDimension);
- $worksheet->method('getColumnDimension')
- ->willReturn($columnDimension);
- $cellReference = $this->getMockBuilder(Cell::class)
- ->setMethods(['getWorksheet'])
- ->disableOriginalConstructor()
- ->getMock();
- $cellReference->method('getWorksheet')
- ->willReturn($worksheet);
-
- array_push($args, $cellReference);
- $result = MathTrig::SUBTOTAL(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->fromArray([[0], [1], [1], [2], [3], [5], [8], [13], [21], [34], [55], [89]], null, 'A1', true);
+ $maxCol = $sheet->getHighestColumn();
+ $maxRow = $sheet->getHighestRow();
+ $visibleRows = [
+ '1' => false,
+ '2' => true,
+ '3' => false,
+ '4' => true,
+ '5' => false,
+ '6' => false,
+ '7' => false,
+ '8' => true,
+ '9' => false,
+ '10' => true,
+ '11' => true,
+ '12' => false,
+ ];
+ foreach ($visibleRows as $row => $visible) {
+ $sheet->getRowDimension($row)->setVisible($visible);
+ }
+ $sheet->getCell('D2')->setValue("=SUBTOTAL($type, A1:$maxCol$maxRow)");
+ $result = $sheet->getCell('D2')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerHiddenSUBTOTAL()
+ public function providerSUBTOTALHIDDEN(): array
{
return require 'tests/data/Calculation/MathTrig/SUBTOTALHIDDEN.php';
}
- protected function cellValues(array $cellValues)
+ public function testSubtotalNested(): void
{
- foreach ($cellValues as $k => $v) {
- yield $k => $v;
- }
- }
-
- protected function cellIsFormula(array $cellValues)
- {
- foreach ($cellValues as $cellValue) {
- yield is_string($cellValue) && $cellValue[0] === '=';
- }
- }
-
- /**
- * @dataProvider providerNestedSUBTOTAL
- *
- * @param mixed $expectedResult
- */
- public function testNestedSUBTOTAL($expectedResult, ...$args): void
- {
- $cellValueGenerator = $this->cellValues(Functions::flattenArray(array_slice($args, 1)));
- $cellIsFormulaGenerator = $this->cellIsFormula(Functions::flattenArray(array_slice($args, 1)));
-
- $cell = $this->getMockBuilder(Cell::class)
- ->setMethods(['getValue', 'isFormula'])
- ->disableOriginalConstructor()
- ->getMock();
- $cell->method('getValue')
- ->willReturnCallback(function () use ($cellValueGenerator) {
- $result = $cellValueGenerator->current();
- $cellValueGenerator->next();
-
- return $result;
- });
- $cell->method('isFormula')
- ->willReturnCallback(function () use ($cellIsFormulaGenerator) {
- $result = $cellIsFormulaGenerator->current();
- $cellIsFormulaGenerator->next();
-
- return $result;
- });
- $worksheet = $this->getMockBuilder(Worksheet::class)
- ->setMethods(['cellExists', 'getCell'])
- ->disableOriginalConstructor()
- ->getMock();
- $worksheet->method('cellExists')
- ->willReturn(true);
- $worksheet->method('getCell')
- ->willReturn($cell);
- $cellReference = $this->getMockBuilder(Cell::class)
- ->setMethods(['getWorksheet'])
- ->disableOriginalConstructor()
- ->getMock();
- $cellReference->method('getWorksheet')
- ->willReturn($worksheet);
-
- array_push($args, $cellReference);
-
- $result = MathTrig::SUBTOTAL(...$args);
- self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
- }
-
- public function providerNestedSUBTOTAL()
- {
- return require 'tests/data/Calculation/MathTrig/SUBTOTALNESTED.php';
+ $sheet = $this->sheet;
+ $sheet->fromArray(
+ [
+ [123],
+ [234],
+ ['=SUBTOTAL(1,A1:A2)'],
+ ['=ROMAN(SUBTOTAL(1, A1:A2))'],
+ ['This is text containing "=" and "SUBTOTAL("'],
+ ['=AGGREGATE(1, 0, A1:A2)'],
+ ['=SUM(2, 3)'],
+ ],
+ null,
+ 'A1',
+ true
+ );
+ $maxCol = $sheet->getHighestColumn();
+ $maxRow = $sheet->getHighestRow();
+ $sheet->getCell('H1')->setValue("=SUBTOTAL(9, A1:$maxCol$maxRow)");
+ self::assertEquals(362, $sheet->getCell('H1')->getCalculatedValue());
}
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfTest.php
index f7ff928f..ad560423 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfTest.php
@@ -2,29 +2,40 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class SumIfTest extends TestCase
+class SumIfTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSUMIF
*
* @param mixed $expectedResult
+ * @param mixed $condition
*/
- public function testSUMIF($expectedResult, ...$args): void
+ public function testSUMIF2($expectedResult, array $array1, $condition, ?array $array2 = null): void
{
- $result = MathTrig::SUMIF(...$args);
+ $this->mightHaveException($expectedResult);
+ if ($expectedResult === 'incomplete') {
+ self::markTestIncomplete('Raises formula error - researching solution');
+ }
+ $sheet = $this->sheet;
+ $sheet->fromArray($array1, null, 'A1', true);
+ $maxARow = count($array1);
+ $firstArg = "A1:A$maxARow";
+ //$secondArg = is_string($condition) ? "\"$condition\"" : $condition;
+ $sheet->getCell('B1')->setValue($condition);
+ $secondArg = 'B1';
+ if (empty($array2)) {
+ $sheet->getCell('D1')->setValue("=SUMIF($firstArg, $secondArg)");
+ } else {
+ $sheet->fromArray($array2, null, 'C1', true);
+ $maxCRow = count($array2);
+ $thirdArg = "C1:C$maxCRow";
+ $sheet->getCell('D1')->setValue("=SUMIF($firstArg, $secondArg, $thirdArg)");
+ }
+ $result = $sheet->getCell('D1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSUMIF()
+ public function providerSUMIF(): array
{
return require 'tests/data/Calculation/MathTrig/SUMIF.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfsTest.php
index b7be17c9..1ae6e231 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfsTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumIfsTest.php
@@ -2,17 +2,10 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
+use PhpOffice\PhpSpreadsheet\Calculation\Statistical;
-class SumIfsTest extends TestCase
+class SumIfsTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSUMIFS
*
@@ -20,11 +13,11 @@ class SumIfsTest extends TestCase
*/
public function testSUMIFS($expectedResult, ...$args): void
{
- $result = MathTrig::SUMIFS(...$args);
+ $result = Statistical\Conditional::SUMIFS(...$args);
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSUMIFS()
+ public function providerSUMIFS(): array
{
return require 'tests/data/Calculation/MathTrig/SUMIFS.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumProductTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumProductTest.php
index b34036e5..b2cdb379 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumProductTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumProductTest.php
@@ -3,16 +3,9 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-class SumProductTest extends TestCase
+class SumProductTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSUMPRODUCT
*
@@ -20,11 +13,28 @@ class SumProductTest extends TestCase
*/
public function testSUMPRODUCT($expectedResult, ...$args): void
{
- $result = MathTrig::SUMPRODUCT(...$args);
+ $sheet = $this->sheet;
+ $row = 0;
+ $arrayArg = '';
+ foreach ($args as $arr) {
+ $arr2 = Functions::flattenArray($arr);
+ $startRow = 0;
+ foreach ($arr2 as $arr3) {
+ ++$row;
+ if (!$startRow) {
+ $startRow = $row;
+ }
+ $sheet->getCell("A$row")->setValue($arr3);
+ }
+ $arrayArg .= "A$startRow:A$row,";
+ }
+ $arrayArg = substr($arrayArg, 0, -1); // strip trailing comma
+ $sheet->getCell('B1')->setValue("=SUMPRODUCT($arrayArg)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSUMPRODUCT()
+ public function providerSUMPRODUCT(): array
{
return require 'tests/data/Calculation/MathTrig/SUMPRODUCT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumSqTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumSqTest.php
index f1165e7b..162c578a 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumSqTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumSqTest.php
@@ -2,17 +2,8 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class SumSqTest extends TestCase
+class SumSqTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSUMSQ
*
@@ -20,11 +11,23 @@ class SumSqTest extends TestCase
*/
public function testSUMSQ($expectedResult, ...$args): void
{
- $result = MathTrig::SUMSQ(...$args);
+ $this->mightHaveException($expectedResult);
+ $maxRow = 0;
+ $funcArg = '';
+ $sheet = $this->sheet;
+ foreach ($args as $arg) {
+ ++$maxRow;
+ $funcArg = "A1:A$maxRow";
+ if ($arg !== null) {
+ $sheet->getCell("A$maxRow")->setValue($arg);
+ }
+ }
+ $sheet->getCell('B1')->setValue("=SUMSQ($funcArg)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSUMSQ()
+ public function providerSUMSQ(): array
{
return require 'tests/data/Calculation/MathTrig/SUMSQ.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumTest.php
new file mode 100644
index 00000000..a9ea7f29
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumTest.php
@@ -0,0 +1,29 @@
+sheet;
+ $row = 0;
+ foreach ($args as $arg) {
+ ++$row;
+ $sheet->getCell("A$row")->setValue($arg);
+ }
+ $sheet->getCell('B1')->setValue("=SUM(A1:A$row)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
+ }
+
+ public function providerSUM(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/SUM.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumX2MY2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumX2MY2Test.php
index 3bf2785b..427e5c85 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumX2MY2Test.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumX2MY2Test.php
@@ -3,28 +3,38 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-class SumX2MY2Test extends TestCase
+class SumX2MY2Test extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSUMX2MY2
*
* @param mixed $expectedResult
*/
- public function testSUMX2MY2($expectedResult, ...$args): void
+ public function testSUMX2MY2($expectedResult, array $matrixData1, array $matrixData2): void
{
- $result = MathTrig::SUMX2MY2(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $maxRow = 0;
+ $funcArg1 = '';
+ foreach (Functions::flattenArray($matrixData1) as $arg) {
+ ++$maxRow;
+ $funcArg1 = "A1:A$maxRow";
+ $this->setCell("A$maxRow", $arg);
+ }
+ $maxRow = 0;
+ $funcArg2 = '';
+ foreach (Functions::flattenArray($matrixData2) as $arg) {
+ ++$maxRow;
+ $funcArg2 = "C1:C$maxRow";
+ $this->setCell("C$maxRow", $arg);
+ }
+ $sheet->getCell('B1')->setValue("=SUMX2MY2($funcArg1, $funcArg2)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSUMX2MY2()
+ public function providerSUMX2MY2(): array
{
return require 'tests/data/Calculation/MathTrig/SUMX2MY2.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumX2PY2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumX2PY2Test.php
index a370d79b..100b8566 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumX2PY2Test.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumX2PY2Test.php
@@ -3,28 +3,38 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-class SumX2PY2Test extends TestCase
+class SumX2PY2Test extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSUMX2PY2
*
* @param mixed $expectedResult
*/
- public function testSUMX2PY2($expectedResult, ...$args): void
+ public function testSUMX2PY2($expectedResult, array $matrixData1, array $matrixData2): void
{
- $result = MathTrig::SUMX2PY2(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $maxRow = 0;
+ $funcArg1 = '';
+ foreach (Functions::flattenArray($matrixData1) as $arg) {
+ ++$maxRow;
+ $funcArg1 = "A1:A$maxRow";
+ $this->setCell("A$maxRow", $arg);
+ }
+ $maxRow = 0;
+ $funcArg2 = '';
+ foreach (Functions::flattenArray($matrixData2) as $arg) {
+ ++$maxRow;
+ $funcArg2 = "C1:C$maxRow";
+ $this->setCell("C$maxRow", $arg);
+ }
+ $sheet->getCell('B1')->setValue("=SUMX2PY2($funcArg1, $funcArg2)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSUMX2PY2()
+ public function providerSUMX2PY2(): array
{
return require 'tests/data/Calculation/MathTrig/SUMX2PY2.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumXMY2Test.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumXMY2Test.php
index 1f64523b..43acd4a0 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumXMY2Test.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/SumXMY2Test.php
@@ -3,28 +3,38 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-class SumXMY2Test extends TestCase
+class SumXMY2Test extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerSUMXMY2
*
* @param mixed $expectedResult
*/
- public function testSUMXMY2($expectedResult, ...$args): void
+ public function testSUMXMY2($expectedResult, array $matrixData1, array $matrixData2): void
{
- $result = MathTrig::SUMXMY2(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $maxRow = 0;
+ $funcArg1 = '';
+ foreach (Functions::flattenArray($matrixData1) as $arg) {
+ ++$maxRow;
+ $funcArg1 = "A1:A$maxRow";
+ $this->setCell("A$maxRow", $arg);
+ }
+ $maxRow = 0;
+ $funcArg2 = '';
+ foreach (Functions::flattenArray($matrixData2) as $arg) {
+ ++$maxRow;
+ $funcArg2 = "C1:C$maxRow";
+ $this->setCell("C$maxRow", $arg);
+ }
+ $sheet->getCell('B1')->setValue("=SUMXMY2($funcArg1, $funcArg2)");
+ $result = $sheet->getCell('B1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerSUMXMY2()
+ public function providerSUMXMY2(): array
{
return require 'tests/data/Calculation/MathTrig/SUMXMY2.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php
new file mode 100644
index 00000000..80dd7eff
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1);
+ $sheet->getCell('A1')->setValue("=TAN($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerTan(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/TAN.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php
new file mode 100644
index 00000000..9a55e9b4
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TanhTest.php
@@ -0,0 +1,26 @@
+mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1);
+ $sheet->getCell('A1')->setValue("=TANH($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEqualsWithDelta($expectedResult, $result, 1E-6);
+ }
+
+ public function providerTanh(): array
+ {
+ return require 'tests/data/Calculation/MathTrig/TANH.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TruncTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TruncTest.php
index 5fc248cc..7d7a4b55 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TruncTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/MathTrig/TruncTest.php
@@ -2,29 +2,28 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\MathTrig;
-use PhpOffice\PhpSpreadsheet\Calculation\Functions;
-use PhpOffice\PhpSpreadsheet\Calculation\MathTrig;
-use PHPUnit\Framework\TestCase;
-
-class TruncTest extends TestCase
+class TruncTest extends AllSetupTeardown
{
- protected function setUp(): void
- {
- Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
- }
-
/**
* @dataProvider providerTRUNC
*
* @param mixed $expectedResult
+ * @param string $formula
*/
- public function testTRUNC($expectedResult, ...$args): void
+ public function testTRUNC($expectedResult, $formula): void
{
- $result = MathTrig::TRUNC(...$args);
+ $this->mightHaveException($expectedResult);
+ $sheet = $this->sheet;
+ $sheet->setCellValue('A2', 1.3);
+ $sheet->setCellValue('A3', 2.7);
+ $sheet->setCellValue('A4', -3.8);
+ $sheet->setCellValue('A5', -5.2);
+ $sheet->getCell('A1')->setValue("=TRUNC($formula)");
+ $result = $sheet->getCell('A1')->getCalculatedValue();
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerTRUNC()
+ public function providerTRUNC(): array
{
return require 'tests/data/Calculation/MathTrig/TRUNC.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AveDevTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AveDevTest.php
index 571c06c3..ea3df6bb 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AveDevTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AveDevTest.php
@@ -24,7 +24,7 @@ class AveDevTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerAVEDEV()
+ public function providerAVEDEV(): array
{
return require 'tests/data/Calculation/Statistical/AVEDEV.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageATest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageATest.php
index 1af96dfc..fec65c28 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageATest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageATest.php
@@ -24,7 +24,7 @@ class AverageATest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerAVERAGEA()
+ public function providerAVERAGEA(): array
{
return require 'tests/data/Calculation/Statistical/AVERAGEA.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php
index 69dcfb87..c9648d43 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfTest.php
@@ -24,7 +24,7 @@ class AverageIfTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-12);
}
- public function providerAVERAGEIF()
+ public function providerAVERAGEIF(): array
{
return require 'tests/data/Calculation/Statistical/AVERAGEIF.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfsTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfsTest.php
new file mode 100644
index 00000000..de593764
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/Statistical/AverageIfsTest.php
@@ -0,0 +1,31 @@
+expectException(CalcExp::class);
+ $formula = '=REPT()';
+ } elseif ($rpt === null) {
+ $this->expectException(CalcExp::class);
+ $formula = "=REPT($val)";
+ } else {
+ if (is_bool($val)) {
+ $val = ($val) ? Calculation::getTRUE() : Calculation::getFALSE();
+ }
+ $formula = "=REPT($val, $rpt)";
+ }
+ $spreadsheet = new Spreadsheet();
+ $sheet = $spreadsheet->getActiveSheet();
+ $sheet->getCell('A1')->setValue($formula);
+ $result = $sheet->getCell('A1')->getCalculatedValue();
+ self::assertEquals($expectedResult, $result);
+ }
+
+ public function providerREPT(): array
+ {
+ return require 'tests/data/Calculation/TextData/REPT.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/RightTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/RightTest.php
index 50fc86dc..a2ab3a4c 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/RightTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/RightTest.php
@@ -3,10 +3,16 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
+use PhpOffice\PhpSpreadsheet\Settings;
use PHPUnit\Framework\TestCase;
class RightTest extends TestCase
{
+ protected function tearDown(): void
+ {
+ Settings::setLocale('en_US');
+ }
+
/**
* @dataProvider providerRIGHT
*
@@ -18,8 +24,44 @@ class RightTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerRIGHT()
+ public function providerRIGHT(): array
{
return require 'tests/data/Calculation/TextData/RIGHT.php';
}
+
+ /**
+ * @dataProvider providerLocaleRIGHT
+ *
+ * @param string $expectedResult
+ * @param mixed $value
+ * @param mixed $locale
+ * @param mixed $characters
+ */
+ public function testLowerWithLocaleBoolean($expectedResult, $locale, $value, $characters): void
+ {
+ $newLocale = Settings::setLocale($locale);
+ if ($newLocale === false) {
+ Settings::setLocale('en_US');
+ self::markTestSkipped('Unable to set locale for locale-specific test');
+ }
+
+ $result = TextData::RIGHT($value, $characters);
+ self::assertEquals($expectedResult, $result);
+
+ Settings::setLocale('en_US');
+ }
+
+ public function providerLocaleRIGHT(): array
+ {
+ return [
+ ['RAI', 'fr_FR', true, 3],
+ ['AAR', 'nl_NL', true, 3],
+ ['OSI', 'fi', true, 3],
+ ['ИНА', 'bg', true, 3],
+ ['UX', 'fr_FR', false, 2],
+ ['WAAR', 'nl_NL', false, 4],
+ ['ÄTOSI', 'fi', false, 5],
+ ['ЖЬ', 'bg', false, 2],
+ ];
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SearchTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SearchTest.php
index 7bb92e83..14f5735b 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SearchTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SearchTest.php
@@ -18,7 +18,7 @@ class SearchTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerSEARCH()
+ public function providerSEARCH(): array
{
return require 'tests/data/Calculation/TextData/SEARCH.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SubstituteTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SubstituteTest.php
index 2a9d1012..792e1a15 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SubstituteTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/SubstituteTest.php
@@ -18,7 +18,7 @@ class SubstituteTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerSUBSTITUTE()
+ public function providerSUBSTITUTE(): array
{
return require 'tests/data/Calculation/TextData/SUBSTITUTE.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TTest.php
index c7606c05..9ca47f91 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TTest.php
@@ -11,7 +11,7 @@ class TTest extends TestCase
* @dataProvider providerT
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $value
*/
public function testT($expectedResult, $value): void
{
@@ -19,7 +19,7 @@ class TTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerT()
+ public function providerT(): array
{
return require 'tests/data/Calculation/TextData/T.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextJoinTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextJoinTest.php
index e8fb404d..78e72f96 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextJoinTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextJoinTest.php
@@ -18,7 +18,7 @@ class TextJoinTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerTEXTJOIN()
+ public function providerTEXTJOIN(): array
{
return require 'tests/data/Calculation/TextData/TEXTJOIN.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextTest.php
index 8d7b238b..91418065 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TextTest.php
@@ -18,7 +18,7 @@ class TextTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerTEXT()
+ public function providerTEXT(): array
{
return require 'tests/data/Calculation/TextData/TEXT.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TrimTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TrimTest.php
index 91890ded..302dce4f 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TrimTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/TrimTest.php
@@ -11,7 +11,7 @@ class TrimTest extends TestCase
* @dataProvider providerTRIM
*
* @param mixed $expectedResult
- * @param $character
+ * @param mixed $character
*/
public function testTRIM($expectedResult, $character): void
{
@@ -19,7 +19,7 @@ class TrimTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerTRIM()
+ public function providerTRIM(): array
{
return require 'tests/data/Calculation/TextData/TRIM.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php
index 13fb0b86..45f7aea8 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/UpperTest.php
@@ -3,15 +3,21 @@
namespace PhpOffice\PhpSpreadsheetTests\Calculation\Functions\TextData;
use PhpOffice\PhpSpreadsheet\Calculation\TextData;
+use PhpOffice\PhpSpreadsheet\Settings;
use PHPUnit\Framework\TestCase;
class UpperTest extends TestCase
{
+ protected function tearDown(): void
+ {
+ Settings::setLocale('en_US');
+ }
+
/**
* @dataProvider providerUPPER
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $value
*/
public function testUPPER($expectedResult, $value): void
{
@@ -19,8 +25,43 @@ class UpperTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerUPPER()
+ public function providerUPPER(): array
{
return require 'tests/data/Calculation/TextData/UPPER.php';
}
+
+ /**
+ * @dataProvider providerLocaleLOWER
+ *
+ * @param string $expectedResult
+ * @param mixed $value
+ * @param mixed $locale
+ */
+ public function testLowerWithLocaleBoolean($expectedResult, $locale, $value): void
+ {
+ $newLocale = Settings::setLocale($locale);
+ if ($newLocale === false) {
+ Settings::setLocale('en_US');
+ self::markTestSkipped('Unable to set locale for locale-specific test');
+ }
+
+ $result = TextData::UPPERCASE($value);
+ self::assertEquals($expectedResult, $result);
+
+ Settings::setLocale('en_US');
+ }
+
+ public function providerLocaleLOWER(): array
+ {
+ return [
+ ['VRAI', 'fr_FR', true],
+ ['WAAR', 'nl_NL', true],
+ ['TOSI', 'fi', true],
+ ['ИСТИНА', 'bg', true],
+ ['FAUX', 'fr_FR', false],
+ ['ONWAAR', 'nl_NL', false],
+ ['EPÄTOSI', 'fi', false],
+ ['ЛОЖЬ', 'bg', false],
+ ];
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ValueTest.php b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ValueTest.php
index 355193de..b3ba1246 100644
--- a/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ValueTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/Functions/TextData/ValueTest.php
@@ -8,10 +8,19 @@ use PHPUnit\Framework\TestCase;
class ValueTest extends TestCase
{
+ /**
+ * @var string
+ */
private $currencyCode;
+ /**
+ * @var string
+ */
private $decimalSeparator;
+ /**
+ * @var string
+ */
private $thousandsSeparator;
protected function setUp(): void
@@ -32,7 +41,7 @@ class ValueTest extends TestCase
* @dataProvider providerVALUE
*
* @param mixed $expectedResult
- * @param $value
+ * @param mixed $value
*/
public function testVALUE($expectedResult, $value): void
{
@@ -44,7 +53,7 @@ class ValueTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerVALUE()
+ public function providerVALUE(): array
{
return require 'tests/data/Calculation/TextData/VALUE.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php
index dfa01822..4e8335f1 100644
--- a/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php
@@ -10,8 +10,14 @@ use PHPUnit\Framework\TestCase;
class FunctionsTest extends TestCase
{
+ /**
+ * @var string
+ */
private $compatibilityMode;
+ /**
+ * @var string
+ */
private $returnDate;
protected function setUp(): void
@@ -123,7 +129,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsBlank()
+ public function providerIsBlank(): array
{
return require 'tests/data/Calculation/Functions/IS_BLANK.php';
}
@@ -139,7 +145,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsErr()
+ public function providerIsErr(): array
{
return require 'tests/data/Calculation/Functions/IS_ERR.php';
}
@@ -155,7 +161,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsError()
+ public function providerIsError(): array
{
return require 'tests/data/Calculation/Functions/IS_ERROR.php';
}
@@ -171,7 +177,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerErrorType()
+ public function providerErrorType(): array
{
return require 'tests/data/Calculation/Functions/ERROR_TYPE.php';
}
@@ -187,7 +193,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsLogical()
+ public function providerIsLogical(): array
{
return require 'tests/data/Calculation/Functions/IS_LOGICAL.php';
}
@@ -203,7 +209,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsNa()
+ public function providerIsNa(): array
{
return require 'tests/data/Calculation/Functions/IS_NA.php';
}
@@ -219,7 +225,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsNumber()
+ public function providerIsNumber(): array
{
return require 'tests/data/Calculation/Functions/IS_NUMBER.php';
}
@@ -235,7 +241,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsText()
+ public function providerIsText(): array
{
return require 'tests/data/Calculation/Functions/IS_TEXT.php';
}
@@ -251,7 +257,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsNonText()
+ public function providerIsNonText(): array
{
return require 'tests/data/Calculation/Functions/IS_NONTEXT.php';
}
@@ -267,7 +273,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsEven()
+ public function providerIsEven(): array
{
return require 'tests/data/Calculation/Functions/IS_EVEN.php';
}
@@ -283,7 +289,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsOdd()
+ public function providerIsOdd(): array
{
return require 'tests/data/Calculation/Functions/IS_ODD.php';
}
@@ -299,7 +305,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerTYPE()
+ public function providerTYPE(): array
{
return require 'tests/data/Calculation/Functions/TYPE.php';
}
@@ -315,7 +321,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerN()
+ public function providerN(): array
{
return require 'tests/data/Calculation/Functions/N.php';
}
@@ -368,7 +374,7 @@ class FunctionsTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerIsFormula()
+ public function providerIsFormula(): array
{
return require 'tests/data/Calculation/Functions/ISFORMULA.php';
}
@@ -384,7 +390,7 @@ class FunctionsTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerIfCondition()
+ public function providerIfCondition(): array
{
return require 'tests/data/Calculation/Functions/IF_CONDITION.php';
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php b/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php
index 04dc0a32..af8b8079 100644
--- a/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/LookupRefTest.php
@@ -69,8 +69,14 @@ class LookupRefTest extends TestCase
self::assertEqualsWithDelta($expectedResult, $result, 1E-8);
}
- public function providerFormulaText()
+ public function providerFormulaText(): array
{
return require 'tests/data/Calculation/LookupRef/FORMULATEXT.php';
}
+
+ public function testFormulaTextWithoutCell(): void
+ {
+ $result = LookupRef::FORMULATEXT('A1');
+ self::assertEquals(Functions::REF(), $result);
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Calculation/TranslationTest.php b/tests/PhpSpreadsheetTests/Calculation/TranslationTest.php
new file mode 100644
index 00000000..e2384460
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Calculation/TranslationTest.php
@@ -0,0 +1,57 @@
+compatibilityMode = Functions::getCompatibilityMode();
+ $this->returnDate = Functions::getReturnDateType();
+ Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL);
+ Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
+ }
+
+ protected function tearDown(): void
+ {
+ Functions::setCompatibilityMode($this->compatibilityMode);
+ Functions::setReturnDateType($this->returnDate);
+ }
+
+ /**
+ * @dataProvider providerTranslations
+ */
+ public function testTranslation(string $expectedResult, string $locale, string $formula): void
+ {
+ $validLocale = Settings::setLocale($locale);
+ if (!$validLocale) {
+ self::markTestSkipped("Unable to set locale to {$locale}");
+ }
+
+ $translatedFormula = Calculation::getInstance()->_translateFormulaToLocale($formula);
+ self::assertSame($expectedResult, $translatedFormula);
+
+ $restoredFormula = Calculation::getInstance()->_translateFormulaToEnglish($translatedFormula);
+ self::assertSame($formula, $restoredFormula);
+ }
+
+ public function providerTranslations(): array
+ {
+ return require 'tests/data/Calculation/Translations.php';
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php b/tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php
index ea20fbf3..f8f02f0e 100644
--- a/tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php
+++ b/tests/PhpSpreadsheetTests/Calculation/XlfnFunctionsTest.php
@@ -75,7 +75,7 @@ class XlfnFunctionsTest extends \PHPUnit\Framework\TestCase
$sheet->setSelectedCell('B1');
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($workbook, 'Xlsx');
- $oufil = tempnam(File::sysGetTempDir(), 'phpspreadsheet-test');
+ $oufil = File::temporaryFilename();
$writer->save($oufil);
$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
diff --git a/tests/PhpSpreadsheetTests/Cell/AddressHelperTest.php b/tests/PhpSpreadsheetTests/Cell/AddressHelperTest.php
index 9b21767b..3f9c8302 100644
--- a/tests/PhpSpreadsheetTests/Cell/AddressHelperTest.php
+++ b/tests/PhpSpreadsheetTests/Cell/AddressHelperTest.php
@@ -18,7 +18,7 @@ class AddressHelperTest extends TestCase
self::assertSame($expectedValue, $actualValue);
}
- public function providerR1C1ConversionToA1Absolute()
+ public function providerR1C1ConversionToA1Absolute(): array
{
return require 'tests/data/Cell/R1C1ConversionToA1Absolute.php';
}
@@ -26,9 +26,13 @@ class AddressHelperTest extends TestCase
/**
* @dataProvider providerR1C1ConversionToA1Relative
*/
- public function testR1C1ConversionToA1Relative(string $expectedValue, string $address, ?int $row = null, ?int $column = null): void
- {
- $args = [$address];
+ public function testR1C1ConversionToA1Relative(
+ string $expectedValue,
+ string $address,
+ ?int $row = null,
+ ?int $column = null
+ ): void {
+ $args = [];
if ($row !== null) {
$args[] = $row;
}
@@ -36,12 +40,12 @@ class AddressHelperTest extends TestCase
$args[] = $column;
}
- $actualValue = AddressHelper::convertToA1(...$args);
+ $actualValue = AddressHelper::convertToA1($address, ...$args);
self::assertSame($expectedValue, $actualValue);
}
- public function providerR1C1ConversionToA1Relative()
+ public function providerR1C1ConversionToA1Relative(): array
{
return require 'tests/data/Cell/R1C1ConversionToA1Relative.php';
}
@@ -56,7 +60,7 @@ class AddressHelperTest extends TestCase
AddressHelper::convertToA1($address);
}
- public function providerR1C1ConversionToA1Exception()
+ public function providerR1C1ConversionToA1Exception(): array
{
return require 'tests/data/Cell/R1C1ConversionToA1Exception.php';
}
@@ -71,7 +75,7 @@ class AddressHelperTest extends TestCase
self::assertSame($expectedValue, $actualValue);
}
- public function providerA1ConversionToR1C1Absolute()
+ public function providerA1ConversionToR1C1Absolute(): array
{
return require 'tests/data/Cell/A1ConversionToR1C1Absolute.php';
}
@@ -86,7 +90,7 @@ class AddressHelperTest extends TestCase
self::assertSame($expectedValue, $actualValue);
}
- public function providerA1ConversionToR1C1Relative()
+ public function providerA1ConversionToR1C1Relative(): array
{
return require 'tests/data/Cell/A1ConversionToR1C1Relative.php';
}
@@ -101,7 +105,7 @@ class AddressHelperTest extends TestCase
AddressHelper::convertToR1C1($address);
}
- public function providerA1ConversionToR1C1Exception()
+ public function providerA1ConversionToR1C1Exception(): array
{
return require 'tests/data/Cell/A1ConversionToR1C1Exception.php';
}
diff --git a/tests/PhpSpreadsheetTests/Cell/AdvancedValueBinderTest.php b/tests/PhpSpreadsheetTests/Cell/AdvancedValueBinderTest.php
index 630a2944..7b4bbb42 100644
--- a/tests/PhpSpreadsheetTests/Cell/AdvancedValueBinderTest.php
+++ b/tests/PhpSpreadsheetTests/Cell/AdvancedValueBinderTest.php
@@ -13,10 +13,19 @@ use PHPUnit\Framework\TestCase;
class AdvancedValueBinderTest extends TestCase
{
+ /**
+ * @var string
+ */
private $currencyCode;
+ /**
+ * @var string
+ */
private $decimalSeparator;
+ /**
+ * @var string
+ */
private $thousandsSeparator;
protected function setUp(): void
@@ -33,25 +42,8 @@ class AdvancedValueBinderTest extends TestCase
StringHelper::setThousandsSeparator($this->thousandsSeparator);
}
- public function provider()
- {
- $currencyUSD = NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;
- $currencyEURO = str_replace('$', '€', NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);
-
- return [
- ['10%', 0.1, NumberFormat::FORMAT_PERCENTAGE_00, ',', '.', '$'],
- ['$10.11', 10.11, $currencyUSD, ',', '.', '$'],
- ['$1,010.12', 1010.12, $currencyUSD, ',', '.', '$'],
- ['$20,20', 20.2, $currencyUSD, '.', ',', '$'],
- ['$2.020,20', 2020.2, $currencyUSD, '.', ',', '$'],
- ['€2.020,20', 2020.2, $currencyEURO, '.', ',', '€'],
- ['€ 2.020,20', 2020.2, $currencyEURO, '.', ',', '€'],
- ['€2,020.22', 2020.22, $currencyEURO, ',', '.', '€'],
- ];
- }
-
/**
- * @dataProvider provider
+ * @dataProvider currencyProvider
*
* @param mixed $value
* @param mixed $valueBinded
@@ -63,7 +55,8 @@ class AdvancedValueBinderTest extends TestCase
public function testCurrency($value, $valueBinded, $format, $thousandsSeparator, $decimalSeparator, $currencyCode): void
{
$sheet = $this->getMockBuilder(Worksheet::class)
- ->setMethods(['getStyle', 'getNumberFormat', 'setFormatCode', 'getCellCollection'])
+ ->onlyMethods(['getStyle', 'getCellCollection'])
+ ->addMethods(['getNumberFormat', 'setFormatCode'])
->getMock();
$cellCollection = $this->getMockBuilder(Cells::class)
->disableOriginalConstructor()
@@ -75,9 +68,11 @@ class AdvancedValueBinderTest extends TestCase
$sheet->expects(self::once())
->method('getStyle')
->willReturnSelf();
+ // @phpstan-ignore-next-line
$sheet->expects(self::once())
->method('getNumberFormat')
->willReturnSelf();
+ // @phpstan-ignore-next-line
$sheet->expects(self::once())
->method('setFormatCode')
->with($format)
@@ -96,4 +91,235 @@ class AdvancedValueBinderTest extends TestCase
$binder->bindValue($cell, $value);
self::assertEquals($valueBinded, $cell->getValue());
}
+
+ public function currencyProvider(): array
+ {
+ $currencyUSD = NumberFormat::FORMAT_CURRENCY_USD_SIMPLE;
+ $currencyEURO = str_replace('$', '€', NumberFormat::FORMAT_CURRENCY_USD_SIMPLE);
+
+ return [
+ ['$10.11', 10.11, $currencyUSD, ',', '.', '$'],
+ ['$1,010.12', 1010.12, $currencyUSD, ',', '.', '$'],
+ ['$20,20', 20.2, $currencyUSD, '.', ',', '$'],
+ ['$2.020,20', 2020.2, $currencyUSD, '.', ',', '$'],
+ ['€2.020,20', 2020.2, $currencyEURO, '.', ',', '€'],
+ ['€ 2.020,20', 2020.2, $currencyEURO, '.', ',', '€'],
+ ['€2,020.22', 2020.22, $currencyEURO, ',', '.', '€'],
+ ];
+ }
+
+ /**
+ * @dataProvider fractionProvider
+ *
+ * @param mixed $value
+ * @param mixed $valueBinded
+ * @param mixed $format
+ */
+ public function testFractions($value, $valueBinded, $format): void
+ {
+ $sheet = $this->getMockBuilder(Worksheet::class)
+ ->onlyMethods(['getStyle', 'getCellCollection'])
+ ->addMethods(['getNumberFormat', 'setFormatCode'])
+ ->getMock();
+
+ $cellCollection = $this->getMockBuilder(Cells::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cellCollection->expects(self::any())
+ ->method('getParent')
+ ->willReturn($sheet);
+
+ $sheet->expects(self::once())
+ ->method('getStyle')
+ ->willReturnSelf();
+ // @phpstan-ignore-next-line
+ $sheet->expects(self::once())
+ ->method('getNumberFormat')
+ ->willReturnSelf();
+ // @phpstan-ignore-next-line
+ $sheet->expects(self::once())
+ ->method('setFormatCode')
+ ->with($format)
+ ->willReturnSelf();
+ $sheet->expects(self::any())
+ ->method('getCellCollection')
+ ->willReturn($cellCollection);
+
+ $cell = new Cell(null, DataType::TYPE_STRING, $sheet);
+
+ $binder = new AdvancedValueBinder();
+ $binder->bindValue($cell, $value);
+ self::assertEquals($valueBinded, $cell->getValue());
+ }
+
+ public function fractionProvider(): array
+ {
+ return [
+ ['1/5', 0.2, '?/?'],
+ ['-1/5', -0.2, '?/?'],
+ ['12/5', 2.4, '??/?'],
+ ['2/100', 0.02, '?/???'],
+ ['15/12', 1.25, '??/??'],
+ ['20/100', 0.2, '??/???'],
+ ['1 3/5', 1.6, '# ?/?'],
+ ['-1 3/5', -1.6, '# ?/?'],
+ ['1 4/20', 1.2, '# ?/??'],
+ ['1 16/20', 1.8, '# ??/??'],
+ ['12 20/100', 12.2, '# ??/???'],
+ ];
+ }
+
+ /**
+ * @dataProvider percentageProvider
+ *
+ * @param mixed $value
+ * @param mixed $valueBinded
+ * @param mixed $format
+ */
+ public function testPercentages($value, $valueBinded, $format): void
+ {
+ $sheet = $this->getMockBuilder(Worksheet::class)
+ ->onlyMethods(['getStyle', 'getCellCollection'])
+ ->addMethods(['getNumberFormat', 'setFormatCode'])
+ ->getMock();
+ $cellCollection = $this->getMockBuilder(Cells::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cellCollection->expects(self::any())
+ ->method('getParent')
+ ->willReturn($sheet);
+
+ $sheet->expects(self::once())
+ ->method('getStyle')
+ ->willReturnSelf();
+ // @phpstan-ignore-next-line
+ $sheet->expects(self::once())
+ ->method('getNumberFormat')
+ ->willReturnSelf();
+ // @phpstan-ignore-next-line
+ $sheet->expects(self::once())
+ ->method('setFormatCode')
+ ->with($format)
+ ->willReturnSelf();
+ $sheet->expects(self::any())
+ ->method('getCellCollection')
+ ->willReturn($cellCollection);
+
+ $cell = new Cell(null, DataType::TYPE_STRING, $sheet);
+
+ $binder = new AdvancedValueBinder();
+ $binder->bindValue($cell, $value);
+ self::assertEquals($valueBinded, $cell->getValue());
+ }
+
+ public function percentageProvider(): array
+ {
+ return [
+ ['10%', 0.1, NumberFormat::FORMAT_PERCENTAGE_00],
+ ['-12%', -0.12, NumberFormat::FORMAT_PERCENTAGE_00],
+ ['120%', 1.2, NumberFormat::FORMAT_PERCENTAGE_00],
+ ['12.5%', 0.125, NumberFormat::FORMAT_PERCENTAGE_00],
+ ];
+ }
+
+ /**
+ * @dataProvider timeProvider
+ *
+ * @param mixed $value
+ * @param mixed $valueBinded
+ * @param mixed $format
+ */
+ public function testTimes($value, $valueBinded, $format): void
+ {
+ $sheet = $this->getMockBuilder(Worksheet::class)
+ ->onlyMethods(['getStyle', 'getCellCollection'])
+ ->addMethods(['getNumberFormat', 'setFormatCode'])
+ ->getMock();
+
+ $cellCollection = $this->getMockBuilder(Cells::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cellCollection->expects(self::any())
+ ->method('getParent')
+ ->willReturn($sheet);
+
+ $sheet->expects(self::once())
+ ->method('getStyle')
+ ->willReturnSelf();
+ // @phpstan-ignore-next-line
+ $sheet->expects(self::once())
+ ->method('getNumberFormat')
+ ->willReturnSelf();
+ // @phpstan-ignore-next-line
+ $sheet->expects(self::once())
+ ->method('setFormatCode')
+ ->with($format)
+ ->willReturnSelf();
+ $sheet->expects(self::any())
+ ->method('getCellCollection')
+ ->willReturn($cellCollection);
+
+ $cell = new Cell(null, DataType::TYPE_STRING, $sheet);
+
+ $binder = new AdvancedValueBinder();
+ $binder->bindValue($cell, $value);
+ self::assertEquals($valueBinded, $cell->getValue());
+ }
+
+ public function timeProvider(): array
+ {
+ return [
+ ['1:20', 0.05555555556, NumberFormat::FORMAT_DATE_TIME3],
+ ['09:17', 0.386805555556, NumberFormat::FORMAT_DATE_TIME3],
+ ['15:00', 0.625, NumberFormat::FORMAT_DATE_TIME3],
+ ['17:12:35', 0.71707175926, NumberFormat::FORMAT_DATE_TIME4],
+ ['23:58:20', 0.99884259259, NumberFormat::FORMAT_DATE_TIME4],
+ ];
+ }
+
+ /**
+ * @dataProvider stringProvider
+ */
+ public function testStringWrapping(string $value, bool $wrapped): void
+ {
+ $sheet = $this->getMockBuilder(Worksheet::class)
+ ->onlyMethods(['getStyle', 'getCellCollection'])
+ ->addMethods(['getAlignment', 'setWrapText'])
+ ->getMock();
+ $cellCollection = $this->getMockBuilder(Cells::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $cellCollection->expects(self::any())
+ ->method('getParent')
+ ->willReturn($sheet);
+
+ $sheet->expects($wrapped ? self::once() : self::never())
+ ->method('getStyle')
+ ->willReturnSelf();
+ // @phpstan-ignore-next-line
+ $sheet->expects($wrapped ? self::once() : self::never())
+ ->method('getAlignment')
+ ->willReturnSelf();
+ // @phpstan-ignore-next-line
+ $sheet->expects($wrapped ? self::once() : self::never())
+ ->method('setWrapText')
+ ->with($wrapped)
+ ->willReturnSelf();
+ $sheet->expects(self::any())
+ ->method('getCellCollection')
+ ->willReturn($cellCollection);
+
+ $cell = new Cell(null, DataType::TYPE_STRING, $sheet);
+
+ $binder = new AdvancedValueBinder();
+ $binder->bindValue($cell, $value);
+ }
+
+ public function stringProvider(): array
+ {
+ return [
+ ['Hello World', false],
+ ["Hello\nWorld", true],
+ ];
+ }
}
diff --git a/tests/PhpSpreadsheetTests/Cell/CellTest.php b/tests/PhpSpreadsheetTests/Cell/CellTest.php
index 0d9ce337..980f0170 100644
--- a/tests/PhpSpreadsheetTests/Cell/CellTest.php
+++ b/tests/PhpSpreadsheetTests/Cell/CellTest.php
@@ -23,7 +23,7 @@ class CellTest extends TestCase
self::assertSame($expected, $cell->getValue());
}
- public function providerSetValueExplicit()
+ public function providerSetValueExplicit(): array
{
return require 'tests/data/Cell/SetValueExplicit.php';
}
@@ -42,7 +42,7 @@ class CellTest extends TestCase
$cell->setValueExplicit($value, $dataType);
}
- public function providerSetValueExplicitException()
+ public function providerSetValueExplicitException(): array
{
return require 'tests/data/Cell/SetValueExplicitException.php';
}
diff --git a/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php b/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php
index 8e0e98a9..9a0a2c21 100644
--- a/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php
+++ b/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php
@@ -24,7 +24,7 @@ class CoordinateTest extends TestCase
self::assertEquals($stringBack, $string, 'should be able to get the original input with opposite method');
}
- public function providerColumnString()
+ public function providerColumnString(): array
{
return require 'tests/data/ColumnString.php';
}
@@ -74,7 +74,7 @@ class CoordinateTest extends TestCase
self::assertEquals($columnIndexBack, $columnIndex, 'should be able to get the original input with opposite method');
}
- public function providerColumnIndex()
+ public function providerColumnIndex(): array
{
return require 'tests/data/ColumnIndex.php';
}
@@ -91,11 +91,25 @@ class CoordinateTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerCoordinates()
+ public function providerCoordinates(): array
{
return require 'tests/data/CellCoordinates.php';
}
+ /**
+ * @dataProvider providerIndexesFromString
+ */
+ public function testIndexesFromString(array $expectedResult, string $rangeSet): void
+ {
+ $result = Coordinate::indexesFromString($rangeSet);
+ self::assertSame($expectedResult, $result);
+ }
+
+ public function providerIndexesFromString(): array
+ {
+ return require 'tests/data/Cell/IndexesFromString.php';
+ }
+
public function testCoordinateFromStringWithRangeAddress(): void
{
$cellAddress = 'A1:AI2012';
@@ -153,7 +167,7 @@ class CoordinateTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerAbsoluteCoordinates()
+ public function providerAbsoluteCoordinates(): array
{
return require 'tests/data/CellAbsoluteCoordinate.php';
}
@@ -185,7 +199,7 @@ class CoordinateTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerAbsoluteReferences()
+ public function providerAbsoluteReferences(): array
{
return require 'tests/data/CellAbsoluteReference.php';
}
@@ -223,7 +237,7 @@ class CoordinateTest extends TestCase
}
}
- public function providerSplitRange()
+ public function providerSplitRange(): array
{
return require 'tests/data/CellSplitRange.php';
}
@@ -232,14 +246,15 @@ class CoordinateTest extends TestCase
* @dataProvider providerBuildRange
*
* @param mixed $expectedResult
+ * @param mixed $rangeSets
*/
- public function testBuildRange($expectedResult, ...$args): void
+ public function testBuildRange($expectedResult, $rangeSets): void
{
- $result = Coordinate::buildRange(...$args);
+ $result = Coordinate::buildRange($rangeSets);
self::assertEquals($expectedResult, $result);
}
- public function providerBuildRange()
+ public function providerBuildRange(): array
{
return require 'tests/data/CellBuildRange.php';
}
@@ -248,7 +263,17 @@ class CoordinateTest extends TestCase
{
$this->expectException(TypeError::class);
- $cellRange = '';
+ $cellRange = null;
+ // @phpstan-ignore-next-line
+ Coordinate::buildRange($cellRange);
+ }
+
+ public function testBuildRangeInvalid2(): void
+ {
+ $this->expectException(Exception::class);
+ $this->expectExceptionMessage('Range does not contain any information');
+
+ $cellRange = [];
Coordinate::buildRange($cellRange);
}
@@ -264,7 +289,7 @@ class CoordinateTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerRangeBoundaries()
+ public function providerRangeBoundaries(): array
{
return require 'tests/data/CellRangeBoundaries.php';
}
@@ -281,7 +306,7 @@ class CoordinateTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerRangeDimension()
+ public function providerRangeDimension(): array
{
return require 'tests/data/CellRangeDimension.php';
}
@@ -298,7 +323,7 @@ class CoordinateTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerGetRangeBoundaries()
+ public function providerGetRangeBoundaries(): array
{
return require 'tests/data/CellGetRangeBoundaries.php';
}
@@ -315,7 +340,7 @@ class CoordinateTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerExtractAllCellReferencesInRange()
+ public function providerExtractAllCellReferencesInRange(): array
{
return require 'tests/data/CellExtractAllCellReferencesInRange.php';
}
@@ -333,7 +358,7 @@ class CoordinateTest extends TestCase
Coordinate::extractAllCellReferencesInRange($range);
}
- public function providerInvalidRange()
+ public function providerInvalidRange(): array
{
return [['Z1:A1'], ['A4:A1'], ['B1:A1'], ['AA1:Z1']];
}
@@ -342,14 +367,15 @@ class CoordinateTest extends TestCase
* @dataProvider providerMergeRangesInCollection
*
* @param mixed $expectedResult
+ * @param mixed $rangeSets
*/
- public function testMergeRangesInCollection($expectedResult, ...$args): void
+ public function testMergeRangesInCollection($expectedResult, $rangeSets): void
{
- $result = Coordinate::mergeRangesInCollection(...$args);
+ $result = Coordinate::mergeRangesInCollection($rangeSets);
self::assertEquals($expectedResult, $result);
}
- public function providerMergeRangesInCollection()
+ public function providerMergeRangesInCollection(): array
{
return require 'tests/data/CellMergeRangesInCollection.php';
}
@@ -366,7 +392,7 @@ class CoordinateTest extends TestCase
self::assertEquals($expectedResult, $result);
}
- public function providerCoordinateIsRange()
+ public function providerCoordinateIsRange(): array
{
return require 'tests/data/CoordinateIsRange.php';
}
diff --git a/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php b/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php
index 95454c16..176dd6ac 100644
--- a/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php
+++ b/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php
@@ -25,6 +25,7 @@ class DataTypeTest extends TestCase
$stringLimit = 32767;
$randString = $this->randr($stringLimit + 10);
$result2 = DataType::checkString($randString);
+ self::assertIsString($result2);
self::assertSame($stringLimit, strlen($result2));
$dirtyString = "bla bla\r\n bla\r test\n";
diff --git a/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php b/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php
index e13cd942..cc9098bf 100644
--- a/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php
+++ b/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php
@@ -8,14 +8,15 @@ use PhpOffice\PhpSpreadsheet\Cell\Cell;
use PhpOffice\PhpSpreadsheet\Cell\DataType;
use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
use PhpOffice\PhpSpreadsheet\RichText\RichText;
+use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
class DefaultValueBinderTest extends TestCase
{
- private function createCellStub()
+ private function createCellStub(): Cell
{
// Create a stub for the Cell class.
- /** @var Cell $cellStub */
+ /** @var Cell&MockObject $cellStub */
$cellStub = $this->getMockBuilder(Cell::class)
->disableOriginalConstructor()
->getMock();
@@ -41,7 +42,7 @@ class DefaultValueBinderTest extends TestCase
self::assertTrue($result);
}
- public function binderProvider()
+ public function binderProvider(): array
{
return [
[null],
@@ -65,14 +66,15 @@ class DefaultValueBinderTest extends TestCase
* @dataProvider providerDataTypeForValue
*
* @param mixed $expectedResult
+ * @param mixed $value
*/
- public function testDataTypeForValue($expectedResult, ...$args): void
+ public function testDataTypeForValue($expectedResult, $value): void
{
- $result = DefaultValueBinder::dataTypeForValue(...$args);
+ $result = DefaultValueBinder::dataTypeForValue($value);
self::assertEquals($expectedResult, $result);
}
- public function providerDataTypeForValue()
+ public function providerDataTypeForValue(): array
{
return require 'tests/data/Cell/DefaultValueBinder.php';
}
diff --git a/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php b/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php
index 9c09aa75..e92fbaf3 100644
--- a/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php
+++ b/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php
@@ -34,7 +34,7 @@ class HyperlinkTest extends TestCase
{
$tooltipValue = 'PhpSpreadsheet Web Site';
- $testInstance = new Hyperlink(null, $tooltipValue);
+ $testInstance = new Hyperlink('', $tooltipValue);
$result = $testInstance->getTooltip();
self::assertEquals($tooltipValue, $result);
@@ -45,7 +45,7 @@ class HyperlinkTest extends TestCase
$initialTooltipValue = 'PhpSpreadsheet Web Site';
$newTooltipValue = 'PhpSpreadsheet Repository on Github';
- $testInstance = new Hyperlink(null, $initialTooltipValue);
+ $testInstance = new Hyperlink('', $initialTooltipValue);
$result = $testInstance->setTooltip($newTooltipValue);
self::assertInstanceOf(Hyperlink::class, $result);
diff --git a/tests/PhpSpreadsheetTests/Cell/ValueBinderWithOverriddenDataTypeForValue.php b/tests/PhpSpreadsheetTests/Cell/ValueBinderWithOverriddenDataTypeForValue.php
index d1b025a9..e2ddc602 100644
--- a/tests/PhpSpreadsheetTests/Cell/ValueBinderWithOverriddenDataTypeForValue.php
+++ b/tests/PhpSpreadsheetTests/Cell/ValueBinderWithOverriddenDataTypeForValue.php
@@ -6,12 +6,15 @@ use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
class ValueBinderWithOverriddenDataTypeForValue extends DefaultValueBinder
{
+ /**
+ * @var bool
+ */
public static $called = false;
- public static function dataTypeForValue($pValue)
+ public static function dataTypeForValue($value)
{
self::$called = true;
- return parent::dataTypeForValue($pValue);
+ return parent::dataTypeForValue($value);
}
}
diff --git a/tests/PhpSpreadsheetTests/Chart/LegendTest.php b/tests/PhpSpreadsheetTests/Chart/LegendTest.php
index 30715365..b12658a4 100644
--- a/tests/PhpSpreadsheetTests/Chart/LegendTest.php
+++ b/tests/PhpSpreadsheetTests/Chart/LegendTest.php
@@ -98,22 +98,11 @@ class LegendTest extends TestCase
$testInstance = new Legend();
foreach ($overlayValues as $overlayValue) {
- $result = $testInstance->setOverlay($overlayValue);
- self::assertTrue($result);
+ $testInstance->setOverlay($overlayValue);
+ self::assertSame($overlayValue, $testInstance->getOverlay());
}
}
- public function testSetInvalidOverlayReturnsFalse(): void
- {
- $testInstance = new Legend();
-
- $result = $testInstance->setOverlay('INVALID');
- self::assertFalse($result);
-
- $result = $testInstance->getOverlay();
- self::assertFalse($result);
- }
-
public function testGetOverlay(): void
{
$OverlayValue = true;
diff --git a/tests/PhpSpreadsheetTests/Collection/CellsTest.php b/tests/PhpSpreadsheetTests/Collection/CellsTest.php
index 539d0232..5e656cf5 100644
--- a/tests/PhpSpreadsheetTests/Collection/CellsTest.php
+++ b/tests/PhpSpreadsheetTests/Collection/CellsTest.php
@@ -91,7 +91,7 @@ class CellsTest extends TestCase
$collection = $this->getMockBuilder(Cells::class)
->setConstructorArgs([new Worksheet(), new Memory()])
- ->setMethods(['has'])
+ ->onlyMethods(['has'])
->getMock();
$collection->method('has')
diff --git a/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php b/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php
index 4d1025d2..828329ac 100644
--- a/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php
+++ b/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php
@@ -6,9 +6,16 @@ use Complex\Complex;
class ComplexAssert
{
+ /**
+ * @var string
+ */
private $errorMessage = '';
- private function testExpectedExceptions($expected, $actual)
+ /**
+ * @param mixed $expected
+ * @param mixed $actual
+ */
+ private function testExpectedExceptions($expected, $actual): bool
{
// Expecting an error, so we do a straight string comparison
if ($expected === $actual) {
@@ -21,7 +28,7 @@ class ComplexAssert
return false;
}
- private function adjustDelta($expected, $actual, $delta)
+ private function adjustDelta(float $expected, float $actual, float $delta): float
{
$adjustedDelta = $delta;
@@ -33,7 +40,11 @@ class ComplexAssert
return $adjustedDelta > 1.0 ? 1.0 : $adjustedDelta;
}
- public function assertComplexEquals($expected, $actual, $delta = 0)
+ /**
+ * @param mixed $expected
+ * @param mixed $actual
+ */
+ public function assertComplexEquals($expected, $actual, float $delta = 0): bool
{
if ($expected === INF || (is_string($expected) && $expected[0] === '#')) {
return $this->testExpectedExceptions($expected, $actual);
@@ -42,16 +53,6 @@ class ComplexAssert
$expectedComplex = new Complex($expected);
$actualComplex = new Complex($actual);
- if (!is_numeric($actualComplex->getReal()) || !is_numeric($expectedComplex->getReal())) {
- if ($actualComplex->getReal() !== $expectedComplex->getReal()) {
- $this->errorMessage = 'Mismatched String: ' . $actualComplex->getReal() . ' !== ' . $expectedComplex->getReal();
-
- return false;
- }
-
- return true;
- }
-
$adjustedDelta = $this->adjustDelta($expectedComplex->getReal(), $actualComplex->getReal(), $delta);
if (abs($actualComplex->getReal() - $expectedComplex->getReal()) > $adjustedDelta) {
$this->errorMessage = 'Mismatched Real part: ' . $actualComplex->getReal() . ' != ' . $expectedComplex->getReal();
@@ -75,7 +76,7 @@ class ComplexAssert
return true;
}
- public function getErrorMessage()
+ public function getErrorMessage(): string
{
return $this->errorMessage;
}
diff --git a/tests/PhpSpreadsheetTests/DefinedNameFormulaTest.php b/tests/PhpSpreadsheetTests/DefinedNameFormulaTest.php
index 14843091..4b17230e 100644
--- a/tests/PhpSpreadsheetTests/DefinedNameFormulaTest.php
+++ b/tests/PhpSpreadsheetTests/DefinedNameFormulaTest.php
@@ -31,7 +31,7 @@ class DefinedNameFormulaTest extends TestCase
}
$allDefinedNames = $spreadSheet->getDefinedNames();
- self::assertSame(count($definedNamesForTest), count($allDefinedNames));
+ self::assertCount(count($definedNamesForTest), $allDefinedNames);
}
public function testGetNamedRanges(): void
@@ -49,7 +49,7 @@ class DefinedNameFormulaTest extends TestCase
}
$allNamedRanges = $spreadSheet->getNamedRanges();
- self::assertSame(count(array_filter($rangeOrFormula)), count($allNamedRanges));
+ self::assertCount(count(array_filter($rangeOrFormula)), $allNamedRanges);
}
public function testGetScopedNamedRange(): void
@@ -65,6 +65,7 @@ class DefinedNameFormulaTest extends TestCase
$spreadSheet->addDefinedName(DefinedName::createInstance($rangeName, $workSheet, $localRangeValue, true));
$localScopedRange = $spreadSheet->getNamedRange($rangeName, $workSheet);
+ self::assertNotNull($localScopedRange);
self::assertSame($localRangeValue, $localScopedRange->getValue());
}
@@ -83,6 +84,7 @@ class DefinedNameFormulaTest extends TestCase
$spreadSheet->addDefinedName(DefinedName::createInstance($rangeName, $workSheet1, $localRangeValue, true));
$localScopedRange = $spreadSheet->getNamedRange($rangeName, $workSheet2);
+ self::assertNotNull($localScopedRange);
self::assertSame($globalRangeValue, $localScopedRange->getValue());
}
@@ -101,7 +103,7 @@ class DefinedNameFormulaTest extends TestCase
}
$allNamedFormulae = $spreadSheet->getNamedFormulae();
- self::assertSame(count(array_filter($rangeOrFormula)), count($allNamedFormulae));
+ self::assertCount(count(array_filter($rangeOrFormula)), $allNamedFormulae);
}
public function testGetScopedNamedFormula(): void
@@ -117,6 +119,7 @@ class DefinedNameFormulaTest extends TestCase
$spreadSheet->addDefinedName(DefinedName::createInstance($formulaName, $workSheet, $localFormulaValue, true));
$localScopedFormula = $spreadSheet->getNamedFormula($formulaName, $workSheet);
+ self::assertNotNull($localScopedFormula);
self::assertSame($localFormulaValue, $localScopedFormula->getValue());
}
@@ -135,6 +138,7 @@ class DefinedNameFormulaTest extends TestCase
$spreadSheet->addDefinedName(DefinedName::createInstance($formulaName, $workSheet1, $localFormulaValue, true));
$localScopedFormula = $spreadSheet->getNamedFormula($formulaName, $workSheet2);
+ self::assertNotNull($localScopedFormula);
self::assertSame($globalFormulaValue, $localScopedFormula->getValue());
}
diff --git a/tests/PhpSpreadsheetTests/DefinedNameTest.php b/tests/PhpSpreadsheetTests/DefinedNameTest.php
index 8a411775..43eddc8a 100644
--- a/tests/PhpSpreadsheetTests/DefinedNameTest.php
+++ b/tests/PhpSpreadsheetTests/DefinedNameTest.php
@@ -47,10 +47,9 @@ class DefinedNameTest extends TestCase
);
self::assertCount(1, $this->spreadsheet->getDefinedNames());
- self::assertSame(
- '=B1',
- $this->spreadsheet->getDefinedName('foo', $this->spreadsheet->getActiveSheet())->getValue()
- );
+ $definedName = $this->spreadsheet->getDefinedName('foo', $this->spreadsheet->getActiveSheet());
+ self::assertNotNull($definedName);
+ self::assertSame('=B1', $definedName->getValue());
}
public function testAddScopedDefinedNameWithSameName(): void
@@ -63,14 +62,13 @@ class DefinedNameTest extends TestCase
);
self::assertCount(2, $this->spreadsheet->getDefinedNames());
- self::assertSame(
- '=A1',
- $this->spreadsheet->getDefinedName('foo', $this->spreadsheet->getActiveSheet())->getValue()
- );
- self::assertSame(
- '=B1',
- $this->spreadsheet->getDefinedName('foo', $this->spreadsheet->getSheetByName('Sheet #2'))->getValue()
- );
+ $definedName1 = $this->spreadsheet->getDefinedName('foo', $this->spreadsheet->getActiveSheet());
+ self::assertNotNull($definedName1);
+ self::assertSame('=A1', $definedName1->getValue());
+
+ $definedName2 = $this->spreadsheet->getDefinedName('foo', $this->spreadsheet->getSheetByName('Sheet #2'));
+ self::assertNotNull($definedName2);
+ self::assertSame('=B1', $definedName2->getValue());
}
public function testRemoveDefinedName(): void
@@ -99,10 +97,9 @@ class DefinedNameTest extends TestCase
$this->spreadsheet->removeDefinedName('Foo', $this->spreadsheet->getActiveSheet());
self::assertCount(1, $this->spreadsheet->getDefinedNames());
- self::assertSame(
- '=B1',
- $this->spreadsheet->getDefinedName('foo', $this->spreadsheet->getSheetByName('Sheet #2'))->getValue()
- );
+ $definedName = $this->spreadsheet->getDefinedName('foo', $this->spreadsheet->getSheetByName('Sheet #2'));
+ self::assertNotNull($definedName);
+ self::assertSame('=B1', $definedName->getValue());
}
public function testRemoveScopedDefinedNameWhenDuplicateNames(): void
@@ -117,10 +114,9 @@ class DefinedNameTest extends TestCase
$this->spreadsheet->removeDefinedName('Foo', $this->spreadsheet->getSheetByName('Sheet #2'));
self::assertCount(1, $this->spreadsheet->getDefinedNames());
- self::assertSame(
- '=A1',
- $this->spreadsheet->getDefinedName('foo')->getValue()
- );
+ $definedName = $this->spreadsheet->getDefinedName('foo');
+ self::assertNotNull($definedName);
+ self::assertSame('=A1', $definedName->getValue());
}
public function testDefinedNameNoWorksheetNoScope(): void
@@ -135,6 +131,7 @@ class DefinedNameTest extends TestCase
DefinedName::createInstance('xyz', $this->spreadsheet->getActiveSheet(), 'A1')
);
+ /** @var NamedRange $namedRange */
$namedRange = $this->spreadsheet->getDefinedName('XYZ');
self::assertInstanceOf(NamedRange::class, $namedRange);
self::assertEquals('A1', $namedRange->getRange());
@@ -147,6 +144,9 @@ class DefinedNameTest extends TestCase
{
$sheet1 = $this->spreadsheet->getSheetByName('Sheet #1');
$sheet2 = $this->spreadsheet->getSheetByName('Sheet #2');
+ self::assertNotNull($sheet1);
+ self::assertNotNull($sheet2);
+
$sheet1->getCell('A1')->setValue(1);
$sheet2->getCell('A1')->setValue(2);
$namedRange = new NamedRange('xyz', $sheet2, '$A$1');
@@ -162,6 +162,9 @@ class DefinedNameTest extends TestCase
{
$sheet1 = $this->spreadsheet->getSheetByName('Sheet #1');
$sheet2 = $this->spreadsheet->getSheetByName('Sheet #2');
+ self::assertNotNull($sheet1);
+ self::assertNotNull($sheet2);
+
$sheet1->getCell('A1')->setValue(1);
$sheet2->getCell('A1')->setValue(2);
$namedRange = new NamedRange('abc', $sheet2, '$A$1');
@@ -177,6 +180,9 @@ class DefinedNameTest extends TestCase
{
$sheet1 = $this->spreadsheet->getSheetByName('Sheet #1');
$sheet2 = $this->spreadsheet->getSheetByName('Sheet #2');
+ self::assertNotNull($sheet1);
+ self::assertNotNull($sheet2);
+
$sheet1->getCell('A1')->setValue(1);
$sheet2->getCell('A1')->setValue(2);
$namedRange = new NamedRange('abc', $sheet2, '$A$1');
@@ -192,12 +198,17 @@ class DefinedNameTest extends TestCase
{
$sheet1 = $this->spreadsheet->getSheetByName('Sheet #1');
$sheet2 = $this->spreadsheet->getSheetByName('Sheet #2');
+ self::assertNotNull($sheet1);
+ self::assertNotNull($sheet2);
+
$sheet1->getCell('A1')->setValue(1);
$sheet2->getCell('A1')->setValue(2);
$namedRange = new NamedRange('abc', $sheet2, '$A$1');
$namedRangeClone = clone $namedRange;
$ss1 = $namedRange->getWorksheet();
$ss2 = $namedRangeClone->getWorksheet();
+ self::assertNotNull($ss1);
+ self::assertNotNull($ss2);
self::assertNotSame($ss1, $ss2);
self::assertEquals($ss1->getTitle(), $ss2->getTitle());
}
diff --git a/tests/PhpSpreadsheetTests/Document/PropertiesTest.php b/tests/PhpSpreadsheetTests/Document/PropertiesTest.php
new file mode 100644
index 00000000..54932bb8
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Document/PropertiesTest.php
@@ -0,0 +1,186 @@
+properties = new Properties();
+ }
+
+ public function testNewInstance(): void
+ {
+ $createdTime = $modifiedTime = time();
+ self::assertSame('Unknown Creator', $this->properties->getCreator());
+ self::assertSame('Unknown Creator', $this->properties->getLastModifiedBy());
+ self::assertSame('Untitled Spreadsheet', $this->properties->getTitle());
+ self::assertSame('Microsoft Corporation', $this->properties->getCompany());
+ self::assertSame($createdTime, $this->properties->getCreated());
+ self::assertSame($modifiedTime, $this->properties->getModified());
+ }
+
+ public function testSetCreator(): void
+ {
+ $creator = 'Mark Baker';
+
+ $this->properties->setCreator($creator);
+ self::assertSame($creator, $this->properties->getCreator());
+ }
+
+ /**
+ * @dataProvider providerCreationTime
+ *
+ * @param mixed $expectedCreationTime
+ * @param mixed $created
+ */
+ public function testSetCreated($expectedCreationTime, $created): void
+ {
+ $expectedCreationTime = $expectedCreationTime ?? time();
+
+ $this->properties->setCreated($created);
+ self::assertSame($expectedCreationTime, $this->properties->getCreated());
+ }
+
+ public function providerCreationTime(): array
+ {
+ return [
+ [null, null],
+ [1615980600, 1615980600],
+ [1615980600, '1615980600'],
+ [1615980600, '2021-03-17 11:30:00Z'],
+ ];
+ }
+
+ public function testSetModifier(): void
+ {
+ $creator = 'Mark Baker';
+
+ $this->properties->setLastModifiedBy($creator);
+ self::assertSame($creator, $this->properties->getLastModifiedBy());
+ }
+
+ /**
+ * @dataProvider providerModifiedTime
+ *
+ * @param mixed $expectedModifiedTime
+ * @param mixed $modified
+ */
+ public function testSetModified($expectedModifiedTime, $modified): void
+ {
+ $expectedModifiedTime = $expectedModifiedTime ?? time();
+
+ $this->properties->setModified($modified);
+ self::assertSame($expectedModifiedTime, $this->properties->getModified());
+ }
+
+ public function providerModifiedTime(): array
+ {
+ return [
+ [null, null],
+ [1615980600, 1615980600],
+ [1615980600, '1615980600'],
+ [1615980600, '2021-03-17 11:30:00Z'],
+ ];
+ }
+
+ public function testSetTitle(): void
+ {
+ $title = 'My spreadsheet title test';
+
+ $this->properties->setTitle($title);
+ self::assertSame($title, $this->properties->getTitle());
+ }
+
+ public function testSetDescription(): void
+ {
+ $description = 'A test for spreadsheet description';
+
+ $this->properties->setDescription($description);
+ self::assertSame($description, $this->properties->getDescription());
+ }
+
+ public function testSetSubject(): void
+ {
+ $subject = 'Test spreadsheet';
+
+ $this->properties->setSubject($subject);
+ self::assertSame($subject, $this->properties->getSubject());
+ }
+
+ public function testSetKeywords(): void
+ {
+ $keywords = 'Test PHPSpreadsheet Spreadsheet Excel LibreOffice Gnumeric OpenSpreadsheetML OASIS';
+
+ $this->properties->setKeywords($keywords);
+ self::assertSame($keywords, $this->properties->getKeywords());
+ }
+
+ public function testSetCategory(): void
+ {
+ $category = 'Testing';
+
+ $this->properties->setCategory($category);
+ self::assertSame($category, $this->properties->getCategory());
+ }
+
+ public function testSetCompany(): void
+ {
+ $company = 'PHPOffice Suite';
+
+ $this->properties->setCompany($company);
+ self::assertSame($company, $this->properties->getCompany());
+ }
+
+ public function testSetManager(): void
+ {
+ $manager = 'Mark Baker';
+
+ $this->properties->setManager($manager);
+ self::assertSame($manager, $this->properties->getManager());
+ }
+
+ /**
+ * @dataProvider providerCustomProperties
+ *
+ * @param mixed $expectedType
+ * @param mixed $expectedValue
+ * @param mixed $propertyName
+ */
+ public function testSetCustomProperties($expectedType, $expectedValue, $propertyName, ...$args): void
+ {
+ $this->properties->setCustomProperty($propertyName, ...$args);
+ self::assertTrue($this->properties->isCustomPropertySet($propertyName));
+ self::assertSame($expectedValue, $this->properties->getCustomPropertyValue($propertyName));
+ self::assertSame($expectedType, $this->properties->getCustomPropertyType($propertyName));
+ }
+
+ public function providerCustomProperties(): array
+ {
+ return [
+ [Properties::PROPERTY_TYPE_STRING, null, 'Editor', null],
+ [Properties::PROPERTY_TYPE_STRING, 'Mark Baker', 'Editor', 'Mark Baker'],
+ [Properties::PROPERTY_TYPE_FLOAT, 1.17, 'Version', 1.17],
+ [Properties::PROPERTY_TYPE_INTEGER, 2, 'Revision', 2],
+ [Properties::PROPERTY_TYPE_BOOLEAN, true, 'Tested', true],
+ [Properties::PROPERTY_TYPE_DATE, '2021-03-17', 'Test Date', '2021-03-17', Properties::PROPERTY_TYPE_DATE],
+ ];
+ }
+
+ public function testGetUnknownCustomProperties(): void
+ {
+ $propertyName = 'I DONT EXIST';
+
+ self::assertFalse($this->properties->isCustomPropertySet($propertyName));
+ self::assertNull($this->properties->getCustomPropertyValue($propertyName));
+ self::assertNull($this->properties->getCustomPropertyType($propertyName));
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Functional/AbstractFunctional.php b/tests/PhpSpreadsheetTests/Functional/AbstractFunctional.php
index f242c698..da821532 100644
--- a/tests/PhpSpreadsheetTests/Functional/AbstractFunctional.php
+++ b/tests/PhpSpreadsheetTests/Functional/AbstractFunctional.php
@@ -21,7 +21,7 @@ abstract class AbstractFunctional extends TestCase
*/
protected function writeAndReload(Spreadsheet $spreadsheet, $format, ?callable $readerCustomizer = null)
{
- $filename = tempnam(File::sysGetTempDir(), 'phpspreadsheet-test');
+ $filename = File::temporaryFilename();
$writer = IOFactory::createWriter($spreadsheet, $format);
$writer->save($filename);
diff --git a/tests/PhpSpreadsheetTests/Functional/ActiveSheetTest.php b/tests/PhpSpreadsheetTests/Functional/ActiveSheetTest.php
index 56682b34..024185c6 100644
--- a/tests/PhpSpreadsheetTests/Functional/ActiveSheetTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/ActiveSheetTest.php
@@ -3,10 +3,11 @@
namespace PhpOffice\PhpSpreadsheetTests\Functional;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
+use PhpOffice\PhpSpreadsheet\Style\Protection;
class ActiveSheetTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Xls'],
@@ -46,6 +47,12 @@ class ActiveSheetTest extends AbstractFunctional
$spreadsheet->createSheet(2);
+ $spreadsheet->setActiveSheetIndex(2)
+ ->setCellValue('F1', 2)
+ ->getCell('F1')
+ ->getStyle()
+ ->getProtection()
+ ->setHidden(Protection::PROTECTION_PROTECTED);
$spreadsheet->setActiveSheetIndex(2)
->setTitle('Test3')
->setCellValue('A1', 4)
diff --git a/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php b/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
index 5cd0aec7..38117059 100644
--- a/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php
@@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class ColumnWidthTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Xlsx'],
@@ -15,8 +15,6 @@ class ColumnWidthTest extends AbstractFunctional
/**
* @dataProvider providerFormats
- *
- * @param $format
*/
public function testReadColumnWidth($format): void
{
diff --git a/tests/PhpSpreadsheetTests/Functional/CommentsTest.php b/tests/PhpSpreadsheetTests/Functional/CommentsTest.php
index 5ba4e7c8..d82f7f96 100644
--- a/tests/PhpSpreadsheetTests/Functional/CommentsTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/CommentsTest.php
@@ -7,7 +7,7 @@ use PhpOffice\PhpSpreadsheet\Style\Alignment;
class CommentsTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Html'],
@@ -21,8 +21,6 @@ class CommentsTest extends AbstractFunctional
* count of comments in correct coords.
*
* @dataProvider providerFormats
- *
- * @param $format
*/
public function testComments($format): void
{
diff --git a/tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php b/tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php
index 3183450f..5ee0b1f5 100644
--- a/tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php
@@ -9,7 +9,7 @@ class ConditionalStopIfTrueTest extends AbstractFunctional
const COLOR_GREEN = 'FF99FF66';
const COLOR_RED = 'FFFF5050';
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Xlsx'],
diff --git a/tests/PhpSpreadsheetTests/Functional/EnclosureTest.php b/tests/PhpSpreadsheetTests/Functional/EnclosureTest.php
index 1f1cb7eb..2ddecfd2 100644
--- a/tests/PhpSpreadsheetTests/Functional/EnclosureTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/EnclosureTest.php
@@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class EnclosureTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Html'],
diff --git a/tests/PhpSpreadsheetTests/Functional/FreezePaneTest.php b/tests/PhpSpreadsheetTests/Functional/FreezePaneTest.php
index 4e725d03..67083949 100644
--- a/tests/PhpSpreadsheetTests/Functional/FreezePaneTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/FreezePaneTest.php
@@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class FreezePaneTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Xls'],
diff --git a/tests/PhpSpreadsheetTests/Functional/MergedCellsTest.php b/tests/PhpSpreadsheetTests/Functional/MergedCellsTest.php
index 39865817..d2e9234f 100644
--- a/tests/PhpSpreadsheetTests/Functional/MergedCellsTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/MergedCellsTest.php
@@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class MergedCellsTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Html'],
diff --git a/tests/PhpSpreadsheetTests/Functional/PrintAreaTest.php b/tests/PhpSpreadsheetTests/Functional/PrintAreaTest.php
index 584f6dd5..93753762 100644
--- a/tests/PhpSpreadsheetTests/Functional/PrintAreaTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/PrintAreaTest.php
@@ -7,7 +7,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class PrintAreaTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Xls'],
diff --git a/tests/PhpSpreadsheetTests/Functional/ReadBlankCellsTest.php b/tests/PhpSpreadsheetTests/Functional/ReadBlankCellsTest.php
index 9dac3437..585871dc 100644
--- a/tests/PhpSpreadsheetTests/Functional/ReadBlankCellsTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/ReadBlankCellsTest.php
@@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class ReadBlankCellsTest extends AbstractFunctional
{
- public function providerSheetFormat()
+ public function providerSheetFormat(): array
{
return [
['Xlsx'],
diff --git a/tests/PhpSpreadsheetTests/Functional/ReadFilterTest.php b/tests/PhpSpreadsheetTests/Functional/ReadFilterTest.php
index 9ab86baa..930288a7 100644
--- a/tests/PhpSpreadsheetTests/Functional/ReadFilterTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/ReadFilterTest.php
@@ -7,7 +7,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class ReadFilterTest extends AbstractFunctional
{
- public function providerCellsValues()
+ public function providerCellsValues(): array
{
$cellValues = [
// one argument as a multidimensional array
diff --git a/tests/PhpSpreadsheetTests/Functional/SelectedCellsTest.php b/tests/PhpSpreadsheetTests/Functional/SelectedCellsTest.php
index 625f2428..a1866b09 100644
--- a/tests/PhpSpreadsheetTests/Functional/SelectedCellsTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/SelectedCellsTest.php
@@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class SelectedCellsTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Xls'],
diff --git a/tests/PhpSpreadsheetTests/Functional/TypeAttributePreservationTest.php b/tests/PhpSpreadsheetTests/Functional/TypeAttributePreservationTest.php
index e6d6377b..bebf0589 100644
--- a/tests/PhpSpreadsheetTests/Functional/TypeAttributePreservationTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/TypeAttributePreservationTest.php
@@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class TypeAttributePreservationTest extends AbstractFunctional
{
- public function providerFormulae()
+ public function providerFormulae(): array
{
$formats = ['Xlsx'];
$data = require 'tests/data/Functional/TypeAttributePreservation/Formula.php';
diff --git a/tests/PhpSpreadsheetTests/Functional/WorkbookViewAttributesTest.php b/tests/PhpSpreadsheetTests/Functional/WorkbookViewAttributesTest.php
index f97ad9cf..8d44c4d2 100644
--- a/tests/PhpSpreadsheetTests/Functional/WorkbookViewAttributesTest.php
+++ b/tests/PhpSpreadsheetTests/Functional/WorkbookViewAttributesTest.php
@@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Spreadsheet;
class WorkbookViewAttributesTest extends AbstractFunctional
{
- public function providerFormats()
+ public function providerFormats(): array
{
return [
['Xlsx'],
diff --git a/tests/PhpSpreadsheetTests/Helper/HtmlTest.php b/tests/PhpSpreadsheetTests/Helper/HtmlTest.php
index d47c2f64..b2fadf42 100644
--- a/tests/PhpSpreadsheetTests/Helper/HtmlTest.php
+++ b/tests/PhpSpreadsheetTests/Helper/HtmlTest.php
@@ -21,7 +21,7 @@ class HtmlTest extends TestCase
self::assertSame($expected, $actual->getPlainText());
}
- public function providerUtf8EncodingSupport()
+ public function providerUtf8EncodingSupport(): array
{
return [
['foo', 'foo'],
diff --git a/tests/PhpSpreadsheetTests/Helper/SampleCoverageTest.php b/tests/PhpSpreadsheetTests/Helper/SampleCoverageTest.php
new file mode 100644
index 00000000..f3f616fe
--- /dev/null
+++ b/tests/PhpSpreadsheetTests/Helper/SampleCoverageTest.php
@@ -0,0 +1,39 @@
+getSamples();
+ self::assertArrayHasKey('Basic', $samples);
+ $basic = $samples['Basic'];
+ self::assertArrayHasKey('02 Types', $basic);
+ self::assertSame('Basic/02_Types.php', $basic['02 Types']);
+ self::assertSame('phpunit', $helper->getPageTitle());
+ self::assertSame('
phpunit
', $helper->getPageHeading());
+ }
+
+ public function testDirectoryFail(): void
+ {
+ $this->expectException(RuntimeException::class);
+
+ $helper = $this->getMockBuilder(Sample::class)
+ ->onlyMethods(['isDirOrMkdir'])
+ ->getMock();
+ $helper->expects(self::once())
+ ->method('isDirOrMkdir')
+ ->with(self::isType('string'))
+ ->willReturn(false);
+ self::assertSame('', $helper->getFilename('a.xlsx'));
+ }
+}
diff --git a/tests/PhpSpreadsheetTests/Helper/SampleTest.php b/tests/PhpSpreadsheetTests/Helper/SampleTest.php
index 8fd6bb47..0817f1d5 100644
--- a/tests/PhpSpreadsheetTests/Helper/SampleTest.php
+++ b/tests/PhpSpreadsheetTests/Helper/SampleTest.php
@@ -25,7 +25,7 @@ class SampleTest extends TestCase
self::assertTrue(true);
}
- public function providerSample()
+ public function providerSample(): array
{
$skipped = [
'Chart/32_Chart_read_write_PDF.php', // Unfortunately JpGraph is not up to date for latest PHP and raise many warnings
@@ -38,6 +38,7 @@ class SampleTest extends TestCase
[
'Pdf/21_Pdf_Domdf.php',
'Pdf/21_Pdf_TCPDF.php',
+ 'Chart/35_Chart_render.php', // idem
]
);
}
@@ -57,6 +58,9 @@ class SampleTest extends TestCase
$result = [];
foreach ($helper->getSamples() as $samples) {
foreach ($samples as $sample) {
+// if (array_pop(explode('/', $sample)) !== 'DGET.php') {
+// continue;
+// }
if (!in_array($sample, $skipped)) {
$file = 'samples/' . $sample;
$result[] = [$file];
diff --git a/tests/PhpSpreadsheetTests/IOFactoryTest.php b/tests/PhpSpreadsheetTests/IOFactoryTest.php
index 886fcb36..4837d6cf 100644
--- a/tests/PhpSpreadsheetTests/IOFactoryTest.php
+++ b/tests/PhpSpreadsheetTests/IOFactoryTest.php
@@ -24,7 +24,7 @@ class IOFactoryTest extends TestCase
self::assertInstanceOf($expected, $actual);
}
- public function providerCreateWriter()
+ public function providerCreateWriter(): array
{
return [
['Xls', Writer\Xls::class],
@@ -58,7 +58,7 @@ class IOFactoryTest extends TestCase
self::assertInstanceOf($expected, $actual);
}
- public function providerCreateReader()
+ public function providerCreateReader(): array
{
return [
['Xls', Reader\Xls::class],
@@ -118,7 +118,7 @@ class IOFactoryTest extends TestCase
self::assertInstanceOf(Spreadsheet::class, $actual);
}
- public function providerIdentify()
+ public function providerIdentify(): array
{
return [
['samples/templates/26template.xlsx', 'Xlsx', Reader\Xlsx::class],
diff --git a/tests/PhpSpreadsheetTests/Reader/CsvContiguousFilter.php b/tests/PhpSpreadsheetTests/Reader/CsvContiguousFilter.php
index 9bc16ae0..1abe9940 100644
--- a/tests/PhpSpreadsheetTests/Reader/CsvContiguousFilter.php
+++ b/tests/PhpSpreadsheetTests/Reader/CsvContiguousFilter.php
@@ -7,10 +7,19 @@ use PhpOffice\PhpSpreadsheet\Reader\IReadFilter;
/** Define a Read Filter class implementing IReadFilter */
class CsvContiguousFilter implements IReadFilter
{
+ /**
+ * @var int
+ */
private $startRow = 0;
+ /**
+ * @var int
+ */
private $endRow = 0;
+ /**
+ * @var int
+ */
private $filterType = 0;
/**
diff --git a/tests/PhpSpreadsheetTests/Reader/CsvContiguousTest.php b/tests/PhpSpreadsheetTests/Reader/CsvContiguousTest.php
index 3a417791..82f960e4 100644
--- a/tests/PhpSpreadsheetTests/Reader/CsvContiguousTest.php
+++ b/tests/PhpSpreadsheetTests/Reader/CsvContiguousTest.php
@@ -8,6 +8,9 @@ use PHPUnit\Framework\TestCase;
class CsvContiguousTest extends TestCase
{
+ /**
+ * @var string
+ */
private $inputFileName = 'samples/Reader/sampleData/example2.csv';
public function testContiguous(): void
@@ -23,8 +26,8 @@ class CsvContiguousTest extends TestCase
// Tell the Reader that we want to use the Read Filter that we've Instantiated
// and that we want to store it in contiguous rows/columns
self::assertFalse($reader->getContiguous());
- $reader->setReadFilter($chunkFilter)
- ->setContiguous(true);
+ $reader->setReadFilter($chunkFilter);
+ $reader->setContiguous(true);
// Instantiate a new PhpSpreadsheet object manually
$spreadsheet = new Spreadsheet();
@@ -65,8 +68,8 @@ class CsvContiguousTest extends TestCase
// Tell the Reader that we want to use the Read Filter that we've Instantiated
// and that we want to store it in contiguous rows/columns
- $reader->setReadFilter($chunkFilter)
- ->setContiguous(true);
+ $reader->setReadFilter($chunkFilter);
+ $reader->setContiguous(true);
// Instantiate a new PhpSpreadsheet object manually
$spreadsheet = new Spreadsheet();
diff --git a/tests/PhpSpreadsheetTests/Reader/CsvTest.php b/tests/PhpSpreadsheetTests/Reader/CsvTest.php
index e543ff48..73c281ec 100644
--- a/tests/PhpSpreadsheetTests/Reader/CsvTest.php
+++ b/tests/PhpSpreadsheetTests/Reader/CsvTest.php
@@ -29,7 +29,7 @@ class CsvTest extends TestCase
self::assertSame($expectedValue, $actual, 'should be able to retrieve correct value');
}
- public function providerDelimiterDetection()
+ public function providerDelimiterDetection(): array
{
return [
[
@@ -101,7 +101,7 @@ class CsvTest extends TestCase
self::assertSame($expected, $reader->canRead($filename));
}
- public function providerCanLoad()
+ public function providerCanLoad(): array
{
return [
[false, 'tests/data/Reader/Ods/data.ods'],
@@ -172,7 +172,7 @@ class CsvTest extends TestCase
self::assertEquals(2, $info[0]['totalColumns']);
}
- public function providerEncodings()
+ public function providerEncodings(): array
{
return [
['tests/data/Reader/CSV/encoding.iso88591.csv', 'ISO-8859-1'],
@@ -288,7 +288,7 @@ EOF;
self::assertEquals($delimiter, $reader->getDelimiter());
}
- public function providerEscapes()
+ public function providerEscapes(): array
{
return [
['\\', ';'],
@@ -310,7 +310,7 @@ EOF;
self::assertEquals('sixième', $sheet->getCell('C2')->getValue());
}
- public function providerGuessEncoding()
+ public function providerGuessEncoding(): array
{
return [
['tests/data/Reader/CSV/premiere.utf8.csv'],
diff --git a/tests/PhpSpreadsheetTests/Reader/Html/HtmlHelper.php b/tests/PhpSpreadsheetTests/Reader/Html/HtmlHelper.php
index c09902ff..a6be40c9 100644
--- a/tests/PhpSpreadsheetTests/Reader/Html/HtmlHelper.php
+++ b/tests/PhpSpreadsheetTests/Reader/Html/HtmlHelper.php
@@ -3,13 +3,14 @@
namespace PhpOffice\PhpSpreadsheetTests\Reader\Html;
use PhpOffice\PhpSpreadsheet\Reader\Html;
+use PhpOffice\PhpSpreadsheet\Shared\File;
use PhpOffice\PhpSpreadsheet\Spreadsheet;
class HtmlHelper
{
public static function createHtml(string $html): string
{
- $filename = tempnam(sys_get_temp_dir(), 'html');
+ $filename = File::temporaryFilename();
file_put_contents($filename, $html);
return $filename;
diff --git a/tests/PhpSpreadsheetTests/Reader/Html/HtmlLoadStringTest.php b/tests/PhpSpreadsheetTests/Reader/Html/HtmlLoadStringTest.php
index e1041507..bc4c30ff 100644
--- a/tests/PhpSpreadsheetTests/Reader/Html/HtmlLoadStringTest.php
+++ b/tests/PhpSpreadsheetTests/Reader/Html/HtmlLoadStringTest.php
@@ -89,4 +89,33 @@ class HtmlLoadStringTest extends TestCase
$spreadsheet = $reader->loadFromString($html, $spreadsheet);
self::assertEquals(2, $spreadsheet->getSheetCount());
}
+
+ public function testCanLoadDuplicateTitle(): void
+ {
+ $html = <<<'EOF'
+
+
+Sheet
+
+
+