diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..c2d640e --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +/.buildpath +/.project +/.settings/ \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 110b393..d240acb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,5 @@ +## v1.3.3 + ## v1.3.2 - Initial GitHub load - Previous versions loaded on [SourceForge](https://sourceforge.net/projects/sagacity/) \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..b395466 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,6 @@ +FROM php:7.2.8-apache-stretch +COPY conf/docker-php.ini /usr/local/etc/php/php.ini +RUN apt update && apt -y install zlib1g-dev mysql-client +RUN docker-php-ext-install mysqli zip +RUN mkdir /var/log/sagacity && chown www-data:www-data /var/log/sagacity +EXPOSE 80 diff --git a/conf/docker-php.ini b/conf/docker-php.ini new file mode 100644 index 0000000..490b557 --- /dev/null +++ b/conf/docker-php.ini @@ -0,0 +1,14 @@ +memory_limit=1024M +error_reporting=E_ALL +display_errors=On +display_startup_errors=On +html_errors=On +variables_order="GPCS" +request_order="GPCS" +post_max_size=1G +include_path="./:/var/www/html:/var/www/html/classes:/var/www/html/inc" +file_uploads=On +upload_max_filesize=1G +allow_url_fopen=On +allow_url_include=Off +date.timezone=America/Indiana/Indianapolis \ No newline at end of file diff --git a/config.inc b/config.inc index 3df1759..a35954b 100644 --- a/config.inc +++ b/config.inc @@ -15,6 +15,7 @@ * - Nov 14, 2017 - File created * - May 24, 2018 - Updated constants for 1.3.2 release * - Jun 2, 2018 - Added new STIG_EXCLUSIONS constant to permanently exclude STIGs + * - Aug 28, 2018 - Updated constants for 1.3.3 release */ // @new /** @@ -29,8 +30,8 @@ define('E_DEBUG', 65535); define('DOC_ROOT', '{DOC_ROOT}'); define('PWD_FILE', '{PWD_FILE}'); define('TMP', '{TMP_PATH}'); -define('VER', '1.3.2'); -define('REL_DATE', '2018-05-31'); +define('VER', '1.3.3'); +define('REL_DATE', '2018-08-31'); define('LOG_LEVEL', '{E_ERROR}'); define('LOG_PATH', '{LOG_PATH}'); define('SALT', '{SALT}'); diff --git a/inc/.gitignore b/inc/.gitignore new file mode 100644 index 0000000..80875bd --- /dev/null +++ b/inc/.gitignore @@ -0,0 +1 @@ +/passwd \ No newline at end of file diff --git a/inc/composer.json b/inc/composer.json index 6f2de3b..acd3ccc 100644 --- a/inc/composer.json +++ b/inc/composer.json @@ -1,12 +1,31 @@ { - "require" : { - "phpoffice/phpspreadsheet" : "^1.0", - "cocur/background-process" : "^0.7.0", - "tecnickcom/tcpdf" : "^6.2", - "pacificsec/cpe" : "^1.0", - "monolog/monolog": "^1.23" - }, - "require-dev" : { - "phpunit/phpunit" : "^6.2" - } -} + "require" : { + "phpoffice/phpspreadsheet" : "~1.4", + "cocur/background-process" : "~0.7", + "tecnickcom/tcpdf" : "~6.2", + "pacificsec/cpe" : "1.0.1", + "godsgood33/php-db" : "~1.3" + }, + "require-dev" : { + "phpunit/phpunit" : "~7.3" + }, + "type" : "project", + "homepage" : "https://cyberperspectives.com", + "license" : "Apache-2.0", + "authors" : [{ + "name" : "Ryan Prather", + "email" : "ryan.prather@cyberperspectives.com", + "role" : "Braun" + }, { + "name" : "Jeff Odegard", + "email" : "jeff.odegard@cyberperspectives.com", + "role" : "Brains" + } + ], + "keywords" : [ + "security", + "disa", + "rmf" + ], + "name" : "cyberperspectives\\sagacity" +} \ No newline at end of file diff --git a/inc/composer.lock b/inc/composer.lock index 398686e..8eaaff6 100644 --- a/inc/composer.lock +++ b/inc/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "92ac4709f5221f74a1c7f00e59df8ad7", + "content-hash": "184b710525eca347d52d3a2062cdf1c7", "packages": [ { "name": "cocur/background-process", @@ -44,6 +44,148 @@ ], "time": "2017-02-11T12:41:41+00:00" }, + { + "name": "godsgood33/php-db", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/godsgood33/php-db.git", + "reference": "cdf01f123c16dcb0b294b3b9013557e2d472f1c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/godsgood33/php-db/zipball/cdf01f123c16dcb0b294b3b9013557e2d472f1c9", + "reference": "cdf01f123c16dcb0b294b3b9013557e2d472f1c9", + "shasum": "" + }, + "require": { + "monolog/monolog": "~1.23" + }, + "require-dev": { + "phpunit/phpunit": "~7.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Godsgood33\\Php_Db\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Ryan Prather", + "email": "godsgood33@gmail.com", + "role": "Developer" + } + ], + "description": "PHP Database Library", + "homepage": "https://github.com/godsgood33/php-db", + "keywords": [ + "database", + "library", + "mysql", + "mysqli" + ], + "time": "2018-06-07T18:30:13+00:00" + }, + { + "name": "markbaker/complex", + "version": "1.4.6", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/a78d82ae4e682c3809fc3023d1b0ce654f6ab12b", + "reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b", + "shasum": "" + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", + "phpcompatibility/php-compatibility": "^8.0", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "2.*", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^4.8.35|^5.4.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "^3.3.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + }, + "files": [ + "classes/src/functions/abs.php", + "classes/src/functions/acos.php", + "classes/src/functions/acosh.php", + "classes/src/functions/acot.php", + "classes/src/functions/acoth.php", + "classes/src/functions/acsc.php", + "classes/src/functions/acsch.php", + "classes/src/functions/argument.php", + "classes/src/functions/asec.php", + "classes/src/functions/asech.php", + "classes/src/functions/asin.php", + "classes/src/functions/asinh.php", + "classes/src/functions/atan.php", + "classes/src/functions/atanh.php", + "classes/src/functions/conjugate.php", + "classes/src/functions/cos.php", + "classes/src/functions/cosh.php", + "classes/src/functions/cot.php", + "classes/src/functions/coth.php", + "classes/src/functions/csc.php", + "classes/src/functions/csch.php", + "classes/src/functions/exp.php", + "classes/src/functions/inverse.php", + "classes/src/functions/ln.php", + "classes/src/functions/log2.php", + "classes/src/functions/log10.php", + "classes/src/functions/negative.php", + "classes/src/functions/pow.php", + "classes/src/functions/rho.php", + "classes/src/functions/sec.php", + "classes/src/functions/sech.php", + "classes/src/functions/sin.php", + "classes/src/functions/sinh.php", + "classes/src/functions/sqrt.php", + "classes/src/functions/tan.php", + "classes/src/functions/tanh.php", + "classes/src/functions/theta.php", + "classes/src/operations/add.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/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "time": "2018-07-31T08:38:40+00:00" + }, { "name": "monolog/monolog", "version": "1.23.0", @@ -124,33 +266,59 @@ }, { "name": "pacificsec/cpe", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/pacificsec/cpe.git", - "reference": "3d78d66fc4ea249b6f353a7c48f426835a792d11" + "reference": "52cc49e04388ba00493be634287f6ce3efb30afc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pacificsec/cpe/zipball/3d78d66fc4ea249b6f353a7c48f426835a792d11", - "reference": "3d78d66fc4ea249b6f353a7c48f426835a792d11", + "url": "https://api.github.com/repos/pacificsec/cpe/zipball/52cc49e04388ba00493be634287f6ce3efb30afc", + "reference": "52cc49e04388ba00493be634287f6ce3efb30afc", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, "type": "library", - "notification-url": "https://packagist.org/downloads/" + "autoload": { + "psr-4": { + "PacificSec\\CPE\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Franco", + "email": "antonio.franco@pacificsec.com" + } + ], + "description": "CPE: Common Platform Enumeration for PHP", + "homepage": "https://github.com/pacificsec/cpe", + "keywords": [ + "cpe", + "cve", + "pacificsec", + "security" + ], + "time": "2018-08-22T17:55:09+00:00" }, { "name": "phpoffice/phpspreadsheet", - "version": "1.2.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "36acc372875c4d894dc093825ce4f62209db5a76" + "reference": "125f462a718956f37d81305ca0df4f17cef0f3b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/36acc372875c4d894dc093825ce4f62209db5a76", - "reference": "36acc372875c4d894dc093825ce4f62209db5a76", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/125f462a718956f37d81305ca0df4f17cef0f3b9", + "reference": "125f462a718956f37d81305ca0df4f17cef0f3b9", "shasum": "" }, "require": { @@ -166,6 +334,7 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", + "markbaker/complex": "^1.4.1", "php": "^5.6|^7.0", "psr/simple-cache": "^1.0" }, @@ -175,7 +344,7 @@ "jpgraph/jpgraph": "^4.0", "mpdf/mpdf": "^7.0.0", "phpunit/phpunit": "^5.7", - "squizlabs/php_codesniffer": "^2.7", + "squizlabs/php_codesniffer": "^3.3", "tecnickcom/tcpdf": "^6.2" }, "suggest": { @@ -223,7 +392,7 @@ "xls", "xlsx" ], - "time": "2018-04-10T03:53:16+00:00" + "time": "2018-08-06T02:58:06+00:00" }, { "name": "psr/log", @@ -440,16 +609,16 @@ }, { "name": "myclabs/deep-copy", - "version": "1.8.0", + "version": "1.8.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6" + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/478465659fd987669df0bd8a9bf22a8710e5f1b6", - "reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", + "reference": "3e01bdad3e18354c3dce54466b7fbe33a9f9f7f8", "shasum": "" }, "require": { @@ -484,26 +653,26 @@ "object", "object graph" ], - "time": "2018-05-29T17:25:09+00:00" + "time": "2018-06-11T23:09:50+00:00" }, { "name": "phar-io/manifest", - "version": "1.0.1", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", - "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^1.0.1", + "phar-io/version": "^2.0", "php": "^5.6 || ^7.0" }, "type": "library", @@ -539,20 +708,20 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2017-03-05T18:14:27+00:00" + "time": "2018-07-08T19:23:20+00:00" }, { "name": "phar-io/version", - "version": "1.0.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", - "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", "shasum": "" }, "require": { @@ -586,7 +755,7 @@ } ], "description": "Library for handling version information and constraints", - "time": "2017-03-05T17:38:23+00:00" + "time": "2018-07-08T19:19:57+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -742,16 +911,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.7.6", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", - "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/4ba436b55987b4bf311cb7c6ba82aa528aac0a06", + "reference": "4ba436b55987b4bf311cb7c6ba82aa528aac0a06", "shasum": "" }, "require": { @@ -763,12 +932,12 @@ }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.7.x-dev" + "dev-master": "1.8.x-dev" } }, "autoload": { @@ -801,44 +970,44 @@ "spy", "stub" ], - "time": "2018-04-18T13:57:24+00:00" + "time": "2018-08-05T17:53:17+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "5.3.2", + "version": "6.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac" + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c89677919c5dd6d3b3852f230a663118762218ac", - "reference": "c89677919c5dd6d3b3852f230a663118762218ac", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a", + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^7.0", - "phpunit/php-file-iterator": "^1.4.2", + "php": "^7.1", + "phpunit/php-file-iterator": "^2.0", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-token-stream": "^2.0.1", + "phpunit/php-token-stream": "^3.0", "sebastian/code-unit-reverse-lookup": "^1.0.1", - "sebastian/environment": "^3.0", + "sebastian/environment": "^3.1", "sebastian/version": "^2.0.1", "theseer/tokenizer": "^1.1" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^7.0" }, "suggest": { - "ext-xdebug": "^2.5.5" + "ext-xdebug": "^2.6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.3.x-dev" + "dev-master": "6.0-dev" } }, "autoload": { @@ -864,29 +1033,29 @@ "testing", "xunit" ], - "time": "2018-04-06T15:36:58+00:00" + "time": "2018-06-01T07:51:50+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cecbc684605bb0cc288828eb5d65d93d5c676d3c", + "reference": "cecbc684605bb0cc288828eb5d65d93d5c676d3c", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -901,7 +1070,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -911,7 +1080,7 @@ "filesystem", "iterator" ], - "time": "2017-11-27T13:52:08+00:00" + "time": "2018-06-11T11:44:00+00:00" }, { "name": "phpunit/php-text-template", @@ -956,28 +1125,28 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.9", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -992,7 +1161,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -1001,33 +1170,33 @@ "keywords": [ "timer" ], - "time": "2017-02-26T11:10:40+00:00" + "time": "2018-02-01T13:07:23+00:00" }, { "name": "phpunit/php-token-stream", - "version": "2.0.2", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "791198a2c6254db10131eecfe8c06670700904db" + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/791198a2c6254db10131eecfe8c06670700904db", - "reference": "791198a2c6254db10131eecfe8c06670700904db", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.2.4" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1050,40 +1219,40 @@ "keywords": [ "tokenizer" ], - "time": "2017-11-27T05:48:46+00:00" + "time": "2018-02-01T13:16:43+00:00" }, { "name": "phpunit/phpunit", - "version": "6.5.8", + "version": "7.3.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "4f21a3c6b97c42952fd5c2837bb354ec0199b97b" + "reference": "34705f81bddc3f505b9599a2ef96e2b4315ba9b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/4f21a3c6b97c42952fd5c2837bb354ec0199b97b", - "reference": "4f21a3c6b97c42952fd5c2837bb354ec0199b97b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/34705f81bddc3f505b9599a2ef96e2b4315ba9b8", + "reference": "34705f81bddc3f505b9599a2ef96e2b4315ba9b8", "shasum": "" }, "require": { + "doctrine/instantiator": "^1.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "^1.6.1", - "phar-io/manifest": "^1.0.1", - "phar-io/version": "^1.0", - "php": "^7.0", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.2", + "phar-io/version": "^2.0", + "php": "^7.1", "phpspec/prophecy": "^1.7", - "phpunit/php-code-coverage": "^5.3", - "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-file-iterator": "^2.0.1", "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^1.0.9", - "phpunit/phpunit-mock-objects": "^5.0.5", - "sebastian/comparator": "^2.1", - "sebastian/diff": "^2.0", + "phpunit/php-timer": "^2.0", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", "sebastian/environment": "^3.1", "sebastian/exporter": "^3.1", "sebastian/global-state": "^2.0", @@ -1092,15 +1261,15 @@ "sebastian/version": "^2.0.1" }, "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2", - "phpunit/dbunit": "<3.0" + "phpunit/phpunit-mock-objects": "*" }, "require-dev": { "ext-pdo": "*" }, "suggest": { + "ext-soap": "*", "ext-xdebug": "*", - "phpunit/php-invoker": "^1.1" + "phpunit/php-invoker": "^2.0" }, "bin": [ "phpunit" @@ -1108,7 +1277,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "6.5.x-dev" + "dev-master": "7.3-dev" } }, "autoload": { @@ -1134,66 +1303,7 @@ "testing", "xunit" ], - "time": "2018-04-10T11:38:34+00:00" - }, - { - "name": "phpunit/phpunit-mock-objects", - "version": "5.0.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/3eaf040f20154d27d6da59ca2c6e28ac8fd56dce", - "reference": "3eaf040f20154d27d6da59ca2c6e28ac8fd56dce", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.0.5", - "php": "^7.0", - "phpunit/php-text-template": "^1.2.1", - "sebastian/exporter": "^3.1" - }, - "conflict": { - "phpunit/phpunit": "<6.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.5" - }, - "suggest": { - "ext-soap": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" - ], - "time": "2018-05-29T13:50:43+00:00" + "time": "2018-08-22T06:39:21+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", @@ -1242,30 +1352,30 @@ }, { "name": "sebastian/comparator", - "version": "2.1.3", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", - "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/5de4fc177adf9bce8df98d8d141a7559d7ccf6da", + "reference": "5de4fc177adf9bce8df98d8d141a7559d7ccf6da", "shasum": "" }, "require": { - "php": "^7.0", - "sebastian/diff": "^2.0 || ^3.0", + "php": "^7.1", + "sebastian/diff": "^3.0", "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^6.4" + "phpunit/phpunit": "^7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1302,32 +1412,33 @@ "compare", "equality" ], - "time": "2018-02-01T13:46:46+00:00" + "time": "2018-07-12T15:12:46+00:00" }, { "name": "sebastian/diff", - "version": "2.0.1", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd" + "reference": "366541b989927187c4ca70490a35615d3fef2dce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", - "reference": "347c1d8b49c5c3ee30c7040ea6fc446790e6bddd", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/366541b989927187c4ca70490a35615d3fef2dce", + "reference": "366541b989927187c4ca70490a35615d3fef2dce", "shasum": "" }, "require": { - "php": "^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^6.2" + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1352,9 +1463,12 @@ "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "diff" + "diff", + "udiff", + "unidiff", + "unified diff" ], - "time": "2017-08-03T08:09:46+00:00" + "time": "2018-06-10T07:54:39+00:00" }, { "name": "sebastian/environment", diff --git a/inc/vendor/cocur/background-process/src/BackgroundProcess.php b/inc/vendor/cocur/background-process/src/BackgroundProcess.php index 938b633..2cc354f 100644 --- a/inc/vendor/cocur/background-process/src/BackgroundProcess.php +++ b/inc/vendor/cocur/background-process/src/BackgroundProcess.php @@ -186,7 +186,7 @@ class BackgroundProcess { /** * @param int $pid PID of process to resume * - * @return Cocur\BackgroundProcess\BackgroundProcess + * @return BackgroundProcess */ static public function createFromPID($pid) { $process = new self(); diff --git a/inc/vendor/composer/autoload_files.php b/inc/vendor/composer/autoload_files.php index d931b8f..23129e8 100644 --- a/inc/vendor/composer/autoload_files.php +++ b/inc/vendor/composer/autoload_files.php @@ -6,5 +6,46 @@ $vendorDir = dirname(dirname(__FILE__)); $baseDir = dirname($vendorDir); return array( - '6124b4c8570aa390c21fafd04a26c69f' => $vendorDir . '/myclabs/deep-copy/src/DeepCopy/deep_copy.php', + 'abede361264e2ae69ec1eee813a101af' => $vendorDir . '/markbaker/complex/classes/src/functions/abs.php', + '21a5860fbef5be28db5ddfbc3cca67c4' => $vendorDir . '/markbaker/complex/classes/src/functions/acos.php', + '1546e3f9d127f2a9bb2d1b6c31c26ef1' => $vendorDir . '/markbaker/complex/classes/src/functions/acosh.php', + 'd2516f7f4fba5ea5905f494b4a8262e0' => $vendorDir . '/markbaker/complex/classes/src/functions/acot.php', + '4511163d560956219b96882c0980b65e' => $vendorDir . '/markbaker/complex/classes/src/functions/acoth.php', + 'c361f5616dc2a8da4fa3e137077cd4ea' => $vendorDir . '/markbaker/complex/classes/src/functions/acsc.php', + '02d68920fc98da71991ce569c91df0f6' => $vendorDir . '/markbaker/complex/classes/src/functions/acsch.php', + '88e19525eae308b4a6aa3419364875d3' => $vendorDir . '/markbaker/complex/classes/src/functions/argument.php', + '60e8e2d0827b58bfc904f13957e51849' => $vendorDir . '/markbaker/complex/classes/src/functions/asec.php', + '13d2f040713999eab66c359b4d79871d' => $vendorDir . '/markbaker/complex/classes/src/functions/asech.php', + '838ab38beb32c68a79d3cd2c007d5a04' => $vendorDir . '/markbaker/complex/classes/src/functions/asin.php', + 'bb28eccd0f8f008333a1b3c163d604ac' => $vendorDir . '/markbaker/complex/classes/src/functions/asinh.php', + '9e483de83558c98f7d3feaa402c78cb3' => $vendorDir . '/markbaker/complex/classes/src/functions/atan.php', + '36b74b5b765ded91ee58c8ee3c0e85e3' => $vendorDir . '/markbaker/complex/classes/src/functions/atanh.php', + '05c15ee9510da7fd6bf6136f436500c0' => $vendorDir . '/markbaker/complex/classes/src/functions/conjugate.php', + 'd3208dfbce2505e370788f9f22f6785f' => $vendorDir . '/markbaker/complex/classes/src/functions/cos.php', + '141cf1fb3a3046f8b64534b0ebab33ca' => $vendorDir . '/markbaker/complex/classes/src/functions/cosh.php', + 'be660df75fd0dbe7fa7c03b7434b3294' => $vendorDir . '/markbaker/complex/classes/src/functions/cot.php', + '01e31ea298a51bc9e91517e3ce6b9e76' => $vendorDir . '/markbaker/complex/classes/src/functions/coth.php', + '803ddd97f7b1da68982a7b087c3476f6' => $vendorDir . '/markbaker/complex/classes/src/functions/csc.php', + '3001cdfd101ec3c32da34ee43c2e149b' => $vendorDir . '/markbaker/complex/classes/src/functions/csch.php', + '77b2d7629ef2a93fabb8c56754a91051' => $vendorDir . '/markbaker/complex/classes/src/functions/exp.php', + '4a4471296dec796c21d4f4b6552396a9' => $vendorDir . '/markbaker/complex/classes/src/functions/inverse.php', + 'c3e9897e1744b88deb56fcdc39d34d85' => $vendorDir . '/markbaker/complex/classes/src/functions/ln.php', + 'a83cacf2de942cff288de15a83afd26d' => $vendorDir . '/markbaker/complex/classes/src/functions/log2.php', + '6a861dacc9ee2f3061241d4c7772fa21' => $vendorDir . '/markbaker/complex/classes/src/functions/log10.php', + '4d2522d968c8ba78d6c13548a1b4200e' => $vendorDir . '/markbaker/complex/classes/src/functions/negative.php', + 'fd587ca933fc0447fa5ab4843bdd97f7' => $vendorDir . '/markbaker/complex/classes/src/functions/pow.php', + '383ef01c62028fc78cd4388082fce3c2' => $vendorDir . '/markbaker/complex/classes/src/functions/rho.php', + '150fbd1b95029dc47292da97ecab9375' => $vendorDir . '/markbaker/complex/classes/src/functions/sec.php', + '549abd9bae174286d660bdaa07407c68' => $vendorDir . '/markbaker/complex/classes/src/functions/sech.php', + '6bfbf5eaea6b17a0ed85cb21ba80370c' => $vendorDir . '/markbaker/complex/classes/src/functions/sin.php', + '22efe13f1a497b8e199540ae2d9dc59c' => $vendorDir . '/markbaker/complex/classes/src/functions/sinh.php', + 'e90135ab8e787795a509ed7147de207d' => $vendorDir . '/markbaker/complex/classes/src/functions/sqrt.php', + 'bb0a7923ffc6a90919cd64ec54ff06bc' => $vendorDir . '/markbaker/complex/classes/src/functions/tan.php', + '2d302f32ce0fd4e433dd91c5bb404a28' => $vendorDir . '/markbaker/complex/classes/src/functions/tanh.php', + '24dd4658a952171a4ee79218c4f9fd06' => $vendorDir . '/markbaker/complex/classes/src/functions/theta.php', + 'e49b7876281d6f5bc39536dde96d1f4a' => $vendorDir . '/markbaker/complex/classes/src/operations/add.php', + '47596e02b43cd6da7700134fd08f88cf' => $vendorDir . '/markbaker/complex/classes/src/operations/subtract.php', + '883af48563631547925fa4c3b48ead07' => $vendorDir . '/markbaker/complex/classes/src/operations/multiply.php', + 'f190e3308e6ca23234a2875edc985c03' => $vendorDir . '/markbaker/complex/classes/src/operations/divideby.php', + 'ac9e33ce6841aa5bf5d16d465a2f03a7' => $vendorDir . '/markbaker/complex/classes/src/operations/divideinto.php', ); diff --git a/inc/vendor/composer/autoload_psr4.php b/inc/vendor/composer/autoload_psr4.php index 111fd3c..076955b 100644 --- a/inc/vendor/composer/autoload_psr4.php +++ b/inc/vendor/composer/autoload_psr4.php @@ -9,6 +9,9 @@ return array( 'Psr\\SimpleCache\\' => array($vendorDir . '/psr/simple-cache/src'), 'Psr\\Log\\' => array($vendorDir . '/psr/log/Psr/Log'), 'PhpOffice\\PhpSpreadsheet\\' => array($vendorDir . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet'), + 'PacificSec\\CPE\\' => array($vendorDir . '/pacificsec/cpe/src'), 'Monolog\\' => array($vendorDir . '/monolog/monolog/src/Monolog'), + 'Godsgood33\\Php_Db\\' => array($vendorDir . '/godsgood33/php-db/src'), + 'Complex\\' => array($vendorDir . '/markbaker/complex/classes/src'), 'Cocur\\BackgroundProcess\\' => array($vendorDir . '/cocur/background-process/src'), ); diff --git a/inc/vendor/composer/autoload_real.php b/inc/vendor/composer/autoload_real.php index 38c051b..73421f3 100644 --- a/inc/vendor/composer/autoload_real.php +++ b/inc/vendor/composer/autoload_real.php @@ -47,6 +47,24 @@ class ComposerAutoloaderInit69a0c53551ee5f4e61c53efb549e5e72 $loader->register(true); + if ($useStaticLoader) { + $includeFiles = Composer\Autoload\ComposerStaticInit69a0c53551ee5f4e61c53efb549e5e72::$files; + } else { + $includeFiles = require __DIR__ . '/autoload_files.php'; + } + foreach ($includeFiles as $fileIdentifier => $file) { + composerRequire69a0c53551ee5f4e61c53efb549e5e72($fileIdentifier, $file); + } + return $loader; } } + +function composerRequire69a0c53551ee5f4e61c53efb549e5e72($fileIdentifier, $file) +{ + if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { + require $file; + + $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; + } +} diff --git a/inc/vendor/composer/autoload_static.php b/inc/vendor/composer/autoload_static.php index 7f8651d..42ceafc 100644 --- a/inc/vendor/composer/autoload_static.php +++ b/inc/vendor/composer/autoload_static.php @@ -6,19 +6,70 @@ namespace Composer\Autoload; class ComposerStaticInit69a0c53551ee5f4e61c53efb549e5e72 { + public static $files = array ( + 'abede361264e2ae69ec1eee813a101af' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/abs.php', + '21a5860fbef5be28db5ddfbc3cca67c4' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acos.php', + '1546e3f9d127f2a9bb2d1b6c31c26ef1' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acosh.php', + 'd2516f7f4fba5ea5905f494b4a8262e0' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acot.php', + '4511163d560956219b96882c0980b65e' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acoth.php', + 'c361f5616dc2a8da4fa3e137077cd4ea' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acsc.php', + '02d68920fc98da71991ce569c91df0f6' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/acsch.php', + '88e19525eae308b4a6aa3419364875d3' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/argument.php', + '60e8e2d0827b58bfc904f13957e51849' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/asec.php', + '13d2f040713999eab66c359b4d79871d' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/asech.php', + '838ab38beb32c68a79d3cd2c007d5a04' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/asin.php', + 'bb28eccd0f8f008333a1b3c163d604ac' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/asinh.php', + '9e483de83558c98f7d3feaa402c78cb3' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/atan.php', + '36b74b5b765ded91ee58c8ee3c0e85e3' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/atanh.php', + '05c15ee9510da7fd6bf6136f436500c0' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/conjugate.php', + 'd3208dfbce2505e370788f9f22f6785f' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/cos.php', + '141cf1fb3a3046f8b64534b0ebab33ca' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/cosh.php', + 'be660df75fd0dbe7fa7c03b7434b3294' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/cot.php', + '01e31ea298a51bc9e91517e3ce6b9e76' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/coth.php', + '803ddd97f7b1da68982a7b087c3476f6' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/csc.php', + '3001cdfd101ec3c32da34ee43c2e149b' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/csch.php', + '77b2d7629ef2a93fabb8c56754a91051' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/exp.php', + '4a4471296dec796c21d4f4b6552396a9' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/inverse.php', + 'c3e9897e1744b88deb56fcdc39d34d85' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/ln.php', + 'a83cacf2de942cff288de15a83afd26d' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/log2.php', + '6a861dacc9ee2f3061241d4c7772fa21' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/log10.php', + '4d2522d968c8ba78d6c13548a1b4200e' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/negative.php', + 'fd587ca933fc0447fa5ab4843bdd97f7' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/pow.php', + '383ef01c62028fc78cd4388082fce3c2' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/rho.php', + '150fbd1b95029dc47292da97ecab9375' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sec.php', + '549abd9bae174286d660bdaa07407c68' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sech.php', + '6bfbf5eaea6b17a0ed85cb21ba80370c' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sin.php', + '22efe13f1a497b8e199540ae2d9dc59c' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sinh.php', + 'e90135ab8e787795a509ed7147de207d' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/sqrt.php', + 'bb0a7923ffc6a90919cd64ec54ff06bc' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/tan.php', + '2d302f32ce0fd4e433dd91c5bb404a28' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/tanh.php', + '24dd4658a952171a4ee79218c4f9fd06' => __DIR__ . '/..' . '/markbaker/complex/classes/src/functions/theta.php', + 'e49b7876281d6f5bc39536dde96d1f4a' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/add.php', + '47596e02b43cd6da7700134fd08f88cf' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/subtract.php', + '883af48563631547925fa4c3b48ead07' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/multiply.php', + 'f190e3308e6ca23234a2875edc985c03' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/divideby.php', + 'ac9e33ce6841aa5bf5d16d465a2f03a7' => __DIR__ . '/..' . '/markbaker/complex/classes/src/operations/divideinto.php', + ); + public static $prefixLengthsPsr4 = array ( 'P' => array ( 'Psr\\SimpleCache\\' => 16, 'Psr\\Log\\' => 8, 'PhpOffice\\PhpSpreadsheet\\' => 25, + 'PacificSec\\CPE\\' => 15, ), 'M' => array ( 'Monolog\\' => 8, ), + 'G' => + array ( + 'Godsgood33\\Php_Db\\' => 18, + ), 'C' => array ( + 'Complex\\' => 8, 'Cocur\\BackgroundProcess\\' => 24, ), ); @@ -36,10 +87,22 @@ class ComposerStaticInit69a0c53551ee5f4e61c53efb549e5e72 array ( 0 => __DIR__ . '/..' . '/phpoffice/phpspreadsheet/src/PhpSpreadsheet', ), + 'PacificSec\\CPE\\' => + array ( + 0 => __DIR__ . '/..' . '/pacificsec/cpe/src', + ), 'Monolog\\' => array ( 0 => __DIR__ . '/..' . '/monolog/monolog/src/Monolog', ), + 'Godsgood33\\Php_Db\\' => + array ( + 0 => __DIR__ . '/..' . '/godsgood33/php-db/src', + ), + 'Complex\\' => + array ( + 0 => __DIR__ . '/..' . '/markbaker/complex/classes/src', + ), 'Cocur\\BackgroundProcess\\' => array ( 0 => __DIR__ . '/..' . '/cocur/background-process/src', diff --git a/inc/vendor/composer/installed.json b/inc/vendor/composer/installed.json index bc55cf8..ddbe219 100644 --- a/inc/vendor/composer/installed.json +++ b/inc/vendor/composer/installed.json @@ -39,6 +39,152 @@ "unix" ] }, + { + "name": "godsgood33/php-db", + "version": "1.3.1", + "version_normalized": "1.3.1.0", + "source": { + "type": "git", + "url": "https://github.com/godsgood33/php-db.git", + "reference": "cdf01f123c16dcb0b294b3b9013557e2d472f1c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/godsgood33/php-db/zipball/cdf01f123c16dcb0b294b3b9013557e2d472f1c9", + "reference": "cdf01f123c16dcb0b294b3b9013557e2d472f1c9", + "shasum": "" + }, + "require": { + "monolog/monolog": "~1.23" + }, + "require-dev": { + "phpunit/phpunit": "~7.2" + }, + "time": "2018-06-07T18:30:13+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Godsgood33\\Php_Db\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Ryan Prather", + "email": "godsgood33@gmail.com", + "role": "Developer" + } + ], + "description": "PHP Database Library", + "homepage": "https://github.com/godsgood33/php-db", + "keywords": [ + "database", + "library", + "mysql", + "mysqli" + ] + }, + { + "name": "markbaker/complex", + "version": "1.4.6", + "version_normalized": "1.4.6.0", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/a78d82ae4e682c3809fc3023d1b0ce654f6ab12b", + "reference": "a78d82ae4e682c3809fc3023d1b0ce654f6ab12b", + "shasum": "" + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", + "phpcompatibility/php-compatibility": "^8.0", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "2.*", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^4.8.35|^5.4.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "^3.3.0" + }, + "time": "2018-07-31T08:38:40+00:00", + "type": "library", + "installation-source": "dist", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + }, + "files": [ + "classes/src/functions/abs.php", + "classes/src/functions/acos.php", + "classes/src/functions/acosh.php", + "classes/src/functions/acot.php", + "classes/src/functions/acoth.php", + "classes/src/functions/acsc.php", + "classes/src/functions/acsch.php", + "classes/src/functions/argument.php", + "classes/src/functions/asec.php", + "classes/src/functions/asech.php", + "classes/src/functions/asin.php", + "classes/src/functions/asinh.php", + "classes/src/functions/atan.php", + "classes/src/functions/atanh.php", + "classes/src/functions/conjugate.php", + "classes/src/functions/cos.php", + "classes/src/functions/cosh.php", + "classes/src/functions/cot.php", + "classes/src/functions/coth.php", + "classes/src/functions/csc.php", + "classes/src/functions/csch.php", + "classes/src/functions/exp.php", + "classes/src/functions/inverse.php", + "classes/src/functions/ln.php", + "classes/src/functions/log2.php", + "classes/src/functions/log10.php", + "classes/src/functions/negative.php", + "classes/src/functions/pow.php", + "classes/src/functions/rho.php", + "classes/src/functions/sec.php", + "classes/src/functions/sech.php", + "classes/src/functions/sin.php", + "classes/src/functions/sinh.php", + "classes/src/functions/sqrt.php", + "classes/src/functions/tan.php", + "classes/src/functions/tanh.php", + "classes/src/functions/theta.php", + "classes/src/operations/add.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/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ] + }, { "name": "monolog/monolog", "version": "1.23.0", @@ -121,36 +267,62 @@ }, { "name": "pacificsec/cpe", - "version": "1.0.0", - "version_normalized": "1.0.0.0", + "version": "1.0.1", + "version_normalized": "1.0.1.0", "source": { "type": "git", "url": "https://github.com/pacificsec/cpe.git", - "reference": "3d78d66fc4ea249b6f353a7c48f426835a792d11" + "reference": "52cc49e04388ba00493be634287f6ce3efb30afc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pacificsec/cpe/zipball/3d78d66fc4ea249b6f353a7c48f426835a792d11", - "reference": "3d78d66fc4ea249b6f353a7c48f426835a792d11", + "url": "https://api.github.com/repos/pacificsec/cpe/zipball/52cc49e04388ba00493be634287f6ce3efb30afc", + "reference": "52cc49e04388ba00493be634287f6ce3efb30afc", "shasum": "" }, + "require": { + "php": ">=5.3.0" + }, + "time": "2018-08-22T17:55:09+00:00", "type": "library", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/" + "installation-source": "source", + "autoload": { + "psr-4": { + "PacificSec\\CPE\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Antonio Franco", + "email": "antonio.franco@pacificsec.com" + } + ], + "description": "CPE: Common Platform Enumeration for PHP", + "homepage": "https://github.com/pacificsec/cpe", + "keywords": [ + "cpe", + "cve", + "pacificsec", + "security" + ] }, { "name": "phpoffice/phpspreadsheet", - "version": "1.2.1", - "version_normalized": "1.2.1.0", + "version": "1.4.0", + "version_normalized": "1.4.0.0", "source": { "type": "git", "url": "https://github.com/PHPOffice/PhpSpreadsheet.git", - "reference": "36acc372875c4d894dc093825ce4f62209db5a76" + "reference": "125f462a718956f37d81305ca0df4f17cef0f3b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/36acc372875c4d894dc093825ce4f62209db5a76", - "reference": "36acc372875c4d894dc093825ce4f62209db5a76", + "url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/125f462a718956f37d81305ca0df4f17cef0f3b9", + "reference": "125f462a718956f37d81305ca0df4f17cef0f3b9", "shasum": "" }, "require": { @@ -166,6 +338,7 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", + "markbaker/complex": "^1.4.1", "php": "^5.6|^7.0", "psr/simple-cache": "^1.0" }, @@ -175,7 +348,7 @@ "jpgraph/jpgraph": "^4.0", "mpdf/mpdf": "^7.0.0", "phpunit/phpunit": "^5.7", - "squizlabs/php_codesniffer": "^2.7", + "squizlabs/php_codesniffer": "^3.3", "tecnickcom/tcpdf": "^6.2" }, "suggest": { @@ -184,7 +357,7 @@ "mpdf/mpdf": "Option for rendering PDF with PDF Writer", "tecnick.com/tcpdf": "Option for rendering PDF with PDF Writer" }, - "time": "2018-04-10T03:53:16+00:00", + "time": "2018-08-06T02:58:06+00:00", "type": "library", "installation-source": "source", "autoload": { diff --git a/inc/vendor/godsgood33/php-db/.gitattributes b/inc/vendor/godsgood33/php-db/.gitattributes new file mode 100644 index 0000000..bdb0cab --- /dev/null +++ b/inc/vendor/godsgood33/php-db/.gitattributes @@ -0,0 +1,17 @@ +# Auto detect text files and perform LF normalization +* text=auto + +# Custom for Visual Studio +*.cs diff=csharp + +# Standard to msysgit +*.doc diff=astextplain +*.DOC diff=astextplain +*.docx diff=astextplain +*.DOCX diff=astextplain +*.dot diff=astextplain +*.DOT diff=astextplain +*.pdf diff=astextplain +*.PDF diff=astextplain +*.rtf diff=astextplain +*.RTF diff=astextplain diff --git a/inc/vendor/godsgood33/php-db/.gitignore b/inc/vendor/godsgood33/php-db/.gitignore new file mode 100644 index 0000000..b0fbc01 --- /dev/null +++ b/inc/vendor/godsgood33/php-db/.gitignore @@ -0,0 +1,4 @@ +.settings/ +.buildpath +code-coverage/ +/vendor/ diff --git a/inc/vendor/godsgood33/php-db/.scrutinizer.yml b/inc/vendor/godsgood33/php-db/.scrutinizer.yml new file mode 100644 index 0000000..5653d85 --- /dev/null +++ b/inc/vendor/godsgood33/php-db/.scrutinizer.yml @@ -0,0 +1,26 @@ +checks: + php: true + +filter: + paths: ["src/*"] + +tools: + external_code_coverage: + timeout: 600 + php_sim: true + php_pdepend: true + php_analyzer: true + php_cs_fixer: true + +build: + nodes: + analysis: + tests: + override: + - php-scrutinizer-run + +build_failure_conditions: + - 'elements.rating(<= C).new.exists' # No new classes/methods with a rating of C or worse allowed + - 'issues.severity(>= MAJOR).new.exists' # New issues of major or higher severity + - 'project.metric_change("scrutinizer.test_coverage", < 0)' # Code Coverage decreased from previous inspection + - 'patches.label("Unused Use Statements").new.exists' # No new unused imports patches allowed \ No newline at end of file diff --git a/inc/vendor/godsgood33/php-db/LICENSE b/inc/vendor/godsgood33/php-db/LICENSE new file mode 100644 index 0000000..261eeb9 --- /dev/null +++ b/inc/vendor/godsgood33/php-db/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/inc/vendor/godsgood33/php-db/README.md b/inc/vendor/godsgood33/php-db/README.md new file mode 100644 index 0000000..80e7912 Binary files /dev/null and b/inc/vendor/godsgood33/php-db/README.md differ diff --git a/inc/vendor/godsgood33/php-db/composer.json b/inc/vendor/godsgood33/php-db/composer.json new file mode 100644 index 0000000..0af1d3a --- /dev/null +++ b/inc/vendor/godsgood33/php-db/composer.json @@ -0,0 +1,37 @@ +{ + "require" : { + "monolog/monolog" : "~1.23" + }, + "name" : "godsgood33/php-db", + "description" : "PHP Database Library", + "homepage" : "https://github.com/godsgood33/php-db", + "license" : "Apache-2.0", + "minimum-stability" : "beta", + "authors" : [{ + "name" : "Ryan Prather", + "email" : "godsgood33@gmail.com", + "role" : "Developer" + } + ], + "support" : { + "source" : "https://github.com/godsgood33/php-db" + }, + "autoload" : { + "psr-4" : { + "Godsgood33\\Php_Db\\" : "src" + } + }, + "type" : "library", + "keywords" : [ + "database", + "library", + "mysql", + "mysqli" + ], + "config" : { + "vendor-dir" : "vendor" + }, + "require-dev" : { + "phpunit/phpunit" : "~7.2" + } +} \ No newline at end of file diff --git a/inc/vendor/godsgood33/php-db/composer.lock b/inc/vendor/godsgood33/php-db/composer.lock new file mode 100644 index 0000000..8188001 --- /dev/null +++ b/inc/vendor/godsgood33/php-db/composer.lock @@ -0,0 +1,1549 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "content-hash": "0c344a5863d864e2eda66940b82218ce", + "packages": [ + { + "name": "monolog/monolog", + "version": "1.23.0", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/monolog.git", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/log": "~1.0" + }, + "provide": { + "psr/log-implementation": "1.0.0" + }, + "require-dev": { + "aws/aws-sdk-php": "^2.4.9 || ^3.0", + "doctrine/couchdb": "~1.0@dev", + "graylog2/gelf-php": "~1.0", + "jakub-onderka/php-parallel-lint": "0.9", + "php-amqplib/php-amqplib": "~2.4", + "php-console/php-console": "^3.1.3", + "phpunit/phpunit": "~4.5", + "phpunit/phpunit-mock-objects": "2.3.0", + "ruflin/elastica": ">=0.90 <3.0", + "sentry/sentry": "^0.13", + "swiftmailer/swiftmailer": "^5.3|^6.0" + }, + "suggest": { + "aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB", + "doctrine/couchdb": "Allow sending log messages to a CouchDB server", + "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-mongo": "Allow sending log messages to a MongoDB server", + "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", + "mongodb/mongodb": "Allow sending log messages to a MongoDB server via PHP Driver", + "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", + "php-console/php-console": "Allow sending log messages to Google Chrome", + "rollbar/rollbar": "Allow sending log messages to Rollbar", + "ruflin/elastica": "Allow sending log messages to an Elastic Search server", + "sentry/sentry": "Allow sending log messages to a Sentry server" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Monolog\\": "src/Monolog" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Sends your logs to files, sockets, inboxes, databases and various web services", + "homepage": "http://github.com/Seldaek/monolog", + "keywords": [ + "log", + "logging", + "psr-3" + ], + "time": "2017-06-19T01:22:40+00:00" + }, + { + "name": "psr/log", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "Psr/Log/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "time": "2016-10-10T12:19:37+00:00" + } + ], + "packages-dev": [ + { + "name": "doctrine/instantiator", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "reference": "185b8868aa9bf7159f5f953ed5afb2d7fcdc3bda", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "athletic/athletic": "~0.1.8", + "ext-pdo": "*", + "ext-phar": "*", + "phpunit/phpunit": "^6.2.3", + "squizlabs/php_codesniffer": "^3.0.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://github.com/doctrine/instantiator", + "keywords": [ + "constructor", + "instantiate" + ], + "time": "2017-07-22T11:58:36+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/478465659fd987669df0bd8a9bf22a8710e5f1b6", + "reference": "478465659fd987669df0bd8a9bf22a8710e5f1b6", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "time": "2018-05-29T17:25:09+00:00" + }, + { + "name": "phar-io/manifest", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/2df402786ab5368a0169091f61a7c1e0eb6852d0", + "reference": "2df402786ab5368a0169091f61a7c1e0eb6852d0", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-03-05T18:14:27+00:00" + }, + { + "name": "phar-io/version", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "shasum": "" + }, + "require": { + "php": ">=5.5" + }, + "require-dev": { + "phpunit/phpunit": "^4.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2017-09-11T18:02:19+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "4.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/94fd0001232e47129dd3504189fa1c7225010d08", + "reference": "94fd0001232e47129dd3504189fa1c7225010d08", + "shasum": "" + }, + "require": { + "php": "^7.0", + "phpdocumentor/reflection-common": "^1.0.0", + "phpdocumentor/type-resolver": "^0.4.0", + "webmozart/assert": "^1.0" + }, + "require-dev": { + "doctrine/instantiator": "~1.0.5", + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2017-11-30T07:14:17+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "0.4.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", + "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "shasum": "" + }, + "require": { + "php": "^5.5 || ^7.0", + "phpdocumentor/reflection-common": "^1.0" + }, + "require-dev": { + "mockery/mockery": "^0.9.4", + "phpunit/phpunit": "^5.2||^4.8.24" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "time": "2017-07-14T14:27:02+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.7.6", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "reference": "33a7e3c4fda54e912ff6338c48823bd5c0f0b712", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.0.2", + "php": "^5.3|^7.0", + "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0", + "sebastian/comparator": "^1.1|^2.0|^3.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" + }, + "require-dev": { + "phpspec/phpspec": "^2.5|^3.2", + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.7.x-dev" + } + }, + "autoload": { + "psr-0": { + "Prophecy\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2018-04-18T13:57:24+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "6.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/865662550c384bc1db7e51d29aeda1c2c161d69a", + "reference": "865662550c384bc1db7e51d29aeda1c2c161d69a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-xmlwriter": "*", + "php": "^7.1", + "phpunit/php-file-iterator": "^2.0", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.1", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "suggest": { + "ext-xdebug": "^2.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "time": "2018-06-01T07:51:50+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "e20525b0c2945c7c317fff95660698cb3d2a53bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/e20525b0c2945c7c317fff95660698cb3d2a53bc", + "reference": "e20525b0c2945c7c317fff95660698cb3d2a53bc", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "time": "2018-05-28T12:13:49+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "time": "2015-06-21T13:50:34+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "time": "2018-02-01T13:07:23+00:00" + }, + { + "name": "phpunit/php-token-stream", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "keywords": [ + "tokenizer" + ], + "time": "2018-02-01T13:16:43+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "7.2.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "00bc0b93f0ff4f557e9ea766557fde96da9a03dd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/00bc0b93f0ff4f557e9ea766557fde96da9a03dd", + "reference": "00bc0b93f0ff4f557e9ea766557fde96da9a03dd", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "myclabs/deep-copy": "^1.7", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0.7", + "phpunit/php-file-iterator": "^2.0", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "sebastian/comparator": "^3.0", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" + }, + "conflict": { + "phpunit/phpunit-mock-objects": "*" + }, + "require-dev": { + "ext-pdo": "*" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*", + "phpunit/php-invoker": "^2.0" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "time": "2018-06-05T03:40:05+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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" + }, + { + "name": "sebastian/comparator", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "reference": "ed5fd2281113729f1ebcc64d101ad66028aeb3d5", + "shasum": "" + }, + "require": { + "php": "^7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "time": "2018-04-18T13:33:00+00:00" + }, + { + "name": "sebastian/diff", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/e09160918c66281713f1c324c1f4c4c3037ba1e8", + "reference": "e09160918c66281713f1c324c1f4c4c3037ba1e8", + "shasum": "" + }, + "require": { + "php": "^7.1" + }, + "require-dev": { + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "time": "2018-02-01T13:45:15+00:00" + }, + { + "name": "sebastian/environment", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "time": "2017-07-01T08:51:00+00:00" + }, + { + "name": "sebastian/exporter", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/234199f4528de6d12aaa58b612e98f7d36adb937", + "reference": "234199f4528de6d12aaa58b612e98f7d36adb937", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "time": "2017-04-03T13:19:02+00:00" + }, + { + "name": "sebastian/global-state", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "time": "2017-04-27T15:39:26+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "reference": "7cfd9e65d11ffb5af41198476395774d4c8a84c5", + "shasum": "" + }, + "require": { + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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" + }, + { + "name": "sebastian/object-reflector", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "773f97c67f28de00d397be301821b06708fca0be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/773f97c67f28de00d397be301821b06708fca0be", + "reference": "773f97c67f28de00d397be301821b06708fca0be", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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" + }, + { + "name": "sebastian/recursion-context", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "reference": "5b0cd723502bac3b006cbf3dbf7a1e3fcefe4fa8", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "time": "2017-03-03T06:23:57+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "shasum": "" + }, + "require": { + "php": ">=5.6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "time": "2015-07-28T20:34:47+00:00" + }, + { + "name": "sebastian/version", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "time": "2016-10-03T07:35:21+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.6", + "sebastian/version": "^1.0.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.3-dev" + } + }, + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2018-01-29T19:49:41+00:00" + } + ], + "aliases": [], + "minimum-stability": "beta", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [] +} diff --git a/inc/vendor/godsgood33/php-db/examples/create_table_json.json b/inc/vendor/godsgood33/php-db/examples/create_table_json.json new file mode 100644 index 0000000..08cc67a --- /dev/null +++ b/inc/vendor/godsgood33/php-db/examples/create_table_json.json @@ -0,0 +1,136 @@ +{ + "tables": [ + { + "schema": "db", + "name": "settings", + "primary_key": [ + "id" + ], + "unique": [ + "meta_key" + ], + "fields": [ + { + "name": "id", + "dataType": "int(11)", + "type": 3, + "length": 11, + "values": [], + "ai": true, + "nn": true, + "default": "" + }, + { + "name": "meta_key", + "dataType": "varchar(100)", + "type": 253, + "length": 100, + "values": [], + "ai": false, + "nn": true, + "default": "" + }, + { + "name": "meta_value", + "dataType": "mediumtext", + "type": 250, + "length": null, + "values": [], + "ai": false, + "nn": false, + "default": null + } + ] + }, + { + "schema": "db", + "name": "test", + "primary_key": [ + "id", + "fk" + ], + "fields": [ + { + "name": "id", + "dataType": "int(11)", + "type": 3, + "length": 11, + "values": [], + "ai": true, + "nn": true, + "default": "" + }, + { + "name": "fk", + "dataType": "int(11)", + "type": 3, + "length": 11, + "values": [], + "ai": false, + "nn": true, + "default": "" + }, + { + "name": "default", + "dataType": "tinyint(1)", + "type": 1, + "length": 1, + "values": [], + "ai": false, + "nn": false, + "default": "0" + }, + { + "name": "enum", + "dataType": "enum", + "type": 247, + "length": null, + "values": [ + "1", + "2" + ], + "ai": false, + "nn": false, + "default": "1" + } + ], + "constraints": [ + { + "id": "con_1", + "local": "fk", + "schema": "db", + "table": "test", + "field": "id", + "update": null, + "delete": null + } + ], + "index": [ + { + "id": "default_idx", + "type": "index", + "ref": "default" + } + ] + }, + { + "schema": "db", + "name": "test2", + "primary_key": [ + "id" + ], + "fields": [ + { + "name": "id", + "dataType": "int(11)", + "type": 3, + "length": 11, + "values": [], + "ai": true, + "nn": true, + "default": "" + } + ] + } + ] +} \ No newline at end of file diff --git a/inc/vendor/godsgood33/php-db/phpunit.xml b/inc/vendor/godsgood33/php-db/phpunit.xml new file mode 100644 index 0000000..4ff2356 --- /dev/null +++ b/inc/vendor/godsgood33/php-db/phpunit.xml @@ -0,0 +1,16 @@ + + + + + tests/ + + + + + src/ + + + \ No newline at end of file diff --git a/inc/vendor/godsgood33/php-db/src/DBConfig.php b/inc/vendor/godsgood33/php-db/src/DBConfig.php new file mode 100644 index 0000000..002d7bc --- /dev/null +++ b/inc/vendor/godsgood33/php-db/src/DBConfig.php @@ -0,0 +1,50 @@ +_c = $dbh; + } else { + if (PHP_DB_SERVER == '{IP|hostname}' || PHP_DB_USER == '{username}' || PHP_DB_PWD == '{password}' || PHP_DB_SCHEMA == '{schema}') { + throw new Error("Need to update DBConfig.php", E_ERROR); + } + $this->_c = new mysqli(PHP_DB_SERVER, PHP_DB_USER, PHP_DB_PWD, PHP_DB_SCHEMA); + } + + if ($this->_c->connect_errno) { + throw new Error("Could not create database class due to error {$this->_c->error}", E_ERROR); + } + + $this->_logPath = $strLogPath; + touch($this->_logPath . "/db.log"); + + $this->_logger = new Logger('db', [ + new StreamHandler(realpath($this->_logPath . "/db.log"), $this->_logLevel) + ]); + + if (PHP_SAPI == 'cli') { + $stream = new StreamHandler("php://output", $this->_logLevel); + $stream->setFormatter(new LineFormatter("%datetime% %level_name% %message%" . PHP_EOL, "H:i:s.u")); + $this->_logger->pushHandler($stream); + } + + $this->_logger->info("Database connected"); + $this->_logger->debug("Connection details:", [ + 'Server' => PHP_DB_SERVER, + 'User' => PHP_DB_USER, + 'Schema' => PHP_DB_SCHEMA + ]); + + $this->setVar("time_zone", "+00:00"); + $this->setVar("sql_mode", ""); + } + + /** + * Function to make sure that the database is connected + * + * @return boolean + */ + public function isConnected() + { + $this->_logger->debug("Pinging server"); + return $this->_c->ping(); + } + + /** + * Setter function for _logger + * + * @param Logger $log + */ + public function setLogger(Logger $log) + { + $this->_logger->debug("Setting logger"); + $this->_logger = $log; + } + + /** + * Getter function for _logger + * + * @return string + */ + public function getLogLevel() + { + $this->_logger->debug("Getting log level ({$this->_logLevel})"); + return $this->_logLevel; + } + + /** + * Function to set the log level just in case there needs to be a change to the default log level + * + * @param string $strLevel + */ + public function setLogLevel($strLevel) + { + $this->_logger->debug("Setting log level to {$strLevel}"); + $this->_logLevel = $strLevel; + + $handles = []; + + foreach ($this->_logger->getHandlers() as $h) { + $h->/** @scrutinizer ignore-call */ + setLevel($strLevel); + $handles[] = $h; + } + + $this->_logger->setHandlers($handles); + } + + /** + * Getter function for _queryType + * + * @return int + */ + public function getQueryType() + { + return $this->_queryType; + } + + /** + * Setter function for _queryType + * + * @param int $qt + */ + public function setQueryType($qt) + { + $this->_queryType = $qt; + } + + /** + * Getter function for _sql + * + * @return string + */ + public function getSql() + { + return $this->_sql; + } + + /** + * Function to return the currently selected database schema + * + * @return string + */ + public function getSchema() + { + if ($res = $this->_c->query("SELECT DATABASE()")) { + $row = $res->fetch_row(); + + $this->_logger->debug("Getting schema {$row[0]}"); + return $row[0]; + } + return null; + } + + /** + * Function to set schema + * + * @param string $strSchema + */ + public function setSchema($strSchema) + { + $this->_logger->debug("Setting schema to {$strSchema}"); + if (! $this->_c->select_db($strSchema)) { + $this->_logger->emergency("Unknown schema {$strSchema}"); + return false; + } + return true; + } + + /** + * Method to set a MYSQL variable + * + * @param string $strName + * @param string $strVal + * + * @return boolean + */ + public function setVar($strName, $strVal) + { + if (! $strName || ! $strVal) { + $this->_logger->debug("name or value are blank", [ + 'name' => $strName, + 'value' => $strVal + ]); + return false; + } + + $this->_logger->debug("Setting {$strName} = '{$strVal}'"); + + if ($this->_c->real_query("SET $strName = {$this->_escape($strVal)}")) { + return true; + } else { + $this->_logger->error("Failed to set variable {$this->_c->error}"); + return false; + } + } + + /** + * Function to execute the statement + * + * @param mixed $return + * [optional] + * MYSQLI constant to control what is returned from the mysqli_result object + * @param string $class + * [optional] + * Class to use when returning object + * @param string $strSql + * [optional] + * Optional SQL query + * + * @throws \Exception + * @throws \InvalidArgumentException + * + * @return mixed + */ + public function execute($return = MYSQLI_ASSOC, $class = null, $strSql = null) + { + if (! is_null($strSql)) { + $this->_sql = $strSql; + } + + $query = 'SELECT'; + switch ($this->_queryType) { + case self::SELECT_COUNT: + $query = 'SELECT COUNT'; + break; + case self::INSERT: + case self::EXTENDED_INSERT: + $query = 'INSERT'; + break; + case self::UPDATE: + case self::EXTENDED_UPDATE: + $query = 'UPDATE'; + break; + case self::REPLACE: + case self::EXTENDED_REPLACE: + $query = 'REPLACE'; + break; + case self::DROP: + $query = 'DROP'; + break; + case self::DELETE: + $query = 'DELETE'; + break; + case self::CREATE_TABLE: + $query = 'CREATE TABLE'; + break; + case self::TRUNCATE: + $query = 'TRUNCATE'; + break; + } + + if (is_a($this->_c, 'mysqli')) { + if (! $this->_c->ping()) { + require_once 'DBConfig.php'; + $this->_c = null; + $this->_c = new mysqli(PHP_DB_SERVER, PHP_DB_USER, PHP_DB_PWD, PHP_DB_SCHEMA); + } + } else { + throw new \Error('Database was not connected', E_ERROR); + } + + $this->_logger->info("Executing {$query} query"); + $this->_logger->debug($this->_sql); + + try { + if (in_array($this->_queryType, [ + self::SELECT, + self::SELECT_COUNT + ])) { + $this->_result = $this->_c->query($this->_sql); + if ($this->_c->error) { + $this->_logger->error("There is an error {$this->_c->error}"); + $this->_logger->debug("Errored on query", [$this->_sql]); + throw new Exception("There was an error {$this->_c->error}", E_ERROR); + } + } else { + $this->_result = $this->_c->real_query($this->_sql); + if ($this->_c->errno) { + $this->_logger->error("There was an error {$this->_c->error}"); + $this->_logger->debug("Errored on query", [$this->_sql]); + throw new Exception("There was an error {$this->_c->error}", E_ERROR); + } + } + + if ($return == MYSQLI_OBJECT && ! is_null($class) && class_exists(/** @scrutinizer ignore-type */$class)) { + $this->_logger->debug("Checking results for query", [ + 'class' => get_class($class) + ]); + $this->_result = $this->checkResults($return, $class); + } elseif ($return == MYSQLI_OBJECT && is_null($class)) { + $this->_logger->debug("Checking results for query", [ + 'class' => 'stdClass' + ]); + $this->_result = $this->checkResults($return, 'stdClass'); + } else { + $this->_logger->debug("Checking results for query and returning associative array"); + $this->_result = $this->checkResults(MYSQLI_ASSOC); + } + } catch (Exception $e) {} + + return $this->_result; + } + + /** + * Function to check the results and return what is expected + * + * @param mixed $returnType + * [optional] + * Optional return mysqli_result return type + * @param mixed $class + * + * @return mixed + */ + public function checkResults($returnType = MYSQLI_ASSOC, $class = null) + { + $res = null; + + switch ($this->_queryType) { + case self::SELECT_COUNT: + if (! is_a($this->_result, 'mysqli_result')) { + $this->_logger->error("Error with return on query"); + return; + } + + if ($this->_result->num_rows == 1) { + $row = $this->_result->fetch_assoc(); + if (isset($row['count'])) { + $this->_logger->debug("Returning SELECT_COUNT query", [ + 'count' => $row['count'] + ]); + $res = $row['count']; + } + } elseif ($this->_result->num_rows > 1) { + $this->_logger->debug("Returning SELECT_COUNT query", [ + 'count' => $this->_result->num_rows + ]); + $res = $this->_result->num_rows; + } + + mysqli_free_result($this->_result); + + return $res; + case self::SELECT: + if (! is_a($this->_result, 'mysqli_result')) { + $this->_logger->error("Error with return on query"); + return; + } + + if ($returnType == MYSQLI_OBJECT && ! is_null($class) && class_exists($class)) { + if ($this->_result->num_rows == 1) { + $this->_logger->debug("Returning object from SELECT query", [ + 'type' => get_class($class) + ]); + $res = $this->_result->fetch_object($class); + } elseif ($this->_result->num_rows > 1) { + $this->_logger->debug("Returning object array from SELECT query", [ + 'type' => get_class($class) + ]); + while ($row = $this->_result->fetch_object($class)) { + $res[] = $row; + } + } + } else { + if ($this->_result->num_rows == 1) { + $this->_logger->debug("Fetching results"); + $res = $this->_result->fetch_array($returnType); + } elseif ($this->_result->num_rows > 1) { + $this->_logger->debug("Fetching results array"); + $res = $this->fetchAll($returnType); + } + } + + mysqli_free_result($this->_result); + + return $res; + case self::INSERT: + if ($this->_c->error) { + $this->_logger->error("Database Error {$this->_c->error}"); + return 0; + } + + if ($this->_c->insert_id) { + $this->_logger->debug("Insert successful returning insert_id", [ + 'id' => $this->_c->insert_id + ]); + return $this->_c->insert_id; + } elseif ($this->_c->affected_rows) { + $this->_logger->debug("Insert successful return affected row count", [ + 'count' => $this->_c->affected_rows + ]); + return $this->_c->affected_rows; + } + + $this->_logger->debug("Insert successful, but no ID so returning 1 for success"); + + return 1; + // intentional fall through + case self::EXTENDED_INSERT: + // intentional fall through + case self::EXTENDED_REPLACE: + // intentional fall through + case self::EXTENDED_UPDATE: + // intentional fall through + case self::REPLACE: + // intentional fall through + case self::UPDATE: + // intentional fall through + case self::DELETE: + // intentional fall through + case self::ALTER_TABLE: + if ($this->_c->error) { + $this->_logger->error("Database Error {$this->_c->error}"); + return false; + } elseif ($this->_c->affected_rows) { + $this->_logger->debug("Returning affected row count for {$this->_queryType}", [ + 'count' => $this->_c->affected_rows + ]); + return $this->_c->affected_rows; + } else { + return true; + } + break; + case self::CREATE_TABLE: + // intentional fall through + case self::DROP: + // intentional fall through + case self::TRUNCATE: + $this->_logger->debug("Returning from {$this->_queryType}"); + return true; + } + } + + /** + * Function to pass through calling the query function (used for backwards compatibility and for more complex queries that aren't currently supported) + * Nothing is escaped + * + * @param string $strSql + * [optional] + * Optional query to pass in and execute + * + * @return \mysqli_result|boolean + */ + public function query($strSql = null) + { + if (is_null($strSql)) { + return $this->_c->query($this->_sql); + } else { + return $this->_c->query($strSql); + } + } + + /** + * A function to build a select query + * + * @param string $strTableName + * The table to query + * @param array|string $fields + * [optional] + * Optional array of fields to return (defaults to '*') + * @param array $arrWhere + * [optional] + * Optional 2-dimensional array to build where clause from + * @param array $arrFlags + * [optional] + * Optional 2-dimensional array to allow other flags + * + * @see Database::where() + * @see Database::flags() + * + * @throws \InvalidArgumentException + * + * @return mixed + */ + public function select($strTableName, $fields = null, $arrWhere = [], $arrFlags = []) + { + $this->_sql = null; + $this->_queryType = self::SELECT; + + if (! is_null($strTableName)) { + $this->_logger->debug("Starting SELECT query of {$strTableName}", [ + 'fields' => $this->fields($fields) + ]); + $this->_sql = "SELECT " . $this->fields($fields) . " FROM $strTableName"; + } else { + $this->_logger->emergency("Table name is invalid or wrong type"); + throw new Error("Table name is invalid"); + } + + if (isset($arrFlags['joins']) && is_array($arrFlags['joins']) && count($arrFlags['joins'])) { + $this->_logger->debug("Adding joins", [ + 'joins' => implode(' ', $arrFlags['joins']) + ]); + $this->_sql .= " " . implode(" ", $arrFlags['joins']); + } else { + $this->_logger->debug("No joins"); + } + + if (! is_null($arrWhere) && is_array($arrWhere) && count($arrWhere)) { + $where_str = " WHERE"; + $this->_logger->debug("Parsing where clause and adding to query"); + foreach ($arrWhere as $x => $w) { + $where_str .= $this->parseClause($w, $x); + } + if (strlen($where_str) > strlen(" WHERE")) { + $this->_sql .= $where_str; + } + } + + if (is_array($arrFlags) && count($arrFlags)) { + $this->_logger->debug("Parsing flags and adding to query", $arrFlags); + $this->_sql .= $this->flags($arrFlags); + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to build a query to check the number of rows in a table + * + * @param string $strTableName + * The table to query + * @param array $arrWhere + * [optional] + * Optional 2-dimensional array to build where clause + * @param array $arrFlags + * [optional] + * Optional 2-dimensional array to add flags + * + * @see Database::where() + * @see Database::flags() + * + * @return string|NULL + */ + public function selectCount($strTableName, $arrWhere = [], $arrFlags = []) + { + $this->_sql = null; + $this->_queryType = self::SELECT_COUNT; + + if (! is_null($strTableName)) { + $this->_sql = "SELECT COUNT(1) AS 'count' FROM $strTableName"; + } else { + $this->_logger->emergency("Table name is invalid or wrong type"); + throw new Error("Table name is invalid"); + } + + if (isset($arrFlags['joins']) && is_array($arrFlags['joins'])) { + $this->_sql .= " " . implode(" ", $arrFlags['joins']); + } + + if (! is_null($arrWhere) && is_array($arrWhere) && count($arrWhere)) { + $where_str = " WHERE"; + foreach ($arrWhere as $x => $w) { + $where_str .= $this->parseClause($w, $x); + } + if (strlen($where_str) > strlen(" WHERE")) { + $this->_sql .= $where_str; + } + } + + if (is_array($arrFlags) && count($arrFlags)) { + $this->_sql .= $this->flags($arrFlags); + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to build an insert query statement + * + * @param string $strTableName + * @param array|string $arrParams + * @param boolean $blnToIgnore + * + * @return string|NULL + */ + public function insert($strTableName, $arrParams = null, $blnToIgnore = false) + { + $this->_sql = null; + $this->_queryType = self::INSERT; + + if (! is_null($strTableName)) { + $this->_sql = "INSERT" . ($blnToIgnore ? " IGNORE" : "") . " INTO $strTableName" . (is_array($arrParams) && count($arrParams) ? " (`" . implode("`,`", array_keys($arrParams)) . "`)" : null); + } else { + throw new Error("Table name is invalid"); + } + + if (is_array($arrParams) && count($arrParams)) { + $this->_sql .= " VALUES (" . implode(",", array_map([ + $this, + '_escape' + ], array_values($arrParams))) . ")"; + } elseif (is_string($arrParams) && stripos($arrParams, 'SELECT') !== false) { + $this->_sql .= " {$arrParams}"; + } else { + throw new Error("Invalid type passed to insert " . gettype($arrParams)); + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to create an extended insert query statement + * + * @param string $strTableName + * The table name that the data is going to be inserted on + * @param array $arrFields + * An array of field names that each value represents + * @param array|string $params + * An array of array of values or a string with a SELECT statement to populate the insert with + * @param boolean $blnToIgnore + * [optional] + * Boolean to decide if we need to use the INSERT IGNORE INTO syntax + * + * @return NULL|string Returns the SQL if self::$autorun is set to false, else it returns the output from running. + */ + public function extendedInsert($strTableName, $arrFields, $params, $blnToIgnore = false) + { + $this->_sql = null; + $this->_queryType = self::EXTENDED_INSERT; + + if (! is_null($strTableName) && is_string($strTableName)) { + $this->_sql = "INSERT " . ($blnToIgnore ? "IGNORE " : "") . "INTO $strTableName " . "(`" . implode("`,`", $arrFields) . "`)"; + } else { + throw new Error("Table name is invalid"); + } + + if (is_array($params) && count($params)) { + $this->_sql .= " VALUES "; + if (isset($params[0]) && is_array($params[0])) { + foreach ($params as $p) { + if (count($p) != count($arrFields)) { + $this->_logger->emergency("Inconsistent number of fields to values in extended_insert", [ + $p + ]); + throw new Error("Inconsistent number of fields in fields and values in extended_insert " . print_r($p, true)); + } + $this->sql .= "(" . implode(",", array_map([$this, '_escape'], array_values($p))) . ")"; + + if ($p != end($params)) { + $this->_sql .= ","; + } + } + } else { + $this->sql .= "(" . implode("),(", array_map([$this, '_escape'], array_values($params))) . ")"; + } + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Build a statement to update a table + * + * @param string $strTableName + * The table name to update + * @param array $arrParams + * Name/value pairs of the field name and value + * @param array $arrWhere + * [optional] + * Two-dimensional array to create where clause + * @param array $arrFlags + * [optional] + * Two-dimensional array to create other flag options (joins, order, and group) + * + * @see Database::where() + * @see Database::flags() + * + * @return NULL|string + */ + public function update($strTableName, $arrParams, $arrWhere = [], $arrFlags = []) + { + $this->_sql = "UPDATE "; + $this->_queryType = self::UPDATE; + + if (! is_null($strTableName) && is_string($strTableName)) { + $this->_sql .= $strTableName; + + if (isset($arrFlags['joins']) && is_array($arrFlags['joins'])) { + $this->_sql .= " " . implode(" ", $arrFlags['joins']); + unset($arrFlags['joins']); + } + + $this->_sql .= " SET "; + } else { + throw new Error("Table name is invalid"); + } + + if (is_array($arrParams) && count($arrParams)) { + foreach ($arrParams as $f => $p) { + if ((strpos($f, "`") === false) && (strpos($f, ".") === false) && (strpos($f, "*") === false) && (stripos($f, " as ") === false)) { + $f = "`{$f}`"; + } + + if (! is_null($p)) { + $this->_sql .= "$f={$this->_escape($p)},"; + } else { + $this->_sql .= "$f=NULL,"; + } + } + } else { + throw new Error("No fields to update"); + } + + $this->_sql = substr($this->_sql, 0, - 1); + + if (! is_null($arrWhere) && is_array($arrWhere) && count($arrWhere)) { + $where_str = " WHERE"; + foreach ($arrWhere as $x => $w) { + $where_str .= $this->parseClause($w, $x); + } + if (strlen($where_str) > strlen(" WHERE")) { + $this->_sql .= $where_str; + } + } + + if (! is_null($arrFlags) && is_array($arrFlags) && count($arrFlags)) { + $this->_sql .= $this->flags($arrFlags); + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to offer an extended updated functionality by using two different tables. + * + * @param string $strTableToUpdate + * The table that you want to update (alias 'tbu' is automatically added) + * @param string $strOriginalTable + * The table with the data you want to overwrite to_be_updated table (alias 'o' is automatically added) + * @param string $strLinkField + * The common index value between them that will join the fields + * @param array|string $arrParams + * If string only a single field is updated (tbu.$params = o.$params) + * If array each element in the array is a field to be updated (tbu.$param = o.$param) + * + * @return mixed + */ + public function extendedUpdate($strTableToUpdate, $strOriginalTable, $strLinkField, $arrParams) + { + $this->_sql = "UPDATE "; + $this->_queryType = self::EXTENDED_UPDATE; + + if (! is_null($strTableToUpdate) && ! is_null($strOriginalTable) && ! is_null($strLinkField)) { + $this->_sql .= "$strTableToUpdate tbu INNER JOIN $strOriginalTable o USING ($strLinkField) SET "; + } else { + throw new Error("Missing necessary fields"); + } + + if (is_array($arrParams) && count($arrParams)) { + foreach ($arrParams as $param) { + if ($param != $strLinkField) { + $this->_sql .= "tbu.`$param` = o.`$param`,"; + } + } + $this->_sql = substr($this->_sql, 0, - 1); + } elseif (is_string($arrParams)) { + $this->_sql .= "tbu.`$arrParams` = o.`$arrParams`"; + } else { + throw new Exception("Do not understand datatype " . gettype($arrParams), E_ERROR); + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to build a replace query + * + * @param string $strTableName + * The table to update + * @param array $arrParams + * Name/value pair to insert + * + * @return NULL|string + */ + public function replace($strTableName, $arrParams) + { + $this->_sql = null; + $this->_queryType = self::REPLACE; + + if (! is_null($strTableName) && is_string($strTableName)) { + $this->_sql = "REPLACE INTO $strTableName " . "(`" . implode("`,`", array_keys($arrParams)) . "`)"; + } else { + throw new Error("Table name is invalid"); + } + + $this->_sql .= " VALUES (" . implode(",", array_map([ + $this, + '_escape' + ], array_values($arrParams))) . ")"; + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to build an extended replace statement + * + * @param string $strTableName + * Table name to update + * @param array $arrFields + * Array of fields + * @param array $arrParams + * Two-dimensional array of values + * + * @return NULL|string + */ + public function extendedReplace($strTableName, $arrFields, $arrParams) + { + $this->_sql = null; + $this->_queryType = self::EXTENDED_REPLACE; + + if (! is_array($arrFields) || ! count($arrFields)) { + throw new Exception("Error with the field type"); + } + + if (! is_null($strTableName) && is_string($strTableName)) { + $this->_sql = "REPLACE INTO $strTableName " . "(`" . implode("`,`", $arrFields) . "`)"; + } else { + throw new Error("Table name is invalid"); + } + + if (is_array($arrParams) && count($arrParams)) { + $this->_sql .= " VALUES "; + foreach ($arrParams as $p) { + $this->_sql .= "(" . implode(",", array_map([ + $this, + '_escape' + ], array_values($p))) . ")"; + + if ($p != end($arrParams)) { + $this->_sql .= ","; + } + } + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to build a delete statement + * + * @param string $strTableName + * Table name to act on + * @param array $arrFields + * [optional] + * Optional list of fields to delete (used when including multiple tables) + * @param array $arrWhere + * [optional] + * Optional 2-dimensional array to build where clause from + * @param array $arrJoins + * [optional] + * Optional 2-dimensional array to add other flags + * + * @see Database::where() + * @see Database::flags() + * + * @return string|NULL + */ + public function delete($strTableName, $arrFields = [], $arrWhere = [], $arrJoins = []) + { + $this->_sql = "DELETE"; + $this->_queryType = self::DELETE; + + $this->_logger->debug("Deleting table data"); + + if (! is_null($arrFields) && is_array($arrFields) && count($arrFields)) { + $this->_sql .= " " . implode(",", $arrFields); + } + + if (! is_null($strTableName) && is_string($strTableName)) { + $this->_sql .= " FROM $strTableName"; + } else { + throw new Error("Table name is invalid"); + } + + if (! is_null($arrJoins) && is_array($arrJoins) && count($arrJoins)) { + $this->_sql .= " " . implode(" ", $arrJoins); + } + + if (! is_null($arrWhere) && is_array($arrWhere) && count($arrWhere)) { + $where_str = " WHERE"; + foreach ($arrWhere as $x => $w) { + $where_str .= $this->parseClause($w, $x); + } + if (strlen($where_str) > strlen(" WHERE")) { + $this->_sql .= $where_str; + } + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to build a drop table statement (automatically executes) + * + * @param string $strTableName + * Table to drop + * @param string $strType + * [optional] + * Type of item to drop ('table', 'view') (defaulted to 'table') + * @param boolean $blnIsTemp + * [optional] + * Optional boolean if this is a temporary table + * + * @return string|NULL + */ + public function drop($strTableName, $strType = 'table', $blnIsTemp = false) + { + $this->_sql = null; + $this->_queryType = self::DROP; + + switch ($strType) { + case 'table': + $strType = 'TABLE'; + break; + case 'view': + $strType = 'VIEW'; + break; + default: + throw new Error("Invalid type " . gettype($strType), E_ERROR); + } + + if (! is_null($strTableName) && is_string($strTableName)) { + $this->_sql = "DROP" . ($blnIsTemp ? " TEMPORARY" : "") . " $strType IF EXISTS `{$strTableName}`"; + } else { + throw new Error("Table name is invalid"); + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to build a truncate table statement (automatically executes) + * + * @param string $strTableName + * Table to truncate + * + * @throws \Error + * + * @return string|NULL + */ + public function truncate($strTableName) + { + $this->_sql = null; + $this->_queryType = self::TRUNCATE; + + if (! is_null($strTableName) && is_string($strTableName)) { + $this->_sql = "TRUNCATE TABLE $strTableName"; + } else { + throw new Error("Table name is invalid"); + } + + if (self::$autorun) { + return $this->execute(MYSQLI_BOTH); + } + + return $this->_sql; + } + + /** + * Function to build a create temporary table statement + * + * @param string $strTableName + * Name to give the table when creating + * @param boolean $blnIsTemp + * [optional] + * Optional boolean to make the table a temporary table + * @param mixed $strSelect + * [optional] + * Optional parameter if null uses last built statement + * If string, will be made the SQL statement executed to create the table + * If array, 2-dimensional array with "field", "datatype" values to build table fields + * + * @return NULL|string + */ + public function createTable($strTableName, $blnIsTemp = false, $strSelect = null) + { + $this->_queryType = self::CREATE_TABLE; + + if (is_null($strSelect) && ! is_null($this->_sql) && substr($this->_sql, 0, 6) == 'SELECT') { + $this->_sql = "CREATE" . ($blnIsTemp ? " TEMPORARY" : "") . " TABLE IF NOT EXISTS $strTableName AS ($this->_sql)"; + } elseif (! is_null($strTableName) && is_string($strTableName) && is_string($strSelect)) { + $this->_sql = "CREATE" . ($blnIsTemp ? " TEMPORARY" : "") . " TABLE IF NOT EXISTS $strTableName AS ($strSelect)"; + } elseif (! is_null($strTableName) && is_string($strTableName) && is_array($strSelect)) { + $this->_sql = "CREATE" . ($blnIsTemp ? " TEMPORARY" : "") . " TABLE IF NOT EXISTS $strTableName ("; + + foreach ($strSelect as $field) { + $default = null; + if (isset($field['default'])) { + $default = (is_null($field['default']) ? "" : " DEFAULT '{$field['default']}'"); + } + $this->_sql .= "`{$field['field']}` {$field['datatype']}" . $default . (isset($field['option']) ? " {$field['option']}" : '') . ","; + } + $this->_sql = substr($this->_sql, 0, - 1) . ")"; + } + + if (self::$autorun) { + return $this->execute(); + } + + return $this->_sql; + } + + /** + * Function to create a table using a stdClass object derived from JSON + * + * @param \stdClass $json + * + * @example /examples/create_table_json.json + * + */ + public function createTableJson($json) + { + $this->_queryType = self::CREATE_TABLE; + $this->_c->select_db($json->schema); + + $this->_sql = "CREATE TABLE IF NOT EXISTS `{$json->name}` ("; + foreach ($json->fields as $field) { + $this->_sql .= "`{$field->name}` {$field->dataType}"; + + if ($field->dataType == 'enum') { + $this->_sql .= "('" . implode("','", $field->values) . "')"; + } + + if ($field->ai) { + $this->_sql .= " AUTO_INCREMENT"; + } + + if ($field->nn) { + $this->_sql .= " NOT NULL"; + } else { + if ($field->default === null) { + $this->_sql .= " DEFAULT NULL"; + } elseif (strlen($field->default)) { + $this->_sql .= " DEFAULT '{$field->default}'"; + } + } + + if ($field != end($json->fields)) { + $this->_sql .= ","; + } + } + + if (isset($json->index) && count($json->index)) { + foreach ($json->index as $ind) { + $this->_sql .= ", " . strtoupper($ind->type) . " `{$ind->id}` (`{$ind->ref}`)"; + } + } + + if (isset($json->constraints) && count($json->constraints)) { + foreach ($json->constraints as $con) { + $this->_sql .= ", CONSTRAINT `{$con->id}` " . "FOREIGN KEY (`{$con->local}`) " . "REFERENCES `{$con->schema}`.`{$con->table}` (`{$con->field}`) " . "ON DELETE " . (is_null($con->delete) ? "NO ACTION" : strtoupper($con->delete)) . " " . "ON UPDATE " . (is_null($con->update) ? "NO ACTION" : strtoupper($con->update)); + } + } + + if (isset($json->unique) && count($json->unique)) { + $this->_sql .= ", UNIQUE(`" . implode("`,`", $json->unique) . "`)"; + } + + if (isset($json->primary_key) && count($json->primary_key)) { + $this->_sql .= ", PRIMARY KEY(`" . implode("`,`", $json->primary_key) . "`))"; + } else { + if (substr($this->_sql, - 1) == ',') { + $this->_sql = substr($this->_sql, 0, - 1); + } + + $this->_sql .= ")"; + } + + $this->execute(MYSQLI_BOTH); + } + + /** + * Function to alter a existing table + * + * @param string $strTableName + * Table to alter + * @param int $intAction + * What action should be taken ('add-column', 'drop-column', 'modify-column') + * @param mixed $arrParams + * For add column this is a stdClass object that has the same elements as the example json + * + * @return mixed + */ + public function alterTable($strTableName, $intAction, $arrParams) + { + $this->_queryType = self::ALTER_TABLE; + $this->_sql = "ALTER TABLE $strTableName"; + if ($intAction == self::ADD_COLUMN) { + $nn = ($arrParams->nn ? " NOT NULL" : ""); + $default = null; + if ($arrParams->default === null) { + $default = " DEFAULT NULL"; + } elseif (strlen($arrParams->default)) { + $default = " DEFAULT {$this->_escape($arrParams->default)}"; + } + $this->_sql .= " ADD COLUMN `{$arrParams->name}` {$arrParams->dataType}" . $nn . $default; + } elseif ($intAction == self::DROP_COLUMN) { + $this->_sql .= " DROP COLUMN "; + foreach ($arrParams as $col) { + $this->_sql .= "`{$col->name}`"; + + if ($col != end($arrParams)) { + $this->_sql .= ","; + } + } + } elseif ($intAction == self::MODIFY_COLUMN) { + $this->_sql .= " MODIFY COLUMN"; + $nn = ($arrParams->nn ? " NOT NULL" : ""); + $default = null; + if ($arrParams->default === null) { + $default = " DEFAULT NULL"; + } elseif (strlen($arrParams->default)) { + $default = " DEFAULT {$this->_escape($arrParams->default)}"; + } + $this->_sql .= " `{$arrParams->name}` `{$arrParams->new_name}` {$arrParams->dataType}" . $nn . $default; + } + + if (self::$autorun) { + return $this->execute(); + } + + return $this->_sql; + } + + /** + * Check to see if a field in a table exists + * + * @param string $strTableName + * Table to check + * @param string $strFieldName + * Field name to find + * + * @return boolean Returns TRUE if field is found in that schema and table, otherwise FALSE + */ + public function fieldExists($strTableName, $strFieldName) + { + $fdata = $this->fieldData($strTableName); + + if (is_array($fdata) && count($fdata)) { + foreach ($fdata as $field) { + if ($field->name == $strFieldName) { + return true; + } + } + } + + return false; + } + + /** + * Function to get the column data (datatype, flags, defaults, etc) + * + * @param string $strTableName + * Table to query + * @param mixed $field + * [optional] + * Optional field to retrieve data (if null, returns data from all fields) + * + * @return array + */ + public function fieldData($strTableName, $field = null) + { + if (is_null($field)) { + $res = $this->_c->query("SELECT * FROM $strTableName LIMIT 1"); + } elseif (is_array($field)) { + $res = $this->_c->query("SELECT `" . implode("`,`", $field) . "` FROM $strTableName LIMIT 1"); + } elseif (is_string($field)) { + $res = $this->_c->query("SELECT $field FROM $strTableName LIMIT 1"); + } else { + return null; + } + + $fields = null; + if (is_a($res, 'mysqli_result')) { + $fields = $res->fetch_fields(); + foreach ($fields as $i => $f) { + $fields["{$f->name}"] = $f; + unset($fields[$i]); + } + } + + return $fields; + } + + /** + * Function to check that all field parameters are set correctly + * + * @param object $field_data + * @param object $check + * @param array $pks + * @param object $index + * + * @return array|string + */ + public function fieldCheck($field_data, $check, $pks, $index) + { + $default = null; + $ret = null; + + $nn = ($check->nn ? " NOT NULL" : null); + if ($check->default === null) { + $default = " DEFAULT NULL"; + } elseif (strlen($check->default)) { + $default = " DEFAULT '{$check->default}'"; + } + + if ($field_data->type != $check->type && $check->type != MYSQLI_TYPE_ENUM) { + $this->_logger->notice("Wrong datatype", [ + 'name' => $field_data->name, + 'datatype' => $check->dataType + ]); + $ret = " CHANGE COLUMN `{$field_data->name}` `{$check->name}` {$check->dataType}" . "{$nn}{$default}"; + } elseif (! is_null($check->length) && $field_data->length != $check->length) { + $this->_logger->notice("Incorrect size", [ + 'name' => $field_data->name, + 'current' => $field_data->length, + 'new_size' => $check->length + ]); + $ret = " CHANGE COLUMN `{$field_data->name}` `{$check->name}` {$check->dataType}" . "{$nn}{$default}"; + } elseif ($check->type == MYSQLI_TYPE_ENUM && ! ($field_data->flags & MYSQLI_ENUM_FLAG)) { + $this->_logger->notice("Setting ENUM type", [ + 'name' => $field_data->name, + 'values' => implode(",", $check->values) + ]); + $ret = " CHANGE COLUMN `{$field_data->name}` `{$check->name}` {$check->dataType}('" . implode("','", $check->values) . "')" . "{$nn}{$default}"; + } + + if (! is_null($index) && count($index)) { + foreach ($index as $ind) { + if ($check->name == $ind->ref && ! ($field_data->flags & MYSQLI_MULTIPLE_KEY_FLAG)) { + $this->_logger->debug("Missing index", [ + 'name' => $field_data->name + ]); + $ret .= ($ret ? "," : "") . " ADD INDEX `{$ind->id}` (`{$ind->ref}` ASC)"; + } + } + } + + if (in_array($check->name, $pks) && ! ($field_data->flags & MYSQLI_PRI_KEY_FLAG)) { + $this->_logger->debug("Setting PKs", [ + 'keys' => implode(',', $pks) + ]); + $ret .= ($ret ? "," : "") . " DROP PRIMARY KEY, ADD PRIMARY KEY(`" . implode("`,`", $pks) . "`)"; + } + + return $ret; + } + + /** + * Function to check for the existence of a table within a schema + * + * @param string $strSchema + * The schema to search in + * @param string $strTableName + * Table to search for + * + * @return integer|boolean Returns number of tables that match if table is found in that schema, otherwise FALSE + */ + public function tableExists($strSchema, $strTableName) + { + if (! $this->_c->select_db($strSchema)) { + fwrite("php://stdout", $this->_c->error . PHP_EOL); + } + $sql = "SHOW TABLES LIKE '{$strTableName}'"; + + if ($res = $this->_c->query($sql)) { + if (gettype($res) == 'object' && is_a($res, 'mysqli_result') && $res->num_rows) { + return $res->num_rows; + } + } else { + if ($this->_c->errno) { + fwrite("php://stdout", $this->_c->error . PHP_EOL); + } + } + + return false; + } + + /** + * Function to detect if string is a JSON object or not + * + * @param string $strVal + * + * @return boolean + */ + public function isJson($strVal) + { + json_decode($strVal); + return (json_last_error() == JSON_ERROR_NONE); + } + + /** + * Function to escape SQL characters to prevent SQL injection + * + * @param mixed $val + * Value to escape + * @param boolean $blnEscape + * Decide if we should escape or not + * + * @return string Escaped value + */ + public function _escape($val, $blnEscape = true) + { + if (is_null($val) || (is_string($val) && strtolower($val) == 'null')) { + return 'NULL'; + } elseif (is_numeric($val) || is_string($val)) { + if (stripos($val, "IF(") !== false) { + return $val; + } + elseif ($blnEscape) { + return "'{$this->_c->real_escape_string($val)}'"; + } + return $val; + } elseif (is_a($val, 'DateTime')) { + return "'{$val->format(MYSQL_DATETIME)}'"; + } elseif (is_bool($val)) { + return $val ? "'1'" : "'0'"; + } elseif (gettype($val) == 'object' && method_exists($val, '_escape')) { + $ret = call_user_func([ + $val, + '_escape' + ]); + if ($ret !== false) { + return $ret; + } else { + throw new Exception("Error in return from _escape method in " . get_class($val), E_ERROR); + } + } elseif (gettype($val) == 'object') { + $this->_logger->error("Unknown object to escape " . get_class($val) . " in SQL string {$this->_sql}"); + return; + } + + throw new Exception("Unknown datatype to escape in SQL string {$this->_sql} " . gettype($val), E_ERROR); + } + + /** + * Function to retrieve all results + * + * @param int $intResultType + * + * @return mixed + */ + public function fetchAll($intResultType = MYSQLI_ASSOC) + { + $res = []; + if (method_exists('mysqli_result', 'fetch_all')) { // Compatibility layer with PHP < 5.3 + $res = $this->_result->fetch_all($intResultType); + } else { + while ($tmp = $this->_result->fetch_array($intResultType)) { + $res[] = $tmp; + } + } + + return $res; + } + + /** + * Function to populate the fields for the SQL + * + * @param array|string $fields + * [optional] + * Optional array of fields to string together to create a field list + * + * @return string + */ + public function fields($fields = null) + { + $ret = null; + + if (is_array($fields) && count($fields) && isset($fields[0]) && is_string($fields[0])) { + foreach ($fields as $field) { + if ((strpos($field, '`') === false) && (strpos($field, '.') === false) && (strpos($field, '*') === false) && (strpos($field, 'JSON_') === false) && (stripos($field, ' as ') === false)) { + $ret .= "`$field`,"; + } else { + $ret .= "$field,"; + } + } + $ret = substr($ret, - 1) == ',' ? substr($ret, 0, - 1) : $ret; + } elseif (is_string($fields)) { + $ret = $fields; + } elseif (is_null($fields)) { + $ret = "*"; + } else { + throw new \InvalidArgumentException("Invalid field type"); + } + + return $ret; + } + + /** + * Function to parse the flags + * + * @param array $flags + * Two-dimensional array to added flags + * + * + * [ + *   'joins' => [ + *     "JOIN table2 t2 ON t2.id=t1.id" + *   ], + *   'group' => 'field', + *   'having' => 'field', + *   'order' => 'field', + *   'start' => 0, + *   'limit' => 0 + * ] + * + * + * @see Database::groups() + * @see Database::having() + * @see Database::order() + * + * @return string + */ + public function flags($arrFlags) + { + $ret = ''; + + if (isset($arrFlags['group'])) { + $ret .= $this->groups($arrFlags['group']); + } + + if (isset($arrFlags['having']) && is_array($arrFlags['having'])) { + $having = " HAVING"; + foreach ($arrFlags['having'] as $x => $h) { + $having .= $this->parseClause($h, $x); + } + if (strlen($having) > strlen(" HAVING")) { + $ret .= $having; + } + } + + if (isset($arrFlags['order'])) { + $ret .= $this->order($arrFlags['order']); + } + + if (isset($arrFlags['limit']) && (is_string($arrFlags['limit']) || is_numeric($arrFlags['limit']))) { + $ret .= " LIMIT "; + if (isset($arrFlags['start']) && (is_string($arrFlags['start']) || is_numeric($arrFlags['start']))) { + $ret .= "{$arrFlags['start']},"; + } + $ret .= "{$arrFlags['limit']}"; + } + + return $ret; + } + + /** + * Function to parse SQL GROUP BY statements + * + * @param mixed $groups + * + * @return string + */ + public function groups($groups) + { + $ret = ''; + if (is_array($groups) && count($groups)) { + $ret .= " GROUP BY"; + + foreach ($groups as $grp) { + $ret .= " $grp"; + + if ($grp != end($groups)) { + $ret .= ","; + } + } + } elseif (is_string($groups)) { + $ret .= " GROUP BY {$groups}"; + } else { + throw (new Exception("Error in datatype for groups " . gettype($groups), E_ERROR)); + } + + return $ret; + } + + /** + * Function to parse SQL ORDER BY statements + * + * @param mixed $order + * + * @return string + */ + public function order($order) + { + $ret = ''; + if (is_array($order)) { + $ret .= " ORDER BY"; + + foreach ($order as $ord) { + $ret .= " {$ord['field']} {$ord['sort']}"; + + if ($ord != end($order)) { + $ret .= ","; + } + } + } elseif (is_string($order)) { + $ret .= " ORDER BY {$order}"; + } + + return $ret; + } + + /** + * Function to see if a constraint exists + * + * @param string $strConstraintId + * + * @return boolean + */ + public function isConstraint($strConstraintId) + { + $res = $this->_c->query("SELECT * FROM information_schema.TABLE_CONSTRAINTS WHERE CONSTRAINT_NAME = '{$strConstraintId}'"); + + if ($res->num_rows) { + return true; + } + + return false; + } + + /** + * Function to parse where and having clauses + * + * @param array $arrClause + * @param int $intIndex + */ + public function parseClause($arrClause, $intIndex) + { + $ret = null; + + $this->_logger->debug("Parsing clause", $arrClause); + + if (! isset($arrClause['field']) && isset($arrClause['close-paren']) && $arrClause['close-paren']) { + $ret .= ")"; + return $ret; + } elseif ($intIndex > 0 && ! isset($arrClause['sql_op'])) { + $this->_logger->warning("Missing sql_op field to identify how current and previous WHERE clause statements should be linked ('AND', 'OR', 'XOR', etc), skipped", [ + 'clause' => implode(",", $arrClause) + ]); + return; + } + + $op = '='; + if (isset($arrClause['op'])) { + $op = $arrClause['op']; + } + + switch ($op) { + case self::BETWEEN: + if (! isset($arrClause['field']) || ! isset($arrClause['low']) || ! isset($arrClause['high'])) { + $this->_logger->warning("Missing field, low, or high for BETWEEN where clause, skipping"); + return; + } + break; + default: + if (! isset($arrClause['field']) || ! isset($arrClause['value'])) { + $this->_logger->warning("Missing field or value for WHERE clause, skipping", $arrClause); + return; + } + } + + if ($intIndex > 0) { + $ret .= " {$arrClause['sql_op']}"; + } + + if (isset($arrClause['open-paren']) && $arrClause['open-paren']) { + $ret .= " ("; + } + + if (isset($arrClause['backticks']) && ! $arrClause['backticks']) { + $field = $arrClause['field']; + } else { + $field = "`{$arrClause['field']}`"; + } + + if ($op == self::IN || $op == self::NOT_IN) { + if (is_string($arrClause['value'])) { + $ret .= " {$field} {$op} " . (strpos($arrClause['value'], '(') !== false ? $arrClause['value'] : "({$arrClause['value']})"); + } elseif (is_array($arrClause['value'])) { + $ret .= " {$field} {$op} (" . implode(",", array_map([ + $this, + '_escape' + ], $arrClause['value'])) . ")"; + } else { + $this->_logger->error("Invalid datatype for IN WHERE clause, only string and array allowed " . gettype($arrClause['value']), $arrClause); + throw new Exception("Invalid datatype for IN WHERE clause", E_ERROR); + } + } elseif ($op == self::BETWEEN) { + $ret .= " {$field} BETWEEN {$this->_escape($arrClause['low'])} AND {$this->_escape($arrClause['high'])}"; + } else { + if (isset($arrClause['escape']) && ! $arrClause['escape']) { + $value = $arrClause['value']; + } else { + $value = $this->_escape($arrClause['value']); + } + + if (isset($arrClause['case_insensitive']) && $arrClause['case_insensitive']) { + $ret .= " LOWER({$field}) {$op} LOWER({$this->_escape($arrClause['value'])})"; + } elseif (preg_match("/\(SELECT/", $arrClause['value'])) { + $ret .= " {$field} {$op} {$arrClause['value']}"; + } else { + $ret .= " {$field} {$op} {$value}"; + } + } + + if (isset($arrClause['close-paren']) && $arrClause['close-paren']) { + $ret .= ")"; + } + + return $ret; + } +} diff --git a/inc/vendor/godsgood33/php-db/tests/DatabaseTest.php b/inc/vendor/godsgood33/php-db/tests/DatabaseTest.php new file mode 100644 index 0000000..366efad --- /dev/null +++ b/inc/vendor/godsgood33/php-db/tests/DatabaseTest.php @@ -0,0 +1,794 @@ +db = new Database(realpath(__DIR__)); + // Database::$autorun = true; + } + + public function testCanCreateDatabaseInstance() + { + $this->assertInstanceOf("Godsgood33\Php_Db\Database", $this->db); + } + + public function testGetSchema() + { + $schema = $this->db->getSchema(); + $this->assertEquals("db", $schema); + } + + public function testSetSchemaWithNonExistentSchema() + { + $ret = $this->db->setSchema("george"); + $this->assertFalse($ret); + } + + public function testDatabaseConnection() + { + $this->assertTrue($this->db->isConnected()); + } + + public function testPassInMysqliConnection() + { + $conn = new mysqli(PHP_DB_SERVER, PHP_DB_USER, PHP_DB_PWD, PHP_DB_SCHEMA); + if ($conn->connect_errno) { + fwrite(STDOUT, $conn->connect_error); + } + + $this->db = new Database(realpath(__DIR__), $conn); + + $this->assertInstanceOf("Godsgood33\Php_Db\Database", $this->db); + } + + public function testSetLogLevel() + { + $this->db->setLogLevel(Logger::DEBUG); + $this->assertEquals(Logger::DEBUG, $this->db->getLogLevel()); + } + + /** + * @expectedException TypeError + */ + public function testSelectWithInvalidTableName() + { + $this->db->select(new stdClass()); + } + + public function testSelectWithNoParameters() + { + // query table with NO parameters + $this->db->select("test"); + $this->assertEquals("SELECT * FROM test", $this->db->getSql()); + } + + public function testSelectWithNullFieldParameter() + { + // query table with null fields parameter + $this->db->select("test", null); + $this->assertEquals("SELECT * FROM test", $this->db->getSql()); + } + + public function testSelectWithOneArrayParameter() + { + // query table with one parameter + $this->db->select("test", [ + 'id' + ]); + $this->assertEquals("SELECT `id` FROM test", $this->db->getSql()); + } + + public function testSelectWithTwoArrayParameters() + { + // query table with 2 parameters + $this->db->select("test", [ + 'id', + 'name' + ]); + $this->assertEquals("SELECT `id`,`name` FROM test", $this->db->getSql()); + } + + public function testSelectWithOneStringParameter() + { + // query table with string parameter + $this->db->select("test", 'id'); + $this->assertEquals("SELECT id FROM test", $this->db->getSql()); + } + + /** + * @expectedException InvalidArgumentException + */ + public function testSelectWithStdClassParameter() + { + // query table with object parameter + $this->db->select("test", new stdClass()); + $this->assertEquals("SELECT FROM test", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testSelectWithNullWhereParameter() + { + // query table with null where parameter + $this->db->select("test", 'id', null); + $this->assertEquals("SELECT id FROM test", $this->db->getSql()); + } + + public function testSelectWithEmptyArrayWhereParameter() + { + // query table with empty array where paramter + $this->db->select("test", 'id', []); + $this->assertEquals("SELECT id FROM test", $this->db->getSql()); + } + + public function testSelectWithImcompleteWhereArrayParameter() + { + // query with incomplete WHERE clause + $this->db->select("test", 'id', [ + [ + 'field' => 'id' + ] + ]); + $this->assertEquals("SELECT id FROM test", $this->db->getSql()); + } + + public function testGroupWithString() + { + // $this->markTestIncomplete(); + + // query with single group by string + $sql = $this->db->groups('name'); + $this->assertEquals(" GROUP BY name", $sql); + } + + public function testGroupWithArray() + { + // query with array group by string + $sql = $this->db->groups([ + 'name', + 'id' + ]); + $this->assertEquals(" GROUP BY name, id", $sql); + } + + /** + * @expectedException Exception + */ + public function testGroupWrongUnknownDataType() + { + // $this->markTestIncomplete(); + + // query group with invalid datatype (stdClass) should throw Exception + $this->db->groups(new stdClass()); + } + + public function testOrderWithString() + { + // $this->markTestIncomplete(); + + // query with single name order parameter + $sql = $this->db->order("name"); + $this->assertEquals(" ORDER BY name", $sql); + } + + public function testOrderWithArray() + { + // query with order array + $sql = $this->db->order([ + [ + 'field' => 'id', + 'sort' => 'ASC' + ], + [ + 'field' => 'name', + 'sort' => 'DESC' + ] + ]); + $this->assertEquals(" ORDER BY id ASC, name DESC", $sql); + } + + public function testOrderWithObject() + { + // query with invalid datatype (stdClass) will return empty string + $sql = $this->db->order(new stdClass()); + $this->assertEquals("", $sql); + } + + public function testFlags() + { + // $this->markTestIncomplete(); + + // query flags with all parameters + $sql = $this->db->flags([ + 'group' => 'name', + 'order' => 'name', + 'having' => [ + [ + 'field' => 'id', + 'op' => '=', + 'value' => 1 + ] + ], + 'limit' => '10', + 'start' => '5' + ]); + $this->assertEquals(" GROUP BY name HAVING `id` = '1' ORDER BY name LIMIT 5,10", $sql); + } + + public function testCreateTemporaryTable() + { + $this->db->select("test"); + $this->db->createTable('test2', true); + $this->assertEquals("CREATE TEMPORARY TABLE IF NOT EXISTS test2 AS (SELECT * FROM test)", $this->db->getSql()); + } + + public function testCreateTable() + { + // Database::$autorun = false; + $this->db->createTable('test', false, $this->db->select("test")); + $this->assertEquals("CREATE TABLE IF NOT EXISTS test AS (SELECT * FROM test)", $this->db->getSql()); + // Database::$autorun = true; + } + + public function testCreateTableWithArrayParameter() + { + $this->db->createTable("test", true, [ + [ + 'field' => 'id', + 'datatype' => 'int(11)', + 'option' => 'PRIMARY KEY' + ], + [ + 'field' => 'name', + 'datatype' => 'varchar(100)', + 'default' => null + ], + [ + 'field' => 'email', + 'datatype' => 'varchar(100)', + 'default' => '' + ] + ]); + $this->assertEquals("CREATE TEMPORARY TABLE IF NOT EXISTS test (`id` int(11) PRIMARY KEY,`name` varchar(100),`email` varchar(100) DEFAULT '')", $this->db->getSql()); + } + + public function testCreateTableJson() + { + $json = json_decode(file_get_contents(dirname(dirname(__FILE__)) . "/examples/create_table_json.json")); + + $this->db->createTableJson($json->tables[0]); + $this->assertEquals("CREATE TABLE IF NOT EXISTS `settings` (`id` int(11) AUTO_INCREMENT NOT NULL,`meta_key` varchar(100) NOT NULL,`meta_value` mediumtext DEFAULT NULL, UNIQUE(`meta_key`), PRIMARY KEY(`id`))", $this->db->getSql()); + } + + public function testCreateTableJson2() + { + $json = json_decode(file_get_contents(dirname(dirname(__FILE__)) . "/examples/create_table_json.json")); + + $this->db->createTableJson($json->tables[1]); + $this->assertEquals("CREATE TABLE IF NOT EXISTS `test` (`id` int(11) AUTO_INCREMENT NOT NULL,`fk` int(11) NOT NULL,`default` tinyint(1) DEFAULT '0',`enum` enum('1','2') DEFAULT '1', INDEX `default_idx` (`default`), CONSTRAINT `con_1` FOREIGN KEY (`fk`) REFERENCES `db`.`test` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION, PRIMARY KEY(`id`,`fk`))", $this->db->getSql()); + } + + public function testCreateTableJson3() + { + $json = json_decode(file_get_contents(dirname(dirname(__FILE__)) . "/examples/create_table_json.json")); + + $this->db->createTableJson($json->tables[2]); + $this->assertEquals("CREATE TABLE IF NOT EXISTS `test2` (`id` int(11) AUTO_INCREMENT NOT NULL, PRIMARY KEY(`id`))", $this->db->getSql()); + } + + public function testTableExists() + { + $tbl_count = $this->db->tableExists('db', 'settings'); + $this->assertEquals(1, $tbl_count); + } + + public function testMultipleTableExists() + { + $tbl_count = $this->db->tableExists('db', 'test%'); + $this->assertEquals(2, $tbl_count); + } + + public function testTableNotPresent() + { + $tbl_not_present = $this->db->tableExists('db', "users"); + $this->assertFalse($tbl_not_present); + } + + public function testAlterTableAddColumn() + { + $new = new stdClass(); + $new->name = 'newCol'; + $new->dataType = 'tinyint(1)'; + $new->nn = false; + $new->default = null; + + $this->db->alterTable('test', Database::ADD_COLUMN, $new); + $this->assertEquals("ALTER TABLE test ADD COLUMN `newCol` tinyint(1) DEFAULT NULL", $this->db->getSql()); + } + + public function testAlterTableModifyColumn() + { + $mod = new stdClass(); + $mod->name = 'default'; + $mod->new_name = 'default2'; + $mod->dataType = 'int(1)'; + $mod->nn = true; + $mod->default = 1; + + $this->db->alterTable("test", Database::MODIFY_COLUMN, $mod); + $this->assertEquals("ALTER TABLE test MODIFY COLUMN `default` `default2` int(1) NOT NULL DEFAULT '1'", $this->db->getSql()); + } + + public function testAlterTableDropColumn() + { + $drop = new stdClass(); + $drop->name = 'newCol'; + + $this->db->alterTable("test", Database::DROP_COLUMN, [ + $drop + ]); + $this->assertEquals("ALTER TABLE test DROP COLUMN `newCol`", $this->db->getSql()); + } + + public function testSelectCountWithNoParameters() + { + $this->db->selectCount("test"); + $this->assertEquals("SELECT COUNT(1) AS 'count' FROM test", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testSelectCountWithStdClassParameterForTable() + { + $this->db->selectCount(new stdClass()); + } + + public function testSelectCountWithArrayWhereParameter() + { + $this->db->selectCount("test", [ + [ + 'field' => 'name', + 'value' => 'Ed' + ] + ], [ + 'joins' => [ + "JOIN settings s ON s.id = test.id" + ] + ]); + $this->assertEquals("SELECT COUNT(1) AS 'count' FROM test JOIN settings s ON s.id = test.id WHERE `name` = 'Ed'", $this->db->getSql()); + } + + public function testInsertWithOneElementArrayParameter() + { + // query with one parameter + $this->db->insert("test", [ + 'id' => 1 + ]); + $this->assertEquals("INSERT INTO test (`id`) VALUES ('1')", $this->db->getSql()); + } + + public function testInsertWithTwoElementArrayParameter() + { + // query with 2 parameters + $this->db->insert("test", [ + 'id' => 1, + 'name' => 'Ed' + ], true); + $this->assertEquals("INSERT IGNORE INTO test (`id`,`name`) VALUES ('1','Ed')", $this->db->getSql()); + } + + public function testInsertWithSelectStatement() + { + // insert query using SELECT statement + $this->db->insert("test", "SELECT id FROM settings"); + $this->assertEquals("INSERT INTO test SELECT id FROM settings", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testInsertInvalidTableNameDataType() + { + $this->db->insert(new stdClass()); + } + + /** + * @expectedException Error + */ + public function testInsertInvalidParameterDataType() + { + $this->db->insert("test", new stdClass()); + } + + public function testEInsert() + { + // extended insert query with fields and 2 items + $this->db->extendedInsert("test", [ + 'id', + 'name' + ], [ + [ + 1, + 'Ed' + ], + [ + 2, + 'Frank' + ] + ]); + $this->assertEquals("INSERT INTO test (`id`,`name`) VALUES ('1','Ed'),('2','Frank')", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testEInsertInvalidTableNameDatatype() + { + $this->db->extendedInsert(new stdClass(), [], []); + } + + /** + * @expectedException Error + */ + public function testEInsertDifferentFieldValuePairs() + { + $this->db->extendedInsert('test', [ + 'id', + 'name' + ], [ + [ + 1 + ], + [ + 2 + ] + ]); + } + + /** + * @expectedException Error + */ + public function testEInsertDifferentFieldValuePairs2() + { + $this->db->extendedInsert('test', [ + 'id', + 'name' + ], [ + [ + 1, + 'Ed' + ], + [ + 2 + ] + ]); + } + + public function testUpdateWithOneElementArrayParameter() + { + $this->db->update('test', [ + 'name' => 'Frank' + ]); + $this->assertEquals("UPDATE test SET `name`='Frank'", $this->db->getSql()); + } + + public function testUpdateWithOneElementAndWhereArray() + { + $this->db->update('test', [ + 'name' => 'Frank' + ], [ + [ + 'field' => 'id', + 'value' => 1 + ] + ]); + $this->assertEquals("UPDATE test SET `name`='Frank' WHERE `id` = '1'", $this->db->getSql()); + } + + public function testUpdateWithOneElementAndJoinClause() + { + $this->db->update('test t', [ + 't.name' => 'Frank' + ], [], [ + 'joins' => [ + "JOIN settings s ON s.id=t.id" + ] + ]); + $this->assertEquals("UPDATE test t JOIN settings s ON s.id=t.id SET t.name='Frank'", $this->db->getSql()); + } + + public function testUpdateWithOneElementAndLimitClause() + { + $this->db->update('test', [ + 'name' => 'Frank' + ], [], [ + 'limit' => 1 + ]); + $this->assertEquals("UPDATE test SET `name`='Frank' LIMIT 1", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testUpdateInvalidTableNameDatatype() + { + $this->db->update(new stdClass(), []); + } + + public function testEUpdateWithArrayList() + { + $this->db->extendedUpdate("test", "settings", "id", [ + 'name' + ]); + $this->assertEquals("UPDATE test tbu INNER JOIN settings o USING (id) SET tbu.`name` = o.`name`", $this->db->getSql()); + } + + public function testEUpdateWithStringList() + { + $this->db->extendedUpdate("test", "settings", "id", "name"); + $this->assertEquals("UPDATE test tbu INNER JOIN settings o USING (id) SET tbu.`name` = o.`name`", $this->db->getSql()); + } + + /** + * @expectedException Exception + */ + public function testEUpdateInvalidParamDatatype() + { + $this->db->extendedUpdate('test', 'settings', 'id', new stdClass()); + } + + public function testReplace() + { + $this->db->replace("test", [ + 'id' => 1 + ]); + $this->assertEquals("REPLACE INTO test (`id`) VALUES ('1')", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testReplaceInvalidTableNameDatatype() + { + $this->db->replace(new stdClass(), []); + } + + public function testEReplace() + { + $this->db->extendedReplace("test", [ + 'id', + 'name' + ], [ + [ + 1, + 'Ed' + ], + [ + 2, + 'Frank' + ] + ]); + $this->assertEquals("REPLACE INTO test (`id`,`name`) VALUES ('1','Ed'),('2','Frank')", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testEReplaceInvalidTableNameDatatype() + { + $this->db->extendedReplace(new stdClass(), [], []); + } + + public function testFieldExists() + { + $id_exists = $this->db->fieldExists('test', 'id'); + $this->assertTrue($id_exists); + } + + public function testFieldDoesNotExist() + { + $phone_not_exists = $this->db->fieldExists('test', 'phone'); + $this->assertFalse($phone_not_exists); + } + + public function testFieldData() + { + $id = new stdClass(); + $id->name = 'id'; + $id->orgname = 'id'; + $id->table = 'test2'; + $id->orgtable = 'test2'; + $id->def = null; + $id->db = 'db'; + $id->catalog = 'def'; + $id->max_length = 0; + $id->length = 11; + $id->charsetnr = 63; + $id->flags = 49667; + $id->type = 3; + $id->decimals = 0; + + // query all fields in table + $fd = $this->db->fieldData("test2"); + $this->assertEquals([ + 'id' => $id + ], $fd); + + // query single field in table + $fd = $this->db->fieldData('test2', 'id'); + $this->assertEquals([ + 'id' => $id + ], $fd); + + // query array of fields in table + $fd = $this->db->fieldData('test2', [ + 'id' + ]); + $this->assertEquals([ + 'id' => $id + ], $fd); + + // invalid datatype for field name + $fd = $this->db->fieldData('test2', new stdClass()); + $this->assertEquals(null, $fd); + } + + public function testEscapeDontEscapeNow() + { + // $this->markTestIncomplete(); + $ret = $this->db->_escape('NOW()', false); + $this->assertEquals("NOW()", $ret); + } + + public function testEscapeDontEscapeBackticks() + { + $ret = $this->db->_escape("t.`id`", false); + $this->assertEquals("t.`id`", $ret); + } + + public function testEscapeEscapeDateTime() + { + $dt = new DateTime("2017-01-01 00:00:00"); + $ret = $this->db->_escape($dt); + $this->assertEquals("'2017-01-01 00:00:00'", $ret); + } + + public function testEscapeBoolean() + { + $ret = $this->db->_escape(true); + $this->assertEquals("'1'", $ret); + } + + public function testEscapeClassWithEscapeMethod() + { + $tc = new TestClass(); + $tc->var = "test's"; + $ret = $this->db->_escape($tc); + $this->assertEquals("test\'s", $ret); + } + + public function testEscapeUnknownClassToEscape() + { + // $this->markTestIncomplete(); + $tc2 = new TestClass2(); + $tc2->var = "test"; + $ret = $this->db->_escape($tc2); + + $this->assertEquals("", $ret); + } + + public function testDeleteBasic() + { + $this->db->delete("test"); + $this->assertEquals("DELETE FROM test", $this->db->getSql()); + } + + public function testDeleteWithWhereClause() + { + $this->db->delete('test', [ + 'id' + ], [ + [ + 'field' => 'id', + 'op' => '=', + 'value' => 1 + ] + ]); + $this->assertEquals("DELETE id FROM test WHERE `id` = '1'", $this->db->getSql()); + } + + public function testDeleteWithJoin() + { + $this->db->delete('test t', [], [], [ + 'joins' => "JOIN settings s ON s.id=t.id" + ]); + $this->assertEquals("DELETE FROM test t JOIN settings s ON s.id=t.id", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testDeleteInvalidTableNameDatatype() + { + $this->db->delete(new stdClass()); + } + + public function testTruncate() + { + $this->db->truncate('test'); + $this->assertEquals("TRUNCATE TABLE test", $this->db->getSql()); + } + + /** + * @expectedException TypeError + */ + public function testTruncateInvalidTableNameDatatype() + { + $this->db->truncate(new stdClass()); + } + + public function testDropSettingsTable() + { + // Database::$autorun = false; + $sql = $this->db->drop("settings"); + $this->assertEquals("DROP TABLE IF EXISTS `settings`", $sql); + // Database::$autorun = true; + } + + public function testDropTestTable() + { + // Database::$autorun = false; + $sql = $this->db->drop("test"); + $this->assertEquals("DROP TABLE IF EXISTS `test`", $sql); + // Database::$autorun = true; + } + + public function testDropView() + { + // Database::$autorun = false; + $sql = $this->db->drop("test", "view"); + $this->assertEquals("DROP VIEW IF EXISTS `test`", $sql); + // Database::$autorun = true; + } + + /** + * @expectedException TypeError + */ + public function testDropInvalidTableNameDatatype() + { + $this->db->drop(new stdClass()); + } + + /** + * @expectedException TypeError + */ + public function testDropInvalidTypeDatatype() + { + $this->db->drop('test', new stdClass()); + } + + public function testSetSchema() + { + // set the schema and validate that it is what we set it to + $this->db->setSchema("test"); + $row = $this->db->query("SELECT DATABASE()"); + $this->assertEquals("test", $row->fetch_array()[0]); + } +} \ No newline at end of file diff --git a/inc/vendor/godsgood33/php-db/tests/TestClass.php b/inc/vendor/godsgood33/php-db/tests/TestClass.php new file mode 100644 index 0000000..836a54c --- /dev/null +++ b/inc/vendor/godsgood33/php-db/tests/TestClass.php @@ -0,0 +1,24 @@ +var); + } +} \ No newline at end of file diff --git a/inc/vendor/godsgood33/php-db/tests/TestClass2.php b/inc/vendor/godsgood33/php-db/tests/TestClass2.php new file mode 100644 index 0000000..4d01a9e --- /dev/null +++ b/inc/vendor/godsgood33/php-db/tests/TestClass2.php @@ -0,0 +1,5 @@ +add($complexString2); +``` +or pass all values to the appropriate function +``` +$complexString1 = '1.23-4.56i'; +$complexString2 = '2.34+5.67i'; + +echo Complex\add($complexString1, $complexString2); +``` +If you want to perform the same operation against multiple values (e.g. to add three or more complex numbers), then you can pass multiple arguments to any of the operations. + +You can pass these arguments as Complex objects, or as an array or string that will parse to a complex object. + +## Using functions + +When calling any of the available functions for a complex value, you can either call the relevant method for the Complex object +``` +$complexString = '1.23-4.56i'; + +$complexObject = new Complex\Complex($complexString); +echo $complexObject->sinh(); +``` +or you can call the function as you would in procedural code, passing the Complex object as an argument +``` +$complexString = '1.23-4.56i'; + +$complexObject = new Complex\Complex($complexString); +echo Complex\sinh($complexObject); +``` +When called procedurally using the function, you can pass in the argument as a Complex object, or as an array or string that will parse to a complex object. +``` +$complexString = '1.23-4.56i'; + +echo Complex\sinh($complexString); +``` + +In the case of the `pow()` function (the only implemented function that requires an additional argument) you need to pass both arguments when calling the function procedurally + +``` +$complexString = '1.23-4.56i'; + +$complexObject = new Complex\Complex($complexString); +echo Complex\pow($complexObject, 2); +``` +or pass the additional argument when calling the method +``` +$complexString = '1.23-4.56i'; + +$complexObject = new Complex\Complex($complexString); +echo $complexObject->pow(2); +``` diff --git a/inc/vendor/markbaker/complex/classes/Autoloader.php b/inc/vendor/markbaker/complex/classes/Autoloader.php new file mode 100644 index 0000000..9a8fcc1 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/Autoloader.php @@ -0,0 +1,53 @@ +regex = $regex; + parent::__construct($it, $regex); + } +} + +class FilenameFilter extends FilesystemRegexFilter +{ + // Filter files against the regex + public function accept() + { + return (!$this->isFile() || preg_match($this->regex, $this->getFilename())); + } +} + + +$srcFolder = __DIR__ . DIRECTORY_SEPARATOR . 'src'; +$srcDirectory = new RecursiveDirectoryIterator($srcFolder); + +$filteredFileList = new FilenameFilter($srcDirectory, '/(?:php)$/i'); +$filteredFileList = new FilenameFilter($filteredFileList, '/^(?!.*(Complex|Exception)\.php).*$/i'); + +foreach (new RecursiveIteratorIterator($filteredFileList) as $file) { + if ($file->isFile()) { + include_once $file; + } +} diff --git a/inc/vendor/markbaker/complex/classes/src/Complex.php b/inc/vendor/markbaker/complex/classes/src/Complex.php new file mode 100644 index 0000000..5671eb2 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/Complex.php @@ -0,0 +1,387 @@ + 0.0 && empty($suffix)) { + $suffix = 'i'; + } + + // Set parsed values in our properties + $this->realPart = (float) $realPart; + $this->imaginaryPart = (float) $imaginaryPart; + $this->suffix = strtolower($suffix); + } + + /** + * Gets the real part of this complex number + * + * @return Float + */ + public function getReal() + { + return $this->realPart; + } + + /** + * Gets the imaginary part of this complex number + * + * @return Float + */ + public function getImaginary() + { + return $this->imaginaryPart; + } + + /** + * Gets the suffix of this complex number + * + * @return String + */ + public function getSuffix() + { + return $this->suffix; + } + + /** + * Returns true if this is a real value, false if a complex value + * + * @return Bool + */ + public function isReal() + { + return $this->imaginaryPart == 0.0; + } + + /** + * Returns true if this is a complex value, false if a real value + * + * @return Bool + */ + public function isComplex() + { + return !$this->isReal(); + } + + public function format() + { + $str = ""; + if ($this->imaginaryPart != 0.0) { + if (\abs($this->imaginaryPart) != 1.0) { + $str .= $this->imaginaryPart . $this->suffix; + } else { + $str .= (($this->imaginaryPart < 0.0) ? '-' : '') . $this->suffix; + } + } + if ($this->realPart != 0.0) { + if (($str) && ($this->imaginaryPart > 0.0)) { + $str = "+" . $str; + } + $str = $this->realPart . $str; + } + if (!$str) { + $str = "0.0"; + } + + return $str; + } + + public function __toString() + { + return $this->format(); + } + + /** + * Validates whether the argument is a valid complex number, converting scalar or array values if possible + * + * @param mixed $complex The value to validate + * @return Complex + * @throws Exception If the argument isn't a Complex number or cannot be converted to one + */ + public static function validateComplexArgument($complex) + { + if (is_scalar($complex) || is_array($complex)) { + $complex = new Complex($complex); + } elseif (!is_object($complex) || !($complex instanceof Complex)) { + throw new Exception('Value is not a valid complex number'); + } + + return $complex; + } + + /** + * Returns the reverse of this complex number + * + * @return Complex + */ + public function reverse() + { + return new Complex( + $this->imaginaryPart, + $this->realPart, + ($this->realPart == 0.0) ? null : $this->suffix + ); + } + + public function invertImaginary() + { + return new Complex( + $this->realPart, + $this->imaginaryPart * -1, + ($this->imaginaryPart == 0.0) ? null : $this->suffix + ); + } + + public function invertReal() + { + return new Complex( + $this->realPart * -1, + $this->imaginaryPart, + ($this->imaginaryPart == 0.0) ? null : $this->suffix + ); + } + + protected static $functions = [ + 'abs', + 'acos', + 'acosh', + 'acot', + 'acoth', + 'acsc', + 'acsch', + 'argument', + 'asec', + 'asech', + 'asin', + 'asinh', + 'atan', + 'atanh', + 'conjugate', + 'cos', + 'cosh', + 'cot', + 'coth', + 'csc', + 'csch', + 'exp', + 'inverse', + 'ln', + 'log2', + 'log10', + 'negative', + 'pow', + 'rho', + 'sec', + 'sech', + 'sin', + 'sinh', + 'sqrt', + 'tan', + 'tanh', + 'theta', + ]; + + protected static $operations = [ + 'add', + 'subtract', + 'multiply', + 'divideby', + 'divideinto', + ]; + + /** + * Returns the result of the function call or operation + * + * @return Complex|float + * @throws Exception|\InvalidArgumentException + */ + public function __call($functionName, $arguments) + { + $functionName = strtolower(str_replace('_', '', $functionName)); + + // Test for function calls + if (in_array($functionName, self::$functions)) { + $functionName = "\\" . __NAMESPACE__ . "\\{$functionName}"; + return $functionName($this, ...$arguments); + } + // Test for operation calls + if (in_array($functionName, self::$operations)) { + $functionName = "\\" . __NAMESPACE__ . "\\{$functionName}"; + return $functionName($this, ...$arguments); + } + throw new Exception('Function or Operation does not exist'); + } +} diff --git a/inc/vendor/markbaker/complex/classes/src/Exception.php b/inc/vendor/markbaker/complex/classes/src/Exception.php new file mode 100644 index 0000000..a2beb73 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/Exception.php @@ -0,0 +1,13 @@ +getReal() - $invsqrt->getImaginary(), + $complex->getImaginary() + $invsqrt->getReal() + ); + $log = ln($adjust); + + return new Complex( + $log->getImaginary(), + -1 * $log->getReal() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/acosh.php b/inc/vendor/markbaker/complex/classes/src/functions/acosh.php new file mode 100644 index 0000000..18a992e --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/acosh.php @@ -0,0 +1,34 @@ +isReal() && ($complex->getReal() > 1)) { + return new Complex(\acosh($complex->getReal())); + } + + $acosh = acos($complex) + ->reverse(); + if ($acosh->getReal() < 0.0) { + $acosh = $acosh->invertReal(); + } + + return $acosh; +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/acot.php b/inc/vendor/markbaker/complex/classes/src/functions/acot.php new file mode 100644 index 0000000..11bee46 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/acot.php @@ -0,0 +1,25 @@ +getReal() == 0.0 && $complex->getImaginary() == 0.0) { + return INF; + } + + return asin(inverse($complex)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/acsch.php b/inc/vendor/markbaker/complex/classes/src/functions/acsch.php new file mode 100644 index 0000000..bb45d34 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/acsch.php @@ -0,0 +1,29 @@ +getReal() == 0.0 && $complex->getImaginary() == 0.0) { + return INF; + } + + return asinh(inverse($complex)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/argument.php b/inc/vendor/markbaker/complex/classes/src/functions/argument.php new file mode 100644 index 0000000..d7209cc --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/argument.php @@ -0,0 +1,28 @@ +getReal() == 0.0 && $complex->getImaginary() == 0.0) { + return INF; + } + + return acos(inverse($complex)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/asech.php b/inc/vendor/markbaker/complex/classes/src/functions/asech.php new file mode 100644 index 0000000..b36c40e --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/asech.php @@ -0,0 +1,29 @@ +getReal() == 0.0 && $complex->getImaginary() == 0.0) { + return INF; + } + + return acosh(inverse($complex)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/asin.php b/inc/vendor/markbaker/complex/classes/src/functions/asin.php new file mode 100644 index 0000000..9c982ac --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/asin.php @@ -0,0 +1,37 @@ +getReal() - $complex->getImaginary(), + $invsqrt->getImaginary() + $complex->getReal() + ); + $log = ln($adjust); + + return new Complex( + $log->getImaginary(), + -1 * $log->getReal() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/asinh.php b/inc/vendor/markbaker/complex/classes/src/functions/asinh.php new file mode 100644 index 0000000..c1243fd --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/asinh.php @@ -0,0 +1,33 @@ +isReal() && ($complex->getReal() > 1)) { + return new Complex(\asinh($complex->getReal())); + } + + $asinh = clone $complex; + $asinh = $asinh->reverse() + ->invertReal(); + $asinh = asin($asinh); + return $asinh->reverse() + ->invertImaginary(); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/atan.php b/inc/vendor/markbaker/complex/classes/src/functions/atan.php new file mode 100644 index 0000000..2c75dcf --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/atan.php @@ -0,0 +1,45 @@ +isReal()) { + return new Complex(\atan($complex->getReal())); + } + + $t1Value = new Complex(-1 * $complex->getImaginary(), $complex->getReal()); + $uValue = new Complex(1, 0); + + $d1Value = clone $uValue; + $d1Value = subtract($d1Value, $t1Value); + $d2Value = add($t1Value, $uValue); + $uResult = $d1Value->divideBy($d2Value); + $uResult = ln($uResult); + + return new Complex( + (($uResult->getImaginary() == M_PI) ? -M_PI : $uResult->getImaginary()) * -0.5, + $uResult->getReal() * 0.5, + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/atanh.php b/inc/vendor/markbaker/complex/classes/src/functions/atanh.php new file mode 100644 index 0000000..c53f2a9 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/atanh.php @@ -0,0 +1,38 @@ +isReal()) { + $real = $complex->getReal(); + if ($real >= -1.0 && $real <= 1.0) { + return new Complex(\atanh($real)); + } else { + return new Complex(\atanh(1 / $real), (($real < 0.0) ? M_PI_2 : -1 * M_PI_2)); + } + } + + $iComplex = clone $complex; + $iComplex = $iComplex->invertImaginary() + ->reverse(); + return atan($iComplex) + ->invertReal() + ->reverse(); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/conjugate.php b/inc/vendor/markbaker/complex/classes/src/functions/conjugate.php new file mode 100644 index 0000000..bd1984b --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/conjugate.php @@ -0,0 +1,28 @@ +getReal(), + -1 * $complex->getImaginary(), + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/cos.php b/inc/vendor/markbaker/complex/classes/src/functions/cos.php new file mode 100644 index 0000000..80a4683 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/cos.php @@ -0,0 +1,34 @@ +isReal()) { + return new Complex(\cos($complex->getReal())); + } + + return conjugate( + new Complex( + \cos($complex->getReal()) * \cosh($complex->getImaginary()), + \sin($complex->getReal()) * \sinh($complex->getImaginary()), + $complex->getSuffix() + ) + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/cosh.php b/inc/vendor/markbaker/complex/classes/src/functions/cosh.php new file mode 100644 index 0000000..a4bea65 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/cosh.php @@ -0,0 +1,32 @@ +isReal()) { + return new Complex(\cosh($complex->getReal())); + } + + return new Complex( + \cosh($complex->getReal()) * \cos($complex->getImaginary()), + \sinh($complex->getReal()) * \sin($complex->getImaginary()), + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/cot.php b/inc/vendor/markbaker/complex/classes/src/functions/cot.php new file mode 100644 index 0000000..339101e --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/cot.php @@ -0,0 +1,29 @@ +getReal() == 0.0 && $complex->getImaginary() == 0.0) { + return new Complex(INF); + } + + return inverse(tan($complex)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/coth.php b/inc/vendor/markbaker/complex/classes/src/functions/coth.php new file mode 100644 index 0000000..7fe705a --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/coth.php @@ -0,0 +1,24 @@ +getReal() == 0.0 && $complex->getImaginary() == 0.0) { + return INF; + } + + return inverse(sin($complex)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/csch.php b/inc/vendor/markbaker/complex/classes/src/functions/csch.php new file mode 100644 index 0000000..f450098 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/csch.php @@ -0,0 +1,29 @@ +getReal() == 0.0 && $complex->getImaginary() == 0.0) { + return INF; + } + + return inverse(sinh($complex)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/exp.php b/inc/vendor/markbaker/complex/classes/src/functions/exp.php new file mode 100644 index 0000000..4cac696 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/exp.php @@ -0,0 +1,34 @@ +getReal() == 0.0) && (\abs($complex->getImaginary()) == M_PI)) { + return new Complex(-1.0, 0.0); + } + + $rho = \exp($complex->getReal()); + + return new Complex( + $rho * \cos($complex->getImaginary()), + $rho * \sin($complex->getImaginary()), + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/inverse.php b/inc/vendor/markbaker/complex/classes/src/functions/inverse.php new file mode 100644 index 0000000..7d3182a --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/inverse.php @@ -0,0 +1,29 @@ +getReal() == 0.0 && $complex->getImaginary() == 0.0) { + throw new \InvalidArgumentException('Division by zero'); + } + + return $complex->divideInto(1.0); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/ln.php b/inc/vendor/markbaker/complex/classes/src/functions/ln.php new file mode 100644 index 0000000..39071cf --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/ln.php @@ -0,0 +1,33 @@ +getReal() == 0.0) && ($complex->getImaginary() == 0.0)) { + throw new \InvalidArgumentException(); + } + + return new Complex( + \log(rho($complex)), + theta($complex), + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/log10.php b/inc/vendor/markbaker/complex/classes/src/functions/log10.php new file mode 100644 index 0000000..694d3d0 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/log10.php @@ -0,0 +1,32 @@ +getReal() == 0.0) && ($complex->getImaginary() == 0.0)) { + throw new \InvalidArgumentException(); + } elseif (($complex->getReal() > 0.0) && ($complex->getImaginary() == 0.0)) { + return new Complex(\log10($complex->getReal()), 0.0, $complex->getSuffix()); + } + + return ln($complex) + ->multiply(\log10(Complex::EULER)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/log2.php b/inc/vendor/markbaker/complex/classes/src/functions/log2.php new file mode 100644 index 0000000..081f2c4 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/log2.php @@ -0,0 +1,32 @@ +getReal() == 0.0) && ($complex->getImaginary() == 0.0)) { + throw new \InvalidArgumentException(); + } elseif (($complex->getReal() > 0.0) && ($complex->getImaginary() == 0.0)) { + return new Complex(\log($complex->getReal(), 2), 0.0, $complex->getSuffix()); + } + + return ln($complex) + ->multiply(\log(Complex::EULER, 2)); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/negative.php b/inc/vendor/markbaker/complex/classes/src/functions/negative.php new file mode 100644 index 0000000..dbd1192 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/negative.php @@ -0,0 +1,31 @@ +getReal(), + -1 * $complex->getImaginary(), + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/pow.php b/inc/vendor/markbaker/complex/classes/src/functions/pow.php new file mode 100644 index 0000000..18ee269 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/pow.php @@ -0,0 +1,40 @@ +getImaginary() == 0.0 && $complex->getReal() >= 0.0) { + return new Complex(\pow($complex->getReal(), $power)); + } + + $rValue = \sqrt(($complex->getReal() * $complex->getReal()) + ($complex->getImaginary() * $complex->getImaginary())); + $rPower = \pow($rValue, $power); + $theta = $complex->argument() * $power; + if ($theta == 0) { + return new Complex(1); + } + + return new Complex($rPower * \cos($theta), $rPower * \sin($theta), $complex->getSuffix()); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/rho.php b/inc/vendor/markbaker/complex/classes/src/functions/rho.php new file mode 100644 index 0000000..750f3f9 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/rho.php @@ -0,0 +1,28 @@ +getReal() * $complex->getReal()) + + ($complex->getImaginary() * $complex->getImaginary()) + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/sec.php b/inc/vendor/markbaker/complex/classes/src/functions/sec.php new file mode 100644 index 0000000..7dd43ea --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/sec.php @@ -0,0 +1,25 @@ +isReal()) { + return new Complex(\sin($complex->getReal())); + } + + return new Complex( + \sin($complex->getReal()) * \cosh($complex->getImaginary()), + \cos($complex->getReal()) * \sinh($complex->getImaginary()), + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/sinh.php b/inc/vendor/markbaker/complex/classes/src/functions/sinh.php new file mode 100644 index 0000000..4c0f650 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/sinh.php @@ -0,0 +1,32 @@ +isReal()) { + return new Complex(\sinh($complex->getReal())); + } + + return new Complex( + \sinh($complex->getReal()) * \cos($complex->getImaginary()), + \cosh($complex->getReal()) * \sin($complex->getImaginary()), + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/sqrt.php b/inc/vendor/markbaker/complex/classes/src/functions/sqrt.php new file mode 100644 index 0000000..9c171b8 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/sqrt.php @@ -0,0 +1,29 @@ +getSuffix()); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/tan.php b/inc/vendor/markbaker/complex/classes/src/functions/tan.php new file mode 100644 index 0000000..014d798 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/tan.php @@ -0,0 +1,40 @@ +isReal()) { + return new Complex(\tan($complex->getReal())); + } + + $real = $complex->getReal(); + $imaginary = $complex->getImaginary(); + $divisor = 1 + \pow(\tan($real), 2) * \pow(\tanh($imaginary), 2); + if ($divisor == 0.0) { + throw new \InvalidArgumentException('Division by zero'); + } + + return new Complex( + \pow(sech($imaginary)->getReal(), 2) * \tan($real) / $divisor, + \pow(sec($real)->getReal(), 2) * \tanh($imaginary) / $divisor, + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/tanh.php b/inc/vendor/markbaker/complex/classes/src/functions/tanh.php new file mode 100644 index 0000000..028741d --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/tanh.php @@ -0,0 +1,35 @@ +getReal(); + $imaginary = $complex->getImaginary(); + $divisor = \cos($imaginary) * \cos($imaginary) + \sinh($real) * \sinh($real); + if ($divisor == 0.0) { + throw new \InvalidArgumentException('Division by zero'); + } + + return new Complex( + \sinh($real) * \cosh($real) / $divisor, + 0.5 * \sin(2 * $imaginary) / $divisor, + $complex->getSuffix() + ); +} diff --git a/inc/vendor/markbaker/complex/classes/src/functions/theta.php b/inc/vendor/markbaker/complex/classes/src/functions/theta.php new file mode 100644 index 0000000..d12866c --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/functions/theta.php @@ -0,0 +1,38 @@ +getReal() == 0.0) { + if ($complex->isReal()) { + return 0.0; + } elseif ($complex->getImaginary() < 0.0) { + return M_PI / -2; + } + return M_PI / 2; + } elseif ($complex->getReal() > 0.0) { + return \atan($complex->getImaginary() / $complex->getReal()); + } elseif ($complex->getImaginary() < 0.0) { + return -(M_PI - \atan(\abs($complex->getImaginary()) / \abs($complex->getReal()))); + } + + return M_PI - \atan($complex->getImaginary() / \abs($complex->getReal())); +} diff --git a/inc/vendor/markbaker/complex/classes/src/operations/add.php b/inc/vendor/markbaker/complex/classes/src/operations/add.php new file mode 100644 index 0000000..10bd42f --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/operations/add.php @@ -0,0 +1,46 @@ +isComplex() && $complex->isComplex() && + $result->getSuffix() !== $complex->getSuffix()) { + throw new Exception('Suffix Mismatch'); + } + + $real = $result->getReal() + $complex->getReal(); + $imaginary = $result->getImaginary() + $complex->getImaginary(); + + $result = new Complex( + $real, + $imaginary, + ($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix()) + ); + } + + return $result; +} diff --git a/inc/vendor/markbaker/complex/classes/src/operations/divideby.php b/inc/vendor/markbaker/complex/classes/src/operations/divideby.php new file mode 100644 index 0000000..089e0ef --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/operations/divideby.php @@ -0,0 +1,56 @@ +isComplex() && $complex->isComplex() && + $result->getSuffix() !== $complex->getSuffix()) { + throw new Exception('Suffix Mismatch'); + } + if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { + throw new \InvalidArgumentException('Division by zero'); + } + + $delta1 = ($result->getReal() * $complex->getReal()) + + ($result->getImaginary() * $complex->getImaginary()); + $delta2 = ($result->getImaginary() * $complex->getReal()) - + ($result->getReal() * $complex->getImaginary()); + $delta3 = ($complex->getReal() * $complex->getReal()) + + ($complex->getImaginary() * $complex->getImaginary()); + + $real = $delta1 / $delta3; + $imaginary = $delta2 / $delta3; + + $result = new Complex( + $real, + $imaginary, + ($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix()) + ); + } + + return $result; +} diff --git a/inc/vendor/markbaker/complex/classes/src/operations/divideinto.php b/inc/vendor/markbaker/complex/classes/src/operations/divideinto.php new file mode 100644 index 0000000..3dfe085 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/operations/divideinto.php @@ -0,0 +1,56 @@ +isComplex() && $complex->isComplex() && + $result->getSuffix() !== $complex->getSuffix()) { + throw new Exception('Suffix Mismatch'); + } + if ($result->getReal() == 0.0 && $result->getImaginary() == 0.0) { + throw new \InvalidArgumentException('Division by zero'); + } + + $delta1 = ($complex->getReal() * $result->getReal()) + + ($complex->getImaginary() * $result->getImaginary()); + $delta2 = ($complex->getImaginary() * $result->getReal()) - + ($complex->getReal() * $result->getImaginary()); + $delta3 = ($result->getReal() * $result->getReal()) + + ($result->getImaginary() * $result->getImaginary()); + + $real = $delta1 / $delta3; + $imaginary = $delta2 / $delta3; + + $result = new Complex( + $real, + $imaginary, + ($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix()) + ); + } + + return $result; +} diff --git a/inc/vendor/markbaker/complex/classes/src/operations/multiply.php b/inc/vendor/markbaker/complex/classes/src/operations/multiply.php new file mode 100644 index 0000000..bf2473e --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/operations/multiply.php @@ -0,0 +1,48 @@ +isComplex() && $complex->isComplex() && + $result->getSuffix() !== $complex->getSuffix()) { + throw new Exception('Suffix Mismatch'); + } + + $real = ($result->getReal() * $complex->getReal()) - + ($result->getImaginary() * $complex->getImaginary()); + $imaginary = ($result->getReal() * $complex->getImaginary()) + + ($result->getImaginary() * $complex->getReal()); + + $result = new Complex( + $real, + $imaginary, + ($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix()) + ); + } + + return $result; +} diff --git a/inc/vendor/markbaker/complex/classes/src/operations/subtract.php b/inc/vendor/markbaker/complex/classes/src/operations/subtract.php new file mode 100644 index 0000000..075ef44 --- /dev/null +++ b/inc/vendor/markbaker/complex/classes/src/operations/subtract.php @@ -0,0 +1,46 @@ +isComplex() && $complex->isComplex() && + $result->getSuffix() !== $complex->getSuffix()) { + throw new Exception('Suffix Mismatch'); + } + + $real = $result->getReal() - $complex->getReal(); + $imaginary = $result->getImaginary() - $complex->getImaginary(); + + $result = new Complex( + $real, + $imaginary, + ($imaginary == 0.0) ? null : max($result->getSuffix(), $complex->getSuffix()) + ); + } + + return $result; +} diff --git a/inc/vendor/markbaker/complex/composer.json b/inc/vendor/markbaker/complex/composer.json new file mode 100644 index 0000000..cb05712 --- /dev/null +++ b/inc/vendor/markbaker/complex/composer.json @@ -0,0 +1,77 @@ +{ + "name": "markbaker/complex", + "type": "library", + "description": "PHP Class for working with complex numbers", + "keywords": ["complex", "mathematics"], + "homepage": "https://github.com/MarkBaker/PHPComplex", + "license": "MIT", + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.35|^5.4.0", + "phpdocumentor/phpdocumentor":"2.*", + "phpmd/phpmd": "2.*", + "sebastian/phpcpd": "2.*", + "phploc/phploc": "2.*", + "squizlabs/php_codesniffer": "^3.3.0", + "phpcompatibility/php-compatibility": "^8.0", + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3" + }, + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + }, + "files": [ + "classes/src/functions/abs.php", + "classes/src/functions/acos.php", + "classes/src/functions/acosh.php", + "classes/src/functions/acot.php", + "classes/src/functions/acoth.php", + "classes/src/functions/acsc.php", + "classes/src/functions/acsch.php", + "classes/src/functions/argument.php", + "classes/src/functions/asec.php", + "classes/src/functions/asech.php", + "classes/src/functions/asin.php", + "classes/src/functions/asinh.php", + "classes/src/functions/atan.php", + "classes/src/functions/atanh.php", + "classes/src/functions/conjugate.php", + "classes/src/functions/cos.php", + "classes/src/functions/cosh.php", + "classes/src/functions/cot.php", + "classes/src/functions/coth.php", + "classes/src/functions/csc.php", + "classes/src/functions/csch.php", + "classes/src/functions/exp.php", + "classes/src/functions/inverse.php", + "classes/src/functions/ln.php", + "classes/src/functions/log2.php", + "classes/src/functions/log10.php", + "classes/src/functions/negative.php", + "classes/src/functions/pow.php", + "classes/src/functions/rho.php", + "classes/src/functions/sec.php", + "classes/src/functions/sech.php", + "classes/src/functions/sin.php", + "classes/src/functions/sinh.php", + "classes/src/functions/sqrt.php", + "classes/src/functions/tan.php", + "classes/src/functions/tanh.php", + "classes/src/functions/theta.php", + "classes/src/operations/add.php", + "classes/src/operations/subtract.php", + "classes/src/operations/multiply.php", + "classes/src/operations/divideby.php", + "classes/src/operations/divideinto.php" + ] + }, + "minimum-stability": "dev" +} \ No newline at end of file diff --git a/inc/vendor/markbaker/complex/examples/complexTest.php b/inc/vendor/markbaker/complex/examples/complexTest.php new file mode 100644 index 0000000..7dafd8a --- /dev/null +++ b/inc/vendor/markbaker/complex/examples/complexTest.php @@ -0,0 +1,154 @@ +add(456); +echo $x, PHP_EOL; + +$x = new Complex(123.456); +$x->add(789.012); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->add(new Complex(-987.654, -32.1)); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->add(-987.654); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->add(new Complex(0, 1)); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->add(new Complex(0, -1)); +echo $x, PHP_EOL; + + +echo PHP_EOL, 'Subtract', PHP_EOL; + +$x = new Complex(123); +$x->subtract(456); +echo $x, PHP_EOL; + +$x = new Complex(123.456); +$x->subtract(789.012); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->subtract(new Complex(-987.654, -32.1)); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->subtract(-987.654); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->subtract(new Complex(0, 1)); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->subtract(new Complex(0, -1)); +echo $x, PHP_EOL; + + +echo PHP_EOL, 'Multiply', PHP_EOL; + +$x = new Complex(123); +$x->multiply(456); +echo $x, PHP_EOL; + +$x = new Complex(123.456); +$x->multiply(789.012); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->multiply(new Complex(-987.654, -32.1)); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->multiply(-987.654); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->multiply(new Complex(0, 1)); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->multiply(new Complex(0, -1)); +echo $x, PHP_EOL; + + +echo PHP_EOL, 'Divide By', PHP_EOL; + +$x = new Complex(123); +$x->divideBy(456); +echo $x, PHP_EOL; + +$x = new Complex(123.456); +$x->divideBy(789.012); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->divideBy(new Complex(-987.654, -32.1)); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->divideBy(-987.654); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->divideBy(new Complex(0, 1)); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->divideBy(new Complex(0, -1)); +echo $x, PHP_EOL; + + +echo PHP_EOL, 'Divide Into', PHP_EOL; + +$x = new Complex(123); +$x->divideInto(456); +echo $x, PHP_EOL; + +$x = new Complex(123.456); +$x->divideInto(789.012); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->divideInto(new Complex(-987.654, -32.1)); +echo $x, PHP_EOL; + +$x = new Complex(123.456, 78.90); +$x->divideInto(-987.654); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->divideInto(new Complex(0, 1)); +echo $x, PHP_EOL; + +$x = new Complex(-987.654, -32.1); +$x->divideInto(new Complex(0, -1)); +echo $x, PHP_EOL; diff --git a/inc/vendor/markbaker/complex/examples/testFunctions.php b/inc/vendor/markbaker/complex/examples/testFunctions.php new file mode 100644 index 0000000..4d5ed73 --- /dev/null +++ b/inc/vendor/markbaker/complex/examples/testFunctions.php @@ -0,0 +1,52 @@ +getMessage(), PHP_EOL; + } + } + echo PHP_EOL; + } +} diff --git a/inc/vendor/markbaker/complex/examples/testOperations.php b/inc/vendor/markbaker/complex/examples/testOperations.php new file mode 100644 index 0000000..f791263 --- /dev/null +++ b/inc/vendor/markbaker/complex/examples/testOperations.php @@ -0,0 +1,34 @@ + ', $result, PHP_EOL; + +echo PHP_EOL; + +echo 'Subtraction', PHP_EOL; + +$result = \Complex\subtract(...$values); +echo '=> ', $result, PHP_EOL; + +echo PHP_EOL; + +echo 'Multiplication', PHP_EOL; + +$result = \Complex\multiply(...$values); +echo '=> ', $result, PHP_EOL; diff --git a/inc/vendor/markbaker/complex/license.md b/inc/vendor/markbaker/complex/license.md new file mode 100644 index 0000000..5b4b156 --- /dev/null +++ b/inc/vendor/markbaker/complex/license.md @@ -0,0 +1,25 @@ +The MIT License (MIT) +===================== + +Copyright © `2017` `Mark Baker` + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the “Software”), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/.gitignore b/inc/vendor/pacificsec/cpe/.gitignore new file mode 100644 index 0000000..a7a214c --- /dev/null +++ b/inc/vendor/pacificsec/cpe/.gitignore @@ -0,0 +1,5 @@ +/.settings/ +/.buildpath +/.project +/vendor/ +/composer.lock diff --git a/inc/vendor/pacificsec/cpe/README.md b/inc/vendor/pacificsec/cpe/README.md index c855f04..d03c72c 100644 --- a/inc/vendor/pacificsec/cpe/README.md +++ b/inc/vendor/pacificsec/cpe/README.md @@ -22,3 +22,45 @@ Features - CPE rich comparison. - CPE Language parsing and evaluation. - MIT Licensed. + +Getting Started +-------- +- Clone repository + +```bash +$ git clone https://github.com/pacificsec/cpe.git +$ cd cpe +``` +- Create a new PHP file to run tests + +```php +unbindURI("cpe:/a:microsoft:internet_explorer%01%01%01%01:?:beta"); +var_dump($wfn); +$wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer:8.%2a:sp%3f"); +var_dump($wfn); +$wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer:8.%02:sp%01"); +var_dump($wfn); +$wfn = $cpenu->unbindURI("cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~"); +var_dump($wfn); +$wfn = $cpenu->unbindFS("cpe:2.3:a:micr\\?osoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*"); +var_dump($wfn); +``` \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/composer.json b/inc/vendor/pacificsec/cpe/composer.json new file mode 100644 index 0000000..b386db0 --- /dev/null +++ b/inc/vendor/pacificsec/cpe/composer.json @@ -0,0 +1,26 @@ +{ + "name" : "pacificsec/cpe", + "type" : "library", + "description" : "CPE: Common Platform Enumeration for PHP", + "keywords" : [ + "cpe", + "cve", + "security", + "pacificsec" + ], + "homepage" : "https://github.com/pacificsec/cpe", + "license" : "MIT", + "authors" : [{ + "name" : "Antonio Franco", + "email" : "antonio.franco@pacificsec.com" + } + ], + "require" : { + "php" : ">=5.3.0" + }, + "autoload" : { + "psr-4" : { + "PacificSec\\CPE\\" : "src" + } + } +} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/src/Common/LogicalValue.php b/inc/vendor/pacificsec/cpe/src/Common/LogicalValue.php new file mode 100644 index 0000000..5d13494 --- /dev/null +++ b/inc/vendor/pacificsec/cpe/src/Common/LogicalValue.php @@ -0,0 +1,44 @@ +. + * + * @see cpe.mitre.org for more information. + * @author Antonio Franco + * @email antonio.franco@pacificsec.com + */ +class LogicalValue { + + private $any = false; + private $na = false; + + // Object must be constructed with the string "ANY" or "NA". + public function __construct($type) { + if ($type == "ANY") { + $this->any = true; + } else if ($type == "NA") { + $this->na = true; + } else { + throw new Exception("LogicalValue must be ANY or NA"); + } + } + + public function isANY(){ + return $this->any; + } + + public function isNA(){ + return $this->na; + } + + public function __toString(){ + if ($this->any){ + return "ANY"; + } + return "NA"; + } +} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/src/Common/Utilities.php b/inc/vendor/pacificsec/cpe/src/Common/Utilities.php new file mode 100644 index 0000000..e1e1f03 --- /dev/null +++ b/inc/vendor/pacificsec/cpe/src/Common/Utilities.php @@ -0,0 +1,166 @@ +. + * + * @see cpe.mitre.org for more information. + * @author Antonio Franco + * @email antonio.franco@pacificsec.com + */ +class Utilities { + + /** + * Searches string for special characters * and ? + * @param string $string to be searched + * @return bool true if string contains wildcard, false otherwise + */ + public static function containsWildcards($string) { + if (strpos($string, "*") !== false || strpos($string, "?") !== false) { + if (!(strpos($string, "\\") !== false)) { + return true; + } + } + return false; + } + + /** + * Checks if given number is even or not + * @param int $num number to check + * @return bool true if number is even, false if not + */ + public static function isEvenNumber($num) { + return (is_int($num) && $num % 2 == 0); + } + + /** + * Counts the number of escape characters in the string beginning and ending + * at the given indices + * @param string $str string to search + * @param int $start beginning index + * @param int $end ending index + * @return number of escape characters in string + * @todo fix the use of $str. The Java version is also not using this variable. + */ + public static function countEscapeCharacters($str, $start, $end) { + $result = 0; + $active = false; + $i = 0; + while ($i < $end) { + if ($active && ($i >= $start)) { + $result = $result + 1; + } + $i = $i + 1; + } + return $result; + } + + /** + * Searches a string for the first unescaped colon and returns the index of + * that colon + * @param string $str string to search + * @return int index of first unescaped colon, or 0 if not found + */ + public static function getUnescapedColonIndex($str) { + $found = false; + $colon_idx = 0; + $start_idx = 0; + // Find the first non-escaped colon. + while (!$found) { + $colon_idx = strpos($str, ":", $start_idx + 1); + // If no colon is found, return 0. + if ($colon_idx === false) { + return 0; + } + // Peek at character before colon. + if (substr($str, $colon_idx-1, 1) == "\\") { + // If colon is escaped, keep looking. + $start_idx = $colon_idx; + } else { + $found = true; + } + } + return $colon_idx; + } + + /** + * Returns true if the string contains only + * alphanumeric characters or the underscore character, + * false otherwise. + * @param string $c the string in question + * @return bool true if $c is alphanumeric or underscore, false if not + */ + public static function isAlphanum($c) { + return (preg_match("/^[a-zA-Z0-9\_]+$/", $c) ? true : false); + } + + /** + * This function is not part of the reference implementation pseudo code + * found in the CPE 2.3 specification. It enforces two rules in the + * specification: + * URI must start with the characters "cpe:/" + * A URI may not contain more than 7 components + * If either rule is violated, a Exception is thrown. + * @param $in string with URI to be validated + */ + public static function validateURI($in) { + // make sure uri starts with cpe:/ + if (strpos(strtolower($in), "cpe:/") !== 0) { + throw new Exception("Error: URI must start with 'cpe:/'. Given: " . $in, 0); + } + // make sure uri doesn't contain more than 7 colons + $count = sizeof(explode(":", $in)); + if ($count > 8) { + throw new Exception("Error parsing URI. Found " . ($count - 8) . " extra components in: " . $in, 0); + } + } + + /** + * This function is not part of the reference implementation pseudo code + * found in the CPE 2.3 specification. It enforces three rules found in the + * specification: + * Formatted string must start with the characters "cpe:2.3:" + * A formatted string must contain 11 components + * A formatted string must not contain empty components + * If any rule is violated, a ParseException is thrown. + * @param $in string with FS to be validated + */ + public static function validateFS($in) { + if (strpos(strtolower($in), "cpe:2.3:") !== 0) { + throw new Exception("Error: Formatted String must start with \"cpe:2.3\". Given: " . $in, 0); + } + + $count = 0; + for ($i = 0; $i != strlen($in); $i++){ + if (substr($in, $i, 1) == ":"){ + if (substr($in, $i - 1, 1) != "\\"){ + $count++; + } + if (($i+1) < strlen($in) && substr($in, $i+1, 1) == ":"){ + throw new Exception("Error parsing formatted string. Found empty component", 0); + } + } + } + if ($count > 12){ + $extra = $count - 12; + $s = "Error parsing formatted string. Found " . $extra . " extra component"; + if ($extra > 1){ + $s = $s . "s"; + } + $s = $s . " in: " . $in; + throw new Exception($s, 0); + } + if ($count < 12){ + $missing = 12 - $count; + $s = "Error parsing formatted string. Missing " . $missing . " component"; + if ($missing > 1){ + $s = $s . "s"; + } + throw new Exception($s, 0); + } + } +} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/src/Common/WellFormedName.php b/inc/vendor/pacificsec/cpe/src/Common/WellFormedName.php new file mode 100644 index 0000000..e3a7253 --- /dev/null +++ b/inc/vendor/pacificsec/cpe/src/Common/WellFormedName.php @@ -0,0 +1,210 @@ +. + * + * @see cpe.mitre.org for details. + * @author Antonio Franco + * @email antonio.franco@pacificsec.com + */ +class WellFormedName { + + // Underlying wfn representation. + private $wfn = null; + // All permissible WFN attributes as defined by specification. + private $attributes = array("part", "vendor", "product", "version", + "update", "edition", "language", "sw_edition", "target_sw", + "target_hw", "other"); + + /** + * Constructs a new WellFormedName object, setting each component to the + * given parameter value. If a parameter is null, the component is set to + * the default value "ANY". + * @param $part string representing the part component + * @param $vendor string representing the vendor component + * @param $product string representing the product component + * @param $version string representing the version component + * @param $update string representing the update component + * @param $edition string representing the edition component + * @param $language string representing the language component + * @param $sw_edition string representing the sw_edition component + * @param $target_sw string representing the target_sw component + * @param $target_hw string representing the target_hw component + * @param $other string representing the other component + */ + public function __construct($part = null, $vendor = null, $product = null, $version = null, + $update = null, $edition = null, $language = null, $sw_edition = null, $target_sw = null, + $target_hw = null, $other = null) { + + $this->wfn = array(); + + // Constructs a new WellFormedName object, with all components set to the default value "ANY". + if ($part === null && $vendor === null && $product === null && $version === null && + $update === null && $edition === null && $language === null && $sw_edition === null && $target_sw === null && + $target_hw === null && $other === null){ + foreach ($this->attributes as $a){ + if ($a != "part"){ + $this->set($a, new LogicalValue("ANY")); + } + } + return; + } + + $this->set("part", $part); + $this->set("vendor", $vendor); + $this->set("product", $product); + $this->set("version", $version); + $this->set("update", $update); + $this->set("edition", $edition); + $this->set("language", $language); + $this->set("sw_edition", $sw_edition); + $this->set("target_sw", $target_sw); + $this->set("target_hw", $target_hw); + $this->set("other", $other); + } + + /** + * @param $attribute string representing the component value to get + * @return string the string value of the given component, or default value "ANY" + * if the component does not exist + */ + public function get($attribute){ + if (array_key_exists($attribute, $this->wfn)) + return $this->wfn[$attribute]; + else + return new LogicalValue("ANY"); + } + + /** + * Sets the given attribute to value, if the attribute is in the list of + * permissible components + * @param $attribute string representing the component to set + * @param $value object or string representing the value of the given component + */ + public final function set($attribute, $value){ + // Iterate over permissible attributes. + foreach ($this->attributes as $a){ + // If the argument is a valid attribute, set that attribute's value. + if ($attribute == $a) { + // check to see if we're setting a LogicalValue ANY or NA + if ($value instanceof LogicalValue){ + // don't allow logical values in part component + if ($attribute == "part"){ + var_dump($value); echo "
\n"; + var_dump($a); echo "
\n"; + var_dump($attribute); echo "
\n"; + throw new Exception("Error! part component cannot be a logical value"); + } + // put the Object in the ht and break + $this->wfn[$attribute] = $value; + break; + } + if ($value == null || $value == ""){ + // if value is null or blank, set attribute to default logical ANY + $this->wfn[$attribute] = new LogicalValue("ANY"); + break; + } + $svalue = $value; + // Reg exs + // check for printable characters - no control characters + if (!preg_match("/^[[:print:]]*$/", $svalue)){ + throw new Exception("Error! encountered non printable character in: " . $svalue, 0); + } + // svalue has whitespace + if (preg_match("/^.*\\s+.*$/", $svalue)){ + throw new Exception("Error! component cannot contain whitespace: " . $svalue, 0); + } + // svalue has more than one unquoted star + if (preg_match("/^\\*{2,}.*$/", $svalue) || preg_match("/^.*\\*{2,}$/", $svalue)){ + throw new Exception("Error! component cannot contain more than one * in sequence: " . $svalue, 0); + } + // svalue has unquoted punctuation embedded + if (preg_match("/^.*(?\\@\\[\\]\\^\\`\\{\\|\\}\\~\\-].*$/", $svalue)) { + throw new Exception("Error! component cannot contain unquoted punctuation: " . $svalue, 0); + } + // svalue has an unquoted * + if (preg_match("/^.+(?wfn[$attribute] = $svalue; + break; + } + // remove leading and trailing ?s + $v = $svalue; + while (strpos($v, "?") === 0) { + // remove all leading ?'s + $v = substr($v, 1); + } + $v = strrev($v); + while (strpos($v, "?") === 0) { + // remove all trailing ?'s (string has been reversed) + $v = substr($v, 1); + } + // back to normal + $v = strrev($v); + // after leading and trailing ?s are removed, check if value + // contains unquoted ?s + if (preg_match("/^.+(?wfn[$attribute] = $svalue; + break; + } + } + } + + /** + * + * @return string representation of the WellFormedName + */ + public function __toString() { + $str = "wfn:["; + foreach ($this->attributes as $attr) { + $str = $str . $attr; + $str = $str . "="; + + $o = $this->wfn[$attr]; + if ($o instanceof LogicalValue) { + $str = $str . $o; + $str = $str . ", "; + } else { + $str = $str . "\""; + $str = $str . $o; + $str = $str . "\", "; + } + } + $str = substr($str, 0, strlen($str)-1); + $str = substr($str, 0, strlen($str)-1); + $str = $str . "]"; + + return $str; + } + +} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/src/Matching/CPENameMatcher.php b/inc/vendor/pacificsec/cpe/src/Matching/CPENameMatcher.php new file mode 100644 index 0000000..a4d4ae3 --- /dev/null +++ b/inc/vendor/pacificsec/cpe/src/Matching/CPENameMatcher.php @@ -0,0 +1,287 @@ +. + * + * @see cpe.mitre.org for more information. + * @author Antonio Franco + * @email antonio.franco@pacificsec.com + */ +class CPENameMatcher { + + /** + * Tests two Well Formed Names for disjointness. + * @param $source WellFormedName Source WFN + * @param $target WellFormedName Target WFN + * @return true if the names are disjoint, false otherwise + */ + public function isDisjoint(WellFormedName $source, WellFormedName $target) { + // if any pairwise comparison is disjoint, the names are disjoint. + $resultList = $this->compareWFNs($source, $target); + foreach ($resultList as $result){ + if ($result == Relation::DISJOINT) + return true; + } + return false; + } + + /** + * Tests two Well Formed Names for equality. + * @param $source WellFormedName Source WFN + * @param $target WellFormedName Target WFN + * @return true if the names are equal, false otherwise + */ + public function isEqual(WellFormedName $source, WellFormedName $target) { + // if every pairwise comparison is equal, the names are equal. + $resultList = $this->compareWFNs($source, $target); + foreach ($resultList as $result){ + if ($result != Relation::EQUAL){ + return false; + } + } + return true; + } + + /** + * Tests if the target Well Formed Name is a subset of the source Well Formed + * Name. + * @param $source WellFormedName Source WFN + * @param $target WellFormedName Target WFN + * @return true if the target is a subset of the source, false otherwise + */ + public function isSubset(WellFormedName $source, WellFormedName $target) { + // if any comparison is anything other than subset or equal, then target is + // not a subset of source. + $resultList = $this->compareWFNs($source, $target); + foreach ($resultList as $result){ + if ($result != Relation::SUBSET && $result != Relation::EQUAL) { + return false; + } + } + return true; + } + + /** + * Tests if the target Well Formed name is a superset of the source Well Formed + * Name. + * @param $source WellFormedName Source WFN + * @param $target WellFormedName Target WFN + * @return true if the target is a superset of the source, false otherwise + */ + public function isSuperset(WellFormedName $source, WellFormedName $target) { + // if any comparison is anything other than superset or equal, then target is not + // a superset of source. + $resultList = $this->compareWFNs($source, $target); + foreach ($resultList as $result){ + if ($result != Relation::SUPERSET && $result != Relation::EQUAL) { + return false; + } + } + return true; + } + + /** + * Compares each attribute value pair in two Well Formed Names. + * @param $source WellFormedName Source WFN + * @param $target WellFormedName Target WFN + * @return array A array mapping attribute string to attribute value Relation + */ + public function compareWFNs(WellFormedName $source, WellFormedName $target) { + $result = array(); + $result["part"] = $this->compare($source->get("part"), $target->get("part")); + $result["vendor"] = $this->compare($source->get("vendor"), $target->get("vendor")); + $result["product"] = $this->compare($source->get("product"), $target->get("product")); + $result["version"] = $this->compare($source->get("version"), $target->get("version")); + $result["update"] = $this->compare($source->get("update"), $target->get("update")); + $result["edition"] = $this->compare($source->get("edition"), $target->get("edition")); + $result["language"] = $this->compare($source->get("language"), $target->get("language")); + $result["sw_edition"] = $this->compare($source->get("sw_edition"), $target->get("sw_edition")); + $result["target_sw"] = $this->compare($source->get("target_sw"), $target->get("target_sw")); + $result["target_hw"] = $this->compare($source->get("target_hw"), $target->get("target_hw")); + $result["other"] = $this->compare($source->get("other"), $target->get("other")); + return $result; + } + + /** + * Compares an attribute value pair. + * @param string $source Source attribute value. + * @param string $target Target attribute value. + * @return int The relation between the two attribute values. + */ + private function compare($source, $target) { + // matching is case insensitive, convert strings to lowercase. + if ($this->isString($source)) { + $source = strtolower($source); + } + if ($this->isString($target)) { + $target = strtolower($target); + } + + // Unquoted wildcard characters yield an undefined result. + if ($this->isString($target) && Utilities::containsWildcards($target)) { + return Relation::UNDEFINED; + } + // If source and target values are equal, then result is equal. + if ($source == $target) { + return Relation::EQUAL; + } + + // Check to see if source or target are Logical Values. + $lvSource = null; + $lvTarget = null; + if ($source instanceof LogicalValue) { + $lvSource = $source; + } + if ($target instanceof LogicalValue) { + $lvTarget = $target; + } + if ($lvSource != null && $lvTarget != null) { + // If Logical Values are equal, result is equal. + if ($lvSource->isANY() == $lvTarget->isANY() || $lvSource->isNA() == $lvTarget->isNA()) { + return Relation::EQUAL; + } + } + // If source value is ANY, result is a superset. + if ($lvSource != null) { + if ($lvSource->isANY()) { + return Relation::SUPERSET; + } + } + // If target value is ANY, result is a subset. + if ($lvTarget != null) { + if ($lvTarget->isANY()) { + return Relation::SUBSET; + } + } + // If source or target is NA, result is disjoint. + if ($lvSource != null) { + if ($lvSource->isNA()) { + return Relation::DISJOINT; + } + } + if ($lvTarget != null) { + if ($lvTarget->isNA()) { + return Relation::DISJOINT; + } + } + // only Strings will get to this point, not LogicalValues + return $this->compareStrings($source, $target); + } + + /** + * Compares a source string to a target string, and addresses the condition + * in which the source string includes unquoted special characters. It + * performs a simple regular expression match, with the assumption that + * (as required) unquoted special characters appear only at the beginning + * and/or the end of the source string. It also properly differentiates + * between unquoted and quoted special characters. + * + * @param $source string Source attribute value. + * @param $target string Target attribute value. + * @return Relation between source and target Strings. + */ + private function compareStrings($source, $target) { + $start = 0; + $end = strlen($source); + $begins = 0; + $ends = 0; + $index = 0; $leftover = 0; $escapes = 0; + + if (substr($source, 0, 1) == "*") { + $start = 1; + $begins = -1; + } else { + while (($start < strlen($source)) && (substr($source, $start, 1) == "?")) { + $start = $start + 1; + $begins = $begins + 1; + } + } + if ((substr($source, $end - 1, 1) == "*") && ($this->isEvenWildcards($source, $end - 1))) { //TODO + $end = $end - 1; + $ends = -1; + } else { + while (($end > 0) && substr($source, $end - 1, 1) == "?" && ($this->isEvenWildcards($source, $end - 1))) { //TODO + $end = $end - 1; + $ends = $ends + 1; + } + } + + $source = substr($source, $start, $end-$start); + $index = -1; + $leftover = strlen($target); + while ($leftover > 0) { + $index = strpos($target, $source, $index + 1); + if ($index === false) { + break; + } + $escapes = Utilities::countEscapeCharacters($target, 0, $index); + if (($index > 0) && ($begins != -1) && ($begins < ($index - $escapes))) { + break; + } + $escapes = Utilities::countEscapeCharacters($target, $index + 1, strlen($target)); + $leftover = strlen($target) - $index - $escapes - strlen($source); + if (($leftover > 0) && (($ends != -1) && ($leftover > $ends))) { + continue; + } + return Relation::SUPERSET; + } + return Relation::DISJOINT; + } + + /** + * Searches a string for the backslash character + * @param $str string to search in + * @param int $idx end index + * @return true if the number of backslash characters is even, false if odd + */ + private function isEvenWildcards($str, $idx) { + $result = 0; + while (($idx > 0) && (strpos($str, "\\", $idx - 1)) !== false) { + $idx = $idx - 1; + $result = $result + 1; + } + return Utilities::isEvenNumber($result); + } + + /** + * Tests if an Object is an instance of the String class + * @param mixed $arg the var to test + * @return bool true if arg is a string, false if not + */ + private function isString($arg) { + return is_string($arg); + } + + /* + * Static method to demonstrate this class. + */ + public static function test() { + // Examples. + $wfn = new WellFormedName("a", "microsoft", "internet_explorer", "8\\.0\\.6001", "beta", new LogicalValue("ANY"), "sp2", null, null, null, null); + $wfn2 = new WellFormedName("a", "microsoft", "internet_explorer", new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY")); + $cpenm = new CPENameMatcher(); + $cpenu = new CPENameUnbinder(); + $cpenb = new CPENameBinder(); + $wfn = $cpenu->unbindURI($cpenb->bindToURI($wfn)); + $wfn2 = $cpenu->unbindFS($cpenb->bindToFS($wfn2)); + var_dump($cpenm->isDisjoint($wfn, $wfn2)); // false + var_dump($cpenm->isEqual($wfn, $wfn2)); // false + var_dump($cpenm->isSubset($wfn, $wfn2)); // true, $wfn2 is a subset of wfn + var_dump($cpenm->isSuperset($wfn, $wfn2)); // false + $wfn = $cpenu->unbindFS("cpe:2.3:a:adobe:*:9.*:*:PalmOS:*:*:*:*:*"); + $wfn2 = $cpenu->unbindURI("cpe:/a::Reader:9.3.2:-:-"); + var_dump($cpenm->isDisjoint($wfn, $wfn2)); // true, $wfn2 and wfn are disjoint + var_dump($cpenm->isEqual($wfn, $wfn2)); // false + var_dump($cpenm->isSubset($wfn, $wfn2)); // false + var_dump($cpenm->isSuperset($wfn, $wfn2)); // false + } +} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Matching/Relation.php b/inc/vendor/pacificsec/cpe/src/Matching/Relation.php similarity index 100% rename from inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Matching/Relation.php rename to inc/vendor/pacificsec/cpe/src/Matching/Relation.php diff --git a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Naming/CPENameBinder.php b/inc/vendor/pacificsec/cpe/src/Naming/CPENameBinder.php similarity index 53% rename from inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Naming/CPENameBinder.php rename to inc/vendor/pacificsec/cpe/src/Naming/CPENameBinder.php index 15e489e..864dc8b 100644 --- a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Naming/CPENameBinder.php +++ b/inc/vendor/pacificsec/cpe/src/Naming/CPENameBinder.php @@ -7,28 +7,41 @@ use PacificSec\CPE\Common\LogicalValue; /** * The CPENameBinder class is a simple implementation - * of the CPE Name binding algorithm, as specified in the - * CPE Naming Standard version 2.3. It is based on Java version - * implemented by Joshua Kraunelis . - * - * @see cpe.mitre.org for more information. + * of the CPE Name binding algorithm, as specified in the + * CPE Naming Standard version 2.3. + * It is based on Java version + * implemented by Joshua Kraunelis . + * + * @see cpe.mitre.org for more information. * @author Antonio Franco * @email antonio.franco@pacificsec.com */ -class CPENameBinder { +class CPENameBinder +{ /** * Binds a {@link WellFormedName} object to a URI. - * @param $w WellFormedName to be bound to URI - * @return URI binding of WFN + * + * @param $w WellFormedName + * to be bound to URI + * @return string URI binding of WFN */ - public function bindToURI(WellFormedName $w) { + public function bindToURI(WellFormedName $w) + { // Initialize the output with the CPE v2.2 URI prefix. $uri = "cpe:/"; // Define the attributes that correspond to the seven components in a v2.2. CPE. - $attributes = array("part", "vendor", "product", "version", "update", "edition", "language"); + $attributes = array( + "part", + "vendor", + "product", + "version", + "update", + "edition", + "language" + ); // Iterate over the well formed name foreach ($attributes as $a) { @@ -56,15 +69,28 @@ class CPENameBinder { /** * Top-level function used to bind WFN w to formatted string. - * @param $w WellFormedName to bind - * @return Formatted String + * + * @param $w WellFormedName + * to bind + * @return string Formatted String */ - public function bindToFS(WellFormedName $w) { + public function bindToFS(WellFormedName $w) + { // Initialize the output with the CPE v2.3 string prefix. $fs = "cpe:2.3:"; - foreach (array("part", "vendor", "product", "version", - "update", "edition", "language", "sw_edition", "target_sw", - "target_hw", "other") as $a) { + foreach (array( + "part", + "vendor", + "product", + "version", + "update", + "edition", + "language", + "sw_edition", + "target_sw", + "target_hw", + "other" + ) as $a) { $v = $this->bindValueForFS($w->get($a)); $fs = $fs . $v; // add a colon except at the very end @@ -78,10 +104,13 @@ class CPENameBinder { /** * Convert the value v to its proper string representation for insertion to * formatted string. - * @param $v value to convert - * @return Formatted value + * + * @param mixed $v + * value to convert + * @return mixed Formatted value */ - private function bindValueForFS($v) { + private function bindValueForFS($v) + { if ($v instanceof LogicalValue) { $l = $v; // The value NA binds to a blank. @@ -97,30 +126,34 @@ class CPENameBinder { } /** - * Inspect each character in string s. Certain nonalpha characters pass + * Inspect each character in string s. + * Certain nonalpha characters pass * thru without escaping into the result, but most retain escaping. - * @param $s - * @return + * + * @param + * $s + * @return */ - private function processQuotedChars($s) { + private function processQuotedChars($s) + { $result = ""; $idx = 0; while ($idx < strlen($s)) { $c = substr($s, $idx, 1); if ($c != "\\") { // unquoted characters pass thru unharmed. - $result = $result . $c; + $result .= $c; } else { // escaped characters are examined. $nextchr = substr($s, $idx + 1, 1); // the period, hyphen and underscore pass unharmed. if ($nextchr == "." || $nextchr == "-" || $nextchr == "_") { - $result = $result . $nextchr; + $result .= $nextchr; $idx = $idx + 2; continue; } else { // all others retain escaping. - $result = $result . "\\" . $nextchr; + $result .= "\\" . $nextchr; $idx = $idx + 2; continue; } @@ -132,12 +165,16 @@ class CPENameBinder { /** * Converts a string to the proper string for including in - * a CPE v2.2-conformant URI. The logical value ANY binds + * a CPE v2.2-conformant URI. + * The logical value ANY binds * to the blank in the 2.2-conformant URI. - * @param $s string to be converted - * @return converted string + * + * @param $s string + * to be converted + * @return string converted string */ - private function bindValueForURI($s) { + private function bindValueForURI($s) + { if ($s instanceof LogicalValue) { $l = $s; // The value NA binds to a blank. @@ -159,10 +196,13 @@ class CPENameBinder { * - Pass alphanumeric characters thru untouched * - Percent-encode quoted non-alphanumerics as needed * - Unquoted special characters are mapped to their special forms - * @param $s string to be transformed - * @return transformed string + * + * @param $s string + * to be transformed + * @return string transformed string */ - private function transformForURI($s) { + private function transformForURI($s) + { $result = ""; $idx = 0; @@ -171,7 +211,7 @@ class CPENameBinder { $thischar = substr($s, $idx, 1); // Alphanumerics (incl. underscore) pass untouched. if (Utilities::isAlphanum($thischar)) { - $result = $result . $thischar; + $result .= $thischar; $idx = $idx + 1; continue; } @@ -179,17 +219,17 @@ class CPENameBinder { if ($thischar == "\\") { $idx = $idx + 1; $nxtchar = substr($s, $idx, 1); - $result = $result . $this->pctEncode($nxtchar); + $result .= $this->pctEncode($nxtchar); $idx = $idx + 1; continue; } // Bind the unquoted '?' special character to "%01". if ($thischar == "?") { - $result = $result . "%01"; + $result .= "%01"; } // Bind the unquoted '*' special character to "%02". if ($thischar == "*") { - $result = $result . "%02"; + $result .= "%02"; } $idx = $idx + 1; } @@ -199,122 +239,98 @@ class CPENameBinder { /** * Returns the appropriate percent-encoding of character c. * Certain characters are returned without encoding. - * @param $c the single character string to be encoded - * @return the percent encoded string + * + * @param string $c the + * single character string to be encoded + * @return string the percent encoded string */ - private function pctEncode($c) { - if ($c == "!") { - return "%21"; + private function pctEncode($c) + { + switch ($c) { + case '!': + return "%21"; + case "\"": + return "%22"; + case "#": + return "%23"; + case "$": + return "%24"; + case "%": + return "%25"; + case "&": + return "%26"; + case "'": + return "%27"; + case "(": + return "%28"; + case ")": + return "%29"; + case "*": + return "%2a"; + case "+": + return "%2b"; + case ",": + return "%2c"; + case "/": + return "%2f"; + case ":": + return "%3a"; + case ";": + return "%3b"; + case "<": + return "%3c"; + case "=": + return "%3d"; + case ">": + return "%3e"; + case "?": + return "%3f"; + case "@": + return "%40"; + case "[": + return "%5b"; + case "\\": + return "%5c"; + case "]": + return "%5d"; + case "^": + return "%5e"; + case "`": + return "%60"; + case "{": + return "%7b"; + case "|": + return "%7c"; + case "}": + return "%7d"; + case "~": + return "%7e"; + default: + return $c; } - if ($c == "\"") { - return "%22"; - } - if ($c == "#") { - return "%23"; - } - if ($c == "$") { - return "%24"; - } - if ($c == "%") { - return "%25"; - } - if ($c == "&") { - return "%26"; - } - if ($c == "'") { - return "%27"; - } - if ($c == "(") { - return "%28"; - } - if ($c == ")") { - return "%29"; - } - if ($c == "*") { - return "%2a"; - } - if ($c == "+") { - return "%2b"; - } - if ($c == ",") { - return "%2c"; - } - // bound without encoding. - if ($c == "-") { - return $c; - } - // bound without encoding. - if ($c == ".") { - return $c; - } - if ($c == "/") { - return "%2f"; - } - if ($c == ":") { - return "%3a"; - } - if ($c == ";") { - return "%3b"; - } - if ($c == "<") { - return "%3c"; - } - if ($c == "=") { - return "%3d"; - } - if ($c == ">") { - return "%3e"; - } - if ($c == "?") { - return "%3f"; - } - if ($c == "@") { - return "%40"; - } - if ($c == "[") { - return "%5b"; - } - if ($c == "\\") { - return "%5c"; - } - if ($c == "]") { - return "%5d"; - } - if ($c == "^") { - return "%5e"; - } - if ($c == "`") { - return "%60"; - } - if ($c == "{") { - return "%7b"; - } - if ($c == "|") { - return "%7c"; - } - if ($c == "}") { - return "%7d"; - } - if ($c == "~") { - return "%7d"; - } - // Shouldn't reach here, return original character - return $c; } /** - * Packs the values of the five arguments into the single - * edition component. If all the values are blank, the + * Packs the values of the five arguments into the single + * edition component. + * If all the values are blank, the * function returns a blank. - * @param $ed edition string - * @param $sw_ed software edition string - * @param $t_sw target software string - * @param $t_hw target hardware string - * @param $oth other edition information string - * @return the packed string, or blank + * + * @param string $ed edition + * string + * @param string $sw_ed software + * edition string + * @param string $t_sw target + * software string + * @param string $t_hw target + * hardware string + * @param string $oth other + * edition information string + * @return string the packed string, or blank */ - private function pack($ed, $sw_ed, $t_sw, $t_hw, $oth) { - if ($sw_ed == "" && $t_sw == "" && $t_hw == "" && $oth == "") { + private function pack($ed, $sw_ed, $t_sw, $t_hw, $oth) + { + if ($sw_ed == "" && $t_sw == "" && $t_hw == "" && $oth == "") { // All the extended attributes are blank, so don't do // any packing, just return ed. return $ed; @@ -326,13 +342,16 @@ class CPENameBinder { /** * Removes trailing colons from the URI. - * @param $s the string to be trimmed - * @return the trimmed string + * + * @param string $s the + * string to be trimmed + * @return string the trimmed string */ - private function trim($s) { + private function trim($s) + { $s1 = strrev($s); $idx = 0; - for ($i = 0; $i != strlen($s1); $i++) { + for ($i = 0; $i != strlen($s1); $i ++) { if (substr($s1, $i, 1) == ":") { $idx = $idx + 1; } else { @@ -341,30 +360,30 @@ class CPENameBinder { } // Return the substring after all trailing colons, // reversed back to its original character order. - return strrev(substr($s1, $idx, strlen($s1)-$idx)); + return strrev(substr($s1, $idx, strlen($s1) - $idx)); } /* * Static method to demonstrate this class. */ - public static function test() { + public static function test() + { // A few examples. - echo "Testing CPENamingBind...
\n"; - $wfn = new WellFormedName("a", "microsoft", "internet_explorer", "8\\.0\\.6001", - "beta", new LogicalValue("ANY"), "sp2", null, null, null, null); - $wfn2 = new WellFormedName(); - - $wfn2->set("part", "a"); - $wfn2->set("vendor", "foo\\\$bar"); - $wfn2->set("product", "insight"); - $wfn2->set("version", "7\\.4\\.0\\.1570"); - $wfn2->set("target_sw", "win2003"); - $wfn2->set("update", new LogicalValue("NA")); - $wfn2->set("sw_edition", "online"); - $wfn2->set("target_hw", "x64"); - $cpenb = new CPENameBinder(); - - echo $cpenb->bindToURI($wfn) . "
\n"; - echo $cpenb->bindToFS($wfn2) . "
\n"; + echo "Testing CPENamingBind...
\n"; + $wfn = new WellFormedName("a", "microsoft", "internet_explorer", "8\\.0\\.6001", "beta", new LogicalValue("ANY"), "sp2", null, null, null, null); + $wfn2 = new WellFormedName(); + + $wfn2->set("part", "a"); + $wfn2->set("vendor", "foo\\\$bar"); + $wfn2->set("product", "insight"); + $wfn2->set("version", "7\\.4\\.0\\.1570"); + $wfn2->set("target_sw", "win2003"); + $wfn2->set("update", new LogicalValue("NA")); + $wfn2->set("sw_edition", "online"); + $wfn2->set("target_hw", "x64"); + $cpenb = new CPENameBinder(); + + echo $cpenb->bindToURI($wfn) . "
\n"; + echo $cpenb->bindToFS($wfn2) . "
\n"; } } \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/src/Naming/CPENameUnbinder.php b/inc/vendor/pacificsec/cpe/src/Naming/CPENameUnbinder.php new file mode 100644 index 0000000..14c3cb4 --- /dev/null +++ b/inc/vendor/pacificsec/cpe/src/Naming/CPENameUnbinder.php @@ -0,0 +1,466 @@ +. + * + * @see cpe.mitre.org for more information. + * @author Antonio Franco + * @email antonio.franco@pacificsec.com + */ +class CPENameUnbinder { + + /** + * Top level function used to unbind a URI to a WFN. + * @param $uri string representing the URI to be unbound. + * @return WellFormedName representing the unbound URI. + * @throws Exception representing parsing errors. + */ + public function unbindURI($uri) { + // Validate the URI + Utilities::validateURI($uri); + // Initialize the empty WFN. + $result = new WellFormedName(); + + for ($i = 0; $i != 8; $i++) { + // get the i'th component of uri + $v = $this->getCompURI($uri, $i); + switch ($i) { + case 1: + $result->set("part", $this->decode($v)); + break; + case 2: + $result->set("vendor", $this->decode($v)); + break; + case 3: + $result->set("product", $this->decode($v)); + break; + case 4: + $result->set("version", $this->decode($v)); + break; + case 5: + $result->set("update", $this->decode($v)); + break; + case 6: + // Special handling for edition component. + // Unpack edition if needed. + if ($v == "" || $v == "-" + || substr($v, 0, 1) != "~") { + // Just a logical value or a non-packed value. + // So unbind to legacy edition, leaving other + // extended attributes unspecified. + $result->set("edition", $this->decode($v)); + } else { + // We have five values packed together here. + $this->unpack($v, $result); + } + break; + case 7: + $result->set("language", $this->decode($v)); + break; + } + } + return $result; + } + + /** + * Top level function to unbind a formatted string to WFN. + * @param string $fs Formatted string to unbind + * @return WellFormedName + * @throws Exception representing parsing error + */ + public function unbindFS($fs) { + // Validate the formatted string + Utilities::validateFS($fs); + // Initialize empty WFN + $result = new WellFormedName(); + // The cpe scheme is the 0th component, the cpe version is the 1st. + // So we start parsing at the 2nd component. + for ($a = 2; $a != 13; $a++) { + // Get the a'th string field. + $v = $this->getCompFS($fs, $a); + // Unbind the string. + $v = $this->unbindValueFS($v); + // Set the value of the corresponding attribute. + switch ($a) { + case 2: + $result->set("part", $v); + break; + case 3: + $result->set("vendor", $v); + break; + case 4: + $result->set("product", $v); + break; + case 5: + $result->set("version", $v); + break; + case 6: + $result->set("update", $v); + break; + case 7: + $result->set("edition", $v); + break; + case 8: + $result->set("language", $v); + break; + case 9: + $result->set("sw_edition", $v); + break; + case 10: + $result->set("target_sw", $v); + break; + case 11: + $result->set("target_hw", $v); + break; + case 12: + $result->set("other", $v); + break; + } + } + return $result; + } + + /** + * Returns the i'th field of the formatted string. The colon is the field + * delimiter unless prefixed by a backslash. + * @param string $fs formatted string to retrieve from + * @param int $i index of field to retrieve from fs. + * @return int value of index of formatted string + */ + private function getCompFS($fs, $i) { + if ($i == 0) { + // return the substring from index 0 to the first occurence of an + // unescaped colon + $colon_idx = Utilities::getUnescapedColonIndex($fs); + // If no colon is found, we are at the end of the formatted string, + // so just return what's left. + if ($colon_idx == 0) { + return $fs; + } + return substr($fs, 0, $colon_idx); + } else { + $substrStart = Utilities::getUnescapedColonIndex($fs) + 1; + $substrLength = strlen($fs) - $substrStart; + return $this->getCompFS(substr($fs, $substrStart, $substrLength), $i - 1); + } + } + + /** + * Takes a string value and returns the appropriate logical value if string + * is the bound form of a logical value. If string is some general value + * string, add quoting of non-alphanumerics as needed. + * @param string $s value to be unbound + * @return string logical value or quoted string + * @throws Exception representing parsing errors + */ + private function unbindValueFS($s) { + if ($s == "*") { + return new LogicalValue("ANY"); + } + if ($s == "-") { + return new LogicalValue("NA"); + } + return $this->addQuoting($s); + } + + /** + * Inspect each character in a string, copying quoted characters, with + * their escaping, into the result. Look for unquoted non alphanumerics + * and if not "*" or "?", add escaping. + * @param $s + * @return + * @throws Exception representing parsing errors. + */ + private function addQuoting($s) { + $result = ""; + $idx = 0; + $embedded = false; + while ($idx < strlen($s)) { + $c = substr($s, $idx, 1); + if (Utilities::isAlphanum($c)) { + // Alphanumeric characters pass untouched. + $result .= $c; + $idx = $idx + 1; + $embedded = true; + continue; + } + if ($c == "\\") { + // Anything quoted in the bound string stays quoted in the + // unbound string. + $result .= substr($s, $idx, 2); + $idx = $idx + 2; + $embedded = true; + continue; + } + if ($c == "*") { + // An unquoted asterisk must appear at the beginning or the end + // of the string. + if ($idx == 0 || $idx == strlen($s) - 1) { + $result .= $c; + $idx = $idx + 1; + $embedded = true; + continue; + } else { + throw new Exception("Error! cannot have unquoted * embedded in formatted string.", 0); + } + } + if ($c == "?") { + // An unquoted question mark must appear at the beginning or + // end of the string, or in a leading or trailing sequence. + if ( // ? legal at beginning or end + (($idx == 0) || ($idx == (strlen($s) - 1))) + // embedded is false, so must be preceded by ? + || (!$embedded && (substr($s, $idx - 1, 1) == "?")) + // embedded is true, so must be followed by ? + || ($embedded && (substr($s, $idx + 1, 1) == "?"))) { + $result .= $c; + $idx = $idx + 1; + $embedded = false; + continue; + } else { + throw new Exception("Error! cannot have unquoted ? embedded in formatted string.", 0); + } + } + // All other characters must be quoted. + $result .= "\\" . $c; + $idx = $idx + 1; + $embedded = true; + } + return $result; + } + + /** + * Return the i'th component of the URI. + * @param $uri string representation of URI to retrieve components from. + * @param int $i Index of component to return. + * @return mixed If i = 0, returns the URI scheme. Otherwise, returns the i'th + * component of uri. + */ + private function getCompURI($uri, $i) { + if ($i == 0) { + return substr($uri, $i, strpos($uri, "/")); + } + $sa = explode(":", $uri); + // If requested component exceeds the number + // of components in URI, return blank + if ($i >= sizeof($sa)) { + return ""; + } + if ($i === 1) { + return substr($sa[$i], 1, strlen($sa[$i])-1); + } + return $sa[$i]; + } + + /** + * Scans a string and returns a copy with all percent-encoded characters + * decoded. This function is the inverse of pctEncode() defined in the + * CPENameBinder class. Only legal percent-encoded forms are decoded. + * Others raise a ParseException. + * @param $s string to be decoded + * @return string decoded string + * @throws Exception representing parsing errors + * @see CPENameBinder#pctEncode + */ + private function decode($s) { + if ($s == "") { + return new LogicalValue("ANY"); + } + if ($s == "-") { + return new LogicalValue("NA"); + } + // Start the scanning loop. + // Normalize: convert all uppercase letters to lowercase first. + $s = strtolower($s); + $result = ""; + $idx = 0; + $embedded = false; + while ($idx < strlen($s)) { + // Get the idx'th character of s. + $c = substr($s, $idx, 1); + // Deal with dot, hyphen, and tilde: decode with quoting. + if ($c == "." || $c == "-" || $c == "~") { + $result .= "\\" . $c; + $idx = $idx + 1; + // a non-%01 encountered. + $embedded = true; + continue; + } + if ($c != "%") { + $result .= $c; + $idx = $idx + 1; + // a non-%01 encountered. + $embedded = true; + continue; + } + // We get here if we have a substring starting w/ '%'. + $form = substr($s, $idx, 3); + if ($form == "%01") { + if (($idx == 0) + || ($idx == strlen($s) - 3) + || (!$embedded && substr($s, $idx - 3, 2) == "%01") + || ($embedded && (strlen($s) >= $idx + 6)) + && (substr($s, $idx + 3, 3) == "%01")) { + $result .= "?"; + $idx = $idx + 3; + continue; + } else { + throw new Exception("Error decoding string", 0); + } + } else if ($form == "%02") { + if (($idx == 0) || ($idx == (strlen($s) - 3))) { + $result .= "*"; + } else { + throw new Exception("Error decoding string", 0); + } + } else if ($form == "%21") { + $result .= "\\!"; + } else if ($form == "%22") { + $result .= "\\\""; + } else if ($form == "%23") { + $result .= "\\#"; + } else if ($form == "%24") { + $result .= "\\$"; + } else if ($form == "%25") { + $result .= "\\%"; + } else if ($form == "%26") { + $result .= "\\&"; + } else if ($form == "%27") { + $result .= "\\'"; + } else if ($form == "%28") { + $result .= "\\("; + } else if ($form == "%29") { + $result .= "\\)"; + } else if ($form == "%2a") { + $result .= "\\*"; + } else if ($form == "%2b") { + $result .= "\\+"; + } else if ($form == "%2c") { + $result .= "\\,"; + } else if ($form == "%2f") { + $result .= "\\/"; + } else if ($form == "%3a") { + $result .= "\\:"; + } else if ($form == "%3b") { + $result .= "\\;"; + } else if ($form == "%3c") { + $result .= "\\<"; + } else if ($form == "%3d") { + $result .= "\\="; + } else if ($form == "%3e") { + $result .= "\\>"; + } else if ($form == "%3f") { + $result .= "\\?"; + } else if ($form == "%40") { + $result .= "\\@"; + } else if ($form == "%5b") { + $result .= "\\["; + } else if ($form == "%5c") { + $result .= "\\\\"; + } else if ($form == "%5d") { + $result .= "\\]"; + } else if ($form == "%5e") { + $result .= "\\^"; + } else if ($form == "%60") { + $result .= "\\`"; + } else if ($form == "%7b") { + $result .= "\\{"; + } else if ($form == "%7c") { + $result .= "\\|"; + } else if ($form == "%7d") { + $result .= "\\}"; + } else if ($form == "%7e") { + $result .= "\\~"; + } else { + throw new Exception("Unknown form: " . $form, 0); + } + $idx = $idx + 3; + $embedded = true; + } + return $result; + } + + /** + * Unpacks the elements in s and sets the attributes in the given + * WellFormedName accordingly. + * @param string $s packed string + * @param $wfn WellFormedName + * @return WellFormedName The augmented WellFormedName. + */ + private function unpack($s, WellFormedName $wfn) { + // Parse out the five elements. + $start = 1; + $ed = ""; $sw_edition = ""; $t_sw = ""; $t_hw = ""; $oth = ""; + $end = strpos($s, "~", $start); + if ($start == $end) { + $ed = ""; + } else { + $ed = substr($s, $start, $end-$start); + } + $start = $end + 1; + $end = strpos($s, "~", $start); + if ($start == $end) { + $sw_edition = ""; + } else { + $sw_edition = substr($s, $start, $end-$start); + } + $start = $end + 1; + $end = strpos($s, "~", $start); + if ($start == $end) { + $t_sw = ""; + } else { + $t_sw = substr($s, $start, $end-$start); + } + $start = $end + 1; + $end = strpos($s, "~", $start); + if ($start == $end) { + $t_hw = ""; + } else { + $t_hw = substr($s, $start, $end-$start); + } + $start = $end + 1; + if ($start >= strlen($s)) { + $oth = ""; + } else { + $oth = substr($s, $start, strlen($s) - 1 - $start); + } + // Set each component in the WFN. + try { + $wfn->set("edition", $this->decode($ed)); + $wfn->set("sw_edition", $this->decode($sw_edition)); + $wfn->set("target_sw", $this->decode($t_sw)); + $wfn->set("target_hw", $this->decode($t_hw)); + $wfn->set("other", $this->decode($oth)); + } catch (Exception $e) { + echo $e->getMessage() . "\n"; + } + return $wfn; + } + + /* + * Static method to demonstrate this class. + */ + public static function test() { + // A few examples. + echo "Testing CPENamingUnbind...
\n"; + $cpenu = new CPENameUnbinder(); + $wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer%01%01%01%01:?:beta"); + echo $wfn . "
\n"; + $wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer:8.%2a:sp%3f"); + echo $wfn . "
\n"; + $wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer:8.%02:sp%01"); + echo $wfn . "
\n"; + $wfn = $cpenu->unbindURI("cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~"); + echo $wfn . "
\n"; + echo $cpenu->unbindFS("cpe:2.3:a:micr\\?osoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*") . "
\n"; + } +} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/LogicalValue.php b/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/LogicalValue.php deleted file mode 100644 index 43529bd..0000000 --- a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/LogicalValue.php +++ /dev/null @@ -1,42 +0,0 @@ -. - * - * @see cpe.mitre.org for more information. - * @author Antonio Franco - * @email antonio.franco@pacificsec.com - */ -class LogicalValue { - - private $any = false; - private $na = false; - - // Object must be constructed with the string "ANY" or "NA". - public function __construct($type) { - if ($type == "ANY") { - $this->any = true; - } else if ($type == "NA") { - $this->na = true; - } else { - throw new Exception("LogicalValue must be ANY or NA"); - } - } - - public function isANY(){ - return $this->any; - } - - public function isNA(){ - return $this->na; - } - - public function __toString(){ - if ($this->any){ - return "ANY"; - } - return "NA"; - } -} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/Utilities.php b/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/Utilities.php deleted file mode 100644 index d93c55a..0000000 --- a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/Utilities.php +++ /dev/null @@ -1,167 +0,0 @@ -. - * - * @see cpe.mitre.org for more information. - * @author Antonio Franco - * @email antonio.franco@pacificsec.com - */ -class Utilities { - - /** - * Searches string for special characters * and ? - * @param $string to be searched - * @return true if string contains wildcard, false otherwise - */ - public static function containsWildcards($string) { - if (strpos($string, "*") !== false || strpos($string, "?") !== false) { - if (!(strpos($string, "\\") !== false)) { - return true; - } - return false; - } - return false; - } - - /** - * Checks if given number is even or not - * @param $num number to check - * @return true if number is even, false if not - */ - public static function isEvenNumber($num) { - return (is_int($num) && $num % 2 == 0); - } - - /** - * Counts the number of escape characters in the string beginning and ending - * at the given indices - * @param $str string to search - * @param $start beginning index - * @param $end ending index - * @return number of escape characters in string - * @todo fix the use of $str. The Java version is also not using this variable. - */ - public static function countEscapeCharacters($str, $start, $end) { - $result = 0; - $active = false; - $i = 0; - while ($i < $end) { - if ($active && ($i >= $start)) { - $result = $result + 1; - } - $i = $i + 1; - } - return $result; - } - - /** - * Searches a string for the first unescaped colon and returns the index of - * that colon - * @param $str string to search - * @return index of first unescaped colon, or 0 if not found - */ - public static function getUnescapedColonIndex($str) { - $found = false; - $colon_idx = 0; - $start_idx = 0; - // Find the first non-escaped colon. - while (!$found) { - $colon_idx = strpos($str, ":", $start_idx + 1); - // If no colon is found, return 0. - if ($colon_idx === false) { - return 0; - } - // Peek at character before colon. - if (substr($str, $colon_idx-1, 1) == "\\") { - // If colon is escaped, keep looking. - $start_idx = $colon_idx; - } else { - $found = true; - } - } - return $colon_idx; - } - - /** - * Returns true if the string contains only - * alphanumeric characters or the underscore character, - * false otherwise. - * @param $c the string in question - * @return true if $c is alphanumeric or underscore, false if not - */ - public static function isAlphanum($c) { - return (preg_match("/^[a-zA-Z0-9]$/", $c) || $c == "_"); - } - - /** - * This function is not part of the reference implementation pseudo code - * found in the CPE 2.3 specification. It enforces two rules in the - * specification: - * URI must start with the characters "cpe:/" - * A URI may not contain more than 7 components - * If either rule is violated, a Exception is thrown. - * @param $in string with URI to be validated - */ - public static function validateURI($in) { - // make sure uri starts with cpe:/ - if (strpos(strtolower($in), "cpe:/") !== 0) { - throw new Exception("Error: URI must start with 'cpe:/'. Given: " . $in, 0); - } - // make sure uri doesn't contain more than 7 colons - $count = sizeof(explode(":", $in)); - if ($count > 8) { - throw new Exception("Error parsing URI. Found " . ($count - 8) . " extra components in: " . $in, 0); - } - } - - /** - * This function is not part of the reference implementation pseudo code - * found in the CPE 2.3 specification. It enforces three rules found in the - * specification: - * Formatted string must start with the characters "cpe:2.3:" - * A formatted string must contain 11 components - * A formatted string must not contain empty components - * If any rule is violated, a ParseException is thrown. - * @param $in string with FS to be validated - */ - public static function validateFS($in) { - if (strpos(strtolower($in), "cpe:2.3:") !== 0) { - throw new Exception("Error: Formatted String must start with \"cpe:2.3\". Given: " . $in, 0); - } - - $count = 0; - for ($i = 0; $i != strlen($in); $i++){ - if (substr($in, $i, 1) == ":"){ - if (substr($in, $i - 1, 1) != "\\"){ - $count++; - } - if (($i+1) < strlen($in) && substr($in, $i+1, 1) == ":"){ - throw new Exception("Error parsing formatted string. Found empty component", 0); - } - } - } - if ($count > 12){ - $extra = $count - 12; - $s = "Error parsing formatted string. Found " . $extra . " extra component"; - if ($extra > 1){ - $s = $s . "s"; - } - $s = $s . " in: " . $in; - throw new Exception($s, 0); - } - if ($count < 12){ - $missing = 12 - $count; - $s = "Error parsing formatted string. Missing " . $missing . " component"; - if ($missing > 1){ - $s = $s . "s"; - } - throw new Exception($s, 0); - } - } -} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/WellFormedName.php b/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/WellFormedName.php deleted file mode 100644 index 6542532..0000000 --- a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Common/WellFormedName.php +++ /dev/null @@ -1,210 +0,0 @@ -. - * - * @see cpe.mitre.org for details. - * @author Antonio Franco - * @email antonio.franco@pacificsec.com - */ -class WellFormedName { - - // Underlying wfn representation. - private $wfn = null; - // All permissible WFN attributes as defined by specification. - const ATTRIBUTES = array("part", "vendor", "product", "version", - "update", "edition", "language", "sw_edition", "target_sw", - "target_hw", "other"); - - /** - * Constructs a new WellFormedName object, setting each component to the - * given parameter value. If a parameter is null, the component is set to - * the default value "ANY". - * @param $part string representing the part component - * @param $vendor string representing the vendor component - * @param $product string representing the product component - * @param $version string representing the version component - * @param $update string representing the update component - * @param $edition string representing the edition component - * @param $language string representing the language component - * @param $sw_edition string representing the sw_edition component - * @param $target_sw string representing the target_sw component - * @param $target_hw string representing the target_hw component - * @param $other string representing the other component - */ - public function __construct($part = null, $vendor = null, $product = null, $version = null, - $update = null, $edition = null, $language = null, $sw_edition = null, $target_sw = null, - $target_hw = null, $other = null) { - - $this->wfn = array(); - - // Constructs a new WellFormedName object, with all components set to the default value "ANY". - if ($part === null && $vendor === null && $product === null && $version === null && - $update === null && $edition === null && $language === null && $sw_edition === null && $target_sw === null && - $target_hw === null && $other === null){ - foreach (WellFormedName::ATTRIBUTES as $a){ - if ($a != "part"){ - $this->set($a, new LogicalValue("ANY")); - } - } - return; - } - - $this->set("part", $part); - $this->set("vendor", $vendor); - $this->set("product", $product); - $this->set("version", $version); - $this->set("update", $update); - $this->set("edition", $edition); - $this->set("language", $language); - $this->set("sw_edition", $sw_edition); - $this->set("target_sw", $target_sw); - $this->set("target_hw", $target_hw); - $this->set("other", $other); - } - - /** - * @param $attribute string representing the component value to get - * @return the string value of the given component, or default value "ANY" - * if the component does not exist - */ - public function get($attribute){ - if (array_key_exists($attribute, $this->wfn)) - return $this->wfn[$attribute]; - else - return new LogicalValue("ANY"); - } - - /** - * Sets the given attribute to value, if the attribute is in the list of - * permissible components - * @param $attribute string representing the component to set - * @param $value object or string representing the value of the given component - */ - public final function set($attribute, $value){ - // Iterate over permissible attributes. - foreach (WellFormedName::ATTRIBUTES as $a){ - // If the argument is a valid attribute, set that attribute's value. - if ($attribute == $a) { - // check to see if we're setting a LogicalValue ANY or NA - if ($value instanceof LogicalValue){ - // don't allow logical values in part component - if ($attribute == "part"){ - var_dump($value); echo "
\n"; - var_dump($a); echo "
\n"; - var_dump($attribute); echo "
\n"; - throw new Exception("Error! part component cannot be a logical value"); - } - // put the Object in the ht and break - $this->wfn[$attribute] = $value; - break; - } - if ($value == null || $value == ""){ - // if value is null or blank, set attribute to default logical ANY - $this->wfn[$attribute] = new LogicalValue("ANY"); - break; - } - $svalue = $value; - // Reg exs - // check for printable characters - no control characters - if (!preg_match("/^[[:print:]]*$/", $svalue)){ - throw new Exception("Error! encountered non printable character in: " . $svalue, 0); - } - // svalue has whitespace - if (preg_match("/^.*\\s+.*$/", $svalue)){ - throw new Exception("Error! component cannot contain whitespace: " . $svalue, 0); - } - // svalue has more than one unquoted star - if (preg_match("/^\\*{2,}.*$/", $svalue) || preg_match("/^.*\\*{2,}$/", $svalue)){ - throw new Exception("Error! component cannot contain more than one * in sequence: " . $svalue, 0); - } - // svalue has unquoted punctuation embedded - if (preg_match("/^.*(?\\@\\[\\]\\^\\`\\{\\|\\}\\~\\-].*$/", $svalue)) { - throw new Exception("Error! component cannot contain unquoted punctuation: " . $svalue, 0); - } - // svalue has an unquoted * - if (preg_match("/^.+(?wfn[$attribute] = $svalue; - break; - } - // remove leading and trailing ?s - $v = $svalue; - while (strpos($v, "?") === 0) { - // remove all leading ?'s - $v = substr($v, 1); - } - $v = strrev($v); - while (strpos($v, "?") === 0) { - // remove all trailing ?'s (string has been reversed) - $v = substr($v, 1); - } - // back to normal - $v = strrev($v); - // after leading and trailing ?s are removed, check if value - // contains unquoted ?s - if (preg_match("/^.+(?wfn[$attribute] = $svalue; - break; - } - } - } - - /** - * - * @return string representation of the WellFormedName - */ - public function __toString() { - $str = "wfn:["; - foreach (WellFormedName::ATTRIBUTES as $attr) { - $str = $str . $attr; - $str = $str . "="; - - $o = $this->wfn[$attr]; - if ($o instanceof LogicalValue) { - $str = $str . $o; - $str = $str . ", "; - } else { - $str = $str . "\""; - $str = $str . $o; - $str = $str . "\", "; - } - } - $str = substr($str, 0, strlen($str)-1); - $str = substr($str, 0, strlen($str)-1); - $str = $str . "]"; - - return $str; - } - -} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Matching/CPENameMatcher.php b/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Matching/CPENameMatcher.php deleted file mode 100644 index 029537f..0000000 --- a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Matching/CPENameMatcher.php +++ /dev/null @@ -1,287 +0,0 @@ -. - * - * @see cpe.mitre.org for more information. - * @author Antonio Franco - * @email antonio.franco@pacificsec.com - */ -class CPENameMatcher { - - /** - * Tests two Well Formed Names for disjointness. - * @param $source WellFormedName Source WFN - * @param $target WellFormedName Target WFN - * @return true if the names are disjoint, false otherwise - */ - public function isDisjoint(WellFormedName $source, WellFormedName $target) { - // if any pairwise comparison is disjoint, the names are disjoint. - $resultList = $this->compareWFNs($source, $target); - foreach ($resultList as $result){ - if ($result == Relation::DISJOINT) - return true; - } - return false; - } - - /** - * Tests two Well Formed Names for equality. - * @param $source WellFormedName Source WFN - * @param $target WellFormedName Target WFN - * @return true if the names are equal, false otherwise - */ - public function isEqual(WellFormedName $source, WellFormedName $target) { - // if every pairwise comparison is equal, the names are equal. - $resultList = $this->compareWFNs($source, $target); - foreach ($resultList as $result){ - if ($result != Relation::EQUAL){ - return false; - } - } - return true; - } - - /** - * Tests if the target Well Formed Name is a subset of the source Well Formed - * Name. - * @param $source WellFormedName Source WFN - * @param $target WellFormedName Target WFN - * @return true if the target is a subset of the source, false otherwise - */ - public function isSubset(WellFormedName $source, WellFormedName $target) { - // if any comparison is anything other than subset or equal, then target is - // not a subset of source. - $resultList = $this->compareWFNs($source, $target); - foreach ($resultList as $result){ - if ($result != Relation::SUBSET && $result != Relation::EQUAL) { - return false; - } - } - return true; - } - - /** - * Tests if the target Well Formed name is a superset of the source Well Formed - * Name. - * @param $source WellFormedName Source WFN - * @param $target WellFormedName Target WFN - * @return true if the target is a superset of the source, false otherwise - */ - public function isSuperset(WellFormedName $source, WellFormedName $target) { - // if any comparison is anything other than superset or equal, then target is not - // a superset of source. - $resultList = $this->compareWFNs($source, $target); - foreach ($resultList as $result){ - if ($result != Relation::SUPERSET && $result != Relation::EQUAL) { - return false; - } - } - return true; - } - - /** - * Compares each attribute value pair in two Well Formed Names. - * @param $source WellFormedName Source WFN - * @param $target WellFormedName Target WFN - * @return A array mapping attribute string to attribute value Relation - */ - public function compareWFNs(WellFormedName $source, WellFormedName $target) { - $result = array(); - $result["part"] = $this->compare($source->get("part"), $target->get("part")); - $result["vendor"] = $this->compare($source->get("vendor"), $target->get("vendor")); - $result["product"] = $this->compare($source->get("product"), $target->get("product")); - $result["version"] = $this->compare($source->get("version"), $target->get("version")); - $result["update"] = $this->compare($source->get("update"), $target->get("update")); - $result["edition"] = $this->compare($source->get("edition"), $target->get("edition")); - $result["language"] = $this->compare($source->get("language"), $target->get("language")); - $result["sw_edition"] = $this->compare($source->get("sw_edition"), $target->get("sw_edition")); - $result["target_sw"] = $this->compare($source->get("target_sw"), $target->get("target_sw")); - $result["target_hw"] = $this->compare($source->get("target_hw"), $target->get("target_hw")); - $result["other"] = $this->compare($source->get("other"), $target->get("other")); - return $result; - } - - /** - * Compares an attribute value pair. - * @param $source Source attribute value. - * @param $target Target attribute value. - * @return The relation between the two attribute values. - */ - private function compare($source, $target) { - // matching is case insensitive, convert strings to lowercase. - if ($this->isString($source)) { - $source = strtolower($source); - } - if ($this->isString($target)) { - $target = strtolower($target); - } - - // Unquoted wildcard characters yield an undefined result. - if ($this->isString($target) && Utilities::containsWildcards($target)) { - return Relation::UNDEFINED; - } - // If source and target values are equal, then result is equal. - if ($source == $target) { - return Relation::EQUAL; - } - - // Check to see if source or target are Logical Values. - $lvSource = null; - $lvTarget = null; - if ($source instanceof LogicalValue) { - $lvSource = $source; - } - if ($target instanceof LogicalValue) { - $lvTarget = $target; - } - if ($lvSource != null && $lvTarget != null) { - // If Logical Values are equal, result is equal. - if ($lvSource->isANY() == $lvTarget->isANY() || $lvSource->isNA() == $lvTarget->isNA()) { - return Relation::EQUAL; - } - } - // If source value is ANY, result is a superset. - if ($lvSource != null) { - if ($lvSource->isANY()) { - return Relation::SUPERSET; - } - } - // If target value is ANY, result is a subset. - if ($lvTarget != null) { - if ($lvTarget->isANY()) { - return Relation::SUBSET; - } - } - // If source or target is NA, result is disjoint. - if ($lvSource != null) { - if ($lvSource->isNA()) { - return Relation::DISJOINT; - } - } - if ($lvTarget != null) { - if ($lvTarget->isNA()) { - return Relation::DISJOINT; - } - } - // only Strings will get to this point, not LogicalValues - return $this->compareStrings($source, $target); - } - - /** - * Compares a source string to a target string, and addresses the condition - * in which the source string includes unquoted special characters. It - * performs a simple regular expression match, with the assumption that - * (as required) unquoted special characters appear only at the beginning - * and/or the end of the source string. It also properly differentiates - * between unquoted and quoted special characters. - * - * @param $source string Source attribute value. - * @param $target string Target attribute value. - * @return Relation between source and target Strings. - */ - private function compareStrings($source, $target) { - $start = 0; - $end = strlen($source); - $begins = 0; - $ends = 0; - $index = 0; $leftover = 0; $escapes = 0; - - if (substr($source, 0, 1) == "*") { - $start = 1; - $begins = -1; - } else { - while (($start < strlen($source)) && (substr($source, $start, 1) == "?")) { - $start = $start + 1; - $begins = $begins + 1; - } - } - if ((substr($source, $end - 1, 1) == "*") && ($this->isEvenWildcards($source, $end - 1))) { //TODO - $end = $end - 1; - $ends = -1; - } else { - while (($end > 0) && substr($source, $end - 1, 1) == "?" && ($this->isEvenWildcards($source, $end - 1))) { //TODO - $end = $end - 1; - $ends = $ends + 1; - } - } - - $source = substr($source, $start, $end-$start); - $index = -1; - $leftover = strlen($target); - while ($leftover > 0) { - $index = strpos($target, $source, $index + 1); - if ($index === false) { - break; - } - $escapes = Utilities::countEscapeCharacters($target, 0, $index); - if (($index > 0) && ($begins != -1) && ($begins < ($index - $escapes))) { - break; - } - $escapes = Utilities::countEscapeCharacters($target, $index + 1, strlen($target)); - $leftover = strlen($target) - $index - $escapes - strlen($source); - if (($leftover > 0) && (($ends != -1) && ($leftover > $ends))) { - continue; - } - return Relation::SUPERSET; - } - return Relation::DISJOINT; - } - - /** - * Searches a string for the backslash character - * @param $str string to search in - * @param $idx end index - * @return true if the number of backslash characters is even, false if odd - */ - private function isEvenWildcards($str, $idx) { - $result = 0; - while (($idx > 0) && (strpos($str, "\\", $idx - 1)) !== false) { - $idx = $idx - 1; - $result = $result + 1; - } - return Utilities::isEvenNumber($result); - } - - /** - * Tests if an Object is an instance of the String class - * @param $arg the var to test - * @return true if arg is a string, false if not - */ - private function isString($arg) { - is_string($arg); - } - - /* - * Static method to demonstrate this class. - */ - public static function test() { - // Examples. - $wfn = new WellFormedName("a", "microsoft", "internet_explorer", "8\\.0\\.6001", "beta", new LogicalValue("ANY"), "sp2", null, null, null, null); - $wfn2 = new WellFormedName("a", "microsoft", "internet_explorer", new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY"), new LogicalValue("ANY")); - $cpenm = new CPENameMatcher(); - $cpenu = new CPENameUnbinder(); - $cpenb = new CPENameBinder(); - $wfn = $cpenu->unbindURI($cpenb->bindToURI($wfn)); - $wfn2 = $cpenu->unbindFS($cpenb->bindToFS($wfn2)); - var_dump($cpenm->isDisjoint($wfn, $wfn2)); // false - var_dump($cpenm->isEqual($wfn, $wfn2)); // false - var_dump($cpenm->isSubset($wfn, $wfn2)); // true, $wfn2 is a subset of wfn - var_dump($cpenm->isSuperset($wfn, $wfn2)); // false - $wfn = $cpenu->unbindFS("cpe:2.3:a:adobe:*:9.*:*:PalmOS:*:*:*:*:*"); - $wfn2 = $cpenu->unbindURI("cpe:/a::Reader:9.3.2:-:-"); - var_dump($cpenm->isDisjoint($wfn, $wfn2)); // true, $wfn2 and wfn are disjoint - var_dump($cpenm->isEqual($wfn, $wfn2)); // false - var_dump($cpenm->isSubset($wfn, $wfn2)); // false - var_dump($cpenm->isSuperset($wfn, $wfn2)); // false - } -} \ No newline at end of file diff --git a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Naming/CPENameUnbinder.php b/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Naming/CPENameUnbinder.php deleted file mode 100644 index 3a1439d..0000000 --- a/inc/vendor/pacificsec/cpe/vendor/PacificSec/CPE/Naming/CPENameUnbinder.php +++ /dev/null @@ -1,466 +0,0 @@ -. - * - * @see cpe.mitre.org for more information. - * @author Antonio Franco - * @email antonio.franco@pacificsec.com - */ -class CPENameUnbinder { - - /** - * Top level function used to unbind a URI to a WFN. - * @param $uri string representing the URI to be unbound. - * @return WellFormedName representing the unbound URI. - * @throws Exception representing parsing errors. - */ - public function unbindURI($uri) { - // Validate the URI - Utilities::validateURI($uri); - // Initialize the empty WFN. - $result = new WellFormedName(); - - for ($i = 0; $i != 8; $i++) { - // get the i'th component of uri - $v = $this->getCompURI($uri, $i); - switch ($i) { - case 1: - $result->set("part", $this->decode($v)); - break; - case 2: - $result->set("vendor", $this->decode($v)); - break; - case 3: - $result->set("product", $this->decode($v)); - break; - case 4: - $result->set("version", $this->decode($v)); - break; - case 5: - $result->set("update", $this->decode($v)); - break; - case 6: - // Special handling for edition component. - // Unpack edition if needed. - if ($v == "" || $v == "-" - || substr($v, 0, 1) != "~") { - // Just a logical value or a non-packed value. - // So unbind to legacy edition, leaving other - // extended attributes unspecified. - $result->set("edition", $this->decode($v)); - } else { - // We have five values packed together here. - $this->unpack($v, $result); - } - break; - case 7: - $result->set("language", $this->decode($v)); - break; - } - } - return $result; - } - - /** - * Top level function to unbind a formatted string to WFN. - * @param $fs Formatted string to unbind - * @return WellFormedName - * @throws Exception representing parsing error - */ - public function unbindFS($fs) { - // Validate the formatted string - Utilities::validateFS($fs); - // Initialize empty WFN - $result = new WellFormedName(); - // The cpe scheme is the 0th component, the cpe version is the 1st. - // So we start parsing at the 2nd component. - for ($a = 2; $a != 13; $a++) { - // Get the a'th string field. - $v = $this->getCompFS($fs, $a); - // Unbind the string. - $v = $this->unbindValueFS($v); - // Set the value of the corresponding attribute. - switch ($a) { - case 2: - $result->set("part", $v); - break; - case 3: - $result->set("vendor", $v); - break; - case 4: - $result->set("product", $v); - break; - case 5: - $result->set("version", $v); - break; - case 6: - $result->set("update", $v); - break; - case 7: - $result->set("edition", $v); - break; - case 8: - $result->set("language", $v); - break; - case 9: - $result->set("sw_edition", $v); - break; - case 10: - $result->set("target_sw", $v); - break; - case 11: - $result->set("target_hw", $v); - break; - case 12: - $result->set("other", $v); - break; - } - } - return $result; - } - - /** - * Returns the i'th field of the formatted string. The colon is the field - * delimiter unless prefixed by a backslash. - * @param $fs formatted string to retrieve from - * @param $i index of field to retrieve from fs. - * @return value of index of formatted string - */ - private function getCompFS($fs, $i) { - if ($i == 0) { - // return the substring from index 0 to the first occurence of an - // unescaped colon - $colon_idx = Utilities::getUnescapedColonIndex($fs); - // If no colon is found, we are at the end of the formatted string, - // so just return what's left. - if ($colon_idx == 0) { - return $fs; - } - return substr($fs, 0, $colon_idx); - } else { - $substrStart = Utilities::getUnescapedColonIndex($fs) + 1; - $substrLength = strlen($fs) - $substrStart; - return $this->getCompFS(substr($fs, $substrStart, $substrLength), $i - 1); - } - } - - /** - * Takes a string value and returns the appropriate logical value if string - * is the bound form of a logical value. If string is some general value - * string, add quoting of non-alphanumerics as needed. - * @param $s value to be unbound - * @return logical value or quoted string - * @throws Exception representing parsing errors - */ - private function unbindValueFS($s) { - if ($s == "*") { - return new LogicalValue("ANY"); - } - if ($s == "-") { - return new LogicalValue("NA"); - } - return $this->addQuoting($s); - } - - /** - * Inspect each character in a string, copying quoted characters, with - * their escaping, into the result. Look for unquoted non alphanumerics - * and if not "*" or "?", add escaping. - * @param $s - * @return - * @throws Exception representing parsing errors. - */ - private function addQuoting($s) { - $result = ""; - $idx = 0; - $embedded = false; - while ($idx < strlen($s)) { - $c = substr($s, $idx, 1); - if (Utilities::isAlphanum($c) || $c == "_") { - // Alphanumeric characters pass untouched. - $result = $result . $c; - $idx = $idx + 1; - $embedded = true; - continue; - } - if ($c == "\\") { - // Anything quoted in the bound string stays quoted in the - // unbound string. - $result = $result . substr($s, $idx, 2); - $idx = $idx + 2; - $embedded = true; - continue; - } - if ($c == "*") { - // An unquoted asterisk must appear at the beginning or the end - // of the string. - if ($idx == 0 || $idx == strlen($s) - 1) { - $result = $result . $c; - $idx = $idx + 1; - $embedded = true; - continue; - } else { - throw new Exception("Error! cannot have unquoted * embedded in formatted string.", 0); - } - } - if ($c == "?") { - // An unquoted question mark must appear at the beginning or - // end of the string, or in a leading or trailing sequence. - if ( // ? legal at beginning or end - (($idx == 0) || ($idx == (strlen($s) - 1))) - // embedded is false, so must be preceded by ? - || (!$embedded && (substr($s, $idx - 1, 1) == "?")) - // embedded is true, so must be followed by ? - || ($embedded && (substr($s, $idx + 1, 1) == "?"))) { - $result = $result . $c; - $idx = $idx + 1; - $embedded = false; - continue; - } else { - throw new Exception("Error! cannot have unquoted ? embedded in formatted string.", 0); - } - } - // All other characters must be quoted. - $result = $result . "\\" . $c; - $idx = $idx + 1; - $embedded = true; - } - return $result; - } - - /** - * Return the i'th component of the URI. - * @param $uri string representation of URI to retrieve components from. - * @param $i Index of component to return. - * @return If i = 0, returns the URI scheme. Otherwise, returns the i'th - * component of uri. - */ - private function getCompURI($uri, $i) { - if ($i == 0) { - return substr($uri, $i, strpos($uri, "/")); - } - $sa = explode(":", $uri); - // If requested component exceeds the number - // of components in URI, return blank - if ($i >= sizeof($sa)) { - return ""; - } - if ($i === 1) { - return substr($sa[$i], 1, strlen($sa[$i])-1); - } - return $sa[$i]; - } - - /** - * Scans a string and returns a copy with all percent-encoded characters - * decoded. This function is the inverse of pctEncode() defined in the - * CPENameBinder class. Only legal percent-encoded forms are decoded. - * Others raise a ParseException. - * @param $s string to be decoded - * @return decoded string - * @throws Exception representing parsing errors - * @see CPENameBinder#pctEncode - */ - private function decode($s) { - if ($s == "") { - return new LogicalValue("ANY"); - } - if ($s == "-") { - return new LogicalValue("NA"); - } - // Start the scanning loop. - // Normalize: convert all uppercase letters to lowercase first. - $s = strtolower($s); - $result = ""; - $idx = 0; - $embedded = false; - while ($idx < strlen($s)) { - // Get the idx'th character of s. - $c = substr($s, $idx, 1); - // Deal with dot, hyphen, and tilde: decode with quoting. - if ($c == "." || $c == "-" || $c == "~") { - $result = $result . "\\" . $c; - $idx = $idx + 1; - // a non-%01 encountered. - $embedded = true; - continue; - } - if ($c != "%") { - $result = $result . $c; - $idx = $idx + 1; - // a non-%01 encountered. - $embedded = true; - continue; - } - // We get here if we have a substring starting w/ '%'. - $form = substr($s, $idx, 3); - if ($form == "%01") { - if (($idx == 0) - || ($idx == strlen($s) - 3) - || (!$embedded && substr($s, $idx - 3, 2) == "%01") - || ($embedded && (strlen($s) >= $idx + 6)) - && (substr($s, $idx + 3, 3) == "%01")) { - $result = $result . "?"; - $idx = $idx + 3; - continue; - } else { - throw new Exception("Error decoding string", 0); - } - } else if ($form == "%02") { - if (($idx == 0) || ($idx == (strlen($s) - 3))) { - $result = $result . "*"; - } else { - throw new Exception("Error decoding string", 0); - } - } else if ($form == "%21") { - $result = $result . "\\!"; - } else if ($form == "%22") { - $result = $result . "\\\""; - } else if ($form == "%23") { - $result = $result . "\\#"; - } else if ($form == "%24") { - $result = $result . "\\$"; - } else if ($form == "%25") { - $result = $result . "\\%"; - } else if ($form == "%26") { - $result = $result . "\\&"; - } else if ($form == "%27") { - $result = $result . "\\'"; - } else if ($form == "%28") { - $result = $result . "\\("; - } else if ($form == "%29") { - $result = $result . "\\)"; - } else if ($form == "%2a") { - $result = $result . "\\*"; - } else if ($form == "%2b") { - $result = $result . "\\+"; - } else if ($form == "%2c") { - $result = $result . "\\,"; - } else if ($form == "%2f") { - $result = $result . "\\/"; - } else if ($form == "%3a") { - $result = $result . "\\))"; - } else if ($form == "%3b") { - $result = $result . "\\;"; - } else if ($form == "%3c") { - $result = $result . "\\<"; - } else if ($form == "%3d") { - $result = $result . "\\="; - } else if ($form == "%3e") { - $result = $result . "\\>"; - } else if ($form == "%3f") { - $result = $result . "\\?"; - } else if ($form == "%40") { - $result = $result . "\\@"; - } else if ($form == "%5b") { - $result = $result . "\\["; - } else if ($form == "%5c") { - $result = $result . "\\\\"; - } else if ($form == "%5d") { - $result = $result . "\\]"; - } else if ($form == "%5e") { - $result = $result . "\\^"; - } else if ($form == "%60") { - $result = $result . "\\`"; - } else if ($form == "%7b") { - $result = $result . "\\{"; - } else if ($form == "%7c") { - $result = $result . "\\|"; - } else if ($form == "%7d") { - $result = $result . "\\}"; - } else if ($form == "%7e") { - $result = $result . "\\~"; - } else { - throw new Exception("Unknown form: " . $form, 0); - } - $idx = $idx + 3; - $embedded = true; - } - return $result; - } - - /** - * Unpacks the elements in s and sets the attributes in the given - * WellFormedName accordingly. - * @param $s packed string - * @param $wfn WellFormedName - * @return The augmented WellFormedName. - */ - private function unpack($s, WellFormedName $wfn) { - // Parse out the five elements. - $start = 1; - $ed = ""; $sw_edition = ""; $t_sw = ""; $t_hw = ""; $oth = ""; - $end = strpos($s, "~", $start); - if ($start == $end) { - $ed = ""; - } else { - $ed = substr($s, $start, $end-$start); - } - $start = $end + 1; - $end = strpos($s, "~", $start); - if ($start == $end) { - $sw_edition = ""; - } else { - $sw_edition = substr($s, $start, $end-$start); - } - $start = $end + 1; - $end = strpos($s, "~", $start); - if ($start == $end) { - $t_sw = ""; - } else { - $t_sw = substr($s, $start, $end-$start); - } - $start = $end + 1; - $end = strpos($s, "~", $start); - if ($start == $end) { - $t_hw = ""; - } else { - $t_hw = substr($s, $start, $end-$start); - } - $start = $end + 1; - if ($start >= strlen($s)) { - $oth = ""; - } else { - $oth = substr($s, $start, strlen($s) - 1 - $start); - } - // Set each component in the WFN. - try { - $wfn->set("edition", $this->decode($ed)); - $wfn->set("sw_edition", $this->decode($sw_edition)); - $wfn->set("target_sw", $this->decode($t_sw)); - $wfn->set("target_hw", $this->decode($t_hw)); - $wfn->set("other", $this->decode($oth)); - } catch (Exception $e) { - echo $e->getMessage() . "\n"; - } - return $wfn; - } - - /* - * Static method to demonstrate this class. - */ - public static function test() { - // A few examples. - echo "Testing CPENamingUnbind...
\n"; - $cpenu = new CPENameUnbinder(); - $wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer%01%01%01%01:?:beta"); - echo $wfn . "
\n"; - $wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer:8.%2a:sp%3f"); - echo $wfn . "
\n"; - $wfn = $cpenu->unbindURI("cpe:/a:microsoft:internet_explorer:8.%02:sp%01"); - echo $wfn . "
\n"; - $wfn = $cpenu->unbindURI("cpe:/a:hp:insight_diagnostics:7.4.0.1570::~~online~win2003~x64~"); - echo $wfn . "
\n"; - echo $cpenu->unbindFS("cpe:2.3:a:micr\\?osoft:internet_explorer:8.0.6001:beta:*:*:*:*:*:*") . "
\n"; - } -} \ No newline at end of file diff --git a/inc/vendor/phpoffice/phpspreadsheet/.sami.php b/inc/vendor/phpoffice/phpspreadsheet/.sami.php new file mode 100644 index 0000000..9a2fca3 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/.sami.php @@ -0,0 +1,24 @@ +files() + ->name('*.php') + ->in($dir = __DIR__ . '/src'); +$versions = GitVersionCollection::create($dir) + ->addFromTags(function ($version) { + return preg_match('~^\d+\.\d+\.\d+$~', $version); + }) + ->add('master'); + +return new Sami($iterator, [ + 'title' => 'PhpSpreadsheet', + 'versions' => $versions, + 'build_dir' => __DIR__ . '/build/%version%', + 'cache_dir' => __DIR__ . '/cache/%version%', + 'remote_repository' => new GitHubRemoteRepository('PHPOffice/PhpSpreadsheet', dirname($dir)), +]); diff --git a/inc/vendor/phpoffice/phpspreadsheet/.travis.yml b/inc/vendor/phpoffice/phpspreadsheet/.travis.yml index 463f195..3a94e66 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/.travis.yml +++ b/inc/vendor/phpoffice/phpspreadsheet/.travis.yml @@ -10,6 +10,7 @@ php: cache: directories: + - cache - vendor - $HOME/.composer/cache @@ -28,7 +29,7 @@ jobs: php: 7.1 script: - ./vendor/bin/php-cs-fixer fix --diff --verbose --dry-run - - ./vendor/bin/phpcs --report-width=200 --report-summary --report-full samples/ src/ tests/ --ignore=samples/Header.php --standard=PSR2 -n + - ./vendor/bin/phpcs --report-width=200 samples/ src/ tests/ --ignore=samples/Header.php --standard=PSR2 -n - stage: Coverage php: 7.1 @@ -38,3 +39,21 @@ jobs: after_script: - wget https://scrutinizer-ci.com/ocular.phar - php ocular.phar code-coverage:upload --format=php-clover tests/coverage-clover.xml + + - stage: API documentation + php: 7.1 + before_script: + - curl -O http://get.sensiolabs.org/sami.phar + script: + - git fetch origin master:master + - git fetch origin --tags + - php sami.phar update .sami.php + - echo '

If you are not automatically redirected, please go to the latest stable API documentation.

' > build/index.html + deploy: + provider: pages + skip-cleanup: true + local-dir: build + github-token: $GITHUB_TOKEN + on: + all_branches: true + condition: $TRAVIS_BRANCH =~ ^master|develop$ diff --git a/inc/vendor/phpoffice/phpspreadsheet/CHANGELOG.md b/inc/vendor/phpoffice/phpspreadsheet/CHANGELOG.md index e2a9bfa..42e6fc2 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/CHANGELOG.md +++ b/inc/vendor/phpoffice/phpspreadsheet/CHANGELOG.md @@ -5,6 +5,95 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/) and this project adheres to [Semantic Versioning](http://semver.org/). +## [1.4.0] - 2018-08-06 + +### Added + +- Add excel function EXACT(value1, value2) support - [#595](https://github.com/PHPOffice/PhpSpreadsheet/pull/595) +- Support workbook view attributes for Xlsx format - [#523](https://github.com/PHPOffice/PhpSpreadsheet/issues/523) +- Read and write hyperlink for drawing image - [#490](https://github.com/PHPOffice/PhpSpreadsheet/pull/490) +- Added calculation engine support for the new bitwise functions that were added in MS Excel 2013 + - BITAND() Returns a Bitwise 'And' of two numbers + - BITOR() Returns a Bitwise 'Or' of two number + - BITXOR() Returns a Bitwise 'Exclusive Or' of two numbers + - BITLSHIFT() Returns a number shifted left by a specified number of bits + - BITRSHIFT() Returns a number shifted right by a specified number of bits +- Added calculation engine support for other new functions that were added in MS Excel 2013 and MS Excel 2016 + - Text Functions + - CONCAT() Synonym for CONCATENATE() + - NUMBERVALUE() Converts text to a number, in a locale-independent way + - UNICHAR() Synonym for CHAR() in PHPSpreadsheet, which has always used UTF-8 internally + - UNIORD() Synonym for ORD() in PHPSpreadsheet, which has always used UTF-8 internally + - TEXTJOIN() Joins together two or more text strings, separated by a delimiter + - Logical Functions + - XOR() Returns a logical Exclusive Or of all arguments + - Date/Time Functions + - ISOWEEKNUM() Returns the ISO 8601 week number of the year for a given date + - Lookup and Reference Functions + - FORMULATEXT() Returns a formula as a string + - Financial Functions + - PDURATION() Calculates the number of periods required for an investment to reach a specified value + - RRI() Calculates the interest rate required for an investment to grow to a specified future value + - Engineering Functions + - ERF.PRECISE() Returns the error function integrated between 0 and a supplied limit + - ERFC.PRECISE() Synonym for ERFC + - Math and Trig Functions + - SEC() Returns the secant of an angle + - SECH() Returns the hyperbolic secant of an angle + - CSC() Returns the cosecant of an angle + - CSCH() Returns the hyperbolic cosecant of an angle + - COT() Returns the cotangent of an angle + - COTH() Returns the hyperbolic cotangent of an angle + - ACOT() Returns the cotangent of an angle + - ACOTH() Returns the hyperbolic cotangent of an angle +- Refactored Complex Engineering Functions to use external complex number library +- Added calculation engine support for the new complex number functions that were added in MS Excel 2013 + - IMCOSH() Returns the hyperbolic cosine of a complex number + - IMCOT() Returns the cotangent of a complex number + - IMCSC() Returns the cosecant of a complex number + - IMCSCH() Returns the hyperbolic cosecant of a complex number + - IMSEC() Returns the secant of a complex number + - IMSECH() Returns the hyperbolic secant of a complex number + - IMSINH() Returns the hyperbolic sine of a complex number + - IMTAN() Returns the tangent of a complex number + +### Fixed + +- Fix ISFORMULA() function to work with a cell reference to another worksheet +- Xlsx reader crashed when reading a file with workbook protection - [#553](https://github.com/PHPOffice/PhpSpreadsheet/pull/553) +- Cell formats with escaped spaces were causing incorrect date formatting - [#557](https://github.com/PHPOffice/PhpSpreadsheet/issues/557) +- Could not open CSV file containing HTML fragment - [#564](https://github.com/PHPOffice/PhpSpreadsheet/issues/564) +- Exclude the vendor folder in migration - [#481](https://github.com/PHPOffice/PhpSpreadsheet/issues/481) +- Chained operations on cell ranges involving borders operated on last cell only [#428](https://github.com/PHPOffice/PhpSpreadsheet/issues/428) +- Avoid memory exhaustion when cloning worksheet with a drawing [#437](https://github.com/PHPOffice/PhpSpreadsheet/issues/437) +- Migration tool keep variables containing $PHPExcel untouched [#598](https://github.com/PHPOffice/PhpSpreadsheet/issues/598) +- Rowspans/colspans were incorrect when adding worksheet using loadIntoExisting [#619](https://github.com/PHPOffice/PhpSpreadsheet/issues/619) + +## [1.3.1] - 2018-06-12 + +### Fixed + +- Ranges across Z and AA columns incorrectly threw an exception - [#545](https://github.com/PHPOffice/PhpSpreadsheet/issues/545) + +## [1.3.0] - 2018-06-10 + +### Added + +- Support to read Xlsm templates with form elements, macros, printer settings, protected elements and back compatibility drawing, and save result without losing important elements of document - [#435](https://github.com/PHPOffice/PhpSpreadsheet/issues/435) +- Expose sheet title maximum length as `Worksheet::SHEET_TITLE_MAXIMUM_LENGTH` - [#482](https://github.com/PHPOffice/PhpSpreadsheet/issues/482) +- Allow escape character to be set in CSV reader – [#492](https://github.com/PHPOffice/PhpSpreadsheet/issues/492) + +### Fixed + +- Subtotal 9 in a group that has other subtotals 9 exclude the totals of the other subtotals in the range - [#332](https://github.com/PHPOffice/PhpSpreadsheet/issues/332) +- `Helper\Html` support UTF-8 HTML input - [#444](https://github.com/PHPOffice/PhpSpreadsheet/issues/444) +- Xlsx loaded an extra empty comment for each real comment - [#375](https://github.com/PHPOffice/PhpSpreadsheet/issues/375) +- Xlsx reader do not read rows and columns filtered out in readFilter at all - [#370](https://github.com/PHPOffice/PhpSpreadsheet/issues/370) +- Make newer Excel versions properly recalculate formulas on document open - [#456](https://github.com/PHPOffice/PhpSpreadsheet/issues/456) +- `Coordinate::extractAllCellReferencesInRange()` throws an exception for an invalid range – [#519](https://github.com/PHPOffice/PhpSpreadsheet/issues/519) +- Fixed parsing of conditionals in COUNTIF functions - [#526](https://github.com/PHPOffice/PhpSpreadsheet/issues/526) +- Corruption errors for saved Xlsx docs with frozen panes - [#532](https://github.com/PHPOffice/PhpSpreadsheet/issues/532) + ## [1.2.1] - 2018-04-10 ### Fixed diff --git a/inc/vendor/phpoffice/phpspreadsheet/README.md b/inc/vendor/phpoffice/phpspreadsheet/README.md index 0a138d7..e63e26e 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/README.md +++ b/inc/vendor/phpoffice/phpspreadsheet/README.md @@ -18,9 +18,7 @@ PhpSpreadsheet is a library written in pure PHP and providing a set of classes t ## Documentation -Read more about it, including install instructions, in the official documentation: - -https://phpspreadsheet.readthedocs.io +Read more about it, including install instructions, in the [official documentation](https://phpspreadsheet.readthedocs.io). Or check out the [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master). Please ask your support questions on [StackOverflow](http://stackoverflow.com/questions/tagged/phpspreadsheet), or have a quick chat on [Gitter](https://gitter.im/PHPOffice/PhpSpreadsheet). diff --git a/inc/vendor/phpoffice/phpspreadsheet/composer.json b/inc/vendor/phpoffice/phpspreadsheet/composer.json index 1c033bb..4a08707 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/composer.json +++ b/inc/vendor/phpoffice/phpspreadsheet/composer.json @@ -25,7 +25,7 @@ "scripts": { "check": [ "php-cs-fixer fix --ansi --dry-run --diff", - "phpcs --report-width=200 --report-summary --report-full samples/ src/ tests/ --ignore=samples/Header.php --standard=PSR2 -n", + "phpcs --report-width=200 samples/ src/ tests/ --ignore=samples/Header.php --standard=PSR2 -n", "phpunit --color=always" ], "fix": [ @@ -46,16 +46,17 @@ "ext-xmlwriter": "*", "ext-zip": "*", "ext-zlib": "*", - "psr/simple-cache": "^1.0" + "psr/simple-cache": "^1.0", + "markbaker/complex": "^1.4.1" }, "require-dev": { "tecnickcom/tcpdf": "^6.2", - "squizlabs/php_codesniffer": "^2.7", "phpunit/phpunit": "^5.7", "dompdf/dompdf": "^0.8.0", "mpdf/mpdf": "^7.0.0", "jpgraph/jpgraph": "^4.0", - "friendsofphp/php-cs-fixer": "@stable" + "friendsofphp/php-cs-fixer": "@stable", + "squizlabs/php_codesniffer": "^3.3" }, "suggest": { "mpdf/mpdf": "Option for rendering PDF with PDF Writer", diff --git a/inc/vendor/phpoffice/phpspreadsheet/composer.lock b/inc/vendor/phpoffice/phpspreadsheet/composer.lock index 2991465..fe9fbc6 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/composer.lock +++ b/inc/vendor/phpoffice/phpspreadsheet/composer.lock @@ -1,11 +1,106 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e61a906bd83393400add286703f10557", + "content-hash": "66067b3ab7afd673a28cf0b31eb9ae20", "packages": [ + { + "name": "markbaker/complex", + "version": "1.4.1", + "source": { + "type": "git", + "url": "https://github.com/MarkBaker/PHPComplex.git", + "reference": "615f5443473cf37729666e2354fd8dfa2cb48e91" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/615f5443473cf37729666e2354fd8dfa2cb48e91", + "reference": "615f5443473cf37729666e2354fd8dfa2cb48e91", + "shasum": "" + }, + "require": { + "php": "^5.6.0|^7.0.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.3", + "phpdocumentor/phpdocumentor": "2.*", + "phploc/phploc": "2.*", + "phpmd/phpmd": "2.*", + "phpunit/phpunit": "^4.8.35|^5.4.0", + "sebastian/phpcpd": "2.*", + "squizlabs/php_codesniffer": "^3.1.1", + "wimg/php-compatibility": "^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Complex\\": "classes/src/" + }, + "files": [ + "classes/src/functions/abs.php", + "classes/src/functions/acos.php", + "classes/src/functions/acosh.php", + "classes/src/functions/acot.php", + "classes/src/functions/acoth.php", + "classes/src/functions/acsc.php", + "classes/src/functions/acsch.php", + "classes/src/functions/argument.php", + "classes/src/functions/asec.php", + "classes/src/functions/asech.php", + "classes/src/functions/asin.php", + "classes/src/functions/asinh.php", + "classes/src/functions/atan.php", + "classes/src/functions/atanh.php", + "classes/src/functions/conjugate.php", + "classes/src/functions/cos.php", + "classes/src/functions/cosh.php", + "classes/src/functions/cot.php", + "classes/src/functions/coth.php", + "classes/src/functions/csc.php", + "classes/src/functions/csch.php", + "classes/src/functions/exp.php", + "classes/src/functions/inverse.php", + "classes/src/functions/ln.php", + "classes/src/functions/log2.php", + "classes/src/functions/log10.php", + "classes/src/functions/negative.php", + "classes/src/functions/pow.php", + "classes/src/functions/rho.php", + "classes/src/functions/sec.php", + "classes/src/functions/sech.php", + "classes/src/functions/sin.php", + "classes/src/functions/sinh.php", + "classes/src/functions/sqrt.php", + "classes/src/functions/tan.php", + "classes/src/functions/tanh.php", + "classes/src/functions/theta.php", + "classes/src/operations/add.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/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mark Baker", + "email": "mark@lange.demon.co.uk" + } + ], + "description": "PHP Class for working with complex numbers", + "homepage": "https://github.com/MarkBaker/PHPComplex", + "keywords": [ + "complex", + "mathematics" + ], + "time": "2018-07-24T19:47:28+00:00" + }, { "name": "psr/simple-cache", "version": "1.0.0", @@ -2106,64 +2201,37 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "2.8.1", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d" + "reference": "628a481780561150481a9ec74709092b9759b3ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", - "reference": "d7cf0d894e8aa4c73712ee4a331cc1eaa37cdc7d", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/628a481780561150481a9ec74709092b9759b3ec", + "reference": "628a481780561150481a9ec74709092b9759b3ec", "shasum": "" }, "require": { "ext-simplexml": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": ">=5.1.2" + "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "bin": [ - "scripts/phpcs", - "scripts/phpcbf" + "bin/phpcs", + "bin/phpcbf" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "3.x-dev" } }, - "autoload": { - "classmap": [ - "CodeSniffer.php", - "CodeSniffer/CLI.php", - "CodeSniffer/Exception.php", - "CodeSniffer/File.php", - "CodeSniffer/Fixer.php", - "CodeSniffer/Report.php", - "CodeSniffer/Reporting.php", - "CodeSniffer/Sniff.php", - "CodeSniffer/Tokens.php", - "CodeSniffer/Reports/", - "CodeSniffer/Tokenizers/", - "CodeSniffer/DocGenerators/", - "CodeSniffer/Standards/AbstractPatternSniff.php", - "CodeSniffer/Standards/AbstractScopeSniff.php", - "CodeSniffer/Standards/AbstractVariableSniff.php", - "CodeSniffer/Standards/IncorrectPatternException.php", - "CodeSniffer/Standards/Generic/Sniffs/", - "CodeSniffer/Standards/MySource/Sniffs/", - "CodeSniffer/Standards/PEAR/Sniffs/", - "CodeSniffer/Standards/PSR1/Sniffs/", - "CodeSniffer/Standards/PSR2/Sniffs/", - "CodeSniffer/Standards/Squiz/Sniffs/", - "CodeSniffer/Standards/Zend/Sniffs/" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" @@ -2180,7 +2248,7 @@ "phpcs", "standards" ], - "time": "2017-03-01T22:17:45+00:00" + "time": "2018-07-26T23:47:18+00:00" }, { "name": "symfony/console", diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/extra/extra.js b/inc/vendor/phpoffice/phpspreadsheet/docs/extra/extra.js deleted file mode 100644 index fdef958..0000000 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/extra/extra.js +++ /dev/null @@ -1,57 +0,0 @@ -var nodemcu = nodemcu || {}; -(function () { - 'use strict'; - - $(document).ready(function () { - fixSearch(); - }); - - /* - * RTD messes up MkDocs' search feature by tinkering with the search box defined in the theme, see - * https://github.com/rtfd/readthedocs.org/issues/1088. This function sets up a DOM4 MutationObserver - * to react to changes to the search form (triggered by RTD on doc ready). It then reverts everything - * the RTD JS code modified. - */ - function fixSearch() { - var target = document.getElementById('rtd-search-form'); - var config = {attributes: true, childList: true}; - - var observer = new MutationObserver(function (mutations) { - // if it isn't disconnected it'll loop infinitely because the observed element is modified - observer.disconnect(); - var form = $('#rtd-search-form'); - form.empty(); - form.attr('action', 'https://' + window.location.hostname + '/en/' + determineSelectedBranch() + '/search.html'); - $('').attr({ - type: "text", - name: "q", - placeholder: "Search docs" - }).appendTo(form); - }); - - if (window.location.origin.indexOf('readthedocs') > -1) { - observer.observe(target, config); - } - } - - /** - * Analyzes the URL of the current page to find out what the selected GitHub branch is. It's usually - * part of the location path. The code needs to distinguish between running MkDocs standalone - * and docs served from RTD. If no valid branch could be determined 'dev' returned. - * - * @returns GitHub branch name - */ - function determineSelectedBranch() { - var branch = 'dev', path = window.location.pathname; - if (window.location.origin.indexOf('readthedocs') > -1) { - // path is like /en///build/ -> extract 'lang' - // split[0] is an '' because the path starts with the separator - var thirdPathSegment = path.split('/')[2]; - // 'latest' is an alias on RTD for the 'dev' branch - which is the default for 'branch' here - if (thirdPathSegment !== 'latest') { - branch = thirdPathSegment; - } - } - return branch; - } -}()); \ No newline at end of file diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/index.md b/inc/vendor/phpoffice/phpspreadsheet/docs/index.md index 79d884d..08a9199 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/index.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/index.md @@ -95,6 +95,8 @@ architecture](./topics/architecture.md), [accessing cells](./topics/accessing-cells.md) and [reading and writing to files](./topics/reading-and-writing-to-file.md). +Or browse the [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master). + # Credits Please refer to the [contributor diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/references/features-cross-reference.md b/inc/vendor/phpoffice/phpspreadsheet/docs/references/features-cross-reference.md index 2d28cd4..716a378 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/references/features-cross-reference.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/references/features-cross-reference.md @@ -750,6 +750,24 @@ + + Drawing hyperlink + + ✔ + + + + + + + ✔ + + + + + $drawing->getHyperlink()->getUrl() + $drawing->setHyperlink()->setUrl($url) + Cell Formatting diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/references/function-list-by-category.md b/inc/vendor/phpoffice/phpspreadsheet/docs/references/function-list-by-category.md index 5561828..185bf4c 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/references/function-list-by-category.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/references/function-list-by-category.md @@ -41,6 +41,7 @@ DAYS360 | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::DAYS360 EDATE | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::EDATE EOMONTH | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::EOMONTH HOUR | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::HOUROFDAY +ISOWEEKNUM | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::ISOWEEKNUM MINUTE | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::MINUTE MONTH | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::MONTHOFYEAR NETWORKDAYS | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::NETWORKDAYS @@ -73,7 +74,9 @@ DEC2HEX | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::DECTOHE DEC2OCT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::DECTOOCT DELTA | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::DELTA ERF | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERF +ERF.PRECISE | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFPRECISE ERFC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFC +ERFC.PRECISE | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFC GESTEP | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::GESTEP HEX2BIN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTOBIN HEX2DEC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTODEC @@ -83,6 +86,10 @@ IMAGINARY | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMAGINA IMARGUMENT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMARGUMENT IMCONJUGATE | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCONJUGATE IMCOS | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOS +IMCOSH | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOSH +IMCOT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOT +IMCSC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCSC +IMCSCH | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCSCH IMDIV | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMDIV IMEXP | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMEXP IMLN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMLN @@ -91,10 +98,14 @@ IMLOG2 | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMLOG2 IMPOWER | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMPOWER IMPRODUCT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMPRODUCT IMREAL | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMREAL +IMSEC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSEC +IMSECH | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSECH IMSIN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSIN +IMSINH | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSINH IMSQRT | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSQRT IMSUB | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSUB IMSUM | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSUM +IMTAN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMTAN OCT2BIN | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::OCTTOBIN OCT2DEC | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::OCTTODEC OCT2HEX | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::OCTTOHEX @@ -137,6 +148,7 @@ ODDFPRICE | **Not yet Implemented** ODDFYIELD | **Not yet Implemented** ODDLPRICE | **Not yet Implemented** ODDLYIELD | **Not yet Implemented** +PDURATION | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PDURATION PMT | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PMT PPMT | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PPMT PRICE | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PRICE @@ -145,6 +157,7 @@ PRICEMAT | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PRICEMAT PV | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PV RATE | \PhpOffice\PhpSpreadsheet\Calculation\Financial::RATE RECEIVED | \PhpOffice\PhpSpreadsheet\Calculation\Financial::RECEIVED +RRI | \PhpOffice\PhpSpreadsheet\Calculation\Financial::RRI SLN | \PhpOffice\PhpSpreadsheet\Calculation\Financial::SLN SYD | \PhpOffice\PhpSpreadsheet\Calculation\Financial::SYD TBILLEQ | \PhpOffice\PhpSpreadsheet\Calculation\Financial::TBILLEQ @@ -169,6 +182,7 @@ ISBLANK | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_BLANK ISERR | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ERR ISERROR | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ERROR ISEVEN | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_EVEN +ISFORMULA | \PhpOffice\PhpSpreadsheet\Calculation\Functions::ISFORMULA ISLOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_LOGICAL ISNA | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NA ISNONTEXT | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NONTEXT @@ -184,13 +198,14 @@ TYPE | \PhpOffice\PhpSpreadsheet\Calculation\Functions::TYPE Excel Function | PhpSpreadsheet Function --------------------|------------------------------------------- -AND | \PhpOffice\PhpSpreadsheet\Calculation\Logical::LOGICAL_AND +AND | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalAnd FALSE | \PhpOffice\PhpSpreadsheet\Calculation\Logical::FALSE IF | \PhpOffice\PhpSpreadsheet\Calculation\Logical::STATEMENT_IF IFERROR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::IFERROR NOT | \PhpOffice\PhpSpreadsheet\Calculation\Logical::NOT -OR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::LOGICAL_OR +OR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalOr TRUE | \PhpOffice\PhpSpreadsheet\Calculation\Logical::TRUE +XOR | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalXor ## CATEGORY_LOOKUP_AND_REFERENCE @@ -201,8 +216,9 @@ AREAS | **Not yet Implemented** CHOOSE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::CHOOSE COLUMN | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::COLUMN COLUMNS | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::COLUMNS +FORMULATEXT | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::FORMULATEXT GETPIVOTDATA | **Not yet Implemented** -HLOOKUP | **Not yet Implemented** +HLOOKUP | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::HLOOKUP HYPERLINK | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::HYPERLINK INDEX | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDEX INDIRECT | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDIRECT @@ -222,6 +238,8 @@ Excel Function | PhpSpreadsheet Function ABS | abs ACOS | acos ACOSH | acosh +ACOT | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ACOT +ACOTH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ACOTH ASIN | asin ASINH | asinh ATAN | atan @@ -231,6 +249,10 @@ CEILING | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CEILING COMBIN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COMBIN COS | cos COSH | cosh +COT | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COT +COTH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COTH +CSC | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CSC +CSCH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CSCH DEGREES | rad2deg EVEN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::EVEN EXP | exp @@ -261,6 +283,8 @@ ROMAN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ROMAN ROUND | round ROUNDDOWN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ROUNDDOWN ROUNDUP | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ROUNDUP +SEC | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SEC +SECH | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SECH SERIESSUM | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SERIESSUM SIGN | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SIGN SIN | sin @@ -270,7 +294,7 @@ SQRTPI | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SQRTPI SUBTOTAL | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUBTOTAL SUM | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUM SUMIF | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMIF -SUMIFS | **Not yet Implemented** +SUMIFS | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMIFS SUMPRODUCT | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMPRODUCT SUMSQ | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMSQ SUMX2MY2 | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMX2MY2 @@ -336,6 +360,7 @@ MIN | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MIN MINA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MINA MINIF | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MINIF MODE | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MODE +MODE.SNGL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MODE NEGBINOMDIST | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::NEGBINOMDIST NORMDIST | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::NORMDIST NORMINV | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::NORMINV @@ -355,6 +380,8 @@ SLOPE | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::SLOPE SMALL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::SMALL STANDARDIZE | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STANDARDIZE STDEV | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEV +STDEV.S | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEV +STDEV.P | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVP STDEVA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVA STDEVP | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVP STDEVPA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVPA @@ -365,6 +392,8 @@ TREND | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::TREND TRIMMEAN | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::TRIMMEAN TTEST | **Not yet Implemented** VAR | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARFunc +VAR.P | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARP +VAR.S | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARFunc VARA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARA VARP | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARP VARPA | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARPA @@ -380,9 +409,10 @@ BAHTTEXT | **Not yet Implemented** CHAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CHARACTER CLEAN | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TRIMNONPRINTABLE CODE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::ASCIICODE +CONCAT | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CONCATENATE CONCATENATE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CONCATENATE DOLLAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData::DOLLAR -EXACT | **Not yet Implemented** +EXACT | \PhpOffice\PhpSpreadsheet\Calculation\TextData::EXACT FIND | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHSENSITIVE FINDB | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHSENSITIVE FIXED | \PhpOffice\PhpSpreadsheet\Calculation\TextData::FIXEDFORMAT @@ -394,6 +424,7 @@ LENB | \PhpOffice\PhpSpreadsheet\Calculation\TextData::STRINGLENG LOWER | \PhpOffice\PhpSpreadsheet\Calculation\TextData::LOWERCASE MID | \PhpOffice\PhpSpreadsheet\Calculation\TextData::MID MIDB | \PhpOffice\PhpSpreadsheet\Calculation\TextData::MID +NUMBERVALUE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::NUMBERVALUE PHONETIC | **Not yet Implemented** PROPER | \PhpOffice\PhpSpreadsheet\Calculation\TextData::PROPERCASE REPLACE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::REPLACE @@ -406,6 +437,9 @@ SEARCHB | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHINSE SUBSTITUTE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SUBSTITUTE T | \PhpOffice\PhpSpreadsheet\Calculation\TextData::RETURNSTRING TEXT | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TEXTFORMAT +TEXTJOIN | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TEXTJOIN TRIM | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TRIMSPACES +UNICHAR | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CHARACTER +UNICODE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::ASCIICODE UPPER | \PhpOffice\PhpSpreadsheet\Calculation\TextData::UPPERCASE -VALUE | **Not yet Implemented** +VALUE | \PhpOffice\PhpSpreadsheet\Calculation\TextData::VALUE diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/references/function-list-by-name.md b/inc/vendor/phpoffice/phpspreadsheet/docs/references/function-list-by-name.md index 8b7ad95..a8caca6 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/references/function-list-by-name.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/references/function-list-by-name.md @@ -9,10 +9,12 @@ ACCRINT | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet ACCRINTM | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::ACCRINTM ACOS | CATEGORY_MATH_AND_TRIG | acos ACOSH | CATEGORY_MATH_AND_TRIG | acosh +ACOT | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ACOT +ACOTH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ACOTH ADDRESS | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::CELL_ADDRESS AMORDEGRC | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::AMORDEGRC AMORLINC | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::AMORLINC -AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::LOGICAL_AND +AND | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalAnd AREAS | CATEGORY_LOOKUP_AND_REFERENCE | **Not yet Implemented** ASC | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** ASIN | CATEGORY_MATH_AND_TRIG | asin @@ -59,12 +61,15 @@ COLUMN | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet COLUMNS | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::COLUMNS COMBIN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COMBIN COMPLEX | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::COMPLEX +CONCAT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CONCATENATE CONCATENATE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CONCATENATE CONFIDENCE | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::CONFIDENCE CONVERT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::CONVERTUOM CORREL | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::CORREL COS | CATEGORY_MATH_AND_TRIG | cos COSH | CATEGORY_MATH_AND_TRIG | cosh +COT | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COT +COTH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::COTH COUNT | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::COUNT COUNTA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::COUNTA COUNTBLANK | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::COUNTBLANK @@ -78,6 +83,8 @@ COUPNUM | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet COUPPCD | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::COUPPCD COVAR | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::COVAR CRITBINOM | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::CRITBINOM +CSC | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CSC +CSCH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::CSCH CUBEKPIMEMBER | CATEGORY_CUBE | **Not yet Implemented** CUBEMEMBER | CATEGORY_CUBE | **Not yet Implemented** CUBEMEMBERPROPERTY | CATEGORY_CUBE | **Not yet Implemented** @@ -131,10 +138,12 @@ EDATE | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet EFFECT | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::EFFECT EOMONTH | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::EOMONTH ERF | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERF +ERF.PRECISE | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFPRECISE ERFC | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFC +ERFC.PRECISE | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::ERFC ERROR.TYPE | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::ERROR_TYPE EVEN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::EVEN -EXACT | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** +EXACT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::EXACT EXP | CATEGORY_MATH_AND_TRIG | exp EXPONDIST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::EXPONDIST @@ -154,6 +163,7 @@ FISHERINV | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet FIXED | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::FIXEDFORMAT FLOOR | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::FLOOR FORECAST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::FORECAST +FORMULATEXT | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::FORMULATEXT FREQUENCY | CATEGORY_STATISTICAL | **Not yet Implemented** FTEST | CATEGORY_STATISTICAL | **Not yet Implemented** FV | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::FV @@ -180,7 +190,7 @@ HARMEAN | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet HEX2BIN | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTOBIN HEX2DEC | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTODEC HEX2OCT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::HEXTOOCT -HLOOKUP | CATEGORY_LOOKUP_AND_REFERENCE | **Not yet Implemented** +HLOOKUP | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::HLOOKUP HOUR | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::HOUROFDAY HYPERLINK | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::HYPERLINK HYPGEOMDIST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::HYPGEOMDIST @@ -196,6 +206,10 @@ IMAGINARY | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet IMARGUMENT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMARGUMENT IMCONJUGATE | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCONJUGATE IMCOS | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOS +IMCOSH | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOSH +IMCOT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCOT +IMCSC | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCSC +IMCSCH | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMCSCH IMDIV | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMDIV IMEXP | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMEXP IMLN | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMLN @@ -204,10 +218,14 @@ IMLOG2 | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet IMPOWER | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMPOWER IMPRODUCT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMPRODUCT IMREAL | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMREAL +IMSEC | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSEC +IMSECH | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSECH IMSIN | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSIN +IMSINH | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSINH IMSQRT | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSQRT IMSUB | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSUB IMSUM | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMSUM +IMTAN | CATEGORY_ENGINEERING | \PhpOffice\PhpSpreadsheet\Calculation\Engineering::IMTAN INDEX | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDEX INDIRECT | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::INDIRECT INFO | CATEGORY_INFORMATION | **Not yet Implemented** @@ -220,11 +238,13 @@ ISBLANK | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet ISERR | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ERR ISERROR | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ERROR ISEVEN | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_EVEN +ISFORMULA | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::ISFORMULA ISLOGICAL | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_LOGICAL ISNA | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NA ISNONTEXT | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NONTEXT ISNUMBER | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_NUMBER ISODD | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_ODD +ISOWEEKNUM | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::ISOWEEKNUM ISPMT | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::ISPMT ISREF | CATEGORY_INFORMATION | **Not yet Implemented** ISTEXT | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet\Calculation\Functions::IS_TEXT @@ -284,6 +304,7 @@ MIRR | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet MMULT | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::MMULT MOD | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::MOD MODE | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MODE +MODE.SNGL | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::MODE MONTH | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::MONTHOFYEAR MROUND | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::MROUND MULTINOMIAL | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::MULTINOMIAL @@ -305,6 +326,7 @@ NOT | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet NOW | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::DATETIMENOW NPER | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::NPER NPV | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::NPV +NUMBERVALUE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::NUMBERVALUE ## O @@ -319,12 +341,13 @@ ODDFYIELD | CATEGORY_FINANCIAL | **Not yet Implemented** ODDLPRICE | CATEGORY_FINANCIAL | **Not yet Implemented** ODDLYIELD | CATEGORY_FINANCIAL | **Not yet Implemented** OFFSET | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::OFFSET -OR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::LOGICAL_OR +OR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalOr ## P Excel Function | Category | PhpSpreadsheet Function --------------------|--------------------------------|------------------------------------------- +PDURATION | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::PDURATION PEARSON | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::CORREL PERCENTILE | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::PERCENTILE PERCENTRANK | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::PERCENTRANK @@ -371,6 +394,7 @@ ROUNDDOWN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet ROUNDUP | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::ROUNDUP ROW | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::ROW ROWS | CATEGORY_LOOKUP_AND_REFERENCE | \PhpOffice\PhpSpreadsheet\Calculation\LookupRef::ROWS +RRI | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::RRI RSQ | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::RSQ RTD | CATEGORY_LOOKUP_AND_REFERENCE | **Not yet Implemented** @@ -380,6 +404,8 @@ Excel Function | Category | PhpSpreadsheet Function --------------------|--------------------------------|------------------------------------------- SEARCH | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHINSENSITIVE SEARCHB | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::SEARCHINSENSITIVE +SEC | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SEC +SECH | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SECH SECOND | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::SECOND SERIESSUM | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SERIESSUM SIGN | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SIGN @@ -393,6 +419,8 @@ SQRT | CATEGORY_MATH_AND_TRIG | sqrt SQRTPI | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SQRTPI STANDARDIZE | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STANDARDIZE STDEV | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEV +STDEV.S | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEV +STDEV.P | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVP STDEVA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVA STDEVP | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVP STDEVPA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::STDEVPA @@ -401,7 +429,7 @@ SUBSTITUTE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet SUBTOTAL | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUBTOTAL SUM | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUM SUMIF | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMIF -SUMIFS | CATEGORY_MATH_AND_TRIG | **Not yet Implemented** +SUMIFS | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMIFS SUMPRODUCT | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMPRODUCT SUMSQ | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMSQ SUMX2MY2 | CATEGORY_MATH_AND_TRIG | \PhpOffice\PhpSpreadsheet\Calculation\MathTrig::SUMX2MY2 @@ -421,6 +449,7 @@ TBILLPRICE | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet TBILLYIELD | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::TBILLYIELD TDIST | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::TDIST TEXT | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TEXTFORMAT +TEXTJOIN | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::TEXTJOIN TIME | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::TIME TIMEVALUE | CATEGORY_DATE_AND_TIME | \PhpOffice\PhpSpreadsheet\Calculation\DateTime::TIMEVALUE TINV | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::TINV @@ -438,6 +467,8 @@ TYPE | CATEGORY_INFORMATION | \PhpOffice\PhpSpreadsheet Excel Function | Category | PhpSpreadsheet Function --------------------|--------------------------------|------------------------------------------- +UNICHAR | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::CHARACTER +UNICODE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::ASCIICODE UPPER | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::UPPERCASE USDOLLAR | CATEGORY_FINANCIAL | **Not yet Implemented** @@ -445,8 +476,10 @@ USDOLLAR | CATEGORY_FINANCIAL | **Not yet Implemented** Excel Function | Category | PhpSpreadsheet Function --------------------|--------------------------------|------------------------------------------- -VALUE | CATEGORY_TEXT_AND_DATA | **Not yet Implemented** +VALUE | CATEGORY_TEXT_AND_DATA | \PhpOffice\PhpSpreadsheet\Calculation\TextData::VALUE VAR | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARFunc +VAR.P | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARP +VAR.S | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARFunc VARA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARA VARP | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARP VARPA | CATEGORY_STATISTICAL | \PhpOffice\PhpSpreadsheet\Calculation\Statistical::VARPA @@ -468,6 +501,8 @@ Excel Function | Category | PhpSpreadsheet Function --------------------|--------------------------------|------------------------------------------- XIRR | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::XIRR XNPV | CATEGORY_FINANCIAL | \PhpOffice\PhpSpreadsheet\Calculation\Financial::XNPV +XOR | CATEGORY_LOGICAL | \PhpOffice\PhpSpreadsheet\Calculation\Logical::logicalXor + ## Y diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/accessing-cells.md b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/accessing-cells.md index c85fb0f..f14e2bd 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/accessing-cells.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/accessing-cells.md @@ -426,9 +426,9 @@ for ($row = 1; $row <= $highestRow; ++$row) { echo '' . PHP_EOL; ``` -Note that we can't use a <= comparison here, because 'AA' would match -as <= 'B', so we increment the highest column letter and then loop -while \$col != the incremented highest column. +Note that we can't use a `<=` comparison here, because `'AA'` would match +as `<= 'B'`, so we increment the highest column letter and then loop +while `$col !=` the incremented highest column. ## Using value binders to facilitate data entry diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/autofilters.md b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/autofilters.md index f7c9421..66321ee 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/autofilters.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/autofilters.md @@ -285,8 +285,8 @@ $columnFilter->createRule() We also set the rule type to CUSTOMFILTER. -This defined two rules, filtering numbers that are >= -20 OR <= -20, so we also need to modify the join condition to reflect AND rather +This defined two rules, filtering numbers that are `>= -20` OR `<= +20`, so we also need to modify the join condition to reflect AND rather than OR. ``` php diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/reading-and-writing-to-file.md b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/reading-and-writing-to-file.md index d9cb9a7..cf58e54 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/reading-and-writing-to-file.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/reading-and-writing-to-file.md @@ -634,16 +634,16 @@ $writer->setSheetIndex(0); #### Setting the images root of the HTML file There might be situations where you want to explicitly set the included -images root. For example, one might want to see +images root. For example, instead of: + + ``` html + + ``` + +You might want to see: ``` html - -``` - -instead of - -``` html -. + ``` You can use the following code to achieve this result: diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/recipes.md b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/recipes.md index 0c6c313..0b40cf3 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/recipes.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/recipes.md @@ -3,12 +3,12 @@ The following pages offer you some widely-used PhpSpreadsheet recipes. Please note that these do NOT offer complete documentation on specific PhpSpreadsheet API functions, but just a bump to get you started. If you -need specific API functions, please refer to the API documentation. +need specific API functions, please refer to the [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master). For example, [setting a worksheet's page orientation and size ](#setting-a-worksheets-page-orientation-and-size) covers setting a page orientation to A4. Other paper formats, like US Letter, are not covered -in this document, but in the PhpSpreadsheet API documentation. +in this document, but in the PhpSpreadsheet [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master). ## Setting a spreadsheet's metadata @@ -132,7 +132,7 @@ will take care of displaying the formula according the applications language. Translation is taken care of by the application! The following line of code writes the formula -`=IF(C4>500,"profit","loss")` into the cell B8. Note that the +`=IF(C4>500,"profit","loss")` into the cell B8. Note that the formula must start with `=` to make PhpSpreadsheet recognise this as a formula. @@ -301,7 +301,7 @@ $spreadsheet->getActiveSheet()->getPageSetup() ``` Note that there are additional page settings available. Please refer to -the API documentation for all possible options. +the [API documentation](https://phpoffice.github.io/PhpSpreadsheet/master) for all possible options. ### Page Setup: Scaling options diff --git a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/worksheets.md b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/worksheets.md index 6100d3a..f97a006 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/docs/topics/worksheets.md +++ b/inc/vendor/phpoffice/phpspreadsheet/docs/topics/worksheets.md @@ -31,8 +31,6 @@ index, use the `getSheet()` method. $spreadsheet->getSheet(1); ``` -If you don't specify a sheet index, then the first worksheet will be -returned. Methods also exist allowing you to reorder the worksheets in the workbook. @@ -71,7 +69,7 @@ $spreadsheet->createSheet(); ``` A new worksheet created using this method will be called -"Worksheet<n>" where "<n>" is the lowest number possible to +`Worksheet` where `` is the lowest number possible to guarantee that the title is unique. Alternatively, you can instantiate a new worksheet (setting the title to diff --git a/inc/vendor/phpoffice/phpspreadsheet/mkdocs.yml b/inc/vendor/phpoffice/phpspreadsheet/mkdocs.yml index 0062000..1a224f5 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/mkdocs.yml +++ b/inc/vendor/phpoffice/phpspreadsheet/mkdocs.yml @@ -5,7 +5,3 @@ edit_uri: edit/develop/docs/ theme: readthedocs extra_css: - extra/extra.css - -extra_javascript: - - extra/extra.js - \ No newline at end of file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_1.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_1.php index 4f1fc48..30efc19 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_1.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_1.php @@ -125,7 +125,7 @@ $autoFilter->getColumn('C') ) ->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); // Filter the Date column on a filter value of the first day of every period of the current year -// We us a dateGroup ruletype for this, although it is still a standard filter +// We us a dateGroup ruletype for this, although it is still a standard filter foreach ($periods as $period) { $endDate = date('t', mktime(0, 0, 0, $period, 1, $currentYear)); diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_2.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_2.php index 63f11a2..1520c97 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_2.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_2.php @@ -108,7 +108,7 @@ $spreadsheet->getActiveSheet()->setAutoFilter($spreadsheet->getActiveSheet()->ca $autoFilter = $spreadsheet->getActiveSheet()->getAutoFilter(); $helper->log('Set active filters'); // Filter the Country column on a filter value of Germany -// As it's just a simple value filter, we can use FILTERTYPE_FILTER +// As it's just a simple value filter, we can use FILTERTYPE_FILTER $autoFilter->getColumn('C') ->setFilterType(Column::AUTOFILTER_FILTERTYPE_FILTER) ->createRule() diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_display.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_display.php index b2b77b7..50986bf 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_display.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Autofilter/10_Autofilter_selection_display.php @@ -125,7 +125,7 @@ $autoFilter->getColumn('C') ) ->setRuleType(Rule::AUTOFILTER_RULETYPE_CUSTOMFILTER); // Filter the Date column on a filter value of the first day of every period of the current year -// We us a dateGroup ruletype for this, although it is still a standard filter +// We us a dateGroup ruletype for this, although it is still a standard filter foreach ($periods as $period) { $endDate = date('t', mktime(0, 0, 0, $period, 1, $currentYear)); diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Basic/08_Conditional_formatting.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Basic/08_Conditional_formatting.php index 0ad45c3..2f54863 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Basic/08_Conditional_formatting.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Basic/08_Conditional_formatting.php @@ -84,7 +84,7 @@ $conditionalStyles[] = $conditional2; $conditionalStyles[] = $conditional3; $spreadsheet->getActiveSheet()->getStyle('B2')->setConditionalStyles($conditionalStyles); -// duplicate the conditional styles across a range of cells +// duplicate the conditional styles across a range of cells $helper->log('Duplicate the conditional formatting across a range of cells'); $spreadsheet->getActiveSheet()->duplicateConditionalStyle( $spreadsheet->getActiveSheet()->getStyle('B2')->getConditionalStyles(), diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Basic/08_Conditional_formatting_2.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Basic/08_Conditional_formatting_2.php index 607578c..818cdd9 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Basic/08_Conditional_formatting_2.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Basic/08_Conditional_formatting_2.php @@ -59,7 +59,7 @@ $conditionalStyles[] = $conditional1; $conditionalStyles[] = $conditional3; $spreadsheet->getActiveSheet()->getStyle('A1')->setConditionalStyles($conditionalStyles); -// duplicate the conditional styles across a range of cells +// duplicate the conditional styles across a range of cells $helper->log('Duplicate the conditional formatting across a range of cells'); $spreadsheet->getActiveSheet()->duplicateConditionalStyle( $spreadsheet->getActiveSheet()->getStyle('A1')->getConditionalStyles(), diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/32_Chart_read_write_HTML.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/32_Chart_read_write_HTML.php index 8071edd..5febbf9 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/32_Chart_read_write_HTML.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/32_Chart_read_write_HTML.php @@ -5,7 +5,7 @@ use PhpOffice\PhpSpreadsheet\Settings; require __DIR__ . '/../Header.php'; -// Change these values to select the Rendering library that you wish to use +// Change these values to select the Rendering library that you wish to use Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class); $inputFileType = 'Xlsx'; diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/32_Chart_read_write_PDF.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/32_Chart_read_write_PDF.php index 7cc5156..ee3ad0e 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/32_Chart_read_write_PDF.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/32_Chart_read_write_PDF.php @@ -7,7 +7,7 @@ require __DIR__ . '/../Header.php'; IOFactory::registerWriter('Pdf', \PhpOffice\PhpSpreadsheet\Writer\Pdf\Mpdf::class); -// Change these values to select the Rendering library that you wish to use +// Change these values to select the Rendering library that you wish to use Settings::setChartRenderer(\PhpOffice\PhpSpreadsheet\Chart\Renderer\JpGraph::class); $inputFileType = 'Xlsx'; diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_area.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_area.php index f44232f..4478d2d 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_area.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_area.php @@ -23,42 +23,42 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_AREACHART, // plotType DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping @@ -68,15 +68,15 @@ $series = new DataSeries( $dataSeriesValues // plotValues ); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_TOPRIGHT, null, false); $title = new Title('Test %age-Stacked Area Chart'); $yAxisLabel = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -88,11 +88,11 @@ $chart = new Chart( $yAxisLabel // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('A7'); $chart->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_bar_stacked.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_bar_stacked.php index 16654a1..7ba4d8d 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_bar_stacked.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_bar_stacked.php @@ -23,42 +23,42 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_BARCHART, // plotType DataSeries::GROUPING_STACKED, // plotGrouping @@ -67,19 +67,19 @@ $series = new DataSeries( $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); -// Set additional dataseries parameters -// Make it a horizontal bar rather than a vertical column graph +// Set additional dataseries parameters +// Make it a horizontal bar rather than a vertical column graph $series->setPlotDirection(DataSeries::DIRECTION_BAR); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_RIGHT, null, false); $title = new Title('Test Chart'); $yAxisLabel = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -91,11 +91,11 @@ $chart = new Chart( $yAxisLabel // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('A7'); $chart->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_column.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_column.php index bc67644..9ffe9d3 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_column.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_column.php @@ -23,42 +23,42 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_BARCHART, // plotType DataSeries::GROUPING_STANDARD, // plotGrouping @@ -67,19 +67,19 @@ $series = new DataSeries( $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); -// Set additional dataseries parameters -// Make it a vertical column rather than a horizontal bar graph +// Set additional dataseries parameters +// Make it a vertical column rather than a horizontal bar graph $series->setPlotDirection(DataSeries::DIRECTION_COL); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_RIGHT, null, false); $title = new Title('Test Column Chart'); $yAxisLabel = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -91,11 +91,11 @@ $chart = new Chart( $yAxisLabel // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('A7'); $chart->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_column_2.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_column_2.php index a00b23b..bba9210 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_column_2.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_column_2.php @@ -31,42 +31,42 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 'Budget' - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 'Forecast' - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E$1', null, 1), // 'Actual' + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 'Budget' + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 'Forecast' + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E$1', null, 1), // 'Actual' ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$B$13', null, 12), // Q1 to Q4 for 2010 to 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$B$13', null, 12), // Q1 to Q4 for 2010 to 2012 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$13', null, 12), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$13', null, 12), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$E$2:$E$13', null, 12), ]; -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_BARCHART, // plotType DataSeries::GROUPING_CLUSTERED, // plotGrouping @@ -75,20 +75,20 @@ $series = new DataSeries( $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); -// Set additional dataseries parameters -// Make it a vertical column rather than a horizontal bar graph +// Set additional dataseries parameters +// Make it a vertical column rather than a horizontal bar graph $series->setPlotDirection(DataSeries::DIRECTION_COL); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_BOTTOM, null, false); $title = new Title('Test Grouped Column Chart'); $xAxisLabel = new Title('Financial Period'); $yAxisLabel = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -100,11 +100,11 @@ $chart = new Chart( $yAxisLabel // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('G2'); $chart->setBottomRightPosition('P20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_composite.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_composite.php index 272048d..83dc34a 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_composite.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_composite.php @@ -31,46 +31,46 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels1 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // Temperature + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // Temperature ]; $dataSeriesLabels2 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // Rainfall + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // Rainfall ]; $dataSeriesLabels3 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // Humidity + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // Humidity ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues1 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$13', null, 12), ]; -// Build the dataseries +// Build the dataseries $series1 = new DataSeries( DataSeries::TYPE_BARCHART, // plotType DataSeries::GROUPING_CLUSTERED, // plotGrouping @@ -79,22 +79,22 @@ $series1 = new DataSeries( $xAxisTickValues, // plotCategory $dataSeriesValues1 // plotValues ); -// Set additional dataseries parameters -// Make it a vertical column rather than a horizontal bar graph +// Set additional dataseries parameters +// Make it a vertical column rather than a horizontal bar graph $series1->setPlotDirection(DataSeries::DIRECTION_COL); -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues2 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$13', null, 12), ]; -// Build the dataseries +// Build the dataseries $series2 = new DataSeries( DataSeries::TYPE_LINECHART, // plotType DataSeries::GROUPING_STANDARD, // plotGrouping @@ -104,18 +104,18 @@ $series2 = new DataSeries( $dataSeriesValues2 // plotValues ); -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues3 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$13', null, 12), ]; -// Build the dataseries +// Build the dataseries $series3 = new DataSeries( DataSeries::TYPE_AREACHART, // plotType DataSeries::GROUPING_STANDARD, // plotGrouping @@ -125,14 +125,14 @@ $series3 = new DataSeries( $dataSeriesValues3 // plotValues ); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series1, $series2, $series3]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_RIGHT, null, false); $title = new Title('Average Weather Chart for Crete'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -144,11 +144,11 @@ $chart = new Chart( null // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('F2'); $chart->setBottomRightPosition('O16'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_line.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_line.php index 3961d70..bdaf011 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_line.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_line.php @@ -23,35 +23,35 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), @@ -59,7 +59,7 @@ $dataSeriesValues = [ ]; $dataSeriesValues[2]->setLineWidth(60000); -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_LINECHART, // plotType DataSeries::GROUPING_STACKED, // plotGrouping @@ -69,15 +69,15 @@ $series = new DataSeries( $dataSeriesValues // plotValues ); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_TOPRIGHT, null, false); $title = new Title('Test Stacked Line Chart'); $yAxisLabel = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -89,11 +89,11 @@ $chart = new Chart( $yAxisLabel // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('A7'); $chart->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_multiple_charts.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_multiple_charts.php index b907a39..10a11e1 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_multiple_charts.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_multiple_charts.php @@ -23,42 +23,42 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels1 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues1 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues1 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series1 = new DataSeries( DataSeries::TYPE_AREACHART, // plotType DataSeries::GROUPING_PERCENT_STACKED, // plotGrouping @@ -68,15 +68,15 @@ $series1 = new DataSeries( $dataSeriesValues1 // plotValues ); -// Set the series in the plot area +// Set the series in the plot area $plotArea1 = new PlotArea(null, [$series1]); -// Set the chart legend +// Set the chart legend $legend1 = new Legend(Legend::POSITION_TOPRIGHT, null, false); $title1 = new Title('Test %age-Stacked Area Chart'); $yAxisLabel1 = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart1 = new Chart( 'chart1', // name $title1, // title @@ -88,49 +88,49 @@ $chart1 = new Chart( $yAxisLabel1 // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart1->setTopLeftPosition('A7'); $chart1->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart1); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels2 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues2 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues2 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series2 = new DataSeries( DataSeries::TYPE_BARCHART, // plotType DataSeries::GROUPING_STANDARD, // plotGrouping @@ -139,19 +139,19 @@ $series2 = new DataSeries( $xAxisTickValues2, // plotCategory $dataSeriesValues2 // plotValues ); -// Set additional dataseries parameters -// Make it a vertical column rather than a horizontal bar graph +// Set additional dataseries parameters +// Make it a vertical column rather than a horizontal bar graph $series2->setPlotDirection(DataSeries::DIRECTION_COL); -// Set the series in the plot area +// Set the series in the plot area $plotArea2 = new PlotArea(null, [$series2]); -// Set the chart legend +// Set the chart legend $legend2 = new Legend(Legend::POSITION_RIGHT, null, false); $title2 = new Title('Test Column Chart'); $yAxisLabel2 = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart2 = new Chart( 'chart2', // name $title2, // title @@ -163,11 +163,11 @@ $chart2 = new Chart( $yAxisLabel2 // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart2->setTopLeftPosition('I7'); $chart2->setBottomRightPosition('P20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart2); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_pie.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_pie.php index 4972644..d4ec075 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_pie.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_pie.php @@ -24,38 +24,38 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels1 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues1 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues1 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series1 = new DataSeries( DataSeries::TYPE_PIECHART, // plotType null, // plotGrouping (Pie charts don't have any grouping) @@ -65,19 +65,19 @@ $series1 = new DataSeries( $dataSeriesValues1 // plotValues ); -// Set up a layout object for the Pie chart +// Set up a layout object for the Pie chart $layout1 = new Layout(); $layout1->setShowVal(true); $layout1->setShowPercent(true); -// Set the series in the plot area +// Set the series in the plot area $plotArea1 = new PlotArea($layout1, [$series1]); -// Set the chart legend +// Set the chart legend $legend1 = new Legend(Legend::POSITION_RIGHT, null, false); $title1 = new Title('Test Pie Chart'); -// Create the chart +// Create the chart $chart1 = new Chart( 'chart1', // name $title1, // title @@ -86,48 +86,48 @@ $chart1 = new Chart( true, // plotVisibleOnly 0, // displayBlanksAs null, // xAxisLabel - null // yAxisLabel - Pie charts don't have a Y-Axis + null // yAxisLabel - Pie charts don't have a Y-Axis ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart1->setTopLeftPosition('A7'); $chart1->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart1); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels2 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues2 = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues2 = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series2 = new DataSeries( DataSeries::TYPE_DONUTCHART, // plotType null, // plotGrouping (Donut charts don't have any grouping) @@ -137,17 +137,17 @@ $series2 = new DataSeries( $dataSeriesValues2 // plotValues ); -// Set up a layout object for the Pie chart +// Set up a layout object for the Pie chart $layout2 = new Layout(); $layout2->setShowVal(true); $layout2->setShowCatName(true); -// Set the series in the plot area +// Set the series in the plot area $plotArea2 = new PlotArea($layout2, [$series2]); $title2 = new Title('Test Donut Chart'); -// Create the chart +// Create the chart $chart2 = new Chart( 'chart2', // name $title2, // title @@ -156,14 +156,14 @@ $chart2 = new Chart( true, // plotVisibleOnly 0, // displayBlanksAs null, // xAxisLabel - null // yAxisLabel - Like Pie charts, Donut charts don't have a Y-Axis + null // yAxisLabel - Like Pie charts, Donut charts don't have a Y-Axis ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart2->setTopLeftPosition('I7'); $chart2->setBottomRightPosition('P20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart2); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_radar.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_radar.php index 9d05f85..e57914a 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_radar.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_radar.php @@ -32,41 +32,41 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$13', null, 12), // Jan to Dec ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$13', null, 12), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$13', null, 12), ]; -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_RADARCHART, // plotType null, // plotGrouping (Radar charts don't have any grouping) @@ -79,17 +79,17 @@ $series = new DataSeries( DataSeries::STYLE_MARKER // plotStyle ); -// Set up a layout object for the Pie chart +// Set up a layout object for the Pie chart $layout = new Layout(); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea($layout, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_RIGHT, null, false); $title = new Title('Test Radar Chart'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -98,14 +98,14 @@ $chart = new Chart( true, // plotVisibleOnly 0, // displayBlanksAs null, // xAxisLabel - null // yAxisLabel - Radar charts don't have a Y-Axis + null // yAxisLabel - Radar charts don't have a Y-Axis ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('F2'); $chart->setBottomRightPosition('M15'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_scatter.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_scatter.php index 2070fe2..12fc2bd 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_scatter.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_scatter.php @@ -23,36 +23,36 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels +// Set the X-Axis Labels $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_SCATTERCHART, // plotType null, // plotGrouping (Scatter charts don't have any grouping) @@ -65,15 +65,15 @@ $series = new DataSeries( DataSeries::STYLE_LINEMARKER // plotStyle ); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_TOPRIGHT, null, false); $title = new Title('Test Scatter Chart'); $yAxisLabel = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -85,11 +85,11 @@ $chart = new Chart( $yAxisLabel // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('A7'); $chart->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_stock.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_stock.php index 2342d1a..7a9f727 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_stock.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Chart/33_Chart_create_stock.php @@ -29,36 +29,36 @@ $worksheet->fromArray( ); $worksheet->getStyle('B2:E6')->getNumberFormat()->setFormatCode(NumberFormat::FORMAT_NUMBER_00); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), //Max / Open new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), //Min / Close new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), //Min Threshold / Min new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$E$1', null, 1), //Max Threshold / Max ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$6', null, 5), // Counts + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$6', null, 5), // Counts ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$6', null, 5), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$6', null, 5), @@ -66,7 +66,7 @@ $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$E$2:$E$6', null, 5), ]; -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_STOCKCHART, // plotType null, // plotGrouping - if we set this to not null, then xlsx throws error @@ -76,16 +76,16 @@ $series = new DataSeries( $dataSeriesValues // plotValues ); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_RIGHT, null, false); $title = new Title('Test Stock Chart'); $xAxisLabel = new Title('Counts'); $yAxisLabel = new Title('Values'); -// Create the chart +// Create the chart $chart = new Chart( 'stock-chart', // name $title, // title @@ -97,11 +97,11 @@ $chart = new Chart( $yAxisLabel // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('A7'); $chart->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); // Save Excel 2007 file diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php b/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php index 892ab33..1856221 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/11_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_1).php @@ -57,7 +57,7 @@ for ($startRow = 2; $startRow <= 240; $startRow += $chunkSize) { // Load only the rows that match our filter from $inputFileName to a PhpSpreadsheet Object $spreadsheet = $reader->load($inputFileName); - // Do some processing here + // Do some processing here $sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true); var_dump($sheetData); diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php b/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php index 0a3e8f3..1f39ec4 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/12_Reading_a_workbook_in_chunks_using_a_configurable_read_filter_(version_2).php @@ -60,7 +60,7 @@ for ($startRow = 2; $startRow <= 240; $startRow += $chunkSize) { // Load only the rows that match our filter from $inputFileName to a PhpSpreadsheet Object $spreadsheet = $reader->load($inputFileName); - // Do some processing here + // Do some processing here $sheetData = $spreadsheet->getActiveSheet()->toArray(null, true, true, true); var_dump($sheetData); diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/20_Reader_worksheet_hyperlink_image.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/20_Reader_worksheet_hyperlink_image.php new file mode 100644 index 0000000..0636e46 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Reader/20_Reader_worksheet_hyperlink_image.php @@ -0,0 +1,54 @@ +log('Start'); + +$spreadsheet = new Spreadsheet(); + +$aSheet = $spreadsheet->getActiveSheet(); + +$gdImage = @imagecreatetruecolor(120, 20); +$textColor = imagecolorallocate($gdImage, 255, 255, 255); +imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor); + +$baseUrl = 'https://phpspreadsheet.readthedocs.io/'; + +$drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing(); +$drawing->setName('In-Memory image 1'); +$drawing->setDescription('In-Memory image 1'); +$drawing->setCoordinates('A1'); +$drawing->setImageResource($gdImage); +$drawing->setRenderingFunction( + \PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::RENDERING_JPEG +); +$drawing->setMimeType(\PhpOffice\PhpSpreadsheet\Worksheet\MemoryDrawing::MIMETYPE_DEFAULT); +$drawing->setHeight(36); +$helper->log('Write image'); + +$hyperLink = new \PhpOffice\PhpSpreadsheet\Cell\Hyperlink($baseUrl, 'test image'); +$drawing->setHyperlink($hyperLink); +$helper->log('Write link: ' . $baseUrl); + +$drawing->setWorksheet($aSheet); + +$filename = tempnam(\PhpOffice\PhpSpreadsheet\Shared\File::sysGetTempDir(), 'phpspreadsheet-test'); + +$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, $inputFileType); +$writer->save($filename); + +$reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader($inputFileType); + +$reloadedSpreadsheet = $reader->load($filename); +unlink($filename); + +$helper->log('reloaded Spreadsheet'); + +foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) { + $helper->log('Read link: ' . $pDrawing->getHyperlink()->getUrl()); +} + +$helper->log('end'); diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/Reading_workbook_data/Custom_properties.php b/inc/vendor/phpoffice/phpspreadsheet/samples/Reading_workbook_data/Custom_properties.php index 3c40440..1c222b5 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/Reading_workbook_data/Custom_properties.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/Reading_workbook_data/Custom_properties.php @@ -25,24 +25,24 @@ foreach ($customPropertyList as $customPropertyName) { // Manipulate properties as appropriate for display purposes switch ($propertyType) { - case 'i': // integer + case 'i': // integer $propertyType = 'integer number'; break; - case 'f': // float + case 'f': // float $propertyType = 'floating point number'; break; - case 's': // string + case 's': // string $propertyType = 'string'; break; - case 'd': // date + case 'd': // date $propertyValue = date('l, d<\s\up>S F Y g:i A', $propertyValue); $propertyType = 'date'; break; - case 'b': // boolean + case 'b': // boolean $propertyValue = ($propertyValue) ? 'TRUE' : 'FALSE'; $propertyType = 'boolean'; diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/bootstrap/js/bootstrap.min.js b/inc/vendor/phpoffice/phpspreadsheet/samples/bootstrap/js/bootstrap.min.js index e1cd129..9bcd2fc 100644 Binary files a/inc/vendor/phpoffice/phpspreadsheet/samples/bootstrap/js/bootstrap.min.js and b/inc/vendor/phpoffice/phpspreadsheet/samples/bootstrap/js/bootstrap.min.js differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/bootstrap/js/jquery.min.js b/inc/vendor/phpoffice/phpspreadsheet/samples/bootstrap/js/jquery.min.js index 03b23ae..f6a6a99 100644 Binary files a/inc/vendor/phpoffice/phpspreadsheet/samples/bootstrap/js/jquery.min.js and b/inc/vendor/phpoffice/phpspreadsheet/samples/bootstrap/js/jquery.min.js differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/samples/templates/chartSpreadsheet.php b/inc/vendor/phpoffice/phpspreadsheet/samples/templates/chartSpreadsheet.php index a63f316..84c8c95 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/samples/templates/chartSpreadsheet.php +++ b/inc/vendor/phpoffice/phpspreadsheet/samples/templates/chartSpreadsheet.php @@ -20,42 +20,42 @@ $worksheet->fromArray( ] ); -// Set the Labels for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Labels for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesLabels = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$B$1', null, 1), // 2010 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$C$1', null, 1), // 2011 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$D$1', null, 1), // 2012 ]; -// Set the X-Axis Labels -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the X-Axis Labels +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $xAxisTickValues = [ - new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 + new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_STRING, 'Worksheet!$A$2:$A$5', null, 4), // Q1 to Q4 ]; -// Set the Data values for each data series we want to plot -// Datatype -// Cell reference for data -// Format Code -// Number of datapoints in series -// Data values -// Data Marker +// Set the Data values for each data series we want to plot +// Datatype +// Cell reference for data +// Format Code +// Number of datapoints in series +// Data values +// Data Marker $dataSeriesValues = [ new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$B$2:$B$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$C$2:$C$5', null, 4), new DataSeriesValues(DataSeriesValues::DATASERIES_TYPE_NUMBER, 'Worksheet!$D$2:$D$5', null, 4), ]; -// Build the dataseries +// Build the dataseries $series = new DataSeries( DataSeries::TYPE_BARCHART, // plotType DataSeries::GROUPING_CLUSTERED, // plotGrouping @@ -64,19 +64,19 @@ $series = new DataSeries( $xAxisTickValues, // plotCategory $dataSeriesValues // plotValues ); -// Set additional dataseries parameters -// Make it a horizontal bar rather than a vertical column graph +// Set additional dataseries parameters +// Make it a horizontal bar rather than a vertical column graph $series->setPlotDirection(DataSeries::DIRECTION_BAR); -// Set the series in the plot area +// Set the series in the plot area $plotArea = new PlotArea(null, [$series]); -// Set the chart legend +// Set the chart legend $legend = new Legend(Legend::POSITION_RIGHT, null, false); $title = new Title('Test Bar Chart'); $yAxisLabel = new Title('Value ($k)'); -// Create the chart +// Create the chart $chart = new Chart( 'chart1', // name $title, // title @@ -88,11 +88,11 @@ $chart = new Chart( $yAxisLabel // yAxisLabel ); -// Set the position where the chart should appear in the worksheet +// Set the position where the chart should appear in the worksheet $chart->setTopLeftPosition('A7'); $chart->setBottomRightPosition('H20'); -// Add the chart to the worksheet +// Add the chart to the worksheet $worksheet->addChart($chart); return $spreadsheet; diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php index 2d3a28c..79b98b9 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Calculation.php @@ -224,6 +224,16 @@ class Calculation 'functionCall' => 'acosh', 'argumentCount' => '1', ], + 'ACOT' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'ACOT'], + 'argumentCount' => '1', + ], + 'ACOTH' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'ACOTH'], + 'argumentCount' => '1', + ], 'ADDRESS' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => [LookupRef::class, 'cellAddress'], @@ -359,6 +369,31 @@ class Calculation 'functionCall' => [Statistical::class, 'BINOMDIST'], 'argumentCount' => '4', ], + 'BITAND' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'BITAND'], + 'argumentCount' => '2', + ], + 'BITOR' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'BITOR'], + 'argumentCount' => '2', + ], + 'BITXOR' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'BITOR'], + 'argumentCount' => '2', + ], + 'BITLSHIFT' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'BITLSHIFT'], + 'argumentCount' => '2', + ], + 'BITRSHIFT' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'BITRSHIFT'], + 'argumentCount' => '2', + ], 'CEILING' => [ 'category' => Category::CATEGORY_MATH_AND_TRIG, 'functionCall' => [MathTrig::class, 'CEILING'], @@ -425,6 +460,11 @@ class Calculation 'functionCall' => [Engineering::class, 'COMPLEX'], 'argumentCount' => '2,3', ], + 'CONCAT' => [ + 'category' => Category::CATEGORY_TEXT_AND_DATA, + 'functionCall' => [TextData::class, 'CONCATENATE'], + 'argumentCount' => '1+', + ], 'CONCATENATE' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, 'functionCall' => [TextData::class, 'CONCATENATE'], @@ -455,6 +495,16 @@ class Calculation 'functionCall' => 'cosh', 'argumentCount' => '1', ], + 'COT' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'COT'], + 'argumentCount' => '1', + ], + 'COTH' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'COTH'], + 'argumentCount' => '1', + ], 'COUNT' => [ 'category' => Category::CATEGORY_STATISTICAL, 'functionCall' => [Statistical::class, 'COUNT'], @@ -520,6 +570,16 @@ class Calculation 'functionCall' => [Statistical::class, 'CRITBINOM'], 'argumentCount' => '3', ], + 'CSC' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'CSC'], + 'argumentCount' => '1', + ], + 'CSCH' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'CSCH'], + 'argumentCount' => '1', + ], 'CUBEKPIMEMBER' => [ 'category' => Category::CATEGORY_CUBE, 'functionCall' => [Functions::class, 'DUMMY'], @@ -735,11 +795,21 @@ class Calculation 'functionCall' => [Engineering::class, 'ERF'], 'argumentCount' => '1,2', ], + 'ERF.PRECISE' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'ERFPRECISE'], + 'argumentCount' => '1', + ], 'ERFC' => [ 'category' => Category::CATEGORY_ENGINEERING, 'functionCall' => [Engineering::class, 'ERFC'], 'argumentCount' => '1', ], + 'ERFC.PRECISE' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'ERFC'], + 'argumentCount' => '1', + ], 'ERROR.TYPE' => [ 'category' => Category::CATEGORY_INFORMATION, 'functionCall' => [Functions::class, 'errorType'], @@ -752,7 +822,7 @@ class Calculation ], 'EXACT' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, - 'functionCall' => [Functions::class, 'DUMMY'], + 'functionCall' => [TextData::class, 'EXACT'], 'argumentCount' => '2', ], 'EXP' => [ @@ -825,6 +895,13 @@ class Calculation 'functionCall' => [Statistical::class, 'FORECAST'], 'argumentCount' => '3', ], + 'FORMULATEXT' => [ + 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, + 'functionCall' => [LookupRef::class, 'FORMULATEXT'], + 'argumentCount' => '1', + 'passCellReference' => true, + 'passByReference' => [true], + ], 'FREQUENCY' => [ 'category' => Category::CATEGORY_STATISTICAL, 'functionCall' => [Functions::class, 'DUMMY'], @@ -961,6 +1038,26 @@ class Calculation 'functionCall' => [Engineering::class, 'IMCOS'], 'argumentCount' => '1', ], + 'IMCOSH' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'IMCOSH'], + 'argumentCount' => '1', + ], + 'IMCOT' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'IMCOT'], + 'argumentCount' => '1', + ], + 'IMCSC' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'IMCSC'], + 'argumentCount' => '1', + ], + 'IMCSCH' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'IMCSCH'], + 'argumentCount' => '1', + ], 'IMDIV' => [ 'category' => Category::CATEGORY_ENGINEERING, 'functionCall' => [Engineering::class, 'IMDIV'], @@ -1001,11 +1098,26 @@ class Calculation 'functionCall' => [Engineering::class, 'IMREAL'], 'argumentCount' => '1', ], + 'IMSEC' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'IMSEC'], + 'argumentCount' => '1', + ], + 'IMSECH' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'IMSECH'], + 'argumentCount' => '1', + ], 'IMSIN' => [ 'category' => Category::CATEGORY_ENGINEERING, 'functionCall' => [Engineering::class, 'IMSIN'], 'argumentCount' => '1', ], + 'IMSINH' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'IMSINH'], + 'argumentCount' => '1', + ], 'IMSQRT' => [ 'category' => Category::CATEGORY_ENGINEERING, 'functionCall' => [Engineering::class, 'IMSQRT'], @@ -1021,6 +1133,11 @@ class Calculation 'functionCall' => [Engineering::class, 'IMSUM'], 'argumentCount' => '1+', ], + 'IMTAN' => [ + 'category' => Category::CATEGORY_ENGINEERING, + 'functionCall' => [Engineering::class, 'IMTAN'], + 'argumentCount' => '1', + ], 'INDEX' => [ 'category' => Category::CATEGORY_LOOKUP_AND_REFERENCE, 'functionCall' => [LookupRef::class, 'INDEX'], @@ -1114,6 +1231,11 @@ class Calculation 'functionCall' => [Functions::class, 'isOdd'], 'argumentCount' => '1', ], + 'ISOWEEKNUM' => [ + 'category' => Category::CATEGORY_DATE_AND_TIME, + 'functionCall' => [DateTime::class, 'ISOWEEKNUM'], + 'argumentCount' => '1', + ], 'ISPMT' => [ 'category' => Category::CATEGORY_FINANCIAL, 'functionCall' => [Financial::class, 'ISPMT'], @@ -1394,6 +1516,11 @@ class Calculation 'functionCall' => [Financial::class, 'NPV'], 'argumentCount' => '2+', ], + 'NUMBERVALUE' => [ + 'category' => Category::CATEGORY_TEXT_AND_DATA, + 'functionCall' => [TextData::class, 'NUMBERVALUE'], + 'argumentCount' => '1+', + ], 'OCT2BIN' => [ 'category' => Category::CATEGORY_ENGINEERING, 'functionCall' => [Engineering::class, 'OCTTOBIN'], @@ -1446,6 +1573,11 @@ class Calculation 'functionCall' => [Logical::class, 'logicalOr'], 'argumentCount' => '1+', ], + 'PDURATION' => [ + 'category' => Category::CATEGORY_FINANCIAL, + 'functionCall' => [Financial::class, 'PDURATION'], + 'argumentCount' => '3', + ], 'PEARSON' => [ 'category' => Category::CATEGORY_STATISTICAL, 'functionCall' => [Statistical::class, 'CORREL'], @@ -1627,6 +1759,11 @@ class Calculation 'functionCall' => [LookupRef::class, 'ROWS'], 'argumentCount' => '1', ], + 'RRI' => [ + 'category' => Category::CATEGORY_FINANCIAL, + 'functionCall' => [Financial::class, 'RRI'], + 'argumentCount' => '3', + ], 'RSQ' => [ 'category' => Category::CATEGORY_STATISTICAL, 'functionCall' => [Statistical::class, 'RSQ'], @@ -1647,6 +1784,16 @@ class Calculation 'functionCall' => [TextData::class, 'SEARCHINSENSITIVE'], 'argumentCount' => '2,3', ], + 'SEC' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'SEC'], + 'argumentCount' => '1', + ], + 'SECH' => [ + 'category' => Category::CATEGORY_MATH_AND_TRIG, + 'functionCall' => [MathTrig::class, 'SECH'], + 'argumentCount' => '1', + ], 'SECOND' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, 'functionCall' => [DateTime::class, 'SECOND'], @@ -1838,6 +1985,11 @@ class Calculation 'functionCall' => [TextData::class, 'TEXTFORMAT'], 'argumentCount' => '2', ], + 'TEXTJOIN' => [ + 'category' => Category::CATEGORY_TEXT_AND_DATA, + 'functionCall' => [TextData::class, 'TEXTJOIN'], + 'argumentCount' => '3+', + ], 'TIME' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, 'functionCall' => [DateTime::class, 'TIME'], @@ -1898,6 +2050,16 @@ class Calculation 'functionCall' => [Functions::class, 'TYPE'], 'argumentCount' => '1', ], + 'UNICHAR' => [ + 'category' => Category::CATEGORY_TEXT_AND_DATA, + 'functionCall' => [TextData::class, 'CHARACTER'], + 'argumentCount' => '1', + ], + 'UNICODE' => [ + 'category' => Category::CATEGORY_TEXT_AND_DATA, + 'functionCall' => [TextData::class, 'ASCIICODE'], + 'argumentCount' => '1', + ], 'UPPER' => [ 'category' => Category::CATEGORY_TEXT_AND_DATA, 'functionCall' => [TextData::class, 'UPPERCASE'], @@ -1918,6 +2080,16 @@ class Calculation 'functionCall' => [Statistical::class, 'VARFunc'], 'argumentCount' => '1+', ], + 'VAR.P' => [ + 'category' => Category::CATEGORY_STATISTICAL, + 'functionCall' => [Statistical::class, 'VARP'], + 'argumentCount' => '1+', + ], + 'VAR.S' => [ + 'category' => Category::CATEGORY_STATISTICAL, + 'functionCall' => [Statistical::class, 'VARFunc'], + 'argumentCount' => '1+', + ], 'VARA' => [ 'category' => Category::CATEGORY_STATISTICAL, 'functionCall' => [Statistical::class, 'VARA'], @@ -1973,6 +2145,11 @@ class Calculation 'functionCall' => [Financial::class, 'XNPV'], 'argumentCount' => '3', ], + 'XOR' => [ + 'category' => Category::CATEGORY_LOGICAL, + 'functionCall' => [Logical::class, 'logicalXor'], + 'argumentCount' => '1+', + ], 'YEAR' => [ 'category' => Category::CATEGORY_DATE_AND_TIME, 'functionCall' => [DateTime::class, 'YEAR'], @@ -2395,10 +2572,10 @@ class Calculation if (self::$functionReplaceToLocale === null) { self::$functionReplaceToLocale = []; - foreach (array_values(self::$localeFunctions) as $localeFunctionName) { + foreach (self::$localeFunctions as $localeFunctionName) { self::$functionReplaceToLocale[] = '$1' . trim($localeFunctionName) . '$2'; } - foreach (array_values(self::$localeBoolean) as $localeBoolean) { + foreach (self::$localeBoolean as $localeBoolean) { self::$functionReplaceToLocale[] = '$1' . trim($localeBoolean) . '$2'; } } @@ -2414,10 +2591,10 @@ class Calculation { if (self::$functionReplaceFromLocale === null) { self::$functionReplaceFromLocale = []; - foreach (array_values(self::$localeFunctions) as $localeFunctionName) { + foreach (self::$localeFunctions as $localeFunctionName) { self::$functionReplaceFromLocale[] = '/(@?[^\w\.])' . preg_quote($localeFunctionName, '/') . '([\s]*\()/Ui'; } - foreach (array_values(self::$localeBoolean) as $excelBoolean) { + foreach (self::$localeBoolean as $excelBoolean) { self::$functionReplaceFromLocale[] = '/(@?[^\w\.])' . preg_quote($excelBoolean, '/') . '([^\w\.])/Ui'; } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTime.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTime.php index 0bd131c..a07a28d 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTime.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/DateTime.php @@ -10,7 +10,7 @@ class DateTime /** * Identify if a year is a leap year or not. * - * @param int $year The year to test + * @param int|string $year The year to test * * @return bool TRUE if the year is a leap year, otherwise FALSE */ @@ -70,7 +70,7 @@ class DateTime (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_GNUMERIC)) { return Functions::VALUE(); } - if ((is_object($dateValue)) && ($dateValue instanceof \DateTime)) { + if ((is_object($dateValue)) && ($dateValue instanceof \DateTimeImmutable)) { $dateValue = Date::PHPToExcel($dateValue); } else { $saveReturnDateType = Functions::getReturnDateType(); @@ -650,7 +650,7 @@ class DateTime * or a standard date string * @param string $unit * - * @return int Interval between the dates + * @return int|string Interval between the dates */ public static function DATEDIF($startDate = 0, $endDate = 0, $unit = 'D') { @@ -792,7 +792,7 @@ class DateTime * occur on the 31st of a month become equal to the 30th of the * same month. * - * @return int Number of days between start date and end date + * @return int|string Number of days between start date and end date */ public static function DAYS360($startDate = 0, $endDate = 0, $method = false) { @@ -942,7 +942,7 @@ class DateTime * @param mixed $endDate Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * - * @return int Interval between the dates + * @return int|string Interval between the dates */ public static function NETWORKDAYS($startDate, $endDate, ...$dateArgs) { @@ -1127,7 +1127,7 @@ class DateTime * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * - * @return int Day of the month + * @return int|string Day of the month */ public static function DAYOFMONTH($dateValue = 1) { @@ -1169,7 +1169,7 @@ class DateTime * 2 Numbers 1 (Monday) through 7 (Sunday). * 3 Numbers 0 (Monday) through 6 (Sunday). * - * @return int Day of the week value + * @return int|string Day of the week value */ public static function WEEKDAY($dateValue = 1, $style = 1) { @@ -1248,7 +1248,7 @@ class DateTime * 1 or omitted Week begins on Sunday. * 2 Week begins on Monday. * - * @return int Week Number + * @return int|string Week Number */ public static function WEEKNUM($dateValue = 1, $method = 1) { @@ -1286,6 +1286,37 @@ class DateTime return (int) $weekOfYear; } + /** + * ISOWEEKNUM. + * + * Returns the ISO 8601 week number of the year for a specified date. + * + * Excel Function: + * ISOWEEKNUM(dateValue) + * + * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), + * PHP DateTime object, or a standard date string + * + * @return int|string Week Number + */ + public static function ISOWEEKNUM($dateValue = 1) + { + $dateValue = Functions::flattenSingleValue($dateValue); + + if ($dateValue === null) { + $dateValue = 1; + } elseif (is_string($dateValue = self::getDateValue($dateValue))) { + return Functions::VALUE(); + } elseif ($dateValue < 0.0) { + return Functions::NAN(); + } + + // Execute function + $PHPDateObject = Date::excelToDateTimeObject($dateValue); + + return (int) $PHPDateObject->format('W'); + } + /** * MONTHOFYEAR. * @@ -1298,7 +1329,7 @@ class DateTime * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * - * @return int Month of the year + * @return int|string Month of the year */ public static function MONTHOFYEAR($dateValue = 1) { @@ -1331,7 +1362,7 @@ class DateTime * @param mixed $dateValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard date string * - * @return int Year + * @return int|string Year */ public static function YEAR($dateValue = 1) { @@ -1363,7 +1394,7 @@ class DateTime * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard time string * - * @return int Hour + * @return int|string Hour */ public static function HOUROFDAY($timeValue = 0) { @@ -1404,7 +1435,7 @@ class DateTime * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard time string * - * @return int Minute + * @return int|string Minute */ public static function MINUTE($timeValue = 0) { @@ -1445,7 +1476,7 @@ class DateTime * @param mixed $timeValue Excel date serial value (float), PHP date timestamp (integer), * PHP DateTime object, or a standard time string * - * @return int Second + * @return int|string Second */ public static function SECOND($timeValue = 0) { diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering.php index 2be5c50..3f1b48b 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Engineering.php @@ -2,6 +2,9 @@ namespace PhpOffice\PhpSpreadsheet\Calculation; +use Complex\Complex; +use Complex\Exception as ComplexException; + class Engineering { /** @@ -718,83 +721,23 @@ class Engineering * * Parses a complex number into its real and imaginary parts, and an I or J suffix * + * @deprecated 2.0.0 No longer used by internal code. Please use the Complex\Complex class instead + * * @param string $complexNumber The complex number * - * @return string[] Indexed on "real", "imaginary" and "suffix" + * @return mixed[] Indexed on "real", "imaginary" and "suffix" */ public static function parseComplex($complexNumber) { - $workString = (string) $complexNumber; - - $realNumber = $imaginary = 0; - // Extract the suffix, if there is one - $suffix = substr($workString, -1); - if (!is_numeric($suffix)) { - $workString = substr($workString, 0, -1); - } else { - $suffix = ''; - } - - // Split the input into its Real and Imaginary components - $leadingSign = 0; - if (strlen($workString) > 0) { - $leadingSign = (($workString[0] == '+') || ($workString[0] == '-')) ? 1 : 0; - } - $power = ''; - $realNumber = strtok($workString, '+-'); - if (strtoupper(substr($realNumber, -1)) == 'E') { - $power = strtok('+-'); - ++$leadingSign; - } - - $realNumber = substr($workString, 0, strlen($realNumber) + strlen($power) + $leadingSign); - - if ($suffix != '') { - $imaginary = substr($workString, strlen($realNumber)); - - if (($imaginary == '') && (($realNumber == '') || ($realNumber == '+') || ($realNumber == '-'))) { - $imaginary = $realNumber . '1'; - $realNumber = '0'; - } elseif ($imaginary == '') { - $imaginary = $realNumber; - $realNumber = '0'; - } elseif (($imaginary == '+') || ($imaginary == '-')) { - $imaginary .= '1'; - } - } + $complex = new Complex($complexNumber); return [ - 'real' => $realNumber, - 'imaginary' => $imaginary, - 'suffix' => $suffix, + 'real' => $complex->getReal(), + 'imaginary' => $complex->getImaginary(), + 'suffix' => $complex->getSuffix(), ]; } - /** - * Cleans the leading characters in a complex number string. - * - * @param string $complexNumber The complex number to clean - * - * @return string The "cleaned" complex number - */ - private static function cleanComplex($complexNumber) - { - if ($complexNumber[0] == '+') { - $complexNumber = substr($complexNumber, 1); - } - if ($complexNumber[0] == '0') { - $complexNumber = substr($complexNumber, 1); - } - if ($complexNumber[0] == '.') { - $complexNumber = '0' . $complexNumber; - } - if ($complexNumber[0] == '+') { - $complexNumber = substr($complexNumber, 1); - } - - return $complexNumber; - } - /** * Formats a number base string value with leading zeroes. * @@ -1745,10 +1688,10 @@ class Engineering /** * COMPLEX. * - * Converts real and imaginary coefficients into a complex number of the form x + yi or x + yj. + * Converts real and imaginary coefficients into a complex number of the form x +/- yi or x +/- yj. * * Excel Function: - * COMPLEX(realNumber,imaginary[,places]) + * COMPLEX(realNumber,imaginary[,suffix]) * * @category Engineering Functions * @@ -1768,34 +1711,9 @@ class Engineering if (((is_numeric($realNumber)) && (is_numeric($imaginary))) && (($suffix == 'i') || ($suffix == 'j') || ($suffix == '')) ) { - $realNumber = (float) $realNumber; - $imaginary = (float) $imaginary; + $complex = new Complex($realNumber, $imaginary, $suffix); - if ($suffix == '') { - $suffix = 'i'; - } - if ($realNumber == 0.0) { - if ($imaginary == 0.0) { - return (string) '0'; - } elseif ($imaginary == 1.0) { - return (string) $suffix; - } elseif ($imaginary == -1.0) { - return (string) '-' . $suffix; - } - - return (string) $imaginary . $suffix; - } elseif ($imaginary == 0.0) { - return (string) $realNumber; - } elseif ($imaginary == 1.0) { - return (string) $realNumber . '+' . $suffix; - } elseif ($imaginary == -1.0) { - return (string) $realNumber . '-' . $suffix; - } - if ($imaginary > 0) { - $imaginary = (string) '+' . $imaginary; - } - - return (string) $realNumber . $imaginary . $suffix; + return (string) $complex; } return Functions::VALUE(); @@ -1820,9 +1738,7 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - - return $parsedComplex['imaginary']; + return (new Complex($complexNumber))->getImaginary(); } /** @@ -1843,9 +1759,7 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - - return $parsedComplex['real']; + return (new Complex($complexNumber))->getReal(); } /** @@ -1864,12 +1778,7 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - - return sqrt( - ($parsedComplex['real'] * $parsedComplex['real']) + - ($parsedComplex['imaginary'] * $parsedComplex['imaginary']) - ); + return (new Complex($complexNumber))->abs(); } /** @@ -1883,27 +1792,18 @@ class Engineering * * @param string $complexNumber the complex number for which you want the argument theta * - * @return float + * @return float|string */ public static function IMARGUMENT($complexNumber) { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - if ($parsedComplex['real'] == 0.0) { - if ($parsedComplex['imaginary'] == 0.0) { - return Functions::DIV0(); - } elseif ($parsedComplex['imaginary'] < 0.0) { - return M_PI / -2; - } - return M_PI / 2; - } elseif ($parsedComplex['real'] > 0.0) { - return atan($parsedComplex['imaginary'] / $parsedComplex['real']); - } elseif ($parsedComplex['imaginary'] < 0.0) { - return 0 - (M_PI - atan(abs($parsedComplex['imaginary']) / abs($parsedComplex['real']))); + $complex = new Complex($complexNumber); + if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { + return Functions::DIV0(); } - return M_PI - atan($parsedComplex['imaginary'] / abs($parsedComplex['real'])); + return $complex->argument(); } /** @@ -1922,19 +1822,7 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - - if ($parsedComplex['imaginary'] == 0.0) { - return $parsedComplex['real']; - } - - return self::cleanComplex( - self::COMPLEX( - $parsedComplex['real'], - 0 - $parsedComplex['imaginary'], - $parsedComplex['suffix'] - ) - ); + return (string) (new Complex($complexNumber))->conjugate(); } /** @@ -1953,19 +1841,83 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); + return (string) (new Complex($complexNumber))->cos(); + } - if ($parsedComplex['imaginary'] == 0.0) { - return cos($parsedComplex['real']); - } + /** + * IMCOSH. + * + * Returns the hyperbolic cosine of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCOSH(complexNumber) + * + * @param string $complexNumber the complex number for which you want the hyperbolic cosine + * + * @return float|string + */ + public static function IMCOSH($complexNumber) + { + $complexNumber = Functions::flattenSingleValue($complexNumber); - return self::IMCONJUGATE( - self::COMPLEX( - cos($parsedComplex['real']) * cosh($parsedComplex['imaginary']), - sin($parsedComplex['real']) * sinh($parsedComplex['imaginary']), - $parsedComplex['suffix'] - ) - ); + return (string) (new Complex($complexNumber))->cosh(); + } + + /** + * IMCOT. + * + * Returns the cotangent of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCOT(complexNumber) + * + * @param string $complexNumber the complex number for which you want the cotangent + * + * @return float|string + */ + public static function IMCOT($complexNumber) + { + $complexNumber = Functions::flattenSingleValue($complexNumber); + + return (string) (new Complex($complexNumber))->cot(); + } + + /** + * IMCSC. + * + * Returns the cosecant of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCSC(complexNumber) + * + * @param string $complexNumber the complex number for which you want the cosecant + * + * @return float|string + */ + public static function IMCSC($complexNumber) + { + $complexNumber = Functions::flattenSingleValue($complexNumber); + + return (string) (new Complex($complexNumber))->csc(); + } + + /** + * IMCSCH. + * + * Returns the hyperbolic cosecant of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMCSCH(complexNumber) + * + * @param string $complexNumber the complex number for which you want the hyperbolic cosecant + * + * @return float|string + */ + public static function IMCSCH($complexNumber) + { + $complexNumber = Functions::flattenSingleValue($complexNumber); + + return (string) (new Complex($complexNumber))->csch(); } /** @@ -1984,17 +1936,83 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); + return (string) (new Complex($complexNumber))->sin(); + } - if ($parsedComplex['imaginary'] == 0.0) { - return sin($parsedComplex['real']); - } + /** + * IMSINH. + * + * Returns the hyperbolic sine of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSINH(complexNumber) + * + * @param string $complexNumber the complex number for which you want the hyperbolic sine + * + * @return float|string + */ + public static function IMSINH($complexNumber) + { + $complexNumber = Functions::flattenSingleValue($complexNumber); - return self::COMPLEX( - sin($parsedComplex['real']) * cosh($parsedComplex['imaginary']), - cos($parsedComplex['real']) * sinh($parsedComplex['imaginary']), - $parsedComplex['suffix'] - ); + return (string) (new Complex($complexNumber))->sinh(); + } + + /** + * IMSEC. + * + * Returns the secant of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSEC(complexNumber) + * + * @param string $complexNumber the complex number for which you want the secant + * + * @return float|string + */ + public static function IMSEC($complexNumber) + { + $complexNumber = Functions::flattenSingleValue($complexNumber); + + return (string) (new Complex($complexNumber))->sec(); + } + + /** + * IMSECH. + * + * Returns the hyperbolic secant of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMSECH(complexNumber) + * + * @param string $complexNumber the complex number for which you want the hyperbolic secant + * + * @return float|string + */ + public static function IMSECH($complexNumber) + { + $complexNumber = Functions::flattenSingleValue($complexNumber); + + return (string) (new Complex($complexNumber))->sech(); + } + + /** + * IMTAN. + * + * Returns the tangent of a complex number in x + yi or x + yj text format. + * + * Excel Function: + * IMTAN(complexNumber) + * + * @param string $complexNumber the complex number for which you want the tangent + * + * @return float|string + */ + public static function IMTAN($complexNumber) + { + $complexNumber = Functions::flattenSingleValue($complexNumber); + + return (string) (new Complex($complexNumber))->tan(); } /** @@ -2013,22 +2031,12 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - $theta = self::IMARGUMENT($complexNumber); if ($theta === Functions::DIV0()) { return '0'; } - $d1 = cos($theta / 2); - $d2 = sin($theta / 2); - $r = sqrt(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); - - if ($parsedComplex['suffix'] == '') { - return self::COMPLEX($d1 * $r, $d2 * $r); - } - - return self::COMPLEX($d1 * $r, $d2 * $r, $parsedComplex['suffix']); + return (string) (new Complex($complexNumber))->sqrt(); } /** @@ -2047,20 +2055,12 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - - if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + $complex = new Complex($complexNumber); + if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { return Functions::NAN(); } - $logR = log(sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary']))); - $t = self::IMARGUMENT($complexNumber); - - if ($parsedComplex['suffix'] == '') { - return self::COMPLEX($logR, $t); - } - - return self::COMPLEX($logR, $t, $parsedComplex['suffix']); + return (string) (new Complex($complexNumber))->ln(); } /** @@ -2079,15 +2079,12 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - - if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + $complex = new Complex($complexNumber); + if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { return Functions::NAN(); - } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return log10($parsedComplex['real']); } - return self::IMPRODUCT(log10(self::EULER), self::IMLN($complexNumber)); + return (string) (new Complex($complexNumber))->log10(); } /** @@ -2106,15 +2103,12 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - - if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { + $complex = new Complex($complexNumber); + if ($complex->getReal() == 0.0 && $complex->getImaginary() == 0.0) { return Functions::NAN(); - } elseif (($parsedComplex['real'] > 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return log($parsedComplex['real'], 2); } - return self::IMPRODUCT(log(self::EULER, 2), self::IMLN($complexNumber)); + return (string) (new Complex($complexNumber))->log2(); } /** @@ -2133,21 +2127,7 @@ class Engineering { $complexNumber = Functions::flattenSingleValue($complexNumber); - $parsedComplex = self::parseComplex($complexNumber); - - if (($parsedComplex['real'] == 0.0) && ($parsedComplex['imaginary'] == 0.0)) { - return '1'; - } - - $e = exp($parsedComplex['real']); - $eX = $e * cos($parsedComplex['imaginary']); - $eY = $e * sin($parsedComplex['imaginary']); - - if ($parsedComplex['suffix'] == '') { - return self::COMPLEX($eX, $eY); - } - - return self::COMPLEX($eX, $eY, $parsedComplex['suffix']); + return (string) (new Complex($complexNumber))->exp(); } /** @@ -2172,18 +2152,7 @@ class Engineering return Functions::VALUE(); } - $parsedComplex = self::parseComplex($complexNumber); - - $r = sqrt(($parsedComplex['real'] * $parsedComplex['real']) + ($parsedComplex['imaginary'] * $parsedComplex['imaginary'])); - $rPower = pow($r, $realNumber); - $theta = self::IMARGUMENT($complexNumber) * $realNumber; - if ($theta == 0) { - return 1; - } elseif ($parsedComplex['imaginary'] == 0.0) { - return self::COMPLEX($rPower * cos($theta), $rPower * sin($theta), $parsedComplex['suffix']); - } - - return self::COMPLEX($rPower * cos($theta), $rPower * sin($theta), $parsedComplex['suffix']); + return (string) (new Complex($complexNumber))->pow($realNumber); } /** @@ -2204,32 +2173,11 @@ class Engineering $complexDividend = Functions::flattenSingleValue($complexDividend); $complexDivisor = Functions::flattenSingleValue($complexDivisor); - $parsedComplexDividend = self::parseComplex($complexDividend); - $parsedComplexDivisor = self::parseComplex($complexDivisor); - - if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] != '') && - ($parsedComplexDividend['suffix'] != $parsedComplexDivisor['suffix']) - ) { + try { + return (string) (new Complex($complexDividend))->divideby(new Complex($complexDivisor)); + } catch (ComplexException $e) { return Functions::NAN(); } - if (($parsedComplexDividend['suffix'] != '') && ($parsedComplexDivisor['suffix'] == '')) { - $parsedComplexDivisor['suffix'] = $parsedComplexDividend['suffix']; - } - - $d1 = ($parsedComplexDividend['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['imaginary']); - $d2 = ($parsedComplexDividend['imaginary'] * $parsedComplexDivisor['real']) - ($parsedComplexDividend['real'] * $parsedComplexDivisor['imaginary']); - $d3 = ($parsedComplexDivisor['real'] * $parsedComplexDivisor['real']) + ($parsedComplexDivisor['imaginary'] * $parsedComplexDivisor['imaginary']); - - $r = $d1 / $d3; - $i = $d2 / $d3; - - if ($i > 0.0) { - return self::cleanComplex($r . '+' . $i . $parsedComplexDivisor['suffix']); - } elseif ($i < 0.0) { - return self::cleanComplex($r . $i . $parsedComplexDivisor['suffix']); - } - - return $r; } /** @@ -2250,21 +2198,11 @@ class Engineering $complexNumber1 = Functions::flattenSingleValue($complexNumber1); $complexNumber2 = Functions::flattenSingleValue($complexNumber2); - $parsedComplex1 = self::parseComplex($complexNumber1); - $parsedComplex2 = self::parseComplex($complexNumber2); - - if ((($parsedComplex1['suffix'] != '') && ($parsedComplex2['suffix'] != '')) && - ($parsedComplex1['suffix'] != $parsedComplex2['suffix']) - ) { + try { + return (string) (new Complex($complexNumber1))->subtract(new Complex($complexNumber2)); + } catch (ComplexException $e) { return Functions::NAN(); - } elseif (($parsedComplex1['suffix'] == '') && ($parsedComplex2['suffix'] != '')) { - $parsedComplex1['suffix'] = $parsedComplex2['suffix']; } - - $d1 = $parsedComplex1['real'] - $parsedComplex2['real']; - $d2 = $parsedComplex1['imaginary'] - $parsedComplex2['imaginary']; - - return self::COMPLEX($d1, $d2, $parsedComplex1['suffix']); } /** @@ -2282,29 +2220,19 @@ class Engineering public static function IMSUM(...$complexNumbers) { // Return value - $returnValue = self::parseComplex('0'); - $activeSuffix = ''; - - // Loop through the arguments + $returnValue = new Complex(0.0); $aArgs = Functions::flattenArray($complexNumbers); - foreach ($aArgs as $arg) { - $parsedComplex = self::parseComplex($arg); - if ($activeSuffix == '') { - $activeSuffix = $parsedComplex['suffix']; - } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { - return Functions::NAN(); + try { + // Loop through the arguments + foreach ($aArgs as $complex) { + $returnValue = $returnValue->add(new Complex($complex)); } - - $returnValue['real'] += $parsedComplex['real']; - $returnValue['imaginary'] += $parsedComplex['imaginary']; + } catch (ComplexException $e) { + return Functions::NAN(); } - if ($returnValue['imaginary'] == 0.0) { - $activeSuffix = ''; - } - - return self::COMPLEX($returnValue['real'], $returnValue['imaginary'], $activeSuffix); + return (string) $returnValue; } /** @@ -2322,29 +2250,19 @@ class Engineering public static function IMPRODUCT(...$complexNumbers) { // Return value - $returnValue = self::parseComplex('1'); - $activeSuffix = ''; - - // Loop through the arguments + $returnValue = new Complex(1.0); $aArgs = Functions::flattenArray($complexNumbers); - foreach ($aArgs as $arg) { - $parsedComplex = self::parseComplex($arg); - $workValue = $returnValue; - if (($parsedComplex['suffix'] != '') && ($activeSuffix == '')) { - $activeSuffix = $parsedComplex['suffix']; - } elseif (($parsedComplex['suffix'] != '') && ($activeSuffix != $parsedComplex['suffix'])) { - return Functions::NAN(); + try { + // Loop through the arguments + foreach ($aArgs as $complex) { + $returnValue = $returnValue->multiply(new Complex($complex)); } - $returnValue['real'] = ($workValue['real'] * $parsedComplex['real']) - ($workValue['imaginary'] * $parsedComplex['imaginary']); - $returnValue['imaginary'] = ($workValue['real'] * $parsedComplex['imaginary']) + ($workValue['imaginary'] * $parsedComplex['real']); + } catch (ComplexException $e) { + return Functions::NAN(); } - if ($returnValue['imaginary'] == 0.0) { - $activeSuffix = ''; - } - - return self::COMPLEX($returnValue['real'], $returnValue['imaginary'], $activeSuffix); + return (string) $returnValue; } /** @@ -2423,6 +2341,179 @@ class Engineering return self::$twoSqrtPi * $sum; } + /** + * Validate arguments passed to the bitwise functions. + * + * @param mixed $value + * + * @throws Exception + * + * @return int + */ + private static function validateBitwiseArgument($value) + { + $value = Functions::flattenSingleValue($value); + + if (is_int($value)) { + return $value; + } elseif (is_numeric($value)) { + if ($value == (int) ($value)) { + $value = (int) ($value); + if (($value > pow(2, 48) - 1) || ($value < 0)) { + throw new Exception(Functions::NAN()); + } + + return $value; + } + + throw new Exception(Functions::NAN()); + } + + throw new Exception(Functions::VALUE()); + } + + /** + * BITAND. + * + * Returns the bitwise AND of two integer values. + * + * Excel Function: + * BITAND(number1, number2) + * + * @category Engineering Functions + * + * @param int $number1 + * @param int $number2 + * + * @return int|string + */ + public static function BITAND($number1, $number2) + { + try { + $number1 = self::validateBitwiseArgument($number1); + $number2 = self::validateBitwiseArgument($number2); + } catch (Exception $e) { + return $e->getMessage(); + } + + return $number1 & $number2; + } + + /** + * BITOR. + * + * Returns the bitwise OR of two integer values. + * + * Excel Function: + * BITOR(number1, number2) + * + * @category Engineering Functions + * + * @param int $number1 + * @param int $number2 + * + * @return int|string + */ + public static function BITOR($number1, $number2) + { + try { + $number1 = self::validateBitwiseArgument($number1); + $number2 = self::validateBitwiseArgument($number2); + } catch (Exception $e) { + return $e->getMessage(); + } + + return $number1 | $number2; + } + + /** + * BITXOR. + * + * Returns the bitwise XOR of two integer values. + * + * Excel Function: + * BITXOR(number1, number2) + * + * @category Engineering Functions + * + * @param int $number1 + * @param int $number2 + * + * @return int|string + */ + public static function BITXOR($number1, $number2) + { + try { + $number1 = self::validateBitwiseArgument($number1); + $number2 = self::validateBitwiseArgument($number2); + } catch (Exception $e) { + return $e->getMessage(); + } + + return $number1 ^ $number2; + } + + /** + * BITLSHIFT. + * + * Returns the number value shifted left by shift_amount bits. + * + * Excel Function: + * BITLSHIFT(number, shift_amount) + * + * @category Engineering Functions + * + * @param int $number + * @param int $shiftAmount + * + * @return int|string + */ + public static function BITLSHIFT($number, $shiftAmount) + { + try { + $number = self::validateBitwiseArgument($number); + } catch (Exception $e) { + return $e->getMessage(); + } + + $shiftAmount = Functions::flattenSingleValue($shiftAmount); + + $result = $number << $shiftAmount; + if ($result > pow(2, 48) - 1) { + return Functions::NAN(); + } + + return $result; + } + + /** + * BITRSHIFT. + * + * Returns the number value shifted right by shift_amount bits. + * + * Excel Function: + * BITRSHIFT(number, shift_amount) + * + * @category Engineering Functions + * + * @param int $number + * @param int $shiftAmount + * + * @return int|string + */ + public static function BITRSHIFT($number, $shiftAmount) + { + try { + $number = self::validateBitwiseArgument($number); + } catch (Exception $e) { + return $e->getMessage(); + } + + $shiftAmount = Functions::flattenSingleValue($shiftAmount); + + return $number >> $shiftAmount; + } + /** * ERF. * @@ -2431,7 +2522,7 @@ class Engineering * Note: In Excel 2007 or earlier, if you input a negative value for the upper or lower bound arguments, * the function would return a #NUM! error. However, in Excel 2010, the function algorithm was * improved, so that it can now calculate the function for both positive and negative ranges. - * PhpSpreadsheet follows Excel 2010 behaviour, and accepts nagative arguments. + * PhpSpreadsheet follows Excel 2010 behaviour, and accepts negative arguments. * * Excel Function: * ERF(lower[,upper]) @@ -2440,7 +2531,7 @@ class Engineering * @param float $upper upper bound for integrating ERF. * If omitted, ERF integrates between zero and lower_limit * - * @return float + * @return float|string */ public static function ERF($lower, $upper = null) { @@ -2459,6 +2550,25 @@ class Engineering return Functions::VALUE(); } + /** + * ERFPRECISE. + * + * Returns the error function integrated between the lower and upper bound arguments. + * + * Excel Function: + * ERF.PRECISE(limit) + * + * @param float $limit bound for integrating ERF + * + * @return float|string + */ + public static function ERFPRECISE($limit) + { + $limit = Functions::flattenSingleValue($limit); + + return self::ERF($limit); + } + // // Private method to calculate the erfc value // @@ -2507,7 +2617,7 @@ class Engineering * * @param float $x The lower bound for integrating ERFC * - * @return float + * @return float|string */ public static function ERFC($x) { diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial.php index 24cdfb0..3cb6d40 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Financial.php @@ -6,7 +6,7 @@ use PhpOffice\PhpSpreadsheet\Shared\Date; class Financial { - const FINANCIAL_MAX_ITERATIONS = 128; + const FINANCIAL_MAX_ITERATIONS = 32; const FINANCIAL_PRECISION = 1.0e-08; @@ -63,8 +63,8 @@ class Financial * * Returns the number of days in a specified year, as defined by the "basis" value * - * @param int $year The year against which we're testing - * @param int $basis The type of day count: + * @param int|string $year The year against which we're testing + * @param int|string $basis The type of day count: * 0 or omitted US (NASD) 360 * 1 Actual (365 or 366 in a leap year) * 2 360 @@ -144,7 +144,7 @@ class Financial * 3 Actual/365 * 4 European 30/360 * - * @return float + * @return float|string */ public static function ACCRINT($issue, $firstinterest, $settlement, $rate, $par = 1000, $frequency = 1, $basis = 0) { @@ -197,7 +197,7 @@ class Financial * 3 Actual/365 * 4 European 30/360 * - * @return float + * @return float|string */ public static function ACCRINTM($issue, $settlement, $rate, $par = 1000, $basis = 0) { @@ -401,7 +401,7 @@ class Financial * 3 Actual/365 * 4 European 30/360 * - * @return float + * @return float|string */ public static function COUPDAYBS($settlement, $maturity, $frequency, $basis = 0) { @@ -460,7 +460,7 @@ class Financial * 3 Actual/365 * 4 European 30/360 * - * @return float + * @return float|string */ public static function COUPDAYS($settlement, $maturity, $frequency, $basis = 0) { @@ -489,7 +489,7 @@ class Financial case 1: // Actual/actual if ($frequency == 1) { - $daysPerYear = self::daysPerYear(DateTime::YEAR($maturity), $basis); + $daysPerYear = self::daysPerYear(DateTime::YEAR($settlement), $basis); return $daysPerYear / $frequency; } @@ -534,7 +534,7 @@ class Financial * 3 Actual/365 * 4 European 30/360 * - * @return float + * @return float|string */ public static function COUPDAYSNC($settlement, $maturity, $frequency, $basis = 0) { @@ -651,7 +651,7 @@ class Financial * 3 Actual/365 * 4 European 30/360 * - * @return int + * @return int|string */ public static function COUPNUM($settlement, $maturity, $frequency, $basis = 0) { @@ -769,7 +769,7 @@ class Financial * 0 or omitted At the end of the period. * 1 At the beginning of the period. * - * @return float + * @return float|string */ public static function CUMIPMT($rate, $nper, $pv, $start, $end, $type = 0) { @@ -817,7 +817,7 @@ class Financial * 0 or omitted At the end of the period. * 1 At the beginning of the period. * - * @return float + * @return float|string */ public static function CUMPRINC($rate, $nper, $pv, $start, $end, $type = 0) { @@ -870,7 +870,7 @@ class Financial * @param int $month Number of months in the first year. If month is omitted, * it defaults to 12. * - * @return float + * @return float|string */ public static function DB($cost, $salvage, $life, $period, $month = 12) { @@ -940,7 +940,7 @@ class Financial * If factor is omitted, it is assumed to be 2 (the * double-declining balance method). * - * @return float + * @return float|string */ public static function DDB($cost, $salvage, $life, $period, $factor = 2.0) { @@ -1004,7 +1004,7 @@ class Financial * 3 Actual/365 * 4 European 30/360 * - * @return float + * @return float|string */ public static function DISC($settlement, $maturity, $price, $redemption, $basis = 0) { @@ -1049,7 +1049,7 @@ class Financial * @param float $fractional_dollar Fractional Dollar * @param int $fraction Fraction * - * @return float + * @return float|string */ public static function DOLLARDE($fractional_dollar = null, $fraction = 0) { @@ -1087,7 +1087,7 @@ class Financial * @param float $decimal_dollar Decimal Dollar * @param int $fraction Fraction * - * @return float + * @return float|string */ public static function DOLLARFR($decimal_dollar = null, $fraction = 0) { @@ -1124,7 +1124,7 @@ class Financial * @param float $nominal_rate Nominal interest rate * @param int $npery Number of compounding payments per year * - * @return float + * @return float|string */ public static function EFFECT($nominal_rate = 0, $npery = 0) { @@ -1160,7 +1160,7 @@ class Financial * 0 or omitted At the end of the period. * 1 At the beginning of the period. * - * @return float + * @return float|string */ public static function FV($rate = 0, $nper = 0, $pmt = 0, $pv = 0, $type = 0) { @@ -1230,7 +1230,7 @@ class Financial * 3 Actual/365 * 4 European 30/360 * - * @return float + * @return float|string */ public static function INTRATE($settlement, $maturity, $investment, $redemption, $basis = 0) { @@ -1275,7 +1275,7 @@ class Financial * @param float $fv Future Value * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period * - * @return float + * @return float|string */ public static function IPMT($rate, $per, $nper, $pv, $fv = 0, $type = 0) { @@ -1318,7 +1318,7 @@ class Financial * calculate the internal rate of return. * @param float $guess A number that you guess is close to the result of IRR * - * @return float + * @return float|string */ public static function IRR($values, $guess = 0.1) { @@ -1428,7 +1428,7 @@ class Financial * @param float $finance_rate The interest rate you pay on the money used in the cash flows * @param float $reinvestment_rate The interest rate you receive on the cash flows as you reinvest them * - * @return float + * @return float|string */ public static function MIRR($values, $finance_rate, $reinvestment_rate) { @@ -1470,7 +1470,7 @@ class Financial * @param float $effect_rate Effective interest rate * @param int $npery Number of compounding payments per year * - * @return float + * @return float|string */ public static function NOMINAL($effect_rate = 0, $npery = 0) { @@ -1497,7 +1497,7 @@ class Financial * @param float $fv Future Value * @param int $type Payment type: 0 = at the end of each period, 1 = at the beginning of each period * - * @return float + * @return float|string */ public static function NPER($rate = 0, $pmt = 0, $pv = 0, $fv = 0, $type = 0) { @@ -1556,6 +1556,33 @@ class Financial return $returnValue; } + /** + * PDURATION. + * + * Calculates the number of periods required for an investment to reach a specified value. + * + * @param float $rate Interest rate per period + * @param float $pv Present Value + * @param float $fv Future Value + * + * @return float|string + */ + public static function PDURATION($rate = 0, $pv = 0, $fv = 0) + { + $rate = Functions::flattenSingleValue($rate); + $pv = Functions::flattenSingleValue($pv); + $fv = Functions::flattenSingleValue($fv); + + // Validate parameters + if (!is_numeric($rate) || !is_numeric($pv) || !is_numeric($fv)) { + return Functions::VALUE(); + } elseif ($rate <= 0.0 || $pv <= 0.0 || $fv <= 0.0) { + return Functions::NAN(); + } + + return (log($fv) - log($pv)) / log(1 + $rate); + } + /** * PMT. * @@ -1933,6 +1960,33 @@ class Financial return Functions::VALUE(); } + /** + * RRI. + * + * Calculates the interest rate required for an investment to grow to a specified future value . + * + * @param float $nper The number of periods over which the investment is made + * @param float $pv Present Value + * @param float $fv Future Value + * + * @return float|string + */ + public static function RRI($nper = 0, $pv = 0, $fv = 0) + { + $nper = Functions::flattenSingleValue($nper); + $pv = Functions::flattenSingleValue($pv); + $fv = Functions::flattenSingleValue($fv); + + // Validate parameters + if (!is_numeric($nper) || !is_numeric($pv) || !is_numeric($fv)) { + return Functions::VALUE(); + } elseif ($nper <= 0.0 || $pv <= 0.0 || $fv < 0.0) { + return Functions::NAN(); + } + + return pow($fv / $pv, 1 / $nper) - 1; + } + /** * SLN. * @@ -1942,7 +1996,7 @@ class Financial * @param mixed $salvage Value at the end of the depreciation * @param mixed $life Number of periods over which the asset is depreciated * - * @return float + * @return float|string */ public static function SLN($cost, $salvage, $life) { @@ -1972,7 +2026,7 @@ class Financial * @param mixed $life Number of periods over which the asset is depreciated * @param mixed $period Period * - * @return float + * @return float|string */ public static function SYD($cost, $salvage, $life, $period) { diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php index b6389a8..6fa07de 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Functions.php @@ -277,7 +277,7 @@ class Functions return '=' . $condition; } - preg_match('/([<>=]+)(.*)/', $condition, $matches); + preg_match('/(=|<[>=]?|>=?)(.*)/', $condition, $matches); list(, $operator, $operand) = $matches; if (!is_numeric($operand)) { @@ -355,7 +355,7 @@ class Functions return false; } - return in_array($value, array_values(self::$errorCodes)); + return in_array($value, self::$errorCodes); } /** @@ -648,17 +648,26 @@ class Functions /** * ISFORMULA. * - * @param mixed $value The cell to check + * @param mixed $cellReference The cell to check * @param Cell $pCell The current cell (containing this formula) * * @return bool|string */ - public static function isFormula($value = '', Cell $pCell = null) + public static function isFormula($cellReference = '', Cell $pCell = null) { if ($pCell === null) { return self::REF(); } - return substr($pCell->getWorksheet()->getCell($value)->getValue(), 0, 1) === '='; + preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellReference, $matches); + + $cellReference = $matches[6] . $matches[7]; + $worksheetName = trim($matches[3], "'"); + + $worksheet = (!empty($worksheetName)) + ? $pCell->getWorksheet()->getParent()->getSheetByName($worksheetName) + : $pCell->getWorksheet(); + + return $worksheet->getCell($cellReference)->isFormula(); } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical.php index 6b12692..c36e3fc 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Logical.php @@ -38,6 +38,32 @@ class Logical return false; } + private static function countTrueValues(array $args) + { + $returnValue = 0; + + foreach ($args as $arg) { + // Is it a boolean value? + if (is_bool($arg)) { + $returnValue += $arg; + } elseif ((is_numeric($arg)) && (!is_string($arg))) { + $returnValue += ((int) $arg != 0); + } elseif (is_string($arg)) { + $arg = strtoupper($arg); + if (($arg == 'TRUE') || ($arg == Calculation::getTRUE())) { + $arg = true; + } elseif (($arg == 'FALSE') || ($arg == Calculation::getFALSE())) { + $arg = false; + } else { + return Functions::VALUE(); + } + $returnValue += ($arg != 0); + } + } + + return $returnValue; + } + /** * LOGICAL_AND. * @@ -62,37 +88,23 @@ class Logical */ public static function logicalAnd(...$args) { - // Return value - $returnValue = true; + $args = Functions::flattenArray($args); - // Loop through the arguments - $aArgs = Functions::flattenArray($args); - $argCount = -1; - foreach ($aArgs as $argCount => $arg) { - // Is it a boolean value? - if (is_bool($arg)) { - $returnValue = $returnValue && $arg; - } elseif ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue = $returnValue && ($arg != 0); - } elseif (is_string($arg)) { - $arg = strtoupper($arg); - if (($arg == 'TRUE') || ($arg == Calculation::getTRUE())) { - $arg = true; - } elseif (($arg == 'FALSE') || ($arg == Calculation::getFALSE())) { - $arg = false; - } else { - return Functions::VALUE(); - } - $returnValue = $returnValue && ($arg != 0); - } - } - - // Return - if ($argCount < 0) { + if (count($args) == 0) { return Functions::VALUE(); } - return $returnValue; + $args = array_filter($args, function ($value) { + return $value !== null || (is_string($value) && trim($value) == ''); + }); + $argCount = count($args); + + $returnValue = self::countTrueValues($args); + if (is_string($returnValue)) { + return $returnValue; + } + + return ($returnValue > 0) && ($returnValue == $argCount); } /** @@ -119,37 +131,65 @@ class Logical */ public static function logicalOr(...$args) { - // Return value - $returnValue = false; + $args = Functions::flattenArray($args); - // Loop through the arguments - $aArgs = Functions::flattenArray($args); - $argCount = -1; - foreach ($aArgs as $argCount => $arg) { - // Is it a boolean value? - if (is_bool($arg)) { - $returnValue = $returnValue || $arg; - } elseif ((is_numeric($arg)) && (!is_string($arg))) { - $returnValue = $returnValue || ($arg != 0); - } elseif (is_string($arg)) { - $arg = strtoupper($arg); - if (($arg == 'TRUE') || ($arg == Calculation::getTRUE())) { - $arg = true; - } elseif (($arg == 'FALSE') || ($arg == Calculation::getFALSE())) { - $arg = false; - } else { - return Functions::VALUE(); - } - $returnValue = $returnValue || ($arg != 0); - } - } - - // Return - if ($argCount < 0) { + if (count($args) == 0) { return Functions::VALUE(); } - return $returnValue; + $args = array_filter($args, function ($value) { + return $value !== null || (is_string($value) && trim($value) == ''); + }); + + $returnValue = self::countTrueValues($args); + if (is_string($returnValue)) { + return $returnValue; + } + + return $returnValue > 0; + } + + /** + * LOGICAL_XOR. + * + * Returns the Exclusive Or logical operation for one or more supplied conditions. + * i.e. the Xor function returns TRUE if an odd number of the supplied conditions evaluate to TRUE, and FALSE otherwise. + * + * Excel Function: + * =XOR(logical1[,logical2[, ...]]) + * + * The arguments must evaluate to logical values such as TRUE or FALSE, or the arguments must be arrays + * or references that contain logical values. + * + * Boolean arguments are treated as True or False as appropriate + * Integer or floating point arguments are treated as True, except for 0 or 0.0 which are False + * If any argument value is a string, or a Null, the function returns a #VALUE! error, unless the string holds + * the value TRUE or FALSE, in which case it is evaluated as the corresponding boolean value + * + * @category Logical Functions + * + * @param mixed $args Data values + * + * @return bool|string the logical XOR of the arguments + */ + public static function logicalXor(...$args) + { + $args = Functions::flattenArray($args); + + if (count($args) == 0) { + return Functions::VALUE(); + } + + $args = array_filter($args, function ($value) { + return $value !== null || (is_string($value) && trim($value) == ''); + }); + + $returnValue = self::countTrueValues($args); + if (is_string($returnValue)) { + return $returnValue; + } + + return $returnValue % 2 == 1; } /** @@ -176,6 +216,7 @@ class Logical public static function NOT($logical = false) { $logical = Functions::flattenSingleValue($logical); + if (is_string($logical)) { $logical = strtoupper($logical); if (($logical == 'TRUE') || ($logical == Calculation::getTRUE())) { diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef.php index d8cdc24..71550a7 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/LookupRef.php @@ -866,4 +866,33 @@ class LookupRef return self::VLOOKUP($lookup_value, $lookup_vector, 2); } + + /** + * FORMULATEXT. + * + * @param mixed $cellReference The cell to check + * @param Cell $pCell The current cell (containing this formula) + * + * @return string + */ + public static function FORMULATEXT($cellReference = '', Cell $pCell = null) + { + if ($pCell === null) { + return Functions::REF(); + } + + preg_match('/^' . Calculation::CALCULATION_REGEXP_CELLREF . '$/i', $cellReference, $matches); + + $cellReference = $matches[6] . $matches[7]; + $worksheetName = trim($matches[3], "'"); + $worksheet = (!empty($worksheetName)) + ? $pCell->getWorksheet()->getParent()->getSheetByName($worksheetName) + : $pCell->getWorksheet(); + + if (!$worksheet->getCell($cellReference)->isFormula()) { + return Functions::NA(); + } + + return $worksheet->getCell($cellReference)->getValue(); + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig.php index 46e9f1a..41fc0de 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/MathTrig.php @@ -1081,30 +1081,55 @@ class MathTrig ); } + protected static function filterFormulaArgs($cellReference, $args) + { + return array_filter( + $args, + function ($index) use ($cellReference) { + list(, $row, $column) = explode('.', $index); + if ($cellReference->getWorksheet()->cellExists($column . $row)) { + //take this cell out if it contains the SUBTOTAL or AGGREGATE functions in a formula + $isFormula = $cellReference->getWorksheet()->getCell($column . $row)->isFormula(); + $cellFormula = !preg_match('/^=.*\b(SUBTOTAL|AGGREGATE)\s*\(/i', $cellReference->getWorksheet()->getCell($column . $row)->getValue()); + + return !$isFormula || $cellFormula; + } + + return true; + }, + ARRAY_FILTER_USE_KEY + ); + } + /** * SUBTOTAL. * * Returns a subtotal in a list or database. * * @param int the number 1 to 11 that specifies which function to - * use in calculating subtotals within a list + * use in calculating subtotals within a range + * list + * Numbers 101 to 111 shadow the functions of 1 to 11 + * but ignore any values in the range that are + * in hidden rows or columns * @param array of mixed Data Series * * @return float */ public static function SUBTOTAL(...$args) { + $cellReference = array_pop($args); $aArgs = Functions::flattenArrayIndexed($args); - $cellReference = array_pop($aArgs); $subtotal = array_shift($aArgs); // Calculate if ((is_numeric($subtotal)) && (!is_string($subtotal))) { if ($subtotal > 100) { $aArgs = self::filterHiddenArgs($cellReference, $aArgs); - $subtotal = $subtotal - 100; + $subtotal -= 100; } + $aArgs = self::filterFormulaArgs($cellReference, $aArgs); switch ($subtotal) { case 1: return Statistical::AVERAGE($aArgs); @@ -1433,4 +1458,178 @@ class MathTrig return ((int) ($value * $adjust)) / $adjust; } + + /** + * SEC. + * + * Returns the secant of an angle. + * + * @param float $angle Number + * + * @return float|string The secant of the angle + */ + public static function SEC($angle) + { + $angle = Functions::flattenSingleValue($angle); + + if (!is_numeric($angle)) { + return Functions::VALUE(); + } + + $result = cos($angle); + + return ($result == 0.0) ? Functions::DIV0() : 1 / $result; + } + + /** + * SECH. + * + * Returns the hyperbolic secant of an angle. + * + * @param float $angle Number + * + * @return float|string The hyperbolic secant of the angle + */ + public static function SECH($angle) + { + $angle = Functions::flattenSingleValue($angle); + + if (!is_numeric($angle)) { + return Functions::VALUE(); + } + + $result = cosh($angle); + + return ($result == 0.0) ? Functions::DIV0() : 1 / $result; + } + + /** + * CSC. + * + * Returns the cosecant of an angle. + * + * @param float $angle Number + * + * @return float|string The cosecant of the angle + */ + public static function CSC($angle) + { + $angle = Functions::flattenSingleValue($angle); + + if (!is_numeric($angle)) { + return Functions::VALUE(); + } + + $result = sin($angle); + + return ($result == 0.0) ? Functions::DIV0() : 1 / $result; + } + + /** + * CSCH. + * + * Returns the hyperbolic cosecant of an angle. + * + * @param float $angle Number + * + * @return float|string The hyperbolic cosecant of the angle + */ + public static function CSCH($angle) + { + $angle = Functions::flattenSingleValue($angle); + + if (!is_numeric($angle)) { + return Functions::VALUE(); + } + + $result = sinh($angle); + + return ($result == 0.0) ? Functions::DIV0() : 1 / $result; + } + + /** + * COT. + * + * Returns the cotangent of an angle. + * + * @param float $angle Number + * + * @return float|string The cotangent of the angle + */ + public static function COT($angle) + { + $angle = Functions::flattenSingleValue($angle); + + if (!is_numeric($angle)) { + return Functions::VALUE(); + } + + $result = tan($angle); + + return ($result == 0.0) ? Functions::DIV0() : 1 / $result; + } + + /** + * COTH. + * + * Returns the hyperbolic cotangent of an angle. + * + * @param float $angle Number + * + * @return float|string The hyperbolic cotangent of the angle + */ + public static function COTH($angle) + { + $angle = Functions::flattenSingleValue($angle); + + if (!is_numeric($angle)) { + return Functions::VALUE(); + } + + $result = tanh($angle); + + return ($result == 0.0) ? Functions::DIV0() : 1 / $result; + } + + /** + * ACOT. + * + * Returns the arccotangent of a number. + * + * @param float $number Number + * + * @return float|string The arccotangent of the number + */ + public static function ACOT($number) + { + $number = Functions::flattenSingleValue($number); + + if (!is_numeric($number)) { + return Functions::VALUE(); + } + + return (M_PI / 2) - atan($number); + } + + /** + * ACOTH. + * + * Returns the hyperbolic arccotangent of a number. + * + * @param float $number Number + * + * @return float|string The hyperbolic arccotangent of the number + */ + public static function ACOTH($number) + { + $number = Functions::flattenSingleValue($number); + + if (!is_numeric($number)) { + return Functions::VALUE(); + } + + $result = log(($number + 1) / ($number - 1)) / 2; + + return is_nan($result) ? Functions::NAN() : $result; + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData.php index f0e8a3c..e30b2ff 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/TextData.php @@ -577,4 +577,96 @@ class TextData return (float) $value; } + + /** + * NUMBERVALUE. + * + * @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 + * + * @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 /= pow(10, $percentageAdjustment * 2); + } + } + + return (float) $value; + } + + /** + * Compares two text strings and returns TRUE if they are exactly the same, FALSE otherwise. + * EXACT is case-sensitive but ignores formatting differences. + * Use EXACT to test text being entered into a document. + * + * @param $value1 + * @param $value2 + * + * @return bool + */ + public static function EXACT($value1, $value2) + { + $value1 = Functions::flattenSingleValue($value1); + $value2 = Functions::flattenSingleValue($value2); + + return (string) $value2 === (string) $value1; + } + + /** + * TEXTJOIN. + * + * @param mixed $delimiter + * @param mixed $ignoreEmpty + * @param mixed $args + * + * @return string + */ + 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)) { + if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) { + $arg = (int) $arg; + } else { + $arg = ($arg) ? Calculation::getTRUE() : Calculation::getFALSE(); + } + } + } + + return implode($delimiter, $aArgs); + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/functionlist.txt b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/functionlist.txt index 5ac6cf4..7043f76 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/functionlist.txt +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/functionlist.txt @@ -3,6 +3,8 @@ ACCRINT ACCRINTM ACOS ACOSH +ACOT +ACOTH ADDRESS AMORDEGRC AMORLINC @@ -30,6 +32,11 @@ BIN2DEC BIN2HEX BIN2OCT BINOMDIST +BITAND +BITLSHIFT +BITOR +BITRSHIFT +BITXOR CEILING CELL CHAR @@ -43,12 +50,15 @@ COLUMN COLUMNS COMBIN COMPLEX +CONCAT CONCATENATE CONFIDENCE CONVERT CORREL COS COSH +COT +COTH COUNT COUNTA COUNTBLANK @@ -62,6 +72,8 @@ COUPNUM COUPPCD COVAR CRITBINOM +CSC +CSCH CUBEKPIMEMBER CUBEMEMBER CUBEMEMBERPROPERTY @@ -105,7 +117,9 @@ EDATE EFFECT EOMONTH ERF +ERF.PRECISE ERFC +ERFC.PRECISE ERROR.TYPE EVEN EXACT @@ -149,6 +163,10 @@ IMAGINARY IMARGUMENT IMCONJUGATE IMCOS +IMCOSH +IMCOT +IMCSC +IMCSCH IMEXP IMLN IMLOG10 @@ -156,10 +174,14 @@ IMLOG2 IMPOWER IMPRODUCT IMREAL +IMSEC +IMSECH IMSIN +IMSINH IMSQRT IMSUB IMSUM +IMTAN INDEX INDIRECT INFO @@ -177,6 +199,7 @@ ISNA ISNONTEXT ISNUMBER ISODD +ISOWEEKNUM ISPMT ISREF ISTEXT @@ -229,6 +252,7 @@ NOT NOW NPER NPV +NUMBERVALUE OCT2BIN OCT2DEC OCT2HEX @@ -239,6 +263,7 @@ ODDLPRICE ODDLYIELD OFFSET OR +PDURATION PEARSON PERCENTILE PERCENTRANK @@ -275,10 +300,13 @@ ROUNDDOWN ROUNDUP ROW ROWS +RRI RSQ RTD SEARCH SEARCHB +SEC +SECH SECOND SERIESSUM SIGN @@ -292,6 +320,8 @@ SQRT SQRTPI STANDARDIZE STDEV +STDEV.A +STDEV.P STDEVA STDEVP STDEVPA @@ -315,6 +345,7 @@ TBILLPRICE TBILLYIELD TDIST TEXT +TEXTJOIN TIME TIMEVALUE TINV @@ -327,6 +358,8 @@ TRUE TRUNC TTEST TYPE +UNICHAR +UNIORD UPPER USDOLLAR VALUE @@ -342,6 +375,7 @@ WEIBULL WORKDAY XIRR XNPV +XOR YEAR YEARFRAC YIELD diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php index 1efcb62..366ec49 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Coordinate.php @@ -327,7 +327,7 @@ abstract class Coordinate } /** - * Extract all cell references in range. + * Extract all cell references in range, which may be comprised of multiple cell ranges. * * @param string $pRange Range (e.g. A1 or A1:C10 or A1:E10 A20:E25) * @@ -335,49 +335,12 @@ abstract class Coordinate */ public static function extractAllCellReferencesInRange($pRange) { - // Returnvalue $returnValue = []; // Explode spaces - $cellBlocks = explode(' ', str_replace('$', '', strtoupper($pRange))); + $cellBlocks = self::getCellBlocksFromRangeString($pRange); foreach ($cellBlocks as $cellBlock) { - // Single cell? - if (!self::coordinateIsRange($cellBlock)) { - $returnValue[] = $cellBlock; - - continue; - } - - // Range... - $ranges = self::splitRange($cellBlock); - foreach ($ranges as $range) { - // Single cell? - if (!isset($range[1])) { - $returnValue[] = $range[0]; - - continue; - } - - // Range... - list($rangeStart, $rangeEnd) = $range; - sscanf($rangeStart, '%[A-Z]%d', $startCol, $startRow); - sscanf($rangeEnd, '%[A-Z]%d', $endCol, $endRow); - ++$endCol; - - // Current data - $currentCol = $startCol; - $currentRow = $startRow; - - // Loop cells - while ($currentCol != $endCol) { - while ($currentRow <= $endRow) { - $returnValue[] = $currentCol . $currentRow; - ++$currentRow; - } - ++$currentCol; - $currentRow = $startRow; - } - } + $returnValue = array_merge($returnValue, self::getReferencesForCellBlock($cellBlock)); } // Sort the result by column and row @@ -392,6 +355,60 @@ abstract class Coordinate return array_values($sortKeys); } + /** + * Get all cell references for an individual cell block. + * + * @param string $cellBlock A cell range e.g. A4:B5 + * + * @return array All individual cells in that range + */ + private static function getReferencesForCellBlock($cellBlock) + { + $returnValue = []; + + // Single cell? + if (!self::coordinateIsRange($cellBlock)) { + return (array) $cellBlock; + } + + // Range... + $ranges = self::splitRange($cellBlock); + foreach ($ranges as $range) { + // Single cell? + if (!isset($range[1])) { + $returnValue[] = $range[0]; + + continue; + } + + // Range... + list($rangeStart, $rangeEnd) = $range; + list($startColumn, $startRow) = self::coordinateFromString($rangeStart); + list($endColumn, $endRow) = self::coordinateFromString($rangeEnd); + $startColumnIndex = self::columnIndexFromString($startColumn); + $endColumnIndex = self::columnIndexFromString($endColumn); + ++$endColumnIndex; + + // Current data + $currentColumnIndex = $startColumnIndex; + $currentRow = $startRow; + + self::validateRange($cellBlock, $startColumnIndex, $endColumnIndex, $currentRow, $endRow); + + // Loop cells + while ($currentColumnIndex < $endColumnIndex) { + while ($currentRow <= $endRow) { + $returnValue[] = self::stringFromColumnIndex($currentColumnIndex) . $currentRow; + ++$currentRow; + } + ++$currentColumnIndex; + $currentRow = $startRow; + } + } + + return $returnValue; + } + /** * Convert an associative array of single cell coordinates to values to an associative array * of cell ranges to values. Only adjacent cell coordinates with the same @@ -477,4 +494,33 @@ abstract class Coordinate return $mergedCoordCollection; } + + /** + * Get the individual cell blocks from a range string, splitting by space and removing any $ characters. + * + * @param string $pRange + * + * @return string[] + */ + private static function getCellBlocksFromRangeString($pRange) + { + return explode(' ', str_replace('$', '', strtoupper($pRange))); + } + + /** + * Check that the given range is valid, i.e. that the start column and row are not greater than the end column and + * row. + * + * @param string $cellBlock The original range, for displaying a meaningful error message + * @param int $startColumnIndex + * @param int $endColumnIndex + * @param int $currentRow + * @param int $endRow + */ + private static function validateRange($cellBlock, $startColumnIndex, $endColumnIndex, $currentRow, $endRow) + { + if ($startColumnIndex >= $endColumnIndex || $currentRow > $endRow) { + throw new Exception('Invalid range: "' . $cellBlock . '"'); + } + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php index ad48cb6..e17c20d 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Cell/Hyperlink.php @@ -89,6 +89,14 @@ class Hyperlink return strpos($this->url, 'sheet://') !== false; } + /** + * @return string + */ + public function getTypeHyperlink() + { + return $this->isInternal() ? '' : 'External'; + } + /** * Get hash code. * diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php index 2bda0c9..8056bbe 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Chart/DataSeries.php @@ -217,7 +217,7 @@ class DataSeries /** * Get Plot Order. * - * @return string + * @return int[] */ public function getPlotOrder() { diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php index 61c66a8..eaf7302 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Html.php @@ -603,6 +603,13 @@ class Html $this->stringData = ''; } + /** + * Parse HTML formatting and return the resulting RichText. + * + * @param string $html + * + * @return RichText + */ public function toRichTextObject($html) { $this->initialise(); @@ -611,8 +618,8 @@ class Html $dom = new DOMDocument(); // Load the HTML file into the DOM object // Note the use of error suppression, because typically this will be an html fragment, so not fully valid markup - @$dom->loadHTML($html); - + $prefix = ''; + @$dom->loadHTML($prefix . $html, LIBXML_HTML_NOIMPLIED | LIBXML_HTML_NODEFDTD); // Discard excess white space $dom->preserveWhiteSpace = false; diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Migrator.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Migrator.php index b6d5f2a..26d5fce 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Migrator.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Helper/Migrator.php @@ -4,6 +4,22 @@ namespace PhpOffice\PhpSpreadsheet\Helper; class Migrator { + /** + * @var string[] + */ + private $from; + + /** + * @var string[] + */ + private $to; + + public function __construct() + { + $this->from = array_keys($this->getMapping()); + $this->to = array_values($this->getMapping()); + } + /** * Return the ordered mapping from old PHPExcel class names to new PhpSpreadsheet one. * @@ -204,7 +220,6 @@ class Migrator 'PHPExcel_Settings' => \PhpOffice\PhpSpreadsheet\Settings::class, 'PHPExcel_Style' => \PhpOffice\PhpSpreadsheet\Style\Style::class, 'PHPExcel_Worksheet' => \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet::class, - 'PHPExcel' => \PhpOffice\PhpSpreadsheet\Spreadsheet::class, ]; $methods = [ @@ -249,19 +264,25 @@ class Migrator { $patterns = [ '/*.md', - '/*.php', - '/*.phtml', '/*.txt', '/*.TXT', + '/*.php', + '/*.phpt', + '/*.php3', + '/*.php4', + '/*.php5', + '/*.phtml', ]; - $from = array_keys($this->getMapping()); - $to = array_values($this->getMapping()); - foreach ($patterns as $pattern) { foreach (glob($path . $pattern) as $file) { + if (strpos($path, '/vendor/') !== false) { + echo $file . " skipped\n"; + + continue; + } $original = file_get_contents($file); - $converted = str_replace($from, $to, $original); + $converted = $this->replace($original); if ($original !== $converted) { echo $file . " converted\n"; @@ -290,4 +311,23 @@ class Migrator $this->recursiveReplace($path); } } + + /** + * Migrate the given code from PHPExcel to PhpSpreadsheet. + * + * @param string $original + * + * @return string + */ + public function replace($original) + { + $converted = str_replace($this->from, $this->to, $original); + + // The string "PHPExcel" gets special treatment because of how common it might be. + // This regex requires a word boundary around the string, and it can't be + // preceded by $ or -> (goal is to filter out cases where a variable is named $PHPExcel or similar) + $converted = preg_replace('~(?)(\b|\\\\)PHPExcel\b~', '\\' . \PhpOffice\PhpSpreadsheet\Spreadsheet::class, $converted); + + return $converted; + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv.php index 6adb6ee..6899773 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Csv.php @@ -50,6 +50,13 @@ class Csv extends BaseReader */ private $contiguousRow = -1; + /** + * The character that can escape the enclosure. + * + * @var string + */ + private $escapeCharacter = '\\'; + /** * Create a new CSV Reader instance. */ @@ -254,7 +261,7 @@ class Csv extends BaseReader $worksheetInfo[0]['totalColumns'] = 0; // Loop through each line of the file in turn - while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) { + while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure, $this->escapeCharacter)) !== false) { ++$worksheetInfo[0]['totalRows']; $worksheetInfo[0]['lastColumnIndex'] = max($worksheetInfo[0]['lastColumnIndex'], count($rowData) - 1); } @@ -326,7 +333,7 @@ class Csv extends BaseReader } // Loop through each line of the file in turn - while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure)) !== false) { + while (($rowData = fgetcsv($fileHandle, 0, $this->delimiter, $this->enclosure, $this->escapeCharacter)) !== false) { $columnLetter = 'A'; foreach ($rowData as $rowDatum) { if ($rowDatum != '' && $this->readFilter->readCell($columnLetter, $currentRow)) { @@ -458,6 +465,30 @@ class Csv extends BaseReader return $this->contiguous; } + /** + * Set escape backslashes. + * + * @param string $escapeCharacter + * + * @return $this + */ + public function setEscapeCharacter($escapeCharacter) + { + $this->escapeCharacter = $escapeCharacter; + + return $this; + } + + /** + * Get escape backslashes. + * + * @return string + */ + public function getEscapeCharacter() + { + return $this->escapeCharacter; + } + /** * Can the current IReader read the file? * @@ -476,6 +507,12 @@ class Csv extends BaseReader fclose($this->fileHandle); + // Trust file extension if any + if (strtolower(pathinfo($pFilename, PATHINFO_EXTENSION)) === 'csv') { + return true; + } + + // Attempt to guess mimetype $type = mime_content_type($pFilename); $supportedTypes = [ 'text/csv', diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php index 9d44c8c..b570fa4 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Html.php @@ -554,6 +554,7 @@ class Html extends BaseReader $row = 0; $column = 'A'; $content = ''; + $this->rowspan = []; $this->processDomElement($dom, $spreadsheet->getActiveSheet(), $row, $column, $content); // Return diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/IReadFilter.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/IReadFilter.php index 03c48db..ccfe05a 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/IReadFilter.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/IReadFilter.php @@ -7,9 +7,9 @@ interface IReadFilter /** * Should this cell be read? * - * @param $column string Column address (as a string value like "A", or "IV") - * @param $row int Row number - * @param $worksheetName string Optional worksheet name + * @param string $column Column address (as a string value like "A", or "IV") + * @param int $row Row number + * @param string $worksheetName Optional worksheet name * * @return bool */ diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php index 734ab2a..c6e8512 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xlsx.php @@ -3,6 +3,7 @@ namespace PhpOffice\PhpSpreadsheet\Reader; use PhpOffice\PhpSpreadsheet\Cell\Coordinate; +use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; use PhpOffice\PhpSpreadsheet\Document\Properties; use PhpOffice\PhpSpreadsheet\NamedRange; use PhpOffice\PhpSpreadsheet\Reader\Xlsx\Chart; @@ -25,6 +26,7 @@ use PhpOffice\PhpSpreadsheet\Style\Style; use PhpOffice\PhpSpreadsheet\Worksheet\AutoFilter\Column; use PhpOffice\PhpSpreadsheet\Worksheet\HeaderFooterDrawing; use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; +use SimpleXMLElement; use XMLReader; use ZipArchive; @@ -115,15 +117,17 @@ class Xlsx extends BaseReader $zip->open($pFilename); // The files we're looking at here are small enough that simpleXML is more efficient than XMLReader + //~ http://schemas.openxmlformats.org/package/2006/relationships"); $rels = simplexml_load_string( $this->securityScan($this->getFromZipArchive($zip, '_rels/.rels')) - ); //~ http://schemas.openxmlformats.org/package/2006/relationships"); + ); foreach ($rels->Relationship as $rel) { switch ($rel['Type']) { case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument': + //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $xmlWorkbook = simplexml_load_string( $this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")) - ); //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" + ); if ($xmlWorkbook->sheets) { foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { @@ -157,8 +161,8 @@ class Xlsx extends BaseReader $zip = new ZipArchive(); $zip->open($pFilename); + //~ http://schemas.openxmlformats.org/package/2006/relationships" $rels = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan($this->getFromZipArchive($zip, '_rels/.rels')), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() @@ -166,8 +170,9 @@ class Xlsx extends BaseReader foreach ($rels->Relationship as $rel) { if ($rel['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument') { $dir = dirname($rel['Target']); + + //~ http://schemas.openxmlformats.org/package/2006/relationships" $relsWorkbook = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan( $this->getFromZipArchive($zip, "$dir/_rels/" . basename($rel['Target']) . '.rels') ), @@ -183,8 +188,8 @@ class Xlsx extends BaseReader } } + //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $xmlWorkbook = simplexml_load_string( - //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $this->securityScan( $this->getFromZipArchive($zip, "{$rel['Target']}") ), @@ -193,7 +198,7 @@ class Xlsx extends BaseReader ); if ($xmlWorkbook->sheets) { $dir = dirname($rel['Target']); - /** @var \SimpleXMLElement $eleSheet */ + /** @var SimpleXMLElement $eleSheet */ foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { $tmpInfo = [ 'worksheetName' => (string) $eleSheet['name'], @@ -316,6 +321,60 @@ class Xlsx extends BaseReader return $contents; } + /** + * Set Worksheet column attributes by attributes array passed. + * + * @param Worksheet $docSheet + * @param string $column A, B, ... DX, ... + * @param array $columnAttributes array of attributes (indexes are attribute name, values are value) + * 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'width', ... ? + */ + private function setColumnAttributes(Worksheet $docSheet, $column, array $columnAttributes) + { + if (isset($columnAttributes['xfIndex'])) { + $docSheet->getColumnDimension($column)->setXfIndex($columnAttributes['xfIndex']); + } + if (isset($columnAttributes['visible'])) { + $docSheet->getColumnDimension($column)->setVisible($columnAttributes['visible']); + } + if (isset($columnAttributes['collapsed'])) { + $docSheet->getColumnDimension($column)->setCollapsed($columnAttributes['collapsed']); + } + if (isset($columnAttributes['outlineLevel'])) { + $docSheet->getColumnDimension($column)->setOutlineLevel($columnAttributes['outlineLevel']); + } + if (isset($columnAttributes['width'])) { + $docSheet->getColumnDimension($column)->setWidth($columnAttributes['width']); + } + } + + /** + * Set Worksheet row attributes by attributes array passed. + * + * @param Worksheet $docSheet + * @param int $row 1, 2, 3, ... 99, ... + * @param array $rowAttributes array of attributes (indexes are attribute name, values are value) + * 'xfIndex', 'visible', 'collapsed', 'outlineLevel', 'rowHeight', ... ? + */ + private function setRowAttributes(Worksheet $docSheet, $row, array $rowAttributes) + { + if (isset($rowAttributes['xfIndex'])) { + $docSheet->getRowDimension($row)->setXfIndex($rowAttributes['xfIndex']); + } + if (isset($rowAttributes['visible'])) { + $docSheet->getRowDimension($row)->setVisible($rowAttributes['visible']); + } + if (isset($rowAttributes['collapsed'])) { + $docSheet->getRowDimension($row)->setCollapsed($rowAttributes['collapsed']); + } + if (isset($rowAttributes['outlineLevel'])) { + $docSheet->getRowDimension($row)->setOutlineLevel($rowAttributes['outlineLevel']); + } + if (isset($rowAttributes['rowHeight'])) { + $docSheet->getRowDimension($row)->setRowHeight($rowAttributes['rowHeight']); + } + } + /** * Loads Spreadsheet from file. * @@ -336,13 +395,14 @@ class Xlsx extends BaseReader $excel->removeCellStyleXfByIndex(0); // remove the default style $excel->removeCellXfByIndex(0); // remove the default style } + $unparsedLoadedData = []; $zip = new ZipArchive(); $zip->open($pFilename); // Read the theme first, because we need the colour scheme when reading the styles + //~ http://schemas.openxmlformats.org/package/2006/relationships" $wbRels = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan($this->getFromZipArchive($zip, 'xl/_rels/workbook.xml.rels')), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() @@ -388,8 +448,8 @@ class Xlsx extends BaseReader } } + //~ http://schemas.openxmlformats.org/package/2006/relationships" $rels = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan($this->getFromZipArchive($zip, '_rels/.rels')), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() @@ -444,7 +504,7 @@ class Xlsx extends BaseReader ); if (is_object($xmlCore)) { $docProps = $excel->getProperties(); - /** @var \SimpleXMLElement $xmlProperty */ + /** @var SimpleXMLElement $xmlProperty */ foreach ($xmlCore as $xmlProperty) { $cellDataOfficeAttributes = $xmlProperty->attributes(); if (isset($cellDataOfficeAttributes['name'])) { @@ -470,8 +530,8 @@ class Xlsx extends BaseReader break; case 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument': $dir = dirname($rel['Target']); + //~ http://schemas.openxmlformats.org/package/2006/relationships" $relsWorkbook = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan($this->getFromZipArchive($zip, "$dir/_rels/" . basename($rel['Target']) . '.rels')), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() @@ -480,8 +540,8 @@ class Xlsx extends BaseReader $sharedStrings = []; $xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/sharedStrings']")); + //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $xmlStrings = simplexml_load_string( - //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() @@ -527,8 +587,8 @@ class Xlsx extends BaseReader $styles = []; $cellStyles = []; $xpath = self::getArrayItem($relsWorkbook->xpath("rel:Relationship[@Type='http://schemas.openxmlformats.org/officeDocument/2006/relationships/styles']")); + //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $xmlStyles = simplexml_load_string( - //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $this->securityScan($this->getFromZipArchive($zip, "$dir/$xpath[Target]")), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() @@ -638,8 +698,8 @@ class Xlsx extends BaseReader } } + //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $xmlWorkbook = simplexml_load_string( - //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $this->securityScan($this->getFromZipArchive($zip, "{$rel['Target']}")), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() @@ -655,6 +715,9 @@ class Xlsx extends BaseReader } } + // Set protection + $this->readProtection($excel, $xmlWorkbook); + $sheetId = 0; // keep track of new sheet id in final workbook $oldSheetId = -1; // keep track of old sheet id in final workbook $countSkippedSheets = 0; // keep track of number of skipped sheets @@ -663,7 +726,7 @@ class Xlsx extends BaseReader $charts = $chartDetails = []; if ($xmlWorkbook->sheets) { - /** @var \SimpleXMLElement $eleSheet */ + /** @var SimpleXMLElement $eleSheet */ foreach ($xmlWorkbook->sheets->sheet as $eleSheet) { ++$oldSheetId; @@ -687,8 +750,8 @@ class Xlsx extends BaseReader // reverse $docSheet->setTitle((string) $eleSheet['name'], false, false); $fileWorksheet = $worksheets[(string) self::getArrayItem($eleSheet->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'), 'id')]; + //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $xmlSheet = simplexml_load_string( - //~ http://schemas.openxmlformats.org/spreadsheetml/2006/main" $this->securityScan($this->getFromZipArchive($zip, "$dir/$fileWorksheet")), 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() @@ -811,30 +874,6 @@ class Xlsx extends BaseReader } } - if (isset($xmlSheet->cols) && !$this->readDataOnly) { - foreach ($xmlSheet->cols->col as $col) { - for ($i = (int) ($col['min']); $i <= (int) ($col['max']); ++$i) { - if ($col['style'] && !$this->readDataOnly) { - $docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setXfIndex((int) ($col['style'])); - } - if (self::boolean($col['hidden'])) { - $docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setVisible(false); - } - if (self::boolean($col['collapsed'])) { - $docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setCollapsed(true); - } - if ($col['outlineLevel'] > 0) { - $docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setOutlineLevel((int) ($col['outlineLevel'])); - } - $docSheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setWidth((float) ($col['width'])); - - if ((int) ($col['max']) == 16384) { - break; - } - } - } - } - if (isset($xmlSheet->printOptions) && !$this->readDataOnly) { if (self::boolean((string) $xmlSheet->printOptions['gridLinesSet'])) { $docSheet->setShowGridlines(true); @@ -850,25 +889,11 @@ class Xlsx extends BaseReader } } + $this->readColumnsAndRowsAttributes($xmlSheet, $docSheet); + if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { $cIndex = 1; // Cell Start from 1 foreach ($xmlSheet->sheetData->row as $row) { - if ($row['ht'] && !$this->readDataOnly) { - $docSheet->getRowDimension((int) ($row['r']))->setRowHeight((float) ($row['ht'])); - } - if (self::boolean($row['hidden']) && !$this->readDataOnly) { - $docSheet->getRowDimension((int) ($row['r']))->setVisible(false); - } - if (self::boolean($row['collapsed'])) { - $docSheet->getRowDimension((int) ($row['r']))->setCollapsed(true); - } - if ($row['outlineLevel'] > 0) { - $docSheet->getRowDimension((int) ($row['r']))->setOutlineLevel((int) ($row['outlineLevel'])); - } - if ($row['s'] && !$this->readDataOnly) { - $docSheet->getRowDimension((int) ($row['r']))->setXfIndex((int) ($row['s'])); - } - $rowIndex = 1; foreach ($row->c as $c) { $r = (string) $c['r']; @@ -883,7 +908,7 @@ class Xlsx extends BaseReader if ($this->getReadFilter() !== null) { $coordinates = Coordinate::coordinateFromString($r); - if (!$this->getReadFilter()->readCell($coordinates[0], $coordinates[1], $docSheet->getTitle())) { + if (!$this->getReadFilter()->readCell($coordinates[0], (int) $coordinates[1], $docSheet->getTitle())) { continue; } } @@ -1068,8 +1093,8 @@ class Xlsx extends BaseReader } // Or Date Group elements foreach ($filters->dateGroupItem as $dateGroupItem) { + // Operator is undefined, but always treated as EQUAL $column->createRule()->setRule( - // Operator is undefined, but always treated as EQUAL null, [ 'year' => (string) $dateGroupItem['year'], @@ -1106,8 +1131,8 @@ class Xlsx extends BaseReader $column->setFilterType(Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); // We should only ever have one dynamic filter foreach ($filterColumn->dynamicFilter as $filterRule) { + // Operator is undefined, but always treated as EQUAL $column->createRule()->setRule( - // Operator is undefined, but always treated as EQUAL null, (string) $filterRule['val'], (string) $filterRule['type'] @@ -1185,6 +1210,11 @@ class Xlsx extends BaseReader self::boolean((string) $xmlSheet->pageSetup['useFirstPageNumber'])) { $docPageSetup->setFirstPageNumber((int) ($xmlSheet->pageSetup['firstPageNumber'])); } + + $relAttributes = $xmlSheet->pageSetup->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + if (isset($relAttributes['id'])) { + $unparsedLoadedData['sheets'][$docSheet->getCodeName()]['pageSetupRelId'] = (string) $relAttributes['id']; + } } if ($xmlSheet && $xmlSheet->headerFooter && !$this->readDataOnly) { @@ -1268,13 +1298,23 @@ class Xlsx extends BaseReader } } + // unparsed sheet AlternateContent + if ($xmlSheet && !$this->readDataOnly) { + $mc = $xmlSheet->children('http://schemas.openxmlformats.org/markup-compatibility/2006'); + if ($mc->AlternateContent) { + foreach ($mc->AlternateContent as $alternateContent) { + $unparsedLoadedData['sheets'][$docSheet->getCodeName()]['AlternateContents'][] = $alternateContent->asXML(); + } + } + } + // Add hyperlinks $hyperlinks = []; if (!$this->readDataOnly) { // Locate hyperlink relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { + //~ http://schemas.openxmlformats.org/package/2006/relationships" $relsWorksheet = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan( $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels') ), @@ -1290,7 +1330,7 @@ class Xlsx extends BaseReader // Loop through hyperlinks if ($xmlSheet && $xmlSheet->hyperlinks) { - /** @var \SimpleXMLElement $hyperlink */ + /** @var SimpleXMLElement $hyperlink */ foreach ($xmlSheet->hyperlinks->hyperlink as $hyperlink) { // Link url $linkRel = $hyperlink->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'); @@ -1322,8 +1362,8 @@ class Xlsx extends BaseReader if (!$this->readDataOnly) { // Locate comment relations if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { + //~ http://schemas.openxmlformats.org/package/2006/relationships" $relsWorksheet = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan( $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels') ), @@ -1367,6 +1407,9 @@ class Xlsx extends BaseReader } } + // later we will remove from it real vmlComments + $unparsedVmlDrawings = $vmlComments; + // Loop through VML comments foreach ($vmlComments as $relName => $relPath) { // Load VML comments file @@ -1407,7 +1450,7 @@ class Xlsx extends BaseReader if (($column !== null) && ($row !== null)) { // Set comment properties - $comment = $docSheet->getCommentByColumnAndRow((string) $column, $row + 1); + $comment = $docSheet->getCommentByColumnAndRow($column + 1, $row + 1); $comment->getFillColor()->setRGB($fillColor); // Parse style @@ -1431,16 +1474,31 @@ class Xlsx extends BaseReader $comment->setVisible($stylePair[1] == 'visible'); } } + + unset($unparsedVmlDrawings[$relName]); } } } } + // unparsed vmlDrawing + if ($unparsedVmlDrawings) { + foreach ($unparsedVmlDrawings as $rId => $relPath) { + $rId = substr($rId, 3); // rIdXXX + $unparsedVmlDrawing = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['vmlDrawings']; + $unparsedVmlDrawing[$rId] = []; + $unparsedVmlDrawing[$rId]['filePath'] = self::dirAdd("$dir/$fileWorksheet", $relPath); + $unparsedVmlDrawing[$rId]['relFilePath'] = $relPath; + $unparsedVmlDrawing[$rId]['content'] = $this->securityScan($this->getFromZipArchive($zip, $unparsedVmlDrawing[$rId]['filePath'])); + unset($unparsedVmlDrawing); + } + } + // Header/footer images if ($xmlSheet && $xmlSheet->legacyDrawingHF && !$this->readDataOnly) { if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { + //~ http://schemas.openxmlformats.org/package/2006/relationships" $relsWorksheet = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan( $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels') ), @@ -1457,8 +1515,8 @@ class Xlsx extends BaseReader if ($vmlRelationship != '') { // Fetch linked images + //~ http://schemas.openxmlformats.org/package/2006/relationships" $relsVML = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan( $this->getFromZipArchive($zip, dirname($vmlRelationship) . '/_rels/' . basename($vmlRelationship) . '.rels') ), @@ -1520,8 +1578,8 @@ class Xlsx extends BaseReader // TODO: Autoshapes from twoCellAnchors! if ($zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { + //~ http://schemas.openxmlformats.org/package/2006/relationships" $relsWorksheet = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan( $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels') ), @@ -1537,8 +1595,8 @@ class Xlsx extends BaseReader if ($xmlSheet->drawing && !$this->readDataOnly) { foreach ($xmlSheet->drawing as $drawing) { $fileDrawing = $drawings[(string) self::getArrayItem($drawing->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'), 'id')]; + //~ http://schemas.openxmlformats.org/package/2006/relationships" $relsDrawing = simplexml_load_string( - //~ http://schemas.openxmlformats.org/package/2006/relationships" $this->securityScan( $this->getFromZipArchive($zip, dirname($fileDrawing) . '/_rels/' . basename($fileDrawing) . '.rels') ), @@ -1546,9 +1604,12 @@ class Xlsx extends BaseReader Settings::getLibXmlLoaderOptions() ); $images = []; - + $hyperlinks = []; if ($relsDrawing && $relsDrawing->Relationship) { foreach ($relsDrawing->Relationship as $ele) { + if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink') { + $hyperlinks[(string) $ele['Id']] = (string) $ele['Target']; + } if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image') { $images[(string) $ele['Id']] = self::dirAdd($fileDrawing, $ele['Target']); } elseif ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/chart') { @@ -1570,12 +1631,15 @@ class Xlsx extends BaseReader if ($xmlDrawing->oneCellAnchor) { foreach ($xmlDrawing->oneCellAnchor as $oneCellAnchor) { if ($oneCellAnchor->pic->blipFill) { - /** @var \SimpleXMLElement $blip */ + /** @var SimpleXMLElement $blip */ $blip = $oneCellAnchor->pic->blipFill->children('http://schemas.openxmlformats.org/drawingml/2006/main')->blip; - /** @var \SimpleXMLElement $xfrm */ + /** @var SimpleXMLElement $xfrm */ $xfrm = $oneCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->xfrm; - /** @var \SimpleXMLElement $outerShdw */ + /** @var SimpleXMLElement $outerShdw */ $outerShdw = $oneCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->effectLst->outerShdw; + /** @var \SimpleXMLElement $hlinkClick */ + $hlinkClick = $oneCellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick; + $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')); @@ -1606,6 +1670,9 @@ class Xlsx extends BaseReader $shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), 'val')); $shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), 'val') / 1000); } + + $this->readHyperLinkDrawing($objDrawing, $oneCellAnchor, $hyperlinks); + $objDrawing->setWorksheet($docSheet); } else { // ? Can charts be positioned with a oneCellAnchor ? @@ -1623,6 +1690,7 @@ class Xlsx extends BaseReader $blip = $twoCellAnchor->pic->blipFill->children('http://schemas.openxmlformats.org/drawingml/2006/main')->blip; $xfrm = $twoCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->xfrm; $outerShdw = $twoCellAnchor->pic->spPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->effectLst->outerShdw; + $hlinkClick = $twoCellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick; $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')); @@ -1654,6 +1722,9 @@ class Xlsx extends BaseReader $shadow->getColor()->setRGB(self::getArrayItem($outerShdw->srgbClr->attributes(), 'val')); $shadow->setAlpha(self::getArrayItem($outerShdw->srgbClr->alpha->attributes(), 'val') / 1000); } + + $this->readHyperLinkDrawing($objDrawing, $twoCellAnchor, $hyperlinks); + $objDrawing->setWorksheet($docSheet); } elseif (($this->includeCharts) && ($twoCellAnchor->graphicFrame)) { $fromCoordinate = Coordinate::stringFromColumnIndex(((string) $twoCellAnchor->from->col) + 1) . ($twoCellAnchor->from->row + 1); @@ -1663,7 +1734,7 @@ class Xlsx extends BaseReader $toOffsetX = Drawing::EMUToPixels($twoCellAnchor->to->colOff); $toOffsetY = Drawing::EMUToPixels($twoCellAnchor->to->rowOff); $graphic = $twoCellAnchor->graphicFrame->children('http://schemas.openxmlformats.org/drawingml/2006/main')->graphic; - /** @var \SimpleXMLElement $chartRef */ + /** @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'); @@ -1680,9 +1751,33 @@ class Xlsx extends BaseReader } } } + + // store original rId of drawing files + $unparsedLoadedData['sheets'][$docSheet->getCodeName()]['drawingOriginalIds'] = []; + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing') { + $unparsedLoadedData['sheets'][$docSheet->getCodeName()]['drawingOriginalIds'][(string) $ele['Target']] = (string) $ele['Id']; + } + } + + // unparsed drawing AlternateContent + $xmlAltDrawing = simplexml_load_string( + $this->securityScan($this->getFromZipArchive($zip, $fileDrawing)), + 'SimpleXMLElement', + Settings::getLibXmlLoaderOptions() + )->children('http://schemas.openxmlformats.org/markup-compatibility/2006'); + + if ($xmlAltDrawing->AlternateContent) { + foreach ($xmlAltDrawing->AlternateContent as $alternateContent) { + $unparsedLoadedData['sheets'][$docSheet->getCodeName()]['drawingAlternateContents'][] = $alternateContent->asXML(); + } + } } } + $this->readFormControlProperties($excel, $zip, $dir, $fileWorksheet, $docSheet, $unparsedLoadedData); + $this->readPrinterSettings($excel, $zip, $dir, $fileWorksheet, $docSheet, $unparsedLoadedData); + // Loop through definedNames if ($xmlWorkbook->definedNames) { foreach ($xmlWorkbook->definedNames->definedName as $definedName) { @@ -1826,8 +1921,10 @@ class Xlsx extends BaseReader } if ((!$this->readDataOnly) || (!empty($this->loadSheetsOnly))) { + $workbookView = $xmlWorkbook->bookViews->workbookView; + // active sheet index - $activeTab = (int) ($xmlWorkbook->bookViews->workbookView['activeTab']); // refers to old sheet index + $activeTab = (int) ($workbookView['activeTab']); // refers to old sheet index // keep active sheet index if sheet is still loaded, else first sheet is set as the active if (isset($mapSheetId[$activeTab]) && $mapSheetId[$activeTab] !== null) { @@ -1838,6 +1935,46 @@ class Xlsx extends BaseReader } $excel->setActiveSheetIndex(0); } + + if (isset($workbookView['showHorizontalScroll'])) { + $showHorizontalScroll = (string) $workbookView['showHorizontalScroll']; + $excel->setShowHorizontalScroll($this->castXsdBooleanToBool($showHorizontalScroll)); + } + + if (isset($workbookView['showVerticalScroll'])) { + $showVerticalScroll = (string) $workbookView['showVerticalScroll']; + $excel->setShowVerticalScroll($this->castXsdBooleanToBool($showVerticalScroll)); + } + + if (isset($workbookView['showSheetTabs'])) { + $showSheetTabs = (string) $workbookView['showSheetTabs']; + $excel->setShowSheetTabs($this->castXsdBooleanToBool($showSheetTabs)); + } + + if (isset($workbookView['minimized'])) { + $minimized = (string) $workbookView['minimized']; + $excel->setMinimized($this->castXsdBooleanToBool($minimized)); + } + + if (isset($workbookView['autoFilterDateGrouping'])) { + $autoFilterDateGrouping = (string) $workbookView['autoFilterDateGrouping']; + $excel->setAutoFilterDateGrouping($this->castXsdBooleanToBool($autoFilterDateGrouping)); + } + + if (isset($workbookView['firstSheet'])) { + $firstSheet = (string) $workbookView['firstSheet']; + $excel->setFirstSheetIndex((int) $firstSheet); + } + + if (isset($workbookView['visibility'])) { + $visibility = (string) $workbookView['visibility']; + $excel->setVisibility($visibility); + } + + if (isset($workbookView['tabRatio'])) { + $tabRatio = (string) $workbookView['tabRatio']; + $excel->setTabRatio((int) $tabRatio); + } } break; @@ -1852,6 +1989,18 @@ class Xlsx extends BaseReader 'SimpleXMLElement', Settings::getLibXmlLoaderOptions() ); + + // Default content types + foreach ($contentTypes->Default as $contentType) { + switch ($contentType['ContentType']) { + case 'application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings': + $unparsedLoadedData['default_content_types'][(string) $contentType['Extension']] = (string) $contentType['ContentType']; + + break; + } + } + + // Override content types foreach ($contentTypes->Override as $contentType) { switch ($contentType['ContentType']) { case 'application/vnd.openxmlformats-officedocument.drawingml.chart+xml': @@ -1876,10 +2025,20 @@ class Xlsx extends BaseReader } } } + + break; + + // unparsed + case 'application/vnd.ms-excel.controlproperties+xml': + $unparsedLoadedData['override_content_types'][(string) $contentType['PartName']] = (string) $contentType['ContentType']; + + break; } } } + $excel->setUnparsedLoadedData($unparsedLoadedData); + $zip->close(); return $excel; @@ -1912,7 +2071,7 @@ class Xlsx extends BaseReader /** * @param Style $docStyle - * @param \SimpleXMLElement|\stdClass $style + * @param SimpleXMLElement|\stdClass $style */ private static function readStyle(Style $docStyle, $style) { @@ -1953,7 +2112,7 @@ class Xlsx extends BaseReader // fill if (isset($style->fill)) { if ($style->fill->gradientFill) { - /** @var \SimpleXMLElement $gradientFill */ + /** @var SimpleXMLElement $gradientFill */ $gradientFill = $style->fill->gradientFill[0]; if (!empty($gradientFill['type'])) { $docStyle->getFill()->setFillType((string) $gradientFill['type']); @@ -2042,7 +2201,7 @@ class Xlsx extends BaseReader /** * @param Border $docBorder - * @param \SimpleXMLElement $eleBorder + * @param SimpleXMLElement $eleBorder */ private static function readBorder(Border $docBorder, $eleBorder) { @@ -2055,7 +2214,7 @@ class Xlsx extends BaseReader } /** - * @param \SimpleXMLElement | null $is + * @param SimpleXMLElement | null $is * * @return RichText */ @@ -2215,4 +2374,227 @@ class Xlsx extends BaseReader return $value === 'true' || $value === 'TRUE'; } + + /** + * @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $objDrawing + * @param \SimpleXMLElement $cellAnchor + * @param array $hyperlinks + */ + private function readHyperLinkDrawing($objDrawing, $cellAnchor, $hyperlinks) + { + $hlinkClick = $cellAnchor->pic->nvPicPr->cNvPr->children('http://schemas.openxmlformats.org/drawingml/2006/main')->hlinkClick; + + if ($hlinkClick->count() === 0) { + return; + } + + $hlinkId = (string) $hlinkClick->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships')['id']; + $hyperlink = new Hyperlink( + $hyperlinks[$hlinkId], + (string) self::getArrayItem($cellAnchor->pic->nvPicPr->cNvPr->attributes(), 'name') + ); + $objDrawing->setHyperlink($hyperlink); + } + + private function readProtection(Spreadsheet $excel, SimpleXMLElement $xmlWorkbook) + { + if (!$xmlWorkbook->workbookProtection) { + return; + } + + if ($xmlWorkbook->workbookProtection['lockRevision']) { + $excel->getSecurity()->setLockRevision((bool) $xmlWorkbook->workbookProtection['lockRevision']); + } + + if ($xmlWorkbook->workbookProtection['lockStructure']) { + $excel->getSecurity()->setLockStructure((bool) $xmlWorkbook->workbookProtection['lockStructure']); + } + + if ($xmlWorkbook->workbookProtection['lockWindows']) { + $excel->getSecurity()->setLockWindows((bool) $xmlWorkbook->workbookProtection['lockWindows']); + } + + if ($xmlWorkbook->workbookProtection['revisionsPassword']) { + $excel->getSecurity()->setRevisionsPassword((string) $xmlWorkbook->workbookProtection['revisionsPassword'], true); + } + + if ($xmlWorkbook->workbookProtection['workbookPassword']) { + $excel->getSecurity()->setWorkbookPassword((string) $xmlWorkbook->workbookProtection['workbookPassword'], true); + } + } + + private function readFormControlProperties(Spreadsheet $excel, ZipArchive $zip, $dir, $fileWorksheet, $docSheet, array &$unparsedLoadedData) + { + if (!$zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { + return; + } + + //~ http://schemas.openxmlformats.org/package/2006/relationships" + $relsWorksheet = simplexml_load_string( + $this->securityScan( + $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels') + ), + 'SimpleXMLElement', + Settings::getLibXmlLoaderOptions() + ); + $ctrlProps = []; + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp') { + $ctrlProps[(string) $ele['Id']] = $ele; + } + } + + $unparsedCtrlProps = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['ctrlProps']; + foreach ($ctrlProps as $rId => $ctrlProp) { + $rId = substr($rId, 3); // rIdXXX + $unparsedCtrlProps[$rId] = []; + $unparsedCtrlProps[$rId]['filePath'] = self::dirAdd("$dir/$fileWorksheet", $ctrlProp['Target']); + $unparsedCtrlProps[$rId]['relFilePath'] = (string) $ctrlProp['Target']; + $unparsedCtrlProps[$rId]['content'] = $this->securityScan($this->getFromZipArchive($zip, $unparsedCtrlProps[$rId]['filePath'])); + } + unset($unparsedCtrlProps); + } + + private function readPrinterSettings(Spreadsheet $excel, ZipArchive $zip, $dir, $fileWorksheet, $docSheet, array &$unparsedLoadedData) + { + if (!$zip->locateName(dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels')) { + return; + } + + //~ http://schemas.openxmlformats.org/package/2006/relationships" + $relsWorksheet = simplexml_load_string( + $this->securityScan( + $this->getFromZipArchive($zip, dirname("$dir/$fileWorksheet") . '/_rels/' . basename($fileWorksheet) . '.rels') + ), + 'SimpleXMLElement', + Settings::getLibXmlLoaderOptions() + ); + $sheetPrinterSettings = []; + foreach ($relsWorksheet->Relationship as $ele) { + if ($ele['Type'] == 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings') { + $sheetPrinterSettings[(string) $ele['Id']] = $ele; + } + } + + $unparsedPrinterSettings = &$unparsedLoadedData['sheets'][$docSheet->getCodeName()]['printerSettings']; + foreach ($sheetPrinterSettings as $rId => $printerSettings) { + $rId = substr($rId, 3); // rIdXXX + $unparsedPrinterSettings[$rId] = []; + $unparsedPrinterSettings[$rId]['filePath'] = self::dirAdd("$dir/$fileWorksheet", $printerSettings['Target']); + $unparsedPrinterSettings[$rId]['relFilePath'] = (string) $printerSettings['Target']; + $unparsedPrinterSettings[$rId]['content'] = $this->securityScan($this->getFromZipArchive($zip, $unparsedPrinterSettings[$rId]['filePath'])); + } + unset($unparsedPrinterSettings); + } + + /** + * Convert an 'xsd:boolean' XML value to a PHP boolean value. + * A valid 'xsd:boolean' XML value can be one of the following + * four values: 'true', 'false', '1', '0'. It is case sensitive. + * + * Note that just doing '(bool) $xsdBoolean' is not safe, + * since '(bool) "false"' returns true. + * + * @see https://www.w3.org/TR/xmlschema11-2/#boolean + * + * @param string $xsdBoolean An XML string value of type 'xsd:boolean' + * + * @return bool Boolean value + */ + private function castXsdBooleanToBool($xsdBoolean) + { + if ($xsdBoolean === 'false') { + return false; + } + + return (bool) $xsdBoolean; + } + + /** + * Read columns and rows attributes from XML and set them on the worksheet. + * + * @param SimpleXMLElement $xmlSheet + * @param Worksheet $docSheet + */ + private function readColumnsAndRowsAttributes(SimpleXMLElement $xmlSheet, Worksheet $docSheet) + { + $columnsAttributes = []; + $rowsAttributes = []; + if (isset($xmlSheet->cols) && !$this->readDataOnly) { + foreach ($xmlSheet->cols->col as $col) { + for ($i = (int) ($col['min']); $i <= (int) ($col['max']); ++$i) { + if ($col['style'] && !$this->readDataOnly) { + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['xfIndex'] = (int) $col['style']; + } + if (self::boolean($col['hidden'])) { + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['visible'] = false; + } + if (self::boolean($col['collapsed'])) { + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['collapsed'] = true; + } + if ($col['outlineLevel'] > 0) { + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['outlineLevel'] = (int) $col['outlineLevel']; + } + $columnsAttributes[Coordinate::stringFromColumnIndex($i)]['width'] = (float) $col['width']; + + if ((int) ($col['max']) == 16384) { + break; + } + } + } + } + + if ($xmlSheet && $xmlSheet->sheetData && $xmlSheet->sheetData->row) { + foreach ($xmlSheet->sheetData->row as $row) { + if ($row['ht'] && !$this->readDataOnly) { + $rowsAttributes[(int) $row['r']]['rowHeight'] = (float) $row['ht']; + } + if (self::boolean($row['hidden']) && !$this->readDataOnly) { + $rowsAttributes[(int) $row['r']]['visible'] = false; + } + if (self::boolean($row['collapsed'])) { + $rowsAttributes[(int) $row['r']]['collapsed'] = true; + } + if ($row['outlineLevel'] > 0) { + $rowsAttributes[(int) $row['r']]['outlineLevel'] = (int) $row['outlineLevel']; + } + if ($row['s'] && !$this->readDataOnly) { + $rowsAttributes[(int) $row['r']]['xfIndex'] = (int) $row['s']; + } + } + } + + // set columns/rows attributes + $columnsAttributesSet = []; + $rowsAttributesSet = []; + foreach ($columnsAttributes as $coordColumn => $columnAttributes) { + foreach ($rowsAttributes as $coordRow => $rowAttributes) { + if ($this->getReadFilter() !== null) { + if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { + continue 2; + } + } + } + + if (!isset($columnsAttributesSet[$coordColumn])) { + $this->setColumnAttributes($docSheet, $coordColumn, $columnAttributes); + $columnsAttributesSet[$coordColumn] = true; + } + } + + foreach ($rowsAttributes as $coordRow => $rowAttributes) { + foreach ($columnsAttributes as $coordColumn => $columnAttributes) { + if ($this->getReadFilter() !== null) { + if (!$this->getReadFilter()->readCell($coordColumn, $coordRow, $docSheet->getTitle())) { + continue 2; + } + } + } + + if (!isset($rowsAttributesSet[$coordRow])) { + $this->setRowAttributes($docSheet, $coordRow, $rowAttributes); + $rowsAttributesSet[$coordRow] = true; + } + } + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php index e4f866d..65babc3 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Reader/Xml.php @@ -76,7 +76,7 @@ class Xml extends BaseReader // Read sample data (first 2 KB will do) $data = fread($fileHandle, 2048); fclose($fileHandle); - $data = strtr($data, "'", '"'); // fix headers with single quote + $data = str_replace("'", '"', $data); // fix headers with single quote $valid = true; foreach ($signature as $match) { diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Date.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Date.php index 8f130ad..91c3ee0 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Date.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Date.php @@ -256,7 +256,7 @@ class Date /** * Convert a Unix timestamp to an MS Excel serialized date/time value. * - * @param DateTimeInterface $dateValue Unix Timestamp + * @param int $dateValue Unix Timestamp * * @return float MS Excel serialized date/time value */ diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php index 528a025..8ab9cfb 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/JAMA/Matrix.php @@ -1000,7 +1000,7 @@ class Matrix */ public function times(...$args) { - if (count() > 0) { + if (count($args) > 0) { $match = implode(',', array_map('gettype', $args)); switch ($match) { @@ -1094,7 +1094,7 @@ class Matrix */ public function power(...$args) { - if (count() > 0) { + if (count($args) > 0) { $match = implode(',', array_map('gettype', $args)); switch ($match) { diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/BestFit.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/BestFit.php index 79c52c3..d8e63d5 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/BestFit.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/BestFit.php @@ -142,7 +142,7 @@ class BestFit * * @param int $dp Number of places of decimal precision to display * - * @return string + * @return float */ public function getSlope($dp = 0) { @@ -158,7 +158,7 @@ class BestFit * * @param int $dp Number of places of decimal precision to display * - * @return string + * @return float */ public function getSlopeSE($dp = 0) { @@ -174,7 +174,7 @@ class BestFit * * @param int $dp Number of places of decimal precision to display * - * @return string + * @return float */ public function getIntersect($dp = 0) { @@ -190,7 +190,7 @@ class BestFit * * @param int $dp Number of places of decimal precision to display * - * @return string + * @return float */ public function getIntersectSE($dp = 0) { @@ -217,6 +217,13 @@ class BestFit return $this->goodnessOfFit; } + /** + * Return the goodness of fit for this regression. + * + * @param int $dp Number of places of decimal precision to return + * + * @return float + */ public function getGoodnessOfFitPercent($dp = 0) { if ($dp != 0) { @@ -242,6 +249,11 @@ class BestFit return $this->stdevOfResiduals; } + /** + * @param int $dp Number of places of decimal precision to return + * + * @return float + */ public function getSSRegression($dp = 0) { if ($dp != 0) { @@ -251,6 +263,11 @@ class BestFit return $this->SSRegression; } + /** + * @param int $dp Number of places of decimal precision to return + * + * @return float + */ public function getSSResiduals($dp = 0) { if ($dp != 0) { @@ -260,6 +277,11 @@ class BestFit return $this->SSResiduals; } + /** + * @param int $dp Number of places of decimal precision to return + * + * @return float + */ public function getDFResiduals($dp = 0) { if ($dp != 0) { @@ -269,6 +291,11 @@ class BestFit return $this->DFResiduals; } + /** + * @param int $dp Number of places of decimal precision to return + * + * @return float + */ public function getF($dp = 0) { if ($dp != 0) { @@ -278,6 +305,11 @@ class BestFit return $this->f; } + /** + * @param int $dp Number of places of decimal precision to return + * + * @return float + */ public function getCovariance($dp = 0) { if ($dp != 0) { @@ -287,6 +319,11 @@ class BestFit return $this->covariance; } + /** + * @param int $dp Number of places of decimal precision to return + * + * @return float + */ public function getCorrelation($dp = 0) { if ($dp != 0) { @@ -296,6 +333,9 @@ class BestFit return $this->correlation; } + /** + * @return float[] + */ public function getYBestFitValues() { return $this->yBestFitValues; diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php index 6073970..83c9200 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Shared/Trend/PolynomialBestFit.php @@ -164,7 +164,7 @@ class PolynomialBestFit extends BestFit $this->intersect = array_shift($coefficients); $this->slope = $coefficients; - $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum); + $this->calculateGoodnessOfFit($x_sum, $y_sum, $xx_sum, $yy_sum, $xy_sum, 0, 0, 0); foreach ($this->xValues as $xKey => $xValue) { $this->yBestFitValues[$xKey] = $this->getValueOfYForX($xValue); } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php index 659b310..150f71b 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Spreadsheet.php @@ -9,6 +9,17 @@ use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet; class Spreadsheet { + // Allowable values for workbook window visilbity + const VISIBILITY_VISIBLE = 'visible'; + const VISIBILITY_HIDDEN = 'hidden'; + const VISIBILITY_VERY_HIDDEN = 'veryHidden'; + + private static $workbookViewVisibilityValues = [ + self::VISIBILITY_VISIBLE, + self::VISIBILITY_HIDDEN, + self::VISIBILITY_VERY_HIDDEN, + ]; + /** * Unique ID. * @@ -115,6 +126,75 @@ class Spreadsheet */ private $ribbonBinObjects; + /** + * List of unparsed loaded data for export to same format with better compatibility. + * It has to be minimized when the library start to support currently unparsed data. + * + * @var array + */ + private $unparsedLoadedData = []; + + /** + * Controls visibility of the horizonal scroll bar in the application. + * + * @var bool + */ + private $showHorizontalScroll = true; + + /** + * Controls visibility of the horizonal scroll bar in the application. + * + * @var bool + */ + private $showVerticalScroll = true; + + /** + * Controls visibility of the sheet tabs in the application. + * + * @var bool + */ + private $showSheetTabs = true; + + /** + * Specifies a boolean value that indicates whether the workbook window + * is minimized. + * + * @var bool + */ + private $minimized = false; + + /** + * Specifies a boolean value that indicates whether to group dates + * when presenting the user with filtering optiomd in the user + * interface. + * + * @var bool + */ + private $autoFilterDateGrouping = true; + + /** + * Specifies the index to the first sheet in the book view. + * + * @var int + */ + private $firstSheetIndex = 0; + + /** + * Specifies the visible status of the workbook. + * + * @var string + */ + private $visibility = self::VISIBILITY_VISIBLE; + + /** + * Specifies the ratio between the workbook tabs bar and the horizontal + * scroll bar. TabRatio is assumed to be out of 1000 of the horizontal + * window width. + * + * @var int + */ + private $tabRatio = 600; + /** * The workbook has macros ? * @@ -256,6 +336,32 @@ class Spreadsheet } } + /** + * List of unparsed loaded data for export to same format with better compatibility. + * It has to be minimized when the library start to support currently unparsed data. + * + * @internal + * + * @return array + */ + public function getUnparsedLoadedData() + { + return $this->unparsedLoadedData; + } + + /** + * List of unparsed loaded data for export to same format with better compatibility. + * It has to be minimized when the library start to support currently unparsed data. + * + * @internal + * + * @param array $unparsedLoadedData + */ + public function setUnparsedLoadedData(array $unparsedLoadedData) + { + $this->unparsedLoadedData = $unparsedLoadedData; + } + /** * return the extension of a filename. Internal use for a array_map callback (php<5.3 don't like lambda function). * @@ -1182,4 +1288,203 @@ class Spreadsheet { return $this->uniqueID; } + + /** + * Get the visibility of the horizonal scroll bar in the application. + * + * @return bool True if horizonal scroll bar is visible + */ + public function getShowHorizontalScroll() + { + return $this->showHorizontalScroll; + } + + /** + * Set the visibility of the horizonal scroll bar in the application. + * + * @param bool $showHorizontalScroll True if horizonal scroll bar is visible + */ + public function setShowHorizontalScroll($showHorizontalScroll) + { + $this->showHorizontalScroll = (bool) $showHorizontalScroll; + } + + /** + * Get the visibility of the vertical scroll bar in the application. + * + * @return bool True if vertical scroll bar is visible + */ + public function getShowVerticalScroll() + { + return $this->showVerticalScroll; + } + + /** + * Set the visibility of the vertical scroll bar in the application. + * + * @param bool $showVerticalScroll True if vertical scroll bar is visible + */ + public function setShowVerticalScroll($showVerticalScroll) + { + $this->showVerticalScroll = (bool) $showVerticalScroll; + } + + /** + * Get the visibility of the sheet tabs in the application. + * + * @return bool True if the sheet tabs are visible + */ + public function getShowSheetTabs() + { + return $this->showSheetTabs; + } + + /** + * Set the visibility of the sheet tabs in the application. + * + * @param bool $showSheetTabs True if sheet tabs are visible + */ + public function setShowSheetTabs($showSheetTabs) + { + $this->showSheetTabs = (bool) $showSheetTabs; + } + + /** + * Return whether the workbook window is minimized. + * + * @return bool true if workbook window is minimized + */ + public function getMinimized() + { + return $this->minimized; + } + + /** + * Set whether the workbook window is minimized. + * + * @param bool $minimized true if workbook window is minimized + */ + public function setMinimized($minimized) + { + $this->minimized = (bool) $minimized; + } + + /** + * Return whether to group dates when presenting the user with + * filtering optiomd in the user interface. + * + * @return bool true if workbook window is minimized + */ + public function getAutoFilterDateGrouping() + { + return $this->autoFilterDateGrouping; + } + + /** + * Set whether to group dates when presenting the user with + * filtering optiomd in the user interface. + * + * @param bool $autoFilterDateGrouping true if workbook window is minimized + */ + public function setAutoFilterDateGrouping($autoFilterDateGrouping) + { + $this->autoFilterDateGrouping = (bool) $autoFilterDateGrouping; + } + + /** + * Return the first sheet in the book view. + * + * @return int First sheet in book view + */ + public function getFirstSheetIndex() + { + return $this->firstSheetIndex; + } + + /** + * Set the first sheet in the book view. + * + * @param int $firstSheetIndex First sheet in book view + * + * @throws Exception if the given value is invalid + */ + public function setFirstSheetIndex($firstSheetIndex) + { + if ($firstSheetIndex >= 0) { + $this->firstSheetIndex = (int) $firstSheetIndex; + } else { + throw new Exception('First sheet index must be a positive integer.'); + } + } + + /** + * Return the visibility status of the workbook. + * + * This may be one of the following three values: + * - visibile + * + * @return string Visible status + */ + public function getVisibility() + { + return $this->visibility; + } + + /** + * Set the visibility status of the workbook. + * + * Valid values are: + * - 'visible' (self::VISIBILITY_VISIBLE): + * Workbook window is visible + * - 'hidden' (self::VISIBILITY_HIDDEN): + * Workbook window is hidden, but can be shown by the user + * via the user interface + * - 'veryHidden' (self::VISIBILITY_VERY_HIDDEN): + * Workbook window is hidden and cannot be shown in the + * user interface. + * + * @param string $visibility visibility status of the workbook + * + * @throws Exception if the given value is invalid + */ + public function setVisibility($visibility) + { + if ($visibility === null) { + $visibility = self::VISIBILITY_VISIBLE; + } + + if (in_array($visibility, self::$workbookViewVisibilityValues)) { + $this->visibility = $visibility; + } else { + throw new Exception('Invalid visibility value.'); + } + } + + /** + * Get the ratio between the workbook tabs bar and the horizontal scroll bar. + * TabRatio is assumed to be out of 1000 of the horizontal window width. + * + * @return int Ratio between the workbook tabs bar and the horizontal scroll bar + */ + public function getTabRatio() + { + return $this->tabRatio; + } + + /** + * Set the ratio between the workbook tabs bar and the horizontal scroll bar + * TabRatio is assumed to be out of 1000 of the horizontal window width. + * + * @param int $tabRatio Ratio between the tabs bar and the horizontal scroll bar + * + * @throws Exception if the given value is invalid + */ + public function setTabRatio($tabRatio) + { + if ($tabRatio >= 0 || $tabRatio <= 1000) { + $this->tabRatio = (int) $tabRatio; + } else { + throw new Exception('Tab ratio must be between 0 and 1000.'); + } + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php index 8075af4..63ef20a 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/NumberFormat.php @@ -589,7 +589,7 @@ class NumberFormat extends Supervisor } // Convert any other escaped characters to quoted strings, e.g. (\T to "T") - $format = preg_replace('/(\\\(.))(?=(?:[^"]|"[^"]*")*$)/u', '"${2}"', $format); + $format = preg_replace('/(\\\([^ ]))(?=(?:[^"]|"[^"]*")*$)/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); diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Style.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Style.php index c872976..3a8ebaa 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Style.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Style/Style.php @@ -333,6 +333,9 @@ class Style extends Supervisor } } + // restore initial cell selection range + $this->getActiveSheet()->getStyle($pRange); + return $this; } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php index 935ac88..b92c986 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/AutoFilter.php @@ -841,7 +841,7 @@ class AutoFilter $vars = get_object_vars($this); foreach ($vars as $key => $value) { if (is_object($value)) { - if ($key == 'workSheet') { + if ($key === 'workSheet') { // Detach from worksheet $this->{$key} = null; } else { diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php index 6489f92..98b6897 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/BaseDrawing.php @@ -2,6 +2,7 @@ namespace PhpOffice\PhpSpreadsheet\Worksheet; +use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; use PhpOffice\PhpSpreadsheet\Exception as PhpSpreadsheetException; use PhpOffice\PhpSpreadsheet\IComparable; @@ -98,6 +99,13 @@ class BaseDrawing implements IComparable */ protected $shadow; + /** + * Image hyperlink. + * + * @var null|Hyperlink + */ + private $hyperlink; + /** * Create a new BaseDrawing. */ @@ -501,11 +509,29 @@ class BaseDrawing implements IComparable { $vars = get_object_vars($this); foreach ($vars as $key => $value) { - if (is_object($value)) { + if ($key == 'worksheet') { + $this->worksheet = null; + } elseif (is_object($value)) { $this->$key = clone $value; } else { $this->$key = $value; } } } + + /** + * @param null|Hyperlink $pHyperlink + */ + public function setHyperlink(Hyperlink $pHyperlink = null) + { + $this->hyperlink = $pHyperlink; + } + + /** + * @return null|Hyperlink + */ + public function getHyperlink() + { + return $this->hyperlink; + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php index 156a360..42dcd69 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Worksheet/Worksheet.php @@ -37,6 +37,13 @@ class Worksheet implements IComparable const SHEETSTATE_HIDDEN = 'hidden'; const SHEETSTATE_VERYHIDDEN = 'veryHidden'; + /** + * Maximum 31 characters allowed for sheet title. + * + * @var int + */ + const SHEET_TITLE_MAXIMUM_LENGTH = 31; + /** * Invalid characters in sheet title. * @@ -434,9 +441,9 @@ class Worksheet implements IComparable throw new Exception('Invalid character found in sheet code name'); } - // Maximum 31 characters allowed for sheet title - if ($CharCount > 31) { - throw new Exception('Maximum 31 characters allowed in sheet code name.'); + // Enforce maximum characters allowed for sheet title + if ($CharCount > self::SHEET_TITLE_MAXIMUM_LENGTH) { + throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet code name.'); } return $pValue; @@ -458,9 +465,9 @@ class Worksheet implements IComparable throw new Exception('Invalid character found in sheet title'); } - // Maximum 31 characters allowed for sheet title - if (Shared\StringHelper::countCharacters($pValue) > 31) { - throw new Exception('Maximum 31 characters allowed in sheet title.'); + // Enforce maximum characters allowed for sheet title + if (Shared\StringHelper::countCharacters($pValue) > self::SHEET_TITLE_MAXIMUM_LENGTH) { + throw new Exception('Maximum ' . self::SHEET_TITLE_MAXIMUM_LENGTH . ' characters allowed in sheet title.'); } return $pValue; @@ -2956,13 +2963,14 @@ class Worksheet implements IComparable $newCollection = $this->cellCollection->cloneCellCollection($this); $this->cellCollection = $newCollection; } elseif ($key == 'drawingCollection') { - $newCollection = new ArrayObject(); - foreach ($this->drawingCollection as $id => $item) { + $currentCollection = $this->drawingCollection; + $this->drawingCollection = new ArrayObject(); + foreach ($currentCollection as $item) { if (is_object($item)) { - $newCollection[$id] = clone $this->drawingCollection[$id]; + $newDrawing = clone $item; + $newDrawing->setWorksheet($this); } } - $this->drawingCollection = $newCollection; } elseif (($key == 'autoFilter') && ($this->autoFilter instanceof AutoFilter)) { $newAutoFilter = clone $this->autoFilter; $this->autoFilter = $newAutoFilter; diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php index 48df37e..351e54d 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xls/Worksheet.php @@ -827,7 +827,7 @@ class Worksheet extends BIFFwriter $formula = substr($formula, 1); } else { // Error handling - $this->writeString($row, $col, 'Unrecognised character for formula'); + $this->writeString($row, $col, 'Unrecognised character for formula', 0); return -1; } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php index 0982c06..dd19021 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx.php @@ -137,9 +137,9 @@ class Xlsx extends BaseWriter } $hashTablesArray = ['stylesConditionalHashTable', 'fillHashTable', 'fontHashTable', - 'bordersHashTable', 'numFmtHashTable', 'drawingHashTable', - 'styleHashTable', - ]; + 'bordersHashTable', 'numFmtHashTable', 'drawingHashTable', + 'styleHashTable', + ]; // Set HashTable variables foreach ($hashTablesArray as $tableName) { @@ -290,12 +290,26 @@ class Xlsx extends BaseWriter } } - $chartRef1 = $chartRef2 = 0; + $chartRef1 = 0; // Add worksheet relationships (drawings, ...) for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) { // Add relationships $zip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->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) { + $zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']); + } + } + if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) { + foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) { + $zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']); + } + } + $drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection(); $drawingCount = count($drawings); if ($this->includeCharts) { @@ -307,6 +321,9 @@ class Xlsx extends BaseWriter // Drawing relationships $zip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts)); + // Drawings + $zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts)); + } elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) { // Drawings $zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts)); } @@ -320,6 +337,13 @@ class Xlsx extends BaseWriter $zip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i))); } + // Add unparsed relationship parts + if (isset($unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['vmlDrawings'])) { + foreach ($unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['vmlDrawings'] as $vmlDrawing) { + $zip->addFromString($vmlDrawing['filePath'], $vmlDrawing['content']); + } + } + // Add header/footer relationship parts if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) { // VML Drawings diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php index a34d346..6b22d71 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/ContentTypes.php @@ -57,7 +57,8 @@ class ContentTypes extends WriterPart // Yes : not standard content but "macroEnabled" $this->writeOverrideContentType($objWriter, '/xl/workbook.xml', 'application/vnd.ms-excel.sheet.macroEnabled.main+xml'); //... and define a new type for the VBA project - $this->writeDefaultContentType($objWriter, 'bin', 'application/vnd.ms-office.vbaProject'); + // Better use Override, because we can use 'bin' also for xl\printerSettings\printerSettings1.bin + $this->writeOverrideContentType($objWriter, '/xl/vbaProject.bin', 'application/vnd.ms-office.vbaProject'); if ($spreadsheet->hasMacrosCertificate()) { // signed macros ? // Yes : add needed information @@ -88,14 +89,16 @@ class ContentTypes extends WriterPart $this->writeOverrideContentType($objWriter, '/xl/sharedStrings.xml', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sharedStrings+xml'); // Add worksheet relationship content types + $unparsedLoadedData = $spreadsheet->getUnparsedLoadedData(); $chart = 1; for ($i = 0; $i < $sheetCount; ++$i) { $drawings = $spreadsheet->getSheet($i)->getDrawingCollection(); $drawingCount = count($drawings); $chartCount = ($includeCharts) ? $spreadsheet->getSheet($i)->getChartCount() : 0; + $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$spreadsheet->getSheet($i)->getCodeName()]['drawingOriginalIds']); // We need a drawing relationship for the worksheet if we have either drawings or charts - if (($drawingCount > 0) || ($chartCount > 0)) { + if (($drawingCount > 0) || ($chartCount > 0) || $hasUnparsedDrawing) { $this->writeOverrideContentType($objWriter, '/xl/drawings/drawing' . ($i + 1) . '.xml', 'application/vnd.openxmlformats-officedocument.drawing+xml'); } @@ -160,6 +163,20 @@ class ContentTypes extends WriterPart } } + // unparsed defaults + if (isset($unparsedLoadedData['default_content_types'])) { + foreach ($unparsedLoadedData['default_content_types'] as $extName => $contentType) { + $this->writeDefaultContentType($objWriter, $extName, $contentType); + } + } + + // unparsed overrides + if (isset($unparsedLoadedData['override_content_types'])) { + foreach ($unparsedLoadedData['override_content_types'] as $partName => $overrideType) { + $this->writeOverrideContentType($objWriter, $partName, $overrideType); + } + } + $objWriter->endElement(); // Return diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php index a8bd8c0..08256a1 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Drawing.php @@ -43,7 +43,12 @@ class Drawing extends WriterPart $i = 1; $iterator = $pWorksheet->getDrawingCollection()->getIterator(); while ($iterator->valid()) { - $this->writeDrawing($objWriter, $iterator->current(), $i); + /** @var BaseDrawing $pDrawing */ + $pDrawing = $iterator->current(); + $pRelationId = $i; + $hlinkClickId = $pDrawing->getHyperlink() === null ? null : ++$i; + + $this->writeDrawing($objWriter, $pDrawing, $pRelationId, $hlinkClickId); $iterator->next(); ++$i; @@ -59,6 +64,14 @@ class Drawing extends WriterPart } } + // unparsed AlternateContent + $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData(); + if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingAlternateContents'])) { + foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingAlternateContents'] as $drawingAlternateContent) { + $objWriter->writeRaw($drawingAlternateContent); + } + } + $objWriter->endElement(); // Return @@ -142,10 +155,11 @@ class Drawing extends WriterPart * @param XMLWriter $objWriter XML Writer * @param BaseDrawing $pDrawing * @param int $pRelationId + * @param null|int $hlinkClickId * * @throws WriterException */ - public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1) + public function writeDrawing(XMLWriter $objWriter, BaseDrawing $pDrawing, $pRelationId = -1, $hlinkClickId = null) { if ($pRelationId >= 0) { // xdr:oneCellAnchor @@ -179,6 +193,10 @@ class Drawing extends WriterPart $objWriter->writeAttribute('id', $pRelationId); $objWriter->writeAttribute('name', $pDrawing->getName()); $objWriter->writeAttribute('descr', $pDrawing->getDescription()); + + //a:hlinkClick + $this->writeHyperLinkDrawing($objWriter, $hlinkClickId); + $objWriter->endElement(); // xdr:cNvPicPr @@ -482,4 +500,20 @@ class Drawing extends WriterPart return $aDrawings; } + + /** + * @param XMLWriter $objWriter + * @param null|int $hlinkClickId + */ + private function writeHyperLinkDrawing(XMLWriter $objWriter, $hlinkClickId) + { + if ($hlinkClickId === null) { + return; + } + + $objWriter->startElement('a:hlinkClick'); + $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $objWriter->writeAttribute('r:id', 'rId' . $hlinkClickId); + $objWriter->endElement(); + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php index e5d2aa5..76c196b 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Rels.php @@ -195,18 +195,31 @@ class Rels extends WriterPart // Write drawing relationships? $d = 0; + $drawingOriginalIds = []; + $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData(); + if (isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds'])) { + $drawingOriginalIds = $unparsedLoadedData['sheets'][$pWorksheet->getCodeName()]['drawingOriginalIds']; + } + if ($includeCharts) { $charts = $pWorksheet->getChartCollection(); } else { $charts = []; } - if (($pWorksheet->getDrawingCollection()->count() > 0) || - (count($charts) > 0)) { + + if (($pWorksheet->getDrawingCollection()->count() > 0) || (count($charts) > 0) || $drawingOriginalIds) { + $relPath = '../drawings/drawing' . $pWorksheetId . '.xml'; + $rId = ++$d; + + if (isset($drawingOriginalIds[$relPath])) { + $rId = (int) (substr($drawingOriginalIds[$relPath], 3)); + } + $this->writeRelationship( $objWriter, - ++$d, + $rId, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/drawing', - '../drawings/drawing' . $pWorksheetId . '.xml' + $relPath ); } @@ -255,11 +268,32 @@ class Rels extends WriterPart ); } + $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'ctrlProps', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp'); + $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'vmlDrawings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing'); + $this->writeUnparsedRelationship($pWorksheet, $objWriter, 'printerSettings', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings'); + $objWriter->endElement(); return $objWriter->getData(); } + private function writeUnparsedRelationship(\PhpOffice\PhpSpreadsheet\Worksheet\Worksheet $pWorksheet, XMLWriter $objWriter, $relationship, $type) + { + $unparsedLoadedData = $pWorksheet->getParent()->getUnparsedLoadedData(); + if (!isset($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship])) { + return; + } + + foreach ($unparsedLoadedData['sheets'][$pWorksheet->getCodeName()][$relationship] as $rId => $value) { + $this->writeRelationship( + $objWriter, + $rId, + $type, + $value['relFilePath'] + ); + } + } + /** * Write drawing relationships to XML format. * @@ -295,12 +329,16 @@ class Rels extends WriterPart if ($iterator->current() instanceof \PhpOffice\PhpSpreadsheet\Worksheet\Drawing || $iterator->current() instanceof MemoryDrawing) { // Write relationship for image drawing + /** @var \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing */ + $drawing = $iterator->current(); $this->writeRelationship( $objWriter, $i, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/image', - '../media/' . str_replace(' ', '', $iterator->current()->getIndexedFilename()) + '../media/' . str_replace(' ', '', $drawing->getIndexedFilename()) ); + + $i = $this->writeDrawingHyperLink($objWriter, $drawing, $i); } $iterator->next(); @@ -398,4 +436,31 @@ class Rels extends WriterPart throw new WriterException('Invalid parameters passed.'); } } + + /** + * @param $objWriter + * @param \PhpOffice\PhpSpreadsheet\Worksheet\Drawing $drawing + * @param $i + * + * @throws WriterException + * + * @return int + */ + private function writeDrawingHyperLink($objWriter, $drawing, $i) + { + if ($drawing->getHyperlink() === null) { + return $i; + } + + ++$i; + $this->writeRelationship( + $objWriter, + $i, + 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/hyperlink', + $drawing->getHyperlink()->getUrl(), + $drawing->getHyperlink()->getTypeHyperlink() + ); + + return $i; + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php index e9de179..43a1916 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Workbook.php @@ -117,14 +117,14 @@ class Workbook extends WriterPart $objWriter->startElement('workbookView'); $objWriter->writeAttribute('activeTab', $spreadsheet->getActiveSheetIndex()); - $objWriter->writeAttribute('autoFilterDateGrouping', '1'); - $objWriter->writeAttribute('firstSheet', '0'); - $objWriter->writeAttribute('minimized', '0'); - $objWriter->writeAttribute('showHorizontalScroll', '1'); - $objWriter->writeAttribute('showSheetTabs', '1'); - $objWriter->writeAttribute('showVerticalScroll', '1'); - $objWriter->writeAttribute('tabRatio', '600'); - $objWriter->writeAttribute('visibility', 'visible'); + $objWriter->writeAttribute('autoFilterDateGrouping', ($spreadsheet->getAutoFilterDateGrouping() ? 'true' : 'false')); + $objWriter->writeAttribute('firstSheet', $spreadsheet->getFirstSheetIndex()); + $objWriter->writeAttribute('minimized', ($spreadsheet->getMinimized() ? 'true' : 'false')); + $objWriter->writeAttribute('showHorizontalScroll', ($spreadsheet->getShowHorizontalScroll() ? 'true' : 'false')); + $objWriter->writeAttribute('showSheetTabs', ($spreadsheet->getShowSheetTabs() ? 'true' : 'false')); + $objWriter->writeAttribute('showVerticalScroll', ($spreadsheet->getShowVerticalScroll() ? 'true' : 'false')); + $objWriter->writeAttribute('tabRatio', $spreadsheet->getTabRatio()); + $objWriter->writeAttribute('visibility', $spreadsheet->getVisibility()); $objWriter->endElement(); @@ -175,6 +175,7 @@ class Workbook extends WriterPart // fullCalcOnLoad isn't needed if we've recalculating for the save $objWriter->writeAttribute('calcCompleted', ($recalcRequired) ? 1 : 0); $objWriter->writeAttribute('fullCalcOnLoad', ($recalcRequired) ? 0 : 1); + $objWriter->writeAttribute('forceFullCalc', ($recalcRequired) ? 0 : 1); $objWriter->endElement(); } diff --git a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php index f551c60..cb46a12 100644 --- a/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php +++ b/inc/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Writer/Xlsx/Worksheet.php @@ -51,6 +51,12 @@ class Worksheet extends WriterPart $objWriter->writeAttribute('xmlns', 'http://schemas.openxmlformats.org/spreadsheetml/2006/main'); $objWriter->writeAttribute('xmlns:r', 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $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: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'); + // sheetPr $this->writeSheetPr($objWriter, $pSheet); @@ -114,6 +120,9 @@ class Worksheet extends WriterPart // LegacyDrawingHF $this->writeLegacyDrawingHF($objWriter, $pSheet); + // AlternateContent + $this->writeAlternateContent($objWriter, $pSheet); + $objWriter->endElement(); // Return @@ -237,6 +246,7 @@ class Worksheet extends WriterPart } $activeCell = $pSheet->getActiveCell(); + $sqref = $pSheet->getSelectedCells(); // Pane $pane = ''; @@ -248,6 +258,7 @@ class Worksheet extends WriterPart $topLeftCell = $pSheet->getTopLeftCell(); $activeCell = $topLeftCell; + $sqref = $topLeftCell; // pane $pane = 'topRight'; @@ -283,7 +294,7 @@ class Worksheet extends WriterPart $objWriter->writeAttribute('pane', $pane); } $objWriter->writeAttribute('activeCell', $activeCell); - $objWriter->writeAttribute('sqref', $activeCell); + $objWriter->writeAttribute('sqref', $sqref); $objWriter->endElement(); $objWriter->endElement(); @@ -843,6 +854,11 @@ class Worksheet extends WriterPart $objWriter->writeAttribute('useFirstPageNumber', '1'); } + $getUnparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData(); + if (isset($getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId'])) { + $objWriter->writeAttribute('r:id', $getUnparsedLoadedData['sheets'][$pSheet->getCodeName()]['pageSetupRelId']); + } + $objWriter->endElement(); } @@ -1142,16 +1158,27 @@ class Worksheet extends WriterPart * @param PhpspreadsheetWorksheet $pSheet Worksheet * @param bool $includeCharts Flag indicating if we should include drawing details for charts */ - private function writeDrawings(XMLWriter $objWriter = null, PhpspreadsheetWorksheet $pSheet = null, $includeCharts = false) + private function writeDrawings(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet, $includeCharts = false) { + $unparsedLoadedData = $pSheet->getParent()->getUnparsedLoadedData(); + $hasUnparsedDrawing = isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds']); $chartCount = ($includeCharts) ? $pSheet->getChartCollection()->count() : 0; - // If sheet contains drawings, add the relationships - if (($pSheet->getDrawingCollection()->count() > 0) || - ($chartCount > 0)) { - $objWriter->startElement('drawing'); - $objWriter->writeAttribute('r:id', 'rId1'); - $objWriter->endElement(); + if ($chartCount == 0 && $pSheet->getDrawingCollection()->count() == 0 && !$hasUnparsedDrawing) { + return; } + + // If sheet contains drawings, add the relationships + $objWriter->startElement('drawing'); + + $rId = 'rId1'; + if (isset($unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds'])) { + $drawingOriginalIds = $unparsedLoadedData['sheets'][$pSheet->getCodeName()]['drawingOriginalIds']; + // take first. In future can be overriten + $rId = reset($drawingOriginalIds); + } + + $objWriter->writeAttribute('r:id', $rId); + $objWriter->endElement(); } /** @@ -1185,4 +1212,15 @@ class Worksheet extends WriterPart $objWriter->endElement(); } } + + private function writeAlternateContent(XMLWriter $objWriter, PhpspreadsheetWorksheet $pSheet) + { + if (empty($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'])) { + return; + } + + foreach ($pSheet->getParent()->getUnparsedLoadedData()['sheets'][$pSheet->getCodeName()]['AlternateContents'] as $alternateContent) { + $objWriter->writeRaw($alternateContent); + } + } } diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php new file mode 100644 index 0000000..871b6ef --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/CalculationTest.php @@ -0,0 +1,120 @@ +setLocale('en_us'); + } + + /** + * @dataProvider providerBinaryComparisonOperation + * + * @param mixed $formula + * @param mixed $expectedResultExcel + * @param mixed $expectedResultOpenOffice + */ + public function testBinaryComparisonOperation($formula, $expectedResultExcel, $expectedResultOpenOffice) + { + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + $resultExcel = Calculation::getInstance()->_calculateFormulaValue($formula); + self::assertEquals($expectedResultExcel, $resultExcel, 'should be Excel compatible'); + + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + $resultOpenOffice = Calculation::getInstance()->_calculateFormulaValue($formula); + self::assertEquals($expectedResultOpenOffice, $resultOpenOffice, 'should be OpenOffice compatible'); + } + + public function providerBinaryComparisonOperation() + { + return require 'data/CalculationBinaryComparisonOperation.php'; + } + + /** + * @dataProvider providerGetFunctions + * + * @param string $category + * @param array|string $functionCall + * @param string $argumentCount + */ + public function testGetFunctions($category, $functionCall, $argumentCount) + { + self::assertInternalType('callable', $functionCall); + } + + public function providerGetFunctions() + { + return Calculation::getInstance()->getFunctions(); + } + + public function testIsImplemented() + { + $calculation = Calculation::getInstance(); + self::assertFalse($calculation->isImplemented('non-existing-function')); + self::assertFalse($calculation->isImplemented('AREAS')); + self::assertTrue($calculation->isImplemented('coUNt')); + self::assertTrue($calculation->isImplemented('abs')); + } + + /** + * @dataProvider providerCanLoadAllSupportedLocales + * + * @param string $locale + */ + public function testCanLoadAllSupportedLocales($locale) + { + $calculation = Calculation::getInstance(); + self::assertTrue($calculation->setLocale($locale)); + } + + public function providerCanLoadAllSupportedLocales() + { + return [ + ['bg'], + ['cs'], + ['da'], + ['de'], + ['en_us'], + ['es'], + ['fi'], + ['fr'], + ['hu'], + ['it'], + ['nl'], + ['no'], + ['pl'], + ['pt'], + ['pt_br'], + ['ru'], + ['sv'], + ['tr'], + ]; + } + + public function testDoesHandleXlfnFunctions() + { + $calculation = Calculation::getInstance(); + + $tree = $calculation->parseFormula('=_xlfn.ISFORMULA(A1)'); + self::assertCount(3, $tree); + $function = $tree[2]; + self::assertEquals('Function', $function['type']); + + $tree = $calculation->parseFormula('=_xlfn.STDEV.S(A1:B2)'); + self::assertCount(5, $tree); + $function = $tree[4]; + self::assertEquals('Function', $function['type']); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/DateTimeTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/DateTimeTest.php new file mode 100644 index 0000000..a6d781a --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/DateTimeTest.php @@ -0,0 +1,487 @@ +format('d-M-Y'), '31-Jan-2012'); + } + + public function testDATEwith1904Calendar() + { + Date::setExcelCalendar(Date::CALENDAR_MAC_1904); + $result = DateTime::DATE(1918, 11, 11); + Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); + self::assertEquals($result, 5428); + } + + public function testDATEwith1904CalendarError() + { + Date::setExcelCalendar(Date::CALENDAR_MAC_1904); + $result = DateTime::DATE(1901, 1, 31); + Date::setExcelCalendar(Date::CALENDAR_WINDOWS_1900); + self::assertEquals($result, '#NUM!'); + } + + /** + * @dataProvider providerDATEVALUE + * + * @param mixed $expectedResult + */ + public function testDATEVALUE($expectedResult, ...$args) + { + $result = DateTime::DATEVALUE(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerDATEVALUE() + { + return require 'data/Calculation/DateTime/DATEVALUE.php'; + } + + public function testDATEVALUEtoPHP() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC); + $result = DateTime::DATEVALUE('2012-1-31'); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + self::assertEquals(1327968000, $result, null, 1E-8); + } + + public function testDATEVALUEtoPHPObject() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT); + $result = DateTime::DATEVALUE('2012-1-31'); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + // Must return an object... + self::assertInternalType('object', $result); + // ... of the correct type + self::assertTrue(is_a($result, 'DateTime')); + // ... with the correct value + self::assertEquals($result->format('d-M-Y'), '31-Jan-2012'); + } + + /** + * @dataProvider providerYEAR + * + * @param mixed $expectedResult + */ + public function testYEAR($expectedResult, ...$args) + { + $result = DateTime::YEAR(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerYEAR() + { + return require 'data/Calculation/DateTime/YEAR.php'; + } + + /** + * @dataProvider providerMONTH + * + * @param mixed $expectedResult + */ + public function testMONTH($expectedResult, ...$args) + { + $result = DateTime::MONTHOFYEAR(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerMONTH() + { + return require 'data/Calculation/DateTime/MONTH.php'; + } + + /** + * @dataProvider providerWEEKNUM + * + * @param mixed $expectedResult + */ + public function testWEEKNUM($expectedResult, ...$args) + { + $result = DateTime::WEEKNUM(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerWEEKNUM() + { + return require 'data/Calculation/DateTime/WEEKNUM.php'; + } + + /** + * @dataProvider providerISOWEEKNUM + * + * @param mixed $expectedResult + * @param mixed $dateValue + */ + public function testISOWEEKNUM($expectedResult, $dateValue) + { + $result = DateTime::ISOWEEKNUM($dateValue); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerISOWEEKNUM() + { + return require 'data/Calculation/DateTime/ISOWEEKNUM.php'; + } + + /** + * @dataProvider providerWEEKDAY + * + * @param mixed $expectedResult + */ + public function testWEEKDAY($expectedResult, ...$args) + { + $result = DateTime::WEEKDAY(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerWEEKDAY() + { + return require 'data/Calculation/DateTime/WEEKDAY.php'; + } + + /** + * @dataProvider providerDAY + * + * @param mixed $expectedResultExcel + * @param mixed $expectedResultOpenOffice + */ + public function testDAY($expectedResultExcel, $expectedResultOpenOffice, ...$args) + { + $resultExcel = DateTime::DAYOFMONTH(...$args); + self::assertEquals($expectedResultExcel, $resultExcel, null, 1E-8); + + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + $resultOpenOffice = DateTime::DAYOFMONTH(...$args); + self::assertEquals($expectedResultOpenOffice, $resultOpenOffice, null, 1E-8); + } + + public function providerDAY() + { + return require 'data/Calculation/DateTime/DAY.php'; + } + + /** + * @dataProvider providerTIME + * + * @param mixed $expectedResult + */ + public function testTIME($expectedResult, ...$args) + { + $result = DateTime::TIME(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerTIME() + { + return require 'data/Calculation/DateTime/TIME.php'; + } + + public function testTIMEtoPHP() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC); + $result = DateTime::TIME(7, 30, 20); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + self::assertEquals(27020, $result, null, 1E-8); + } + + public function testTIMEtoPHPObject() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT); + $result = DateTime::TIME(7, 30, 20); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + // Must return an object... + self::assertInternalType('object', $result); + // ... of the correct type + self::assertTrue(is_a($result, 'DateTime')); + // ... with the correct value + self::assertEquals($result->format('H:i:s'), '07:30:20'); + } + + /** + * @dataProvider providerTIMEVALUE + * + * @param mixed $expectedResult + */ + public function testTIMEVALUE($expectedResult, ...$args) + { + $result = DateTime::TIMEVALUE(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerTIMEVALUE() + { + return require 'data/Calculation/DateTime/TIMEVALUE.php'; + } + + public function testTIMEVALUEtoPHP() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC); + $result = DateTime::TIMEVALUE('7:30:20'); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + self::assertEquals(23420, $result, null, 1E-8); + } + + public function testTIMEVALUEtoPHPObject() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT); + $result = DateTime::TIMEVALUE('7:30:20'); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + // Must return an object... + self::assertInternalType('object', $result); + // ... of the correct type + self::assertTrue(is_a($result, 'DateTime')); + // ... with the correct value + self::assertEquals($result->format('H:i:s'), '07:30:20'); + } + + /** + * @dataProvider providerHOUR + * + * @param mixed $expectedResult + */ + public function testHOUR($expectedResult, ...$args) + { + $result = DateTime::HOUROFDAY(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerHOUR() + { + return require 'data/Calculation/DateTime/HOUR.php'; + } + + /** + * @dataProvider providerMINUTE + * + * @param mixed $expectedResult + */ + public function testMINUTE($expectedResult, ...$args) + { + $result = DateTime::MINUTE(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerMINUTE() + { + return require 'data/Calculation/DateTime/MINUTE.php'; + } + + /** + * @dataProvider providerSECOND + * + * @param mixed $expectedResult + */ + public function testSECOND($expectedResult, ...$args) + { + $result = DateTime::SECOND(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerSECOND() + { + return require 'data/Calculation/DateTime/SECOND.php'; + } + + /** + * @dataProvider providerNETWORKDAYS + * + * @param mixed $expectedResult + */ + public function testNETWORKDAYS($expectedResult, ...$args) + { + $result = DateTime::NETWORKDAYS(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerNETWORKDAYS() + { + return require 'data/Calculation/DateTime/NETWORKDAYS.php'; + } + + /** + * @dataProvider providerWORKDAY + * + * @param mixed $expectedResult + */ + public function testWORKDAY($expectedResult, ...$args) + { + $result = DateTime::WORKDAY(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerWORKDAY() + { + return require 'data/Calculation/DateTime/WORKDAY.php'; + } + + /** + * @dataProvider providerEDATE + * + * @param mixed $expectedResult + */ + public function testEDATE($expectedResult, ...$args) + { + $result = DateTime::EDATE(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerEDATE() + { + return require 'data/Calculation/DateTime/EDATE.php'; + } + + public function testEDATEtoPHP() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC); + $result = DateTime::EDATE('2012-1-26', -1); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + self::assertEquals(1324857600, $result, null, 1E-8); + } + + public function testEDATEtoPHPObject() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT); + $result = DateTime::EDATE('2012-1-26', -1); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + // Must return an object... + self::assertInternalType('object', $result); + // ... of the correct type + self::assertTrue(is_a($result, 'DateTime')); + // ... with the correct value + self::assertEquals($result->format('d-M-Y'), '26-Dec-2011'); + } + + /** + * @dataProvider providerEOMONTH + * + * @param mixed $expectedResult + */ + public function testEOMONTH($expectedResult, ...$args) + { + $result = DateTime::EOMONTH(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerEOMONTH() + { + return require 'data/Calculation/DateTime/EOMONTH.php'; + } + + public function testEOMONTHtoPHP() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_NUMERIC); + $result = DateTime::EOMONTH('2012-1-26', -1); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + self::assertEquals(1325289600, $result, null, 1E-8); + } + + public function testEOMONTHtoPHPObject() + { + Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT); + $result = DateTime::EOMONTH('2012-1-26', -1); + Functions::setReturnDateType(Functions::RETURNDATE_EXCEL); + // Must return an object... + self::assertInternalType('object', $result); + // ... of the correct type + self::assertTrue(is_a($result, 'DateTime')); + // ... with the correct value + self::assertEquals($result->format('d-M-Y'), '31-Dec-2011'); + } + + /** + * @dataProvider providerDATEDIF + * + * @param mixed $expectedResult + */ + public function testDATEDIF($expectedResult, ...$args) + { + $result = DateTime::DATEDIF(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerDATEDIF() + { + return require 'data/Calculation/DateTime/DATEDIF.php'; + } + + /** + * @dataProvider providerDAYS360 + * + * @param mixed $expectedResult + */ + public function testDAYS360($expectedResult, ...$args) + { + $result = DateTime::DAYS360(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerDAYS360() + { + return require 'data/Calculation/DateTime/DAYS360.php'; + } + + /** + * @dataProvider providerYEARFRAC + * + * @param mixed $expectedResult + */ + public function testYEARFRAC($expectedResult, ...$args) + { + $result = DateTime::YEARFRAC(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerYEARFRAC() + { + return require 'data/Calculation/DateTime/YEARFRAC.php'; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/EngineeringTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/EngineeringTest.php new file mode 100644 index 0000000..09da20c --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/EngineeringTest.php @@ -0,0 +1,1009 @@ +complexAssert = new ComplexAssert(); + Functions::setCompatibilityMode(Functions::COMPATIBILITY_EXCEL); + } + + public function tearDown() + { + $this->complexAssert = null; + } + + /** + * @dataProvider providerBESSELI + * + * @param mixed $expectedResult + */ + public function testBESSELI($expectedResult, ...$args) + { + $result = Engineering::BESSELI(...$args); + self::assertEquals($expectedResult, $result, null, self::BESSEL_PRECISION); + } + + public function providerBESSELI() + { + return require 'data/Calculation/Engineering/BESSELI.php'; + } + + /** + * @dataProvider providerBESSELJ + * + * @param mixed $expectedResult + */ + public function testBESSELJ($expectedResult, ...$args) + { + $result = Engineering::BESSELJ(...$args); + self::assertEquals($expectedResult, $result, null, self::BESSEL_PRECISION); + } + + public function providerBESSELJ() + { + return require 'data/Calculation/Engineering/BESSELJ.php'; + } + + /** + * @dataProvider providerBESSELK + * + * @param mixed $expectedResult + */ + public function testBESSELK($expectedResult, ...$args) + { + $result = Engineering::BESSELK(...$args); + self::assertEquals($expectedResult, $result, null, self::BESSEL_PRECISION); + } + + public function providerBESSELK() + { + return require 'data/Calculation/Engineering/BESSELK.php'; + } + + /** + * @dataProvider providerBESSELY + * + * @param mixed $expectedResult + */ + public function testBESSELY($expectedResult, ...$args) + { + $result = Engineering::BESSELY(...$args); + self::assertEquals($expectedResult, $result, null, self::BESSEL_PRECISION); + } + + public function providerBESSELY() + { + return require 'data/Calculation/Engineering/BESSELY.php'; + } + + /** + * @dataProvider providerCOMPLEX + * + * @param mixed $expectedResult + */ + public function testParseComplex() + { + list($real, $imaginary, $suffix) = [1.23e-4, 5.67e+8, 'j']; + + $result = Engineering::parseComplex('1.23e-4+5.67e+8j'); + $this->assertArrayHasKey('real', $result); + $this->assertEquals($real, $result['real']); + $this->assertArrayHasKey('imaginary', $result); + $this->assertEquals($imaginary, $result['imaginary']); + $this->assertArrayHasKey('suffix', $result); + $this->assertEquals($suffix, $result['suffix']); + } + + /** + * @dataProvider providerCOMPLEX + * + * @param mixed $expectedResult + */ + public function testCOMPLEX($expectedResult, ...$args) + { + $result = Engineering::COMPLEX(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerCOMPLEX() + { + return require 'data/Calculation/Engineering/COMPLEX.php'; + } + + /** + * @dataProvider providerIMAGINARY + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMAGINARY($expectedResult, $value) + { + $result = Engineering::IMAGINARY($value); + self::assertEquals($expectedResult, $result, null, self::COMPLEX_PRECISION); + } + + public function providerIMAGINARY() + { + return require 'data/Calculation/Engineering/IMAGINARY.php'; + } + + /** + * @dataProvider providerIMREAL + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMREAL($expectedResult, $value) + { + $result = Engineering::IMREAL($value); + self::assertEquals($expectedResult, $result, null, self::COMPLEX_PRECISION); + } + + public function providerIMREAL() + { + return require 'data/Calculation/Engineering/IMREAL.php'; + } + + /** + * @dataProvider providerIMABS + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMABS($expectedResult, $value) + { + $result = Engineering::IMABS($value); + self::assertEquals($expectedResult, $result, null, self::COMPLEX_PRECISION); + } + + public function providerIMABS() + { + return require 'data/Calculation/Engineering/IMABS.php'; + } + + /** + * @dataProvider providerIMARGUMENT + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMARGUMENT($expectedResult, $value) + { + $result = Engineering::IMARGUMENT($value); + self::assertEquals($expectedResult, $result, null, self::COMPLEX_PRECISION); + } + + public function providerIMARGUMENT() + { + return require 'data/Calculation/Engineering/IMARGUMENT.php'; + } + + /** + * @dataProvider providerIMCONJUGATE + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMCONJUGATE($expectedResult, $value) + { + $result = Engineering::IMCONJUGATE($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMCONJUGATE() + { + return require 'data/Calculation/Engineering/IMCONJUGATE.php'; + } + + /** + * @dataProvider providerIMCOS + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMCOS($expectedResult, $value) + { + $result = Engineering::IMCOS($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMCOS() + { + return require 'data/Calculation/Engineering/IMCOS.php'; + } + + /** + * @dataProvider providerIMCOSH + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMCOSH($expectedResult, $value) + { + $result = Engineering::IMCOSH($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMCOSH() + { + return require 'data/Calculation/Engineering/IMCOSH.php'; + } + + /** + * @dataProvider providerIMCOT + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMCOT($expectedResult, $value) + { + $result = Engineering::IMCOT($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMCOT() + { + return require 'data/Calculation/Engineering/IMCOT.php'; + } + + /** + * @dataProvider providerIMCSC + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMCSC($expectedResult, $value) + { + $result = Engineering::IMCSC($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMCSC() + { + return require 'data/Calculation/Engineering/IMCSC.php'; + } + + /** + * @dataProvider providerIMCSCH + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMCSCH($expectedResult, $value) + { + $result = Engineering::IMCSCH($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMCSCH() + { + return require 'data/Calculation/Engineering/IMCSCH.php'; + } + + /** + * @dataProvider providerIMSEC + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMSEC($expectedResult, $value) + { + $result = Engineering::IMSEC($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMSEC() + { + return require 'data/Calculation/Engineering/IMSEC.php'; + } + + /** + * @dataProvider providerIMSECH + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMSECH($expectedResult, $value) + { + $result = Engineering::IMSECH($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMSECH() + { + return require 'data/Calculation/Engineering/IMSECH.php'; + } + + /** + * @dataProvider providerIMDIV + * + * @param mixed $expectedResult + */ + public function testIMDIV($expectedResult, ...$args) + { + $result = Engineering::IMDIV(...$args); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMDIV() + { + return require 'data/Calculation/Engineering/IMDIV.php'; + } + + /** + * @dataProvider providerIMEXP + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMEXP($expectedResult, $value) + { + $result = Engineering::IMEXP($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMEXP() + { + return require 'data/Calculation/Engineering/IMEXP.php'; + } + + /** + * @dataProvider providerIMLN + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMLN($expectedResult, $value) + { + $result = Engineering::IMLN($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMLN() + { + return require 'data/Calculation/Engineering/IMLN.php'; + } + + /** + * @dataProvider providerIMLOG2 + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMLOG2($expectedResult, $value) + { + $result = Engineering::IMLOG2($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMLOG2() + { + return require 'data/Calculation/Engineering/IMLOG2.php'; + } + + /** + * @dataProvider providerIMLOG10 + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMLOG10($expectedResult, $value) + { + $result = Engineering::IMLOG10($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMLOG10() + { + return require 'data/Calculation/Engineering/IMLOG10.php'; + } + + /** + * @dataProvider providerIMPOWER + * + * @param mixed $expectedResult + */ + public function testIMPOWER($expectedResult, ...$args) + { + $result = Engineering::IMPOWER(...$args); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMPOWER() + { + return require 'data/Calculation/Engineering/IMPOWER.php'; + } + + /** + * @dataProvider providerIMPRODUCT + * + * @param mixed $expectedResult + */ + public function testIMPRODUCT($expectedResult, ...$args) + { + $result = Engineering::IMPRODUCT(...$args); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMPRODUCT() + { + return require 'data/Calculation/Engineering/IMPRODUCT.php'; + } + + /** + * @dataProvider providerIMSIN + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMSIN($expectedResult, $value) + { + $result = Engineering::IMSIN($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMSIN() + { + return require 'data/Calculation/Engineering/IMSIN.php'; + } + + /** + * @dataProvider providerIMSINH + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMSINH($expectedResult, $value) + { + $result = Engineering::IMSINH($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMSINH() + { + return require 'data/Calculation/Engineering/IMSINH.php'; + } + + /** + * @dataProvider providerIMTAN + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMTAN($expectedResult, $value) + { + $result = Engineering::IMTAN($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMTAN() + { + return require 'data/Calculation/Engineering/IMTAN.php'; + } + + /** + * @dataProvider providerIMSQRT + * + * @param mixed $expectedResult + * @param mixed $value + */ + public function testIMSQRT($expectedResult, $value) + { + $result = Engineering::IMSQRT($value); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMSQRT() + { + return require 'data/Calculation/Engineering/IMSQRT.php'; + } + + /** + * @dataProvider providerIMSUB + * + * @param mixed $expectedResult + */ + public function testIMSUB($expectedResult, ...$args) + { + $result = Engineering::IMSUB(...$args); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMSUB() + { + return require 'data/Calculation/Engineering/IMSUB.php'; + } + + /** + * @dataProvider providerIMSUM + * + * @param mixed $expectedResult + */ + public function testIMSUM($expectedResult, ...$args) + { + $result = Engineering::IMSUM(...$args); + self::assertTrue( + $this->complexAssert->assertComplexEquals($expectedResult, $result, self::COMPLEX_PRECISION), + $this->complexAssert->getErrorMessage() + ); + } + + public function providerIMSUM() + { + return require 'data/Calculation/Engineering/IMSUM.php'; + } + + /** + * @dataProvider providerERF + * + * @param mixed $expectedResult + */ + public function testERF($expectedResult, ...$args) + { + $result = Engineering::ERF(...$args); + self::assertEquals($expectedResult, $result, null, self::ERF_PRECISION); + } + + public function providerERF() + { + return require 'data/Calculation/Engineering/ERF.php'; + } + + /** + * @dataProvider providerERFPRECISE + * + * @param mixed $expectedResult + */ + public function testERFPRECISE($expectedResult, ...$args) + { + $result = Engineering::ERFPRECISE(...$args); + self::assertEquals($expectedResult, $result, null, self::ERF_PRECISION); + } + + public function providerERFPRECISE() + { + return require 'data/Calculation/Engineering/ERFPRECISE.php'; + } + + /** + * @dataProvider providerERFC + * + * @param mixed $expectedResult + */ + public function testERFC($expectedResult, ...$args) + { + $result = Engineering::ERFC(...$args); + self::assertEquals($expectedResult, $result, null, self::ERF_PRECISION); + } + + public function providerERFC() + { + return require 'data/Calculation/Engineering/ERFC.php'; + } + + /** + * @dataProvider providerBIN2DEC + * + * @param mixed $expectedResult + */ + public function testBIN2DEC($expectedResult, ...$args) + { + $result = Engineering::BINTODEC(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerBIN2DEC() + { + return require 'data/Calculation/Engineering/BIN2DEC.php'; + } + + /** + * @dataProvider providerBIN2HEX + * + * @param mixed $expectedResult + */ + public function testBIN2HEX($expectedResult, ...$args) + { + $result = Engineering::BINTOHEX(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerBIN2HEX() + { + return require 'data/Calculation/Engineering/BIN2HEX.php'; + } + + /** + * @dataProvider providerBIN2OCT + * + * @param mixed $expectedResult + */ + public function testBIN2OCT($expectedResult, ...$args) + { + $result = Engineering::BINTOOCT(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerBIN2OCT() + { + return require 'data/Calculation/Engineering/BIN2OCT.php'; + } + + /** + * @dataProvider providerDEC2BIN + * + * @param mixed $expectedResult + */ + public function testDEC2BIN($expectedResult, ...$args) + { + $result = Engineering::DECTOBIN(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerDEC2BIN() + { + return require 'data/Calculation/Engineering/DEC2BIN.php'; + } + + /** + * @dataProvider providerDEC2HEX + * + * @param mixed $expectedResult + */ + public function testDEC2HEX($expectedResult, ...$args) + { + $result = Engineering::DECTOHEX(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerDEC2HEX() + { + return require 'data/Calculation/Engineering/DEC2HEX.php'; + } + + /** + * @dataProvider providerDEC2OCT + * + * @param mixed $expectedResult + */ + public function testDEC2OCT($expectedResult, ...$args) + { + $result = Engineering::DECTOOCT(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerDEC2OCT() + { + return require 'data/Calculation/Engineering/DEC2OCT.php'; + } + + /** + * @dataProvider providerHEX2BIN + * + * @param mixed $expectedResult + */ + public function testHEX2BIN($expectedResult, ...$args) + { + $result = Engineering::HEXTOBIN(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerHEX2BIN() + { + return require 'data/Calculation/Engineering/HEX2BIN.php'; + } + + /** + * @dataProvider providerHEX2DEC + * + * @param mixed $expectedResult + */ + public function testHEX2DEC($expectedResult, ...$args) + { + $result = Engineering::HEXTODEC(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerHEX2DEC() + { + return require 'data/Calculation/Engineering/HEX2DEC.php'; + } + + /** + * @dataProvider providerHEX2OCT + * + * @param mixed $expectedResult + */ + public function testHEX2OCT($expectedResult, ...$args) + { + $result = Engineering::HEXTOOCT(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerHEX2OCT() + { + return require 'data/Calculation/Engineering/HEX2OCT.php'; + } + + /** + * @dataProvider providerOCT2BIN + * + * @param mixed $expectedResult + */ + public function testOCT2BIN($expectedResult, ...$args) + { + $result = Engineering::OCTTOBIN(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerOCT2BIN() + { + return require 'data/Calculation/Engineering/OCT2BIN.php'; + } + + /** + * @dataProvider providerOCT2DEC + * + * @param mixed $expectedResult + */ + public function testOCT2DEC($expectedResult, ...$args) + { + $result = Engineering::OCTTODEC(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerOCT2DEC() + { + return require 'data/Calculation/Engineering/OCT2DEC.php'; + } + + /** + * @dataProvider providerOCT2HEX + * + * @param mixed $expectedResult + */ + public function testOCT2HEX($expectedResult, ...$args) + { + $result = Engineering::OCTTOHEX(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerOCT2HEX() + { + return require 'data/Calculation/Engineering/OCT2HEX.php'; + } + + /** + * @dataProvider providerBITAND + * + * @param mixed $expectedResult + * @param mixed[] $args + */ + public function testBITAND($expectedResult, array $args) + { + $result = Engineering::BITAND(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerBITAND() + { + return require 'data/Calculation/Engineering/BITAND.php'; + } + + /** + * @dataProvider providerBITOR + * + * @param mixed $expectedResult + * @param mixed[] $args + */ + public function testBITOR($expectedResult, array $args) + { + $result = Engineering::BITOR(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerBITOR() + { + return require 'data/Calculation/Engineering/BITOR.php'; + } + + /** + * @dataProvider providerBITXOR + * + * @param mixed $expectedResult + * @param mixed[] $args + */ + public function testBITXOR($expectedResult, array $args) + { + $result = Engineering::BITXOR(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerBITXOR() + { + return require 'data/Calculation/Engineering/BITXOR.php'; + } + + /** + * @dataProvider providerBITLSHIFT + * + * @param mixed $expectedResult + * @param mixed[] $args + */ + public function testBITLSHIFT($expectedResult, array $args) + { + $result = Engineering::BITLSHIFT(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerBITLSHIFT() + { + return require 'data/Calculation/Engineering/BITLSHIFT.php'; + } + + /** + * @dataProvider providerBITRSHIFT + * + * @param mixed $expectedResult + * @param mixed[] $args + */ + public function testBITRSHIFT($expectedResult, array $args) + { + $result = Engineering::BITRSHIFT(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerBITRSHIFT() + { + return require 'data/Calculation/Engineering/BITRSHIFT.php'; + } + + /** + * @dataProvider providerDELTA + * + * @param mixed $expectedResult + */ + public function testDELTA($expectedResult, ...$args) + { + $result = Engineering::DELTA(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerDELTA() + { + return require 'data/Calculation/Engineering/DELTA.php'; + } + + /** + * @dataProvider providerGESTEP + * + * @param mixed $expectedResult + */ + public function testGESTEP($expectedResult, ...$args) + { + $result = Engineering::GESTEP(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerGESTEP() + { + return require 'data/Calculation/Engineering/GESTEP.php'; + } + + public function testGetConversionGroups() + { + $result = Engineering::getConversionGroups(); + self::assertInternalType('array', $result); + } + + public function testGetConversionGroupUnits() + { + $result = Engineering::getConversionGroupUnits(); + self::assertInternalType('array', $result); + } + + public function testGetConversionGroupUnitDetails() + { + $result = Engineering::getConversionGroupUnitDetails(); + self::assertInternalType('array', $result); + } + + public function testGetConversionMultipliers() + { + $result = Engineering::getConversionMultipliers(); + self::assertInternalType('array', $result); + } + + /** + * @dataProvider providerCONVERTUOM + * + * @param mixed $expectedResult + */ + public function testCONVERTUOM($expectedResult, ...$args) + { + $result = Engineering::CONVERTUOM(...$args); + self::assertEquals($expectedResult, $result, null); + } + + public function providerCONVERTUOM() + { + return require 'data/Calculation/Engineering/CONVERTUOM.php'; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php new file mode 100644 index 0000000..d910389 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FinancialTest.php @@ -0,0 +1,613 @@ +markTestIncomplete('TODO: This test should be fixed'); + + $result = Financial::PRICE(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerPRICE() + { + return require 'data/Calculation/Financial/PRICE.php'; + } + + /** + * @dataProvider providerPRICEDISC + * + * @param mixed $expectedResult + */ + public function testPRICEDISC($expectedResult, array $args) + { + $result = Financial::PRICEDISC(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerPRICEDISC() + { + return require 'data/Calculation/Financial/PRICEDISC.php'; + } + + /** + * @dataProvider providerPV + * + * @param mixed $expectedResult + */ + public function testPV($expectedResult, array $args) + { + $result = Financial::PV(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerPV() + { + return require 'data/Calculation/Financial/PV.php'; + } + + /** + * @dataProvider providerRATE + * + * @param mixed $expectedResult + */ + public function testRATE($expectedResult, ...$args) + { + $this->markTestIncomplete('TODO: This test should be fixed'); + + $result = Financial::RATE(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerRATE() + { + return require 'data/Calculation/Financial/RATE.php'; + } + + /** + * @dataProvider providerXIRR + * + * @param mixed $expectedResult + */ + public function testXIRR($expectedResult, ...$args) + { + $this->markTestIncomplete('TODO: This test should be fixed'); + + $result = Financial::XIRR(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerXIRR() + { + return require 'data/Calculation/Financial/XIRR.php'; + } + + /** + * @dataProvider providerPDURATION + * + * @param mixed $expectedResult + */ + public function testPDURATION($expectedResult, array $args) + { + $result = Financial::PDURATION(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerPDURATION() + { + return require 'data/Calculation/Financial/PDURATION.php'; + } + + /** + * @dataProvider providerRRI + * + * @param mixed $expectedResult + */ + public function testRRI($expectedResult, array $args) + { + $result = Financial::RRI(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerRRI() + { + return require 'data/Calculation/Financial/RRI.php'; + } + + /** + * @dataProvider providerSLN + * + * @param mixed $expectedResult + */ + public function testSLN($expectedResult, array $args) + { + $result = Financial::SLN(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerSLN() + { + return require 'data/Calculation/Financial/SLN.php'; + } + + /** + * @dataProvider providerSYD + * + * @param mixed $expectedResult + */ + public function testSYD($expectedResult, array $args) + { + $result = Financial::SYD(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerSYD() + { + return require 'data/Calculation/Financial/SYD.php'; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php new file mode 100644 index 0000000..df2028c --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/FunctionsTest.php @@ -0,0 +1,385 @@ +assertTrue($result); + // Test that mode has been changed + $this->assertEquals(Functions::COMPATIBILITY_GNUMERIC, Functions::getCompatibilityMode()); + } + + public function testInvalidCompatibilityMode() + { + $result = Functions::setCompatibilityMode('INVALIDMODE'); + // Test for a false response for failure + $this->assertFalse($result); + // Test that mode has not been changed + $this->assertEquals(Functions::COMPATIBILITY_EXCEL, Functions::getCompatibilityMode()); + } + + public function testReturnDateType() + { + $result = Functions::setReturnDateType(Functions::RETURNDATE_PHP_OBJECT); + // Test for a true response for success + $this->assertTrue($result); + // Test that mode has been changed + $this->assertEquals(Functions::RETURNDATE_PHP_OBJECT, Functions::getReturnDateType()); + } + + public function testInvalidReturnDateType() + { + $result = Functions::setReturnDateType('INVALIDTYPE'); + // Test for a false response for failure + $this->assertFalse($result); + // Test that mode has not been changed + $this->assertEquals(Functions::RETURNDATE_EXCEL, Functions::getReturnDateType()); + } + + public function testDUMMY() + { + $result = Functions::DUMMY(); + self::assertEquals('#Not Yet Implemented', $result); + } + + public function testDIV0() + { + $result = Functions::DIV0(); + self::assertEquals('#DIV/0!', $result); + } + + public function testNA() + { + $result = Functions::NA(); + self::assertEquals('#N/A', $result); + } + + public function testNAN() + { + $result = Functions::NAN(); + self::assertEquals('#NUM!', $result); + } + + public function testNAME() + { + $result = Functions::NAME(); + self::assertEquals('#NAME?', $result); + } + + public function testREF() + { + $result = Functions::REF(); + self::assertEquals('#REF!', $result); + } + + public function testNULL() + { + $result = Functions::null(); + self::assertEquals('#NULL!', $result); + } + + public function testVALUE() + { + $result = Functions::VALUE(); + self::assertEquals('#VALUE!', $result); + } + + /** + * @dataProvider providerIsBlank + * + * @param mixed $expectedResult + */ + public function testIsBlank($expectedResult, ...$args) + { + $result = Functions::isBlank(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsBlank() + { + return require 'data/Calculation/Functions/IS_BLANK.php'; + } + + /** + * @dataProvider providerIsErr + * + * @param mixed $expectedResult + */ + public function testIsErr($expectedResult, ...$args) + { + $result = Functions::isErr(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsErr() + { + return require 'data/Calculation/Functions/IS_ERR.php'; + } + + /** + * @dataProvider providerIsError + * + * @param mixed $expectedResult + */ + public function testIsError($expectedResult, ...$args) + { + $result = Functions::isError(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsError() + { + return require 'data/Calculation/Functions/IS_ERROR.php'; + } + + /** + * @dataProvider providerErrorType + * + * @param mixed $expectedResult + */ + public function testErrorType($expectedResult, ...$args) + { + $result = Functions::errorType(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerErrorType() + { + return require 'data/Calculation/Functions/ERROR_TYPE.php'; + } + + /** + * @dataProvider providerIsLogical + * + * @param mixed $expectedResult + */ + public function testIsLogical($expectedResult, ...$args) + { + $result = Functions::isLogical(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsLogical() + { + return require 'data/Calculation/Functions/IS_LOGICAL.php'; + } + + /** + * @dataProvider providerIsNa + * + * @param mixed $expectedResult + */ + public function testIsNa($expectedResult, ...$args) + { + $result = Functions::isNa(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsNa() + { + return require 'data/Calculation/Functions/IS_NA.php'; + } + + /** + * @dataProvider providerIsNumber + * + * @param mixed $expectedResult + */ + public function testIsNumber($expectedResult, ...$args) + { + $result = Functions::isNumber(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsNumber() + { + return require 'data/Calculation/Functions/IS_NUMBER.php'; + } + + /** + * @dataProvider providerIsText + * + * @param mixed $expectedResult + */ + public function testIsText($expectedResult, ...$args) + { + $result = Functions::isText(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsText() + { + return require 'data/Calculation/Functions/IS_TEXT.php'; + } + + /** + * @dataProvider providerIsNonText + * + * @param mixed $expectedResult + */ + public function testIsNonText($expectedResult, ...$args) + { + $result = Functions::isNonText(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsNonText() + { + return require 'data/Calculation/Functions/IS_NONTEXT.php'; + } + + /** + * @dataProvider providerIsEven + * + * @param mixed $expectedResult + */ + public function testIsEven($expectedResult, ...$args) + { + $result = Functions::isEven(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsEven() + { + return require 'data/Calculation/Functions/IS_EVEN.php'; + } + + /** + * @dataProvider providerIsOdd + * + * @param mixed $expectedResult + */ + public function testIsOdd($expectedResult, ...$args) + { + $result = Functions::isOdd(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsOdd() + { + return require 'data/Calculation/Functions/IS_ODD.php'; + } + + /** + * @dataProvider providerTYPE + * + * @param mixed $expectedResult + */ + public function testTYPE($expectedResult, ...$args) + { + $result = Functions::TYPE(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerTYPE() + { + return require 'data/Calculation/Functions/TYPE.php'; + } + + /** + * @dataProvider providerN + * + * @param mixed $expectedResult + */ + public function testN($expectedResult, ...$args) + { + $result = Functions::n(...$args); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerN() + { + return require 'data/Calculation/Functions/N.php'; + } + + /** + * @dataProvider providerIsFormula + * + * @param mixed $expectedResult + * @param mixed $reference Reference to the cell we wish to test + * @param mixed $value Value of the cell we wish to test + */ + public function testIsFormula($expectedResult, $reference, $value = 'undefined') + { + $ourCell = null; + if ($value !== 'undefined') { + $remoteCell = $this->getMockBuilder(Cell::class) + ->disableOriginalConstructor() + ->getMock(); + $remoteCell->method('isFormula') + ->will($this->returnValue(substr($value, 0, 1) == '=')); + + $remoteSheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + $remoteSheet->method('getCell') + ->will($this->returnValue($remoteCell)); + + $workbook = $this->getMockBuilder(Spreadsheet::class) + ->disableOriginalConstructor() + ->getMock(); + $workbook->method('getSheetByName') + ->will($this->returnValue($remoteSheet)); + + $sheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + $sheet->method('getCell') + ->will($this->returnValue($remoteCell)); + $sheet->method('getParent') + ->will($this->returnValue($workbook)); + + $ourCell = $this->getMockBuilder(Cell::class) + ->disableOriginalConstructor() + ->getMock(); + $ourCell->method('getWorksheet') + ->will($this->returnValue($sheet)); + } + + $result = Functions::isFormula($reference, $ourCell); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerIsFormula() + { + return require 'data/Calculation/Functions/ISFORMULA.php'; + } + + /** + * @dataProvider providerIfCondition + * + * @param mixed $expectedResult + */ + public function testIfCondition($expectedResult, ...$args) + { + $result = Functions::ifCondition(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerIfCondition() + { + return require 'data/Calculation/Functions/IF_CONDITION.php'; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php new file mode 100644 index 0000000..3dec0c7 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/LogicalTest.php @@ -0,0 +1,123 @@ +getMockBuilder(Cell::class) + ->disableOriginalConstructor() + ->getMock(); + $remoteCell->method('isFormula') + ->will($this->returnValue(substr($value, 0, 1) == '=')); + $remoteCell->method('getValue') + ->will($this->returnValue($value)); + + $remoteSheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + $remoteSheet->method('getCell') + ->will($this->returnValue($remoteCell)); + + $workbook = $this->getMockBuilder(Spreadsheet::class) + ->disableOriginalConstructor() + ->getMock(); + $workbook->method('getSheetByName') + ->will($this->returnValue($remoteSheet)); + + $sheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + $sheet->method('getCell') + ->will($this->returnValue($remoteCell)); + $sheet->method('getParent') + ->will($this->returnValue($workbook)); + + $ourCell = $this->getMockBuilder(Cell::class) + ->disableOriginalConstructor() + ->getMock(); + $ourCell->method('getWorksheet') + ->will($this->returnValue($sheet)); + } + + $result = LookupRef::FORMULATEXT($reference, $ourCell); + self::assertEquals($expectedResult, $result, null, 1E-8); + } + + public function providerFormulaText() + { + return require 'data/Calculation/LookupRef/FORMULATEXT.php'; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/MathTrigTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/MathTrigTest.php new file mode 100644 index 0000000..fa49796 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/MathTrigTest.php @@ -0,0 +1,881 @@ +markTestIncomplete('TODO: This test should be fixed'); + + $result = MathTrig::MINVERSE(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerMINVERSE() + { + return require 'data/Calculation/MathTrig/MINVERSE.php'; + } + + /** + * @dataProvider providerMMULT + * + * @param mixed $expectedResult + */ + public function testMMULT($expectedResult, ...$args) + { + $this->markTestIncomplete('TODO: This test should be fixed'); + + $result = MathTrig::MMULT(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerMMULT() + { + return require 'data/Calculation/MathTrig/MMULT.php'; + } + + /** + * @dataProvider providerMULTINOMIAL + * + * @param mixed $expectedResult + */ + public function testMULTINOMIAL($expectedResult, ...$args) + { + $result = MathTrig::MULTINOMIAL(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerMULTINOMIAL() + { + return require 'data/Calculation/MathTrig/MULTINOMIAL.php'; + } + + /** + * @dataProvider providerMROUND + * + * @param mixed $expectedResult + */ + public function testMROUND($expectedResult, ...$args) + { + Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_VALUE); + $result = MathTrig::MROUND(...$args); + Calculation::setArrayReturnType(Calculation::RETURN_ARRAY_AS_ARRAY); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerMROUND() + { + return require 'data/Calculation/MathTrig/MROUND.php'; + } + + /** + * @dataProvider providerPRODUCT + * + * @param mixed $expectedResult + */ + public function testPRODUCT($expectedResult, ...$args) + { + $result = MathTrig::PRODUCT(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerPRODUCT() + { + return require 'data/Calculation/MathTrig/PRODUCT.php'; + } + + /** + * @dataProvider providerQUOTIENT + * + * @param mixed $expectedResult + */ + public function testQUOTIENT($expectedResult, ...$args) + { + $result = MathTrig::QUOTIENT(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerQUOTIENT() + { + return require 'data/Calculation/MathTrig/QUOTIENT.php'; + } + + /** + * @dataProvider providerROUNDUP + * + * @param mixed $expectedResult + */ + public function testROUNDUP($expectedResult, ...$args) + { + $result = MathTrig::ROUNDUP(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerROUNDUP() + { + return require 'data/Calculation/MathTrig/ROUNDUP.php'; + } + + /** + * @dataProvider providerROUNDDOWN + * + * @param mixed $expectedResult + */ + public function testROUNDDOWN($expectedResult, ...$args) + { + $result = MathTrig::ROUNDDOWN(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerROUNDDOWN() + { + return require 'data/Calculation/MathTrig/ROUNDDOWN.php'; + } + + /** + * @dataProvider providerSERIESSUM + * + * @param mixed $expectedResult + */ + public function testSERIESSUM($expectedResult, ...$args) + { + $result = MathTrig::SERIESSUM(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSERIESSUM() + { + return require 'data/Calculation/MathTrig/SERIESSUM.php'; + } + + /** + * @dataProvider providerSUMSQ + * + * @param mixed $expectedResult + */ + public function testSUMSQ($expectedResult, ...$args) + { + $result = MathTrig::SUMSQ(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSUMSQ() + { + return require 'data/Calculation/MathTrig/SUMSQ.php'; + } + + /** + * @dataProvider providerSUMPRODUCT + * + * @param mixed $expectedResult + */ + public function testSUMPRODUCT($expectedResult, ...$args) + { + $result = MathTrig::SUMPRODUCT(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSUMPRODUCT() + { + return require 'data/Calculation/MathTrig/SUMPRODUCT.php'; + } + + /** + * @dataProvider providerSUMX2MY2 + * + * @param mixed $expectedResult + */ + public function testSUMX2MY2($expectedResult, ...$args) + { + $result = MathTrig::SUMX2MY2(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSUMX2MY2() + { + return require 'data/Calculation/MathTrig/SUMX2MY2.php'; + } + + /** + * @dataProvider providerSUMX2PY2 + * + * @param mixed $expectedResult + */ + public function testSUMX2PY2($expectedResult, ...$args) + { + $result = MathTrig::SUMX2PY2(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSUMX2PY2() + { + return require 'data/Calculation/MathTrig/SUMX2PY2.php'; + } + + /** + * @dataProvider providerSUMXMY2 + * + * @param mixed $expectedResult + */ + public function testSUMXMY2($expectedResult, ...$args) + { + $result = MathTrig::SUMXMY2(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSUMXMY2() + { + return require 'data/Calculation/MathTrig/SUMXMY2.php'; + } + + /** + * @dataProvider providerTRUNC + * + * @param mixed $expectedResult + */ + public function testTRUNC($expectedResult, ...$args) + { + $result = MathTrig::TRUNC(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerTRUNC() + { + return require 'data/Calculation/MathTrig/TRUNC.php'; + } + + /** + * @dataProvider providerROMAN + * + * @param mixed $expectedResult + */ + public function testROMAN($expectedResult, ...$args) + { + $result = MathTrig::ROMAN(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerROMAN() + { + return require 'data/Calculation/MathTrig/ROMAN.php'; + } + + /** + * @dataProvider providerSQRTPI + * + * @param mixed $expectedResult + */ + public function testSQRTPI($expectedResult, ...$args) + { + $result = MathTrig::SQRTPI(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSQRTPI() + { + return require 'data/Calculation/MathTrig/SQRTPI.php'; + } + + /** + * @dataProvider providerSUMIF + * + * @param mixed $expectedResult + */ + public function testSUMIF($expectedResult, ...$args) + { + $result = MathTrig::SUMIF(...$args); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSUMIF() + { + return require 'data/Calculation/MathTrig/SUMIF.php'; + } + + /** + * @dataProvider providerSUBTOTAL + * + * @param mixed $expectedResult + */ + public function testSUBTOTAL($expectedResult, ...$args) + { + $cell = $this->getMockBuilder(Cell::class) + ->setMethods(['getValue']) + ->disableOriginalConstructor() + ->getMock(); + $cell->method('getValue') + ->willReturn(null); + $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::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSUBTOTAL() + { + return require '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; + } + } + + /** + * @dataProvider providerHiddenSUBTOTAL + * + * @param mixed $expectedResult + */ + public function testHiddenSUBTOTAL($expectedResult, ...$args) + { + $visibilityGenerator = $this->rowVisibility(); + + $rowDimension = $this->getMockBuilder(RowDimension::class) + ->setMethods(['getVisible']) + ->disableOriginalConstructor() + ->getMock(); + $rowDimension->method('getVisible') + ->will($this->returnCallback(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']) + ->disableOriginalConstructor() + ->getMock(); + $cell->method('getValue') + ->willReturn(''); + $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); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerHiddenSUBTOTAL() + { + return require 'data/Calculation/MathTrig/SUBTOTALHIDDEN.php'; + } + + protected function cellValues(array $cellValues) + { + foreach ($cellValues as $k => $v) { + yield $k => $v; + } + } + + protected function cellIsFormula(array $cellValues) + { + foreach ($cellValues as $cellValue) { + yield $cellValue[0] === '='; + } + } + + /** + * @dataProvider providerNestedSUBTOTAL + * + * @param mixed $expectedResult + */ + public function testNestedSUBTOTAL($expectedResult, ...$args) + { + $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') + ->will($this->returnCallback(function () use ($cellValueGenerator) { + $result = $cellValueGenerator->current(); + $cellValueGenerator->next(); + + return $result; + })); + $cell->method('isFormula') + ->will($this->returnCallback(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::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerNestedSUBTOTAL() + { + return require 'data/Calculation/MathTrig/SUBTOTALNESTED.php'; + } + + /** + * @dataProvider providerSEC + * + * @param mixed $expectedResult + * @param mixed $angle + */ + public function testSEC($expectedResult, $angle) + { + $result = MathTrig::SEC($angle); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSEC() + { + return require 'data/Calculation/MathTrig/SEC.php'; + } + + /** + * @dataProvider providerSECH + * + * @param mixed $expectedResult + * @param mixed $angle + */ + public function testSECH($expectedResult, $angle) + { + $result = MathTrig::SECH($angle); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerSECH() + { + return require 'data/Calculation/MathTrig/SECH.php'; + } + + /** + * @dataProvider providerCSC + * + * @param mixed $expectedResult + * @param mixed $angle + */ + public function testCSC($expectedResult, $angle) + { + $result = MathTrig::CSC($angle); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerCSC() + { + return require 'data/Calculation/MathTrig/CSC.php'; + } + + /** + * @dataProvider providerCSCH + * + * @param mixed $expectedResult + * @param mixed $angle + */ + public function testCSCH($expectedResult, $angle) + { + $result = MathTrig::CSCH($angle); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerCSCH() + { + return require 'data/Calculation/MathTrig/CSCH.php'; + } + + /** + * @dataProvider providerCOT + * + * @param mixed $expectedResult + * @param mixed $angle + */ + public function testCOT($expectedResult, $angle) + { + $result = MathTrig::COT($angle); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerCOT() + { + return require 'data/Calculation/MathTrig/COT.php'; + } + + /** + * @dataProvider providerCOTH + * + * @param mixed $expectedResult + * @param mixed $angle + */ + public function testCOTH($expectedResult, $angle) + { + $result = MathTrig::COTH($angle); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerCOTH() + { + return require 'data/Calculation/MathTrig/COTH.php'; + } + + /** + * @dataProvider providerACOT + * + * @param mixed $expectedResult + * @param mixed $number + */ + public function testACOT($expectedResult, $number) + { + $result = MathTrig::ACOT($number); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerACOT() + { + return require 'data/Calculation/MathTrig/ACOT.php'; + } + + /** + * @dataProvider providerACOTH + * + * @param mixed $expectedResult + * @param mixed $number + */ + public function testACOTH($expectedResult, $number) + { + $result = MathTrig::ACOTH($number); + self::assertEquals($expectedResult, $result, null, 1E-12); + } + + public function providerACOTH() + { + return require 'data/Calculation/MathTrig/ACOTH.php'; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/TextDataTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/TextDataTest.php new file mode 100644 index 0000000..ffe5c68 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Calculation/TextDataTest.php @@ -0,0 +1,431 @@ +getMockBuilder(Worksheet::class) + ->setMethods(['getStyle', 'getNumberFormat', 'setFormatCode', 'getCellCollection']) + ->getMock(); + $cellCollection = $this->getMockBuilder(Cells::class) + ->disableOriginalConstructor() + ->getMock(); + $cellCollection->expects($this->any()) + ->method('getParent') + ->will($this->returnValue($sheet)); + + $sheet->expects($this->once()) + ->method('getStyle') + ->will($this->returnSelf()); + $sheet->expects($this->once()) + ->method('getNumberFormat') + ->will($this->returnSelf()); + $sheet->expects($this->once()) + ->method('setFormatCode') + ->with($format) + ->will($this->returnSelf()); + $sheet->expects($this->any()) + ->method('getCellCollection') + ->will($this->returnValue($cellCollection)); + + StringHelper::setCurrencyCode($currencyCode); + StringHelper::setDecimalSeparator($decimalSeparator); + StringHelper::setThousandsSeparator($thousandsSeparator); + + $cell = new Cell(null, DataType::TYPE_STRING, $sheet); + + $binder = new AdvancedValueBinder(); + $binder->bindValue($cell, $value); + self::assertEquals($valueBinded, $cell->getValue()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php new file mode 100644 index 0000000..5136226 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/CoordinateTest.php @@ -0,0 +1,367 @@ +getMessage(), 'Column string index can not be longer than 3 characters'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testColumnIndexFromStringTooShort() + { + $cellAddress = ''; + + try { + Coordinate::columnIndexFromString($cellAddress); + } catch (\Exception $e) { + self::assertInstanceOf(Exception::class, $e); + self::assertEquals($e->getMessage(), 'Column string index can not be empty'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerColumnIndex + * + * @param mixed $expectedResult + * @param int $columnIndex + */ + public function testStringFromColumnIndex($expectedResult, $columnIndex) + { + $string = Coordinate::stringFromColumnIndex($columnIndex); + self::assertEquals($expectedResult, $string); + + $columnIndexBack = Coordinate::columnIndexFromString($string); + self::assertEquals($columnIndexBack, $columnIndex, 'should be able to get the original input with opposite method'); + } + + public function providerColumnIndex() + { + return require 'data/ColumnIndex.php'; + } + + /** + * @dataProvider providerCoordinates + * + * @param mixed $expectedResult + */ + public function testCoordinateFromString($expectedResult, ...$args) + { + $result = Coordinate::coordinateFromString(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerCoordinates() + { + return require 'data/CellCoordinates.php'; + } + + public function testCoordinateFromStringWithRangeAddress() + { + $cellAddress = 'A1:AI2012'; + + try { + Coordinate::coordinateFromString($cellAddress); + } catch (\Exception $e) { + self::assertInstanceOf(Exception::class, $e); + self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testCoordinateFromStringWithEmptyAddress() + { + $cellAddress = ''; + + try { + Coordinate::coordinateFromString($cellAddress); + } catch (\Exception $e) { + self::assertInstanceOf(Exception::class, $e); + self::assertEquals($e->getMessage(), 'Cell coordinate can not be zero-length string'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testCoordinateFromStringWithInvalidAddress() + { + $cellAddress = 'AI'; + + try { + Coordinate::coordinateFromString($cellAddress); + } catch (\Exception $e) { + self::assertInstanceOf(Exception::class, $e); + self::assertEquals($e->getMessage(), 'Invalid cell coordinate ' . $cellAddress); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerAbsoluteCoordinates + * + * @param mixed $expectedResult + */ + public function testAbsoluteCoordinateFromString($expectedResult, ...$args) + { + $result = Coordinate::absoluteCoordinate(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerAbsoluteCoordinates() + { + return require 'data/CellAbsoluteCoordinate.php'; + } + + public function testAbsoluteCoordinateFromStringWithRangeAddress() + { + $cellAddress = 'A1:AI2012'; + + try { + Coordinate::absoluteCoordinate($cellAddress); + } catch (\Exception $e) { + self::assertInstanceOf(Exception::class, $e); + self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerAbsoluteReferences + * + * @param mixed $expectedResult + */ + public function testAbsoluteReferenceFromString($expectedResult, ...$args) + { + $result = Coordinate::absoluteReference(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerAbsoluteReferences() + { + return require 'data/CellAbsoluteReference.php'; + } + + public function testAbsoluteReferenceFromStringWithRangeAddress() + { + $cellAddress = 'A1:AI2012'; + + try { + Coordinate::absoluteReference($cellAddress); + } catch (\Exception $e) { + self::assertInstanceOf(Exception::class, $e); + self::assertEquals($e->getMessage(), 'Cell coordinate string can not be a range of cells'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + /** + * @dataProvider providerSplitRange + * + * @param mixed $expectedResult + */ + public function testSplitRange($expectedResult, ...$args) + { + $result = Coordinate::splitRange(...$args); + foreach ($result as $key => $split) { + if (!is_array($expectedResult[$key])) { + self::assertEquals($expectedResult[$key], $split[0]); + } else { + self::assertEquals($expectedResult[$key], $split); + } + } + } + + public function providerSplitRange() + { + return require 'data/CellSplitRange.php'; + } + + /** + * @dataProvider providerBuildRange + * + * @param mixed $expectedResult + */ + public function testBuildRange($expectedResult, ...$args) + { + $result = Coordinate::buildRange(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerBuildRange() + { + return require 'data/CellBuildRange.php'; + } + + public function testBuildRangeInvalid() + { + $this->expectException(\TypeError::class); + + if (PHP_MAJOR_VERSION < 7) { + $this->markTestSkipped('Cannot catch type hinting error with PHP 5.6'); + } + + $cellRange = ''; + Coordinate::buildRange($cellRange); + } + + /** + * @dataProvider providerRangeBoundaries + * + * @param mixed $expectedResult + */ + public function testRangeBoundaries($expectedResult, ...$args) + { + $result = Coordinate::rangeBoundaries(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerRangeBoundaries() + { + return require 'data/CellRangeBoundaries.php'; + } + + /** + * @dataProvider providerRangeDimension + * + * @param mixed $expectedResult + */ + public function testRangeDimension($expectedResult, ...$args) + { + $result = Coordinate::rangeDimension(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerRangeDimension() + { + return require 'data/CellRangeDimension.php'; + } + + /** + * @dataProvider providerGetRangeBoundaries + * + * @param mixed $expectedResult + */ + public function testGetRangeBoundaries($expectedResult, ...$args) + { + $result = Coordinate::getRangeBoundaries(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerGetRangeBoundaries() + { + return require 'data/CellGetRangeBoundaries.php'; + } + + /** + * @dataProvider providerExtractAllCellReferencesInRange + * + * @param mixed $expectedResult + */ + public function testExtractAllCellReferencesInRange($expectedResult, ...$args) + { + $result = Coordinate::extractAllCellReferencesInRange(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerExtractAllCellReferencesInRange() + { + return require 'data/CellExtractAllCellReferencesInRange.php'; + } + + /** + * @dataProvider providerInvalidRange + * + * @param string $range + */ + public function testExtractAllCellReferencesInRangeInvalidRange($range) + { + $this->expectException(Exception::class); + $this->expectExceptionMessage('Invalid range: "' . $range . '"'); + + Coordinate::extractAllCellReferencesInRange($range); + } + + public function providerInvalidRange() + { + return [['Z1:A1'], ['A4:A1'], ['B1:A1'], ['AA1:Z1']]; + } + + /** + * @dataProvider providerMergeRangesInCollection + * + * @param mixed $expectedResult + */ + public function testMergeRangesInCollection($expectedResult, ...$args) + { + $result = Coordinate::mergeRangesInCollection(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerMergeRangesInCollection() + { + return require 'data/CellMergeRangesInCollection.php'; + } + + /** + * @dataProvider providerCoordinateIsRange + * + * @param mixed $expectedResult + */ + public function testCoordinateIsRange($expectedResult, ...$args) + { + $result = Coordinate::coordinateIsRange(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerCoordinateIsRange() + { + return require 'data/CoordinateIsRange.php'; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php new file mode 100644 index 0000000..c450e6e --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataTypeTest.php @@ -0,0 +1,17 @@ +getHashCode()); + $dataValidation->setType(DataValidation::TYPE_CUSTOM); + + self::assertSame('778f6c9e0ffcd5eaa7d8e1432d67f919', $dataValidation->getHashCode()); + self::assertSame('778f6c9e0ffcd5eaa7d8e1432d67f919', $dataValidation->getHashCode(), 'getHashCode() should not have side effect'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataValidatorTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataValidatorTest.php new file mode 100644 index 0000000..9d4db69 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DataValidatorTest.php @@ -0,0 +1,73 @@ +getActiveSheet(); + $testCell = $sheet->getCell('A1'); + + self::assertTrue($testCell->hasValidValue(), 'a cell without any validation data is always valid'); + } + + public function testUnsupportedType() + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $testCell = $sheet->getCell('A1'); + + $validation = $testCell->getDataValidation(); + $validation->setType(DataValidation::TYPE_CUSTOM); + $validation->setAllowBlank(true); + + self::assertFalse($testCell->hasValidValue(), 'cannot assert that value is valid when the validation type is not supported'); + } + + public function testList() + { + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $testCell = $sheet->getCell('A1'); + + $validation = $testCell->getDataValidation(); + $validation->setType(DataValidation::TYPE_LIST); + + // blank value + $testCell->setValue(''); + $validation->setAllowBlank(true); + self::assertTrue($testCell->hasValidValue(), 'cell can be empty'); + $validation->setAllowBlank(false); + self::assertFalse($testCell->hasValidValue(), 'cell can not be empty'); + + // inline list + $validation->setFormula1('"yes,no"'); + $testCell->setValue('foo'); + self::assertFalse($testCell->hasValidValue(), "cell value ('foo') is not allowed"); + $testCell->setValue('yes'); + self::assertTrue($testCell->hasValidValue(), "cell value ('yes') has to be allowed"); + + // list from cells + $sheet->getCell('B1')->setValue(5); + $sheet->getCell('B2')->setValue(6); + $sheet->getCell('B3')->setValue(7); + $testCell = $sheet->getCell('A1'); // redefine $testCell, because it has broken coordinates after using other cells + $validation->setFormula1('B1:B3'); + $testCell->setValue('10'); + self::assertFalse($testCell->hasValidValue(), "cell value ('10') is not allowed"); + $testCell = $sheet->getCell('A1'); // redefine $testCell, because it has broken coordinates after using other cells + $testCell->setValue('5'); + self::assertTrue($testCell->hasValidValue(), "cell value ('5') has to be allowed"); + + $testCell = $sheet->getCell('A1'); // redefine $testCell, because it has broken coordinates after using other cells + $validation->setFormula1('broken : cell : coordinates'); + + self::assertFalse($testCell->hasValidValue(), 'invalid formula should not throw exceptions'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php new file mode 100644 index 0000000..356a721 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/DefaultValueBinderTest.php @@ -0,0 +1,86 @@ +cellStub = $this->getMockBuilder(Cell::class) + ->disableOriginalConstructor() + ->getMock(); + // Configure the stub. + $this->cellStub->expects($this->any()) + ->method('setValueExplicit') + ->will($this->returnValue(true)); + } + + /** + * @dataProvider binderProvider + * + * @param mixed $value + */ + public function testBindValue($value) + { + $this->createCellStub(); + $binder = new DefaultValueBinder(); + $result = $binder->bindValue($this->cellStub, $value); + self::assertTrue($result); + } + + public function binderProvider() + { + return [ + [null], + [''], + ['ABC'], + ['=SUM(A1:B2)'], + [true], + [false], + [123], + [-123.456], + ['123'], + ['-123.456'], + ['#REF!'], + [new DateTime()], + [new DateTimeImmutable()], + ]; + } + + /** + * @dataProvider providerDataTypeForValue + * + * @param mixed $expectedResult + */ + public function testDataTypeForValue($expectedResult, ...$args) + { + $result = DefaultValueBinder::dataTypeForValue(...$args); + self::assertEquals($expectedResult, $result); + } + + public function providerDataTypeForValue() + { + return require 'data/Cell/DefaultValueBinder.php'; + } + + public function testDataTypeForRichTextObject() + { + $objRichText = new RichText(); + $objRichText->createText('Hello World'); + + $expectedResult = DataType::TYPE_INLINE; + $result = DefaultValueBinder::dataTypeForValue($objRichText); + self::assertEquals($expectedResult, $result); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php new file mode 100644 index 0000000..b1337a0 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Cell/HyperlinkTest.php @@ -0,0 +1,81 @@ +getUrl(); + self::assertEquals($urlValue, $result); + } + + public function testSetUrl() + { + $initialUrlValue = 'https://www.example.com'; + $newUrlValue = 'http://github.com/PHPOffice/PhpSpreadsheet'; + + $testInstance = new Hyperlink($initialUrlValue); + $result = $testInstance->setUrl($newUrlValue); + self::assertInstanceOf(Hyperlink::class, $result); + + $result = $testInstance->getUrl(); + self::assertEquals($newUrlValue, $result); + } + + public function testGetTooltip() + { + $tooltipValue = 'PhpSpreadsheet Web Site'; + + $testInstance = new Hyperlink(null, $tooltipValue); + + $result = $testInstance->getTooltip(); + self::assertEquals($tooltipValue, $result); + } + + public function testSetTooltip() + { + $initialTooltipValue = 'PhpSpreadsheet Web Site'; + $newTooltipValue = 'PhpSpreadsheet Repository on Github'; + + $testInstance = new Hyperlink(null, $initialTooltipValue); + $result = $testInstance->setTooltip($newTooltipValue); + self::assertInstanceOf(Hyperlink::class, $result); + + $result = $testInstance->getTooltip(); + self::assertEquals($newTooltipValue, $result); + } + + public function testIsInternal() + { + $initialUrlValue = 'https://www.example.com'; + $newUrlValue = 'sheet://Worksheet1!A1'; + + $testInstance = new Hyperlink($initialUrlValue); + $result = $testInstance->isInternal(); + self::assertFalse($result); + + $testInstance->setUrl($newUrlValue); + $result = $testInstance->isInternal(); + self::assertTrue($result); + } + + public function testGetHashCode() + { + $urlValue = 'https://www.example.com'; + $tooltipValue = 'PhpSpreadsheet Web Site'; + $initialExpectedHash = '3a8d5a682dba27276dce538c39402437'; + + $testInstance = new Hyperlink($urlValue, $tooltipValue); + + $result = $testInstance->getHashCode(); + self::assertEquals($initialExpectedHash, $result); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/DataSeriesValuesTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/DataSeriesValuesTest.php new file mode 100644 index 0000000..ff79803 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/DataSeriesValuesTest.php @@ -0,0 +1,62 @@ +setDataType($dataTypeValue); + self::assertInstanceOf(DataSeriesValues::class, $result); + } + } + + public function testSetInvalidDataTypeThrowsException() + { + $testInstance = new DataSeriesValues(); + + try { + $testInstance->setDataType('BOOLEAN'); + } catch (Exception $e) { + self::assertEquals($e->getMessage(), 'Invalid datatype for chart data series values'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testGetDataType() + { + $dataTypeValue = 'String'; + + $testInstance = new DataSeriesValues(); + $testInstance->setDataType($dataTypeValue); + + $result = $testInstance->getDataType(); + self::assertEquals($dataTypeValue, $result); + } + + public function testGetLineWidth() + { + $testInstance = new DataSeriesValues(); + self::assertEquals(12700, $testInstance->getLineWidth(), 'should have default'); + + $testInstance->setLineWidth(40000); + self::assertEquals(40000, $testInstance->getLineWidth()); + + $testInstance->setLineWidth(1); + self::assertEquals(12700, $testInstance->getLineWidth(), 'should enforce minimum width'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LayoutTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LayoutTest.php new file mode 100644 index 0000000..9ae8046 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LayoutTest.php @@ -0,0 +1,30 @@ +setLayoutTarget($LayoutTargetValue); + self::assertInstanceOf(Layout::class, $result); + } + + public function testGetLayoutTarget() + { + $LayoutTargetValue = 'String'; + + $testInstance = new Layout(); + $testInstance->setLayoutTarget($LayoutTargetValue); + + $result = $testInstance->getLayoutTarget(); + self::assertEquals($LayoutTargetValue, $result); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LegendTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LegendTest.php new file mode 100644 index 0000000..e21baaf --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Chart/LegendTest.php @@ -0,0 +1,127 @@ +setPosition($positionValue); + self::assertTrue($result); + } + } + + public function testSetInvalidPositionReturnsFalse() + { + $testInstance = new Legend(); + + $result = $testInstance->setPosition('BottomLeft'); + self::assertFalse($result); + // Ensure that value is unchanged + $result = $testInstance->getPosition(); + self::assertEquals(Legend::POSITION_RIGHT, $result); + } + + public function testGetPosition() + { + $PositionValue = Legend::POSITION_BOTTOM; + + $testInstance = new Legend(); + $testInstance->setPosition($PositionValue); + + $result = $testInstance->getPosition(); + self::assertEquals($PositionValue, $result); + } + + public function testSetPositionXL() + { + $positionValues = [ + Legend::XL_LEGEND_POSITION_BOTTOM, + Legend::XL_LEGEND_POSITION_CORNER, + Legend::XL_LEGEND_POSITION_CUSTOM, + Legend::XL_LEGEND_POSITION_LEFT, + Legend::XL_LEGEND_POSITION_RIGHT, + Legend::XL_LEGEND_POSITION_TOP, + ]; + + $testInstance = new Legend(); + + foreach ($positionValues as $positionValue) { + $result = $testInstance->setPositionXL($positionValue); + self::assertTrue($result); + } + } + + public function testSetInvalidXLPositionReturnsFalse() + { + $testInstance = new Legend(); + + $result = $testInstance->setPositionXL(999); + self::assertFalse($result); + // Ensure that value is unchanged + $result = $testInstance->getPositionXL(); + self::assertEquals(Legend::XL_LEGEND_POSITION_RIGHT, $result); + } + + public function testGetPositionXL() + { + $PositionValue = Legend::XL_LEGEND_POSITION_CORNER; + + $testInstance = new Legend(); + $testInstance->setPositionXL($PositionValue); + + $result = $testInstance->getPositionXL(); + self::assertEquals($PositionValue, $result); + } + + public function testSetOverlay() + { + $overlayValues = [ + true, + false, + ]; + + $testInstance = new Legend(); + + foreach ($overlayValues as $overlayValue) { + $result = $testInstance->setOverlay($overlayValue); + self::assertTrue($result); + } + } + + public function testSetInvalidOverlayReturnsFalse() + { + $testInstance = new Legend(); + + $result = $testInstance->setOverlay('INVALID'); + self::assertFalse($result); + + $result = $testInstance->getOverlay(); + self::assertFalse($result); + } + + public function testGetOverlay() + { + $OverlayValue = true; + + $testInstance = new Legend(); + $testInstance->setOverlay($OverlayValue); + + $result = $testInstance->getOverlay(); + self::assertEquals($OverlayValue, $result); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Collection/CellsTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Collection/CellsTest.php new file mode 100644 index 0000000..be14aa5 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Collection/CellsTest.php @@ -0,0 +1,117 @@ +getActiveSheet(); + $collection = $sheet->getCellCollection(); + + // Assert empty state + self::assertEquals([], $collection->getCoordinates(), 'cell list should be empty'); + self::assertEquals([], $collection->getSortedCoordinates(), 'sorted cell list should be empty'); + self::assertNull($collection->get('B2'), 'getting non-existing cell must return null'); + self::assertFalse($collection->has('B2'), 'non-existing cell should be non-existent'); + + // Add one cell + $cell1 = $sheet->getCell('B2'); + self::assertSame($cell1, $collection->add('B2', $cell1), 'adding a cell should return the cell'); + + // Assert cell presence + self::assertEquals(['B2'], $collection->getCoordinates(), 'cell list should contains the cell'); + self::assertEquals(['B2'], $collection->getSortedCoordinates(), 'sorted cell list contains the cell'); + self::assertSame($cell1, $collection->get('B2'), 'should get exact same object'); + self::assertTrue($collection->has('B2'), 'cell should exists'); + + // Add a second cell + $cell2 = $sheet->getCell('A1'); + self::assertSame($cell2, $collection->add('A1', $cell2), 'adding a second cell should return the cell'); + self::assertEquals(['B2', 'A1'], $collection->getCoordinates(), 'cell list should contains the cell'); + self::assertEquals(['A1', 'B2'], $collection->getSortedCoordinates(), 'sorted cell list contains the cell'); + + // Assert collection copy + $sheet2 = $spreadsheet->createSheet(); + $collection2 = $collection->cloneCellCollection($sheet2); + self::assertTrue($collection2->has('A1')); + $copiedCell2 = $collection2->get('A1'); + self::assertNotSame($cell2, $copiedCell2, 'copied cell should not be the same object any more'); + self::assertSame($collection2, $copiedCell2->getParent(), 'copied cell should be owned by the copied collection'); + self::assertSame('A1', $copiedCell2->getCoordinate(), 'copied cell should keep attributes'); + + // Assert deletion + $collection->delete('B2'); + self::assertFalse($collection->has('B2'), 'cell should have been deleted'); + self::assertEquals(['A1'], $collection->getCoordinates(), 'cell list should contains the cell'); + + // Assert update + $cell2 = $sheet->getCell('A1'); + self::assertSame($sheet->getCellCollection(), $collection); + self::assertSame($cell2, $collection->update($cell2), 'should update existing cell'); + + $cell3 = $sheet->getCell('C3'); + self::assertSame($cell3, $collection->update($cell3), 'should silently add non-existing cell'); + self::assertEquals(['A1', 'C3'], $collection->getCoordinates(), 'cell list should contains the cell'); + } + + public function testCacheLastCell() + { + $workbook = new Spreadsheet(); + $cells = ['A1', 'A2']; + $sheet = $workbook->getActiveSheet(); + $sheet->setCellValue('A1', 1); + $sheet->setCellValue('A2', 2); + self::assertEquals($cells, $sheet->getCoordinates(), 'list should include last added cell'); + } + + public function testCanGetCellAfterAnotherIsDeleted() + { + $workbook = new Spreadsheet(); + $sheet = $workbook->getActiveSheet(); + $collection = $sheet->getCellCollection(); + $sheet->setCellValue('A1', 1); + $sheet->setCellValue('A2', 1); + $collection->delete('A1'); + $sheet->setCellValue('A3', 1); + self::assertNotNull($collection->get('A2'), 'should be able to get back the cell even when another cell was deleted while this one was the current one'); + } + + public function testThrowsWhenCellCannotBeRetrievedFromCache() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $collection = $this->getMockBuilder(Cells::class) + ->setConstructorArgs([new Worksheet(), new Memory()]) + ->setMethods(['has']) + ->getMock(); + + $collection->method('has') + ->willReturn(true); + + $collection->get('A2'); + } + + public function testThrowsWhenCellCannotBeStoredInCache() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $cache = $this->createMock(Memory::class); + $cell = $this->createMock(Cell::class); + $cache->method('set') + ->willReturn(false); + + $collection = new Cells(new Worksheet(), $cache); + + $collection->add('A1', $cell); + $collection->add('A2', $cell); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php new file mode 100644 index 0000000..762b288 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Custom/ComplexAssert.php @@ -0,0 +1,82 @@ +errorMessage = 'Expected Error: ' . $actual . ' !== ' . $expected; + + return false; + } + + private function adjustDelta($expected, $actual, $delta) + { + $adjustedDelta = $delta; + + if (abs($actual) > 10 && abs($expected) > 10) { + $variance = floor(log10(abs($expected))); + $adjustedDelta *= pow(10, $variance); + } + + return $adjustedDelta > 1.0 ? 1.0 : $adjustedDelta; + } + + public function assertComplexEquals($expected, $actual, $delta = 0) + { + if ($expected === INF || $expected[0] === '#') { + return $this->testExpectedExceptions($expected, $actual); + } + + $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(); + + return false; + } + + $adjustedDelta = $this->adjustDelta($expectedComplex->getImaginary(), $actualComplex->getImaginary(), $delta); + if (abs($actualComplex->getImaginary() - $expectedComplex->getImaginary()) > $adjustedDelta) { + $this->errorMessage = 'Mismatched Imaginary part: ' . $actualComplex->getImaginary() . ' != ' . $expectedComplex->getImaginary(); + + return false; + } + + if ($actualComplex->getSuffix() !== $actualComplex->getSuffix()) { + $this->errorMessage = 'Mismatched Suffix: ' . $actualComplex->getSuffix() . ' != ' . $expectedComplex->getSuffix(); + + return false; + } + + return true; + } + + public function getErrorMessage() + { + return $this->errorMessage; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/AbstractFunctional.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/AbstractFunctional.php new file mode 100644 index 0000000..da9f76e --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/AbstractFunctional.php @@ -0,0 +1,39 @@ +save($filename); + + $reader = IOFactory::createReader($format); + if ($readerCustomizer) { + $readerCustomizer($reader); + } + $reloadedSpreadsheet = $reader->load($filename); + unlink($filename); + + return $reloadedSpreadsheet; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php new file mode 100644 index 0000000..6d4fc2c --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ColumnWidthTest.php @@ -0,0 +1,43 @@ +getActiveSheet(); + $sheet->setCellValue('A1', 'Hello World !'); + $sheet->getColumnDimension('A')->setWidth(20); + $this->assertColumn($spreadsheet); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + $this->assertColumn($reloadedSpreadsheet); + } + + private function assertColumn(Spreadsheet $spreadsheet) + { + $sheet = $spreadsheet->getActiveSheet(); + $columnDimensions = $sheet->getColumnDimensions(); + + self::assertArrayHasKey('A', $columnDimensions); + $column = array_shift($columnDimensions); + self::assertEquals(20, $column->getWidth()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/CommentsTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/CommentsTest.php new file mode 100644 index 0000000..a394c96 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/CommentsTest.php @@ -0,0 +1,44 @@ +getActiveSheet()->getCell('E10')->setValue('Comment'); + $spreadsheet->getActiveSheet() + ->getComment('E10') + ->getText() + ->createText('Comment to test'); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + + $commentsLoaded = $reloadedSpreadsheet->getSheet(0)->getComments(); + self::assertCount(1, $commentsLoaded); + + $commentCoordinate = key($commentsLoaded); + self::assertSame('E10', $commentCoordinate); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php new file mode 100644 index 0000000..3aa3f94 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ConditionalStopIfTrueTest.php @@ -0,0 +1,72 @@ + no styling + $condition0 = new \PhpOffice\PhpSpreadsheet\Style\Conditional(); + $condition0->setConditionType(\PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_EXPRESSION); + $condition0->addCondition('LEN(TRIM(A1))=0'); + $condition0->setStopIfTrue(true); // ! stop here + + // if value below 0.6 (matches also blank cells!) -> red background + $condition1 = new \PhpOffice\PhpSpreadsheet\Style\Conditional(); + $condition1->setConditionType(\PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_CELLIS); + $condition1->setOperatorType(\PhpOffice\PhpSpreadsheet\Style\Conditional::OPERATOR_LESSTHAN); + $condition1->addCondition(0.6); + $condition1->getStyle()->getFill() + ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID) + ->getEndColor()->setARGB(self::COLOR_RED); + + // if value above 0.6 -> green background + $condition2 = new \PhpOffice\PhpSpreadsheet\Style\Conditional(); + $condition2->setConditionType(\PhpOffice\PhpSpreadsheet\Style\Conditional::CONDITION_CELLIS); + $condition2->setOperatorType(\PhpOffice\PhpSpreadsheet\Style\Conditional::OPERATOR_GREATERTHAN); + $condition2->addCondition(0.6); + $condition2->getStyle()->getFill() + ->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID) + ->getEndColor()->setARGB(self::COLOR_GREEN); + + $spreadsheet = new Spreadsheet(); + $spreadsheet->getActiveSheet()->getCell('A1')->setValue(0.7); + $spreadsheet->getActiveSheet()->getCell('A2')->setValue(''); + $spreadsheet->getActiveSheet()->getCell('A3')->setValue(0.4); + + // put all three conditions in sheet + $conditionalStyles = []; + array_push($conditionalStyles, $condition0); + array_push($conditionalStyles, $condition1); + array_push($conditionalStyles, $condition2); + $spreadsheet->getActiveSheet()->setConditionalStyles($pCoordinate, $conditionalStyles); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + + // see if we successfully written "StopIfTrue" + $newConditionalStyles = $reloadedSpreadsheet->getActiveSheet()->getConditionalStyles($pCoordinate); + self::assertTrue($newConditionalStyles[0]->getStopIfTrue(), 'StopIfTrue should be set (=true) on first condition'); + self::assertFalse($newConditionalStyles[1]->getStopIfTrue(), 'StopIfTrue should not be set (=false) on second condition'); + self::assertFalse($newConditionalStyles[2]->getStopIfTrue(), 'StopIfTrue should not be set (=false) on third condition'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php new file mode 100644 index 0000000..9933315 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/DrawingImageHyperlinkTest.php @@ -0,0 +1,42 @@ +getActiveSheet(); + + $gdImage = @imagecreatetruecolor(120, 20); + $textColor = imagecolorallocate($gdImage, 255, 255, 255); + imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor); + + $drawing = new MemoryDrawing(); + $drawing->setName('In-Memory image 1'); + $drawing->setDescription('In-Memory image 1'); + $drawing->setCoordinates('A1'); + $drawing->setImageResource($gdImage); + $drawing->setRenderingFunction( + MemoryDrawing::RENDERING_JPEG + ); + $drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT); + $drawing->setHeight(36); + $hyperLink = new Hyperlink($baseUrl, 'test image'); + $drawing->setHyperlink($hyperLink); + $drawing->setWorksheet($aSheet); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, 'Xlsx'); + + foreach ($reloadedSpreadsheet->getActiveSheet()->getDrawingCollection() as $pDrawing) { + self::assertEquals('https://github.com/PHPOffice/PhpSpreadsheet', $pDrawing->getHyperlink()->getUrl(), 'functional test drawing hyperlink'); + } + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/EnclosureTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/EnclosureTest.php new file mode 100644 index 0000000..3a5f961 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/EnclosureTest.php @@ -0,0 +1,37 @@ +'; + + $spreadsheet = new Spreadsheet(); + $spreadsheet->getActiveSheet()->getCell('A1')->setValue($value); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + + $actual = $reloadedSpreadsheet->getActiveSheet()->getCell('A1')->getCalculatedValue(); + self::assertSame($value, $actual, 'should be able to write and read strings with multiples quotes'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/FreezePaneTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/FreezePaneTest.php new file mode 100644 index 0000000..fda6723 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/FreezePaneTest.php @@ -0,0 +1,75 @@ +getActiveSheet()->freezePane($cellSplit, $topLeftCell); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + + // Read written file + $reloadedActive = $reloadedSpreadsheet->getActiveSheet(); + $actualCellSplit = $reloadedActive->getFreezePane(); + $actualTopLeftCell = $reloadedActive->getTopLeftCell(); + + self::assertSame($cellSplit, $actualCellSplit, 'should be able to set freeze pane'); + self::assertSame($topLeftCell, $actualTopLeftCell, 'should be able to set the top left cell'); + } + + public function providerFormatsInvalidSelectedCells() + { + return [ + ['Xlsx'], + ]; + } + + /** + * @dataProvider providerFormatsInvalidSelectedCells + * + * @param string $format + */ + public function testFreezePaneWithInvalidSelectedCells($format) + { + $cellSplit = 'A7'; + $topLeftCell = 'A24'; + + $spreadsheet = new Spreadsheet(); + $worksheet = $spreadsheet->getActiveSheet(); + + $worksheet->freezePane('A7', 'A24'); + $worksheet->setSelectedCells('F5'); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + + // Read written file + $reloadedActive = $reloadedSpreadsheet->getActiveSheet(); + $actualCellSplit = $reloadedActive->getFreezePane(); + $actualTopLeftCell = $reloadedActive->getTopLeftCell(); + + self::assertSame($cellSplit, $actualCellSplit, 'should be able to set freeze pane'); + self::assertSame($topLeftCell, $actualTopLeftCell, 'should be able to set the top left cell'); + self::assertSame('A24', $reloadedActive->getSelectedCells(), 'selected cell should default to be first cell after the freeze pane'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/HtmlCommentsTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/HtmlCommentsTest.php new file mode 100644 index 0000000..1b49727 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/HtmlCommentsTest.php @@ -0,0 +1,63 @@ +createText($valueSingle); + + $plainMulti = new RichText(); + $plainMulti->createText($valueMulti); + + $richSingle = new RichText(); + $richSingle->createTextRun($valueSingle)->getFont()->setBold(true); + + $richMultiSimple = new RichText(); + $richMultiSimple->createTextRun($valueMulti)->getFont()->setBold(true); + + $richMultiMixed = new RichText(); + $richMultiMixed->createText('I am' . PHP_EOL); + $richMultiMixed->createTextRun('multi-line')->getFont()->setBold(true); + $richMultiMixed->createText(PHP_EOL . 'comment!'); + + return [ + 'single line plain text' => [$plainSingle], + 'multi-line plain text' => [$plainMulti], + 'single line simple rich text' => [$richSingle], + 'multi-line simple rich text' => [$richMultiSimple], + 'multi-line mixed rich text' => [$richMultiMixed], + ]; + } + + /** + * @dataProvider providerCommentRichText + * + * @param mixed $richText + */ + public function testComments($richText) + { + $this->spreadsheet = new Spreadsheet(); + + $this->spreadsheet->getActiveSheet()->getCell('A1')->setValue('Comment'); + + $this->spreadsheet->getActiveSheet() + ->getComment('A1') + ->setText($richText); + + $reloadedSpreadsheet = $this->writeAndReload($this->spreadsheet, 'Html'); + + $actual = $reloadedSpreadsheet->getActiveSheet()->getComment('A1')->getText()->getPlainText(); + self::assertSame($richText->getPlainText(), $actual); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/MergedCellsTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/MergedCellsTest.php new file mode 100644 index 0000000..7a60194 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/MergedCellsTest.php @@ -0,0 +1,42 @@ +setActiveSheetIndex(0); + $spreadsheet->getActiveSheet()->setCellValue('A1', '1'); + $spreadsheet->getActiveSheet()->setCellValue('B1', '2'); + $spreadsheet->getActiveSheet()->setCellValue('A2', '33'); + $spreadsheet->getActiveSheet()->mergeCells('A2:B2'); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + + $actual = 0; + foreach ($reloadedSpreadsheet->getWorksheetIterator() as $worksheet) { + $actual += count($worksheet->getMergeCells()); + } + + self::assertSame(1, $actual, "Format $format failed, could not read 1 merged cell"); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/PrintAreaTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/PrintAreaTest.php new file mode 100644 index 0000000..1a6709c --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/PrintAreaTest.php @@ -0,0 +1,44 @@ +getActiveSheet()->setTitle('Sheet 1'); + $worksheet1->getPageSetup()->setPrintArea('A1:B1'); + + for ($i = 2; $i < 4; ++$i) { + $sheet = $spreadsheet->createSheet()->setTitle("Sheet $i"); + $sheet->getPageSetup()->setPrintArea("A$i:B$i"); + } + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format, function (BaseReader $reader) { + $reader->setLoadSheetsOnly(['Sheet 1', 'Sheet 3']); + }); + + $actual1 = $reloadedSpreadsheet->getSheetByName('Sheet 1')->getPageSetup()->getPrintArea(); + $actual3 = $reloadedSpreadsheet->getSheetByName('Sheet 3')->getPageSetup()->getPrintArea(); + self::assertSame('A1:B1', $actual1, 'should be able to write and read normal page setup'); + self::assertSame('A3:B3', $actual3, 'should be able to write and read page setup even when skipping sheets'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ReadFilterTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ReadFilterTest.php new file mode 100644 index 0000000..288fc57 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/ReadFilterTest.php @@ -0,0 +1,124 @@ +getActiveSheet()->fromArray($arrayData, null, 'A1'); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + $sheet = $reloadedSpreadsheet->getSheet(0); + // test highest column (very specific num of columns because of some 3rd party software) + self::assertSame('J', $sheet->getHighestColumn()); + + // test highest row (very specific num of rows because of some 3rd party software) + self::assertEquals(10, $sheet->getHighestRow()); + + // test top left coordinate + $sortedCoordinates = $sheet->getCellCollection()->getSortedCoordinates(); + $coordinateTopLeft = reset($sortedCoordinates); + self::assertSame('A1', $coordinateTopLeft); + } + + /** + * Test load Xlsx file with many empty cells (and big max row number) with readfilter. + * + * @dataProvider providerCellsValues + * + * @param array $arrayData + * @param mixed $format + */ + public function testXlsxLoadWithReadFilter($format, array $arrayData) + { + $spreadsheet = new Spreadsheet(); + $spreadsheet->getActiveSheet()->fromArray($arrayData, null, 'A1'); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format, function ($reader) { + // Create a stub for the readFilter class. + $readFilterStub = $this->createMock(IReadFilter::class); + $readFilterStub->method('readCell') + ->will($this->returnCallback([$this, 'readFilterReadCell'])); + // apply filter + $reader->setReadFilter($readFilterStub); + }); + $sheet = $reloadedSpreadsheet->getSheet(0); + // test highest column (very specific num of columns because of some 3rd party software) + self::assertSame('D', $sheet->getHighestColumn()); + + // test highest row (very specific num of rows because of some 3rd party software) + self::assertEquals(6, $sheet->getHighestRow()); + + // test top left coordinate + $sortedCoordinates = $sheet->getCellCollection()->getSortedCoordinates(); + $coordinateTopLeft = reset($sortedCoordinates); + self::assertSame('B2', $coordinateTopLeft); + } + + /** + * @see \PhpOffice\PhpSpreadsheet\Reader\IReadFilter::readCell() + * + * @param string $column Column address (as a string value like "A", or "IV") + * @param int $row Row number + * @param string $worksheetName Optional worksheet name + * + * @return bool + */ + public function readFilterReadCell($column, $row, $worksheetName = '') + { + // define filter range + $rowMin = 2; + $rowMax = 6; + $columnMin = 'B'; + $columnMax = 'D'; + + $r = (int) $row; + if ($r > $rowMax || $r < $rowMin) { + return false; + } + + $col = sprintf('%04s', $column); + if ($col > sprintf('%04s', $columnMax) || + $col < sprintf('%04s', $columnMin)) { + return false; + } + + return true; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/TypeAttributePreservationTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/TypeAttributePreservationTest.php new file mode 100644 index 0000000..53cc718 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/TypeAttributePreservationTest.php @@ -0,0 +1,51 @@ +getActiveSheet(); + $sheet->fromArray($values); + + $reloadedSpreadsheet = $this->writeAndReload($spreadsheet, $format); + $reloadedSheet = $reloadedSpreadsheet->getActiveSheet(); + + $expected = $sheet->getCell('A1')->getCalculatedValue(); + + if ($sheet->getCell('A1')->getDataType() === 'f') { + $actual = $reloadedSheet->getCell('A1')->getOldCalculatedValue(); + } else { + $actual = $reloadedSheet->getCell('A1')->getValue(); + } + + self::assertSame($expected, $actual); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/WorkbookViewAttributesTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/WorkbookViewAttributesTest.php new file mode 100644 index 0000000..cce2a95 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Functional/WorkbookViewAttributesTest.php @@ -0,0 +1,80 @@ +getActiveSheet(); + $worksheet1->setTitle('Tweedledee'); + $worksheet1->setCellValue('A1', 1); + $worksheet2 = $workbook->createSheet(); + $worksheet2->setTitle('Tweeldedum'); + $worksheet2->setCellValue('A1', 2); + + // Check that the bookview attributes return default values + $this->assertTrue($workbook->getShowHorizontalScroll()); + $this->assertTrue($workbook->getShowVerticalScroll()); + $this->assertTrue($workbook->getShowSheetTabs()); + $this->assertTrue($workbook->getAutoFilterDateGrouping()); + $this->assertFalse($workbook->getMinimized()); + $this->assertSame(0, $workbook->getFirstSheetIndex()); + $this->assertSame(600, $workbook->getTabRatio()); + $this->assertSame(Spreadsheet::VISIBILITY_VISIBLE, $workbook->getVisibility()); + + // Set the bookview attributes to non-default values + $workbook->setShowHorizontalScroll(false); + $workbook->setShowVerticalScroll(false); + $workbook->setShowSheetTabs(false); + $workbook->setAutoFilterDateGrouping(false); + $workbook->setMinimized(true); + $workbook->setFirstSheetIndex(1); + $workbook->setTabRatio(700); + $workbook->setVisibility(Spreadsheet::VISIBILITY_HIDDEN); + + // Check that bookview attributes were set properly + $this->assertFalse($workbook->getShowHorizontalScroll()); + $this->assertFalse($workbook->getShowVerticalScroll()); + $this->assertFalse($workbook->getShowSheetTabs()); + $this->assertFalse($workbook->getAutoFilterDateGrouping()); + $this->assertTrue($workbook->getMinimized()); + $this->assertSame(1, $workbook->getFirstSheetIndex()); + $this->assertSame(700, $workbook->getTabRatio()); + $this->assertSame(Spreadsheet::VISIBILITY_HIDDEN, $workbook->getVisibility()); + + $workbook2 = $this->writeAndReload($workbook, $format); + + // Check that the read spreadsheet has the right bookview attributes + $this->assertFalse($workbook2->getShowHorizontalScroll()); + $this->assertFalse($workbook2->getShowVerticalScroll()); + $this->assertFalse($workbook2->getShowSheetTabs()); + $this->assertFalse($workbook2->getAutoFilterDateGrouping()); + $this->assertTrue($workbook2->getMinimized()); + $this->assertSame(1, $workbook2->getFirstSheetIndex()); + $this->assertSame(700, $workbook2->getTabRatio()); + $this->assertSame(Spreadsheet::VISIBILITY_HIDDEN, $workbook2->getVisibility()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/HtmlTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/HtmlTest.php new file mode 100644 index 0000000..b15a728 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/HtmlTest.php @@ -0,0 +1,33 @@ +toRichTextObject($input); + + self::assertSame($expected, $actual->getPlainText()); + } + + public function providerUtf8EncodingSupport() + { + return [ + ['foo', 'foo'], + ['können', 'können'], + ['русский', 'русский'], + ["foo\nbar", '

foo

bar

'], + ]; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/MigratorTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/MigratorTest.php new file mode 100644 index 0000000..a64cda8 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/MigratorTest.php @@ -0,0 +1,88 @@ +getMapping() as $classname) { + if (substr_count($classname, '\\')) { + self::assertTrue(class_exists($classname) || interface_exists($classname), 'mapping is wrong, class does not exists in project: ' . $classname); + } + } + } + + public function testReplace() + { + $input = <<<'STRING' +do(); + $fooobjPHPExcel->do(); + $objPHPExcel->do(); + $this->objPHPExcel->do(); + $this->PHPExcel->do(); + + return \PHPExcel_Cell::stringFromColumnIndex(9); + } +} +STRING; + + $expected = <<<'STRING' +do(); + $fooobjPHPExcel->do(); + $objPHPExcel->do(); + $this->objPHPExcel->do(); + $this->PHPExcel->do(); + + return \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex(9); + } +} +STRING; + + $migrator = new Migrator(); + self::assertSame($expected, $migrator->replace($input)); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/SampleTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/SampleTest.php new file mode 100644 index 0000000..be1f50c --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Helper/SampleTest.php @@ -0,0 +1,62 @@ +setOutputCallback(function () { + }); + + require $sample; + } + + public function providerSample() + { + $skipped = [ + 'Chart/32_Chart_read_write_PDF.php', // Unfortunately JpGraph is not up to date for latest PHP and raise many warnings + 'Chart/32_Chart_read_write_HTML.php', // idem + ]; + + // TCPDF does not support PHP 7.2 + if (version_compare(PHP_VERSION, '7.2.0') >= 0) { + $skipped[] = 'Pdf/21_Pdf_TCPDF.php'; + } + + // Unfortunately some tests are too long be ran with code-coverage + // analysis on Travis, so we need to exclude them + global $argv; + if (in_array('--coverage-clover', $argv)) { + $tooLongToBeCovered = [ + 'Basic/06_Largescale.php', + 'Basic/13_CalculationCyclicFormulae.php', + ]; + $skipped = array_merge($skipped, $tooLongToBeCovered); + } + + $helper = new Sample(); + $result = []; + foreach ($helper->getSamples() as $samples) { + foreach ($samples as $sample) { + if (!in_array($sample, $skipped)) { + $file = '../samples/' . $sample; + $result[] = [$file]; + } + } + } + + return $result; + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/IOFactoryTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/IOFactoryTest.php new file mode 100644 index 0000000..4c9c52d --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/IOFactoryTest.php @@ -0,0 +1,147 @@ +expectException(\InvalidArgumentException::class); + + IOFactory::identify('/non/existing/file'); + } + + public function testIdentifyExistingDirectoryThrowExceptions() + { + $this->expectException(\InvalidArgumentException::class); + + IOFactory::identify('.'); + } + + public function testRegisterInvalidWriter() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Writer\Exception::class); + + IOFactory::registerWriter('foo', 'bar'); + } + + public function testRegisterInvalidReader() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Reader\Exception::class); + + IOFactory::registerReader('foo', 'bar'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/CsvTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/CsvTest.php new file mode 100644 index 0000000..eeddbb0 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/CsvTest.php @@ -0,0 +1,109 @@ +getDelimiter()); + + $spreadsheet = $reader->load($filename); + + self::assertSame($expectedDelimiter, $reader->getDelimiter(), 'should be able to infer the delimiter'); + + $actual = $spreadsheet->getActiveSheet()->getCell($cell)->getValue(); + self::assertSame($expectedValue, $actual, 'should be able to retrieve correct value'); + } + + public function providerDelimiterDetection() + { + return [ + [ + __DIR__ . '/../../data/Reader/CSV/enclosure.csv', + ',', + 'C4', + 'username2', + ], + [ + __DIR__ . '/../../data/Reader/CSV/semicolon_separated.csv', + ';', + 'C2', + '25,5', + ], + [ + __DIR__ . '/../../data/Reader/HTML/csv_with_angle_bracket.csv', + ',', + 'B1', + 'Number of items with weight <= 50kg', + ], + [ + __DIR__ . '/../../../samples/Reader/sampleData/example1.csv', + ',', + 'I4', + '100%', + ], + [ + __DIR__ . '/../../../samples/Reader/sampleData/example2.csv', + ',', + 'D8', + -58.373161, + ], + ]; + } + + /** + * @dataProvider providerCanLoad + * + * @param bool $expected + * @param string $filename + */ + public function testCanLoad($expected, $filename) + { + $reader = new Csv(); + self::assertSame($expected, $reader->canRead($filename)); + } + + public function providerCanLoad() + { + return [ + [false, 'data/Reader/Ods/data.ods'], + [false, 'data/Reader/Xml/WithoutStyle.xml'], + [true, 'data/Reader/CSV/enclosure.csv'], + [true, 'data/Reader/CSV/semicolon_separated.csv'], + [true, 'data/Reader/CSV/contains_html.csv'], + [true, 'data/Reader/CSV/csv_without_extension'], + [true, 'data/Reader/HTML/csv_with_angle_bracket.csv'], + [true, 'data/Reader/CSV/empty.csv'], + [true, '../samples/Reader/sampleData/example1.csv'], + [true, '../samples/Reader/sampleData/example2.csv'], + ]; + } + + public function testEscapeCharacters() + { + $reader = (new Csv())->setEscapeCharacter('"'); + $worksheet = $reader->load(__DIR__ . '/../../data/Reader/CSV/backslash.csv') + ->getActiveSheet(); + + $expected = [ + ['field 1', 'field 2\\'], + ['field 3\\', 'field 4'], + ]; + + $this->assertSame('"', $reader->getEscapeCharacter()); + $this->assertSame($expected, $worksheet->toArray()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/HtmlTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/HtmlTest.php new file mode 100644 index 0000000..9f9b11e --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/HtmlTest.php @@ -0,0 +1,46 @@ +canRead($filename)); + } + + public function providerCanReadVerySmallFile() + { + $padding = str_repeat('a', 2048); + + return [ + [true, ' ' . $padding . ' '], + [true, ' ' . $padding . ''], + [true, ''], + [false, ''], + ]; + } + + /** + * @dataProvider providerCanReadVerySmallFile + * + * @param bool $expected + * @param string $content + */ + public function testCanReadVerySmallFile($expected, $content) + { + $filename = tempnam(sys_get_temp_dir(), 'html'); + file_put_contents($filename, $content); + + $reader = new Html(); + $actual = $reader->canRead($filename); + unlink($filename); + + self::assertSame($expected, $actual); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/OdsTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/OdsTest.php new file mode 100644 index 0000000..a6edaee --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/OdsTest.php @@ -0,0 +1,225 @@ +spreadsheetOdsTest) { + $filename = __DIR__ . '/../../../samples/templates/OOCalcTest.ods'; + + // Load into this instance + $reader = new Ods(); + $this->spreadsheetOdsTest = $reader->loadIntoExisting($filename, new Spreadsheet()); + } + + return $this->spreadsheetOdsTest; + } + + /** + * @return Spreadsheet + */ + protected function loadDataFile() + { + if (!$this->spreadsheetData) { + $filename = __DIR__ . '/../../data/Reader/Ods/data.ods'; + + // Load into this instance + $reader = new Ods(); + $this->spreadsheetData = $reader->loadIntoExisting($filename, new Spreadsheet()); + } + + return $this->spreadsheetData; + } + + public function testReadFileProperties() + { + $filename = __DIR__ . '/../../data/Reader/Ods/data.ods'; + + // Load into this instance + $reader = new Ods(); + + // Test "listWorksheetNames" method + + self::assertEquals([ + 'Sheet1', + 'Second Sheet', + ], $reader->listWorksheetNames($filename)); + } + + public function testLoadWorksheets() + { + $spreadsheet = $this->loadDataFile(); + + self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Spreadsheet', $spreadsheet); + + self::assertEquals(2, $spreadsheet->getSheetCount()); + + $firstSheet = $spreadsheet->getSheet(0); + self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Worksheet\Worksheet', $firstSheet); + + $secondSheet = $spreadsheet->getSheet(1); + self::assertInstanceOf('PhpOffice\PhpSpreadsheet\Worksheet\Worksheet', $secondSheet); + } + + public function testReadValueAndComments() + { + $spreadsheet = $this->loadOdsTestFile(); + + $firstSheet = $spreadsheet->getSheet(0); + + self::assertEquals(29, $firstSheet->getHighestRow()); + self::assertEquals('N', $firstSheet->getHighestColumn()); + + // Simple cell value + self::assertEquals('Test String 1', $firstSheet->getCell('A1')->getValue()); + + // Merged cell + self::assertEquals('BOX', $firstSheet->getCell('B18')->getValue()); + + // Comments/Annotations + self::assertEquals( + 'Test for a simple colour-formatted string', + $firstSheet->getComment('A1')->getText()->getPlainText() + ); + + // Data types + self::assertEquals(DataType::TYPE_STRING, $firstSheet->getCell('A1')->getDataType()); + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('B1')->getDataType()); // Int + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('B6')->getDataType()); // Float + self::assertEquals(1.23, $firstSheet->getCell('B6')->getValue()); + self::assertEquals(0, $firstSheet->getCell('G10')->getValue()); + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A10')->getDataType()); // Date + self::assertEquals(22269.0, $firstSheet->getCell('A10')->getValue()); + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A13')->getDataType()); // Time + self::assertEquals(25569.0625, $firstSheet->getCell('A13')->getValue()); + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A15')->getDataType()); // Date + Time + self::assertEquals(22269.0625, $firstSheet->getCell('A15')->getValue()); + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A11')->getDataType()); // Fraction + + self::assertEquals(DataType::TYPE_BOOL, $firstSheet->getCell('D6')->getDataType()); + self::assertTrue($firstSheet->getCell('D6')->getValue()); + + self::assertEquals(DataType::TYPE_FORMULA, $firstSheet->getCell('C6')->getDataType()); // Formula + self::assertEquals('=TRUE()', $firstSheet->getCell('C6')->getValue()); // Formula + + // Percentage, Currency + + $spreadsheet = $this->loadDataFile(); + + $firstSheet = $spreadsheet->getSheet(0); + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A1')->getDataType()); // Percentage (10%) + self::assertEquals(0.1, $firstSheet->getCell('A1')->getValue()); + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A2')->getDataType()); // Percentage (10.00%) + self::assertEquals(0.1, $firstSheet->getCell('A2')->getValue()); + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A4')->getDataType()); // Currency (€10.00) + self::assertEquals(10, $firstSheet->getCell('A4')->getValue()); + + self::assertEquals(DataType::TYPE_NUMERIC, $firstSheet->getCell('A5')->getDataType()); // Currency ($20) + self::assertEquals(20, $firstSheet->getCell('A5')->getValue()); + } + + public function testReadColors() + { + $spreadsheet = $this->loadOdsTestFile(); + $firstSheet = $spreadsheet->getSheet(0); + + // Background color + + $style = $firstSheet->getCell('K3')->getStyle(); + + self::assertEquals('none', $style->getFill()->getFillType()); + self::assertEquals('FFFFFFFF', $style->getFill()->getStartColor()->getARGB()); + self::assertEquals('FF000000', $style->getFill()->getEndColor()->getARGB()); + } + + public function testReadRichText() + { + $spreadsheet = $this->loadOdsTestFile(); + $firstSheet = $spreadsheet->getSheet(0); + + self::assertEquals( + "I don't know if OOCalc supports Rich Text in the same way as Excel, " . + 'And this row should be autofit height with text wrap', + $firstSheet->getCell('A28')->getValue() + ); + } + + public function testReadCellsWithRepeatedSpaces() + { + $spreadsheet = $this->loadDataFile(); + $firstSheet = $spreadsheet->getSheet(0); + + self::assertEquals('This has 4 spaces before and 2 after ', $firstSheet->getCell('A8')->getValue()); + self::assertEquals('This only one after ', $firstSheet->getCell('A9')->getValue()); + self::assertEquals('Test with DIFFERENT styles and multiple spaces: ', $firstSheet->getCell('A10')->getValue()); + self::assertEquals("test with new \nLines", $firstSheet->getCell('A11')->getValue()); + } + + public function testReadHyperlinks() + { + $spreadsheet = $this->loadOdsTestFile(); + $firstSheet = $spreadsheet->getSheet(0); + + $hyperlink = $firstSheet->getCell('A29'); + + self::assertEquals(DataType::TYPE_STRING, $hyperlink->getDataType()); + self::assertEquals('PhpSpreadsheet', $hyperlink->getValue()); + self::assertEquals('https://github.com/PHPOffice/phpspreadsheet', $hyperlink->getHyperlink()->getUrl()); + } + + // Below some test for features not implemented yet + + public function testReadBoldItalicUnderline() + { + $this->markTestIncomplete('Features not implemented yet'); + + $spreadsheet = $this->loadOdsTestFile(); + $firstSheet = $spreadsheet->getSheet(0); + + // Font styles + + $style = $firstSheet->getCell('A1')->getStyle(); + self::assertEquals('FF000000', $style->getFont()->getColor()->getARGB()); + self::assertEquals(11, $style->getFont()->getSize()); + self::assertEquals(Font::UNDERLINE_NONE, $style->getFont()->getUnderline()); + + $style = $firstSheet->getCell('E3')->getStyle(); + self::assertEquals(Font::UNDERLINE_SINGLE, $style->getFont()->getUnderline()); + + $style = $firstSheet->getCell('E1')->getStyle(); + self::assertTrue($style->getFont()->getBold()); + self::assertTrue($style->getFont()->getItalic()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/XlsxTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/XlsxTest.php new file mode 100644 index 0000000..fd14714 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/XlsxTest.php @@ -0,0 +1,19 @@ +load($filename); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/XmlTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/XmlTest.php new file mode 100644 index 0000000..763e177 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Reader/XmlTest.php @@ -0,0 +1,105 @@ +expectException(\PhpOffice\PhpSpreadsheet\Reader\Exception::class); + + $reader = $this->getMockForAbstractClass(BaseReader::class); + $expectedResult = 'FAILURE: Should throw an Exception rather than return a value'; + $result = $reader->securityScanFile($filename); + self::assertEquals($expectedResult, $result); + } + + public function providerInvalidXML() + { + $tests = []; + foreach (glob(__DIR__ . '/../../data/Reader/Xml/XEETestInvalidUTF*.xml') as $file) { + $tests[basename($file)] = [realpath($file)]; + } + + return $tests; + } + + /** + * @dataProvider providerInvalidSimpleXML + * + * @param $filename + */ + public function testInvalidSimpleXML($filename) + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Reader\Exception::class); + + $xmlReader = new Xml(); + $xmlReader->trySimpleXMLLoadString($filename); + } + + public function providerInvalidSimpleXML() + { + $tests = []; + foreach (glob(__DIR__ . '/../../data/Reader/Xml/XEETestInvalidSimpleXML*.xml') as $file) { + $tests[basename($file)] = [realpath($file)]; + } + + return $tests; + } + + /** + * @dataProvider providerValidXML + * + * @param mixed $filename + * @param mixed $expectedResult + */ + public function testValidXML($filename, $expectedResult) + { + $reader = $this->getMockForAbstractClass(BaseReader::class); + $result = $reader->securityScanFile($filename); + self::assertEquals($expectedResult, $result); + } + + public function providerValidXML() + { + $tests = []; + foreach (glob(__DIR__ . '/../../data/Reader/Xml/XEETestValid*.xml') as $file) { + $tests[basename($file)] = [realpath($file), file_get_contents($file)]; + } + + return $tests; + } + + /** + * Check if it can read XML Hyperlink correctly. + */ + public function testReadHyperlinks() + { + $reader = new Xml(); + $spreadsheet = $reader->load('../samples/templates/Excel2003XMLTest.xml'); + $firstSheet = $spreadsheet->getSheet(0); + + $hyperlink = $firstSheet->getCell('L1'); + + self::assertEquals(DataType::TYPE_STRING, $hyperlink->getDataType()); + self::assertEquals('PhpSpreadsheet', $hyperlink->getValue()); + self::assertEquals('http://phpspreadsheet.readthedocs.io/', $hyperlink->getHyperlink()->getUrl()); + } + + public function testReadWithoutStyle() + { + $reader = new Xml(); + $spreadsheet = $reader->load(__DIR__ . '/../../data/Reader/Xml/WithoutStyle.xml'); + self::assertSame('Test String 1', $spreadsheet->getActiveSheet()->getCell('A1')->getValue()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/ReferenceHelperTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/ReferenceHelperTest.php new file mode 100644 index 0000000..08b290d --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/ReferenceHelperTest.php @@ -0,0 +1,56 @@ + $value) { + self::assertEquals($columnExpectedResult[$key], $value); + } + } + + public function testColumnReverseSort() + { + $columnBase = $columnExpectedResult = [ + 'A', 'B', 'Z', + 'AA', 'AB', 'AZ', + 'BA', 'BB', 'BZ', + 'ZA', 'ZB', 'ZZ', + 'AAA', 'AAB', 'AAZ', + 'ABA', 'ABB', 'ABZ', + 'AZA', 'AZB', 'AZZ', + 'BAA', 'BAB', 'BAZ', + 'BBA', 'BBB', 'BBZ', + 'BZA', 'BZB', 'BZZ', + ]; + shuffle($columnBase); + $columnExpectedResult = array_reverse($columnExpectedResult); + usort($columnBase, [ReferenceHelper::class, 'columnReverseSort']); + foreach ($columnBase as $key => $value) { + self::assertEquals($columnExpectedResult[$key], $value); + } + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/SettingsTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/SettingsTest.php new file mode 100644 index 0000000..6878986 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/SettingsTest.php @@ -0,0 +1,40 @@ +prevValue = libxml_disable_entity_loader(); + libxml_disable_entity_loader(false); // Enable entity loader + } + + protected function tearDown() + { + libxml_disable_entity_loader($this->prevValue); + } + + public function testGetXMLSettings() + { + $result = Settings::getLibXmlLoaderOptions(); + self::assertTrue((bool) ((LIBXML_DTDLOAD | LIBXML_DTDATTR) & $result)); + self::assertFalse(libxml_disable_entity_loader()); + } + + public function testSetXMLSettings() + { + Settings::setLibXmlLoaderOptions(LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_DTDVALID); + $result = Settings::getLibXmlLoaderOptions(); + self::assertTrue((bool) ((LIBXML_DTDLOAD | LIBXML_DTDATTR | LIBXML_DTDVALID) & $result)); + self::assertFalse(libxml_disable_entity_loader()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Shared/CodePageTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Shared/CodePageTest.php new file mode 100644 index 0000000..b0e5fbf --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Shared/CodePageTest.php @@ -0,0 +1,54 @@ +getMessage(), 'Unknown codepage: 12345'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } + + public function testNumberToNameWithUnsupportedCodePage() + { + $unsupportedCodePage = 720; + + try { + CodePage::numberToName($unsupportedCodePage); + } catch (Exception $e) { + self::assertEquals($e->getMessage(), 'Code page 720 not supported.'); + + return; + } + $this->fail('An expected exception has not been raised.'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Shared/DateTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Shared/DateTest.php new file mode 100644 index 0000000..4a5479e --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Shared/DateTest.php @@ -0,0 +1,171 @@ +getActiveSheet(); + + $argb = 'FFFF0000'; + $color = new Color($argb); + + $sheet->getStyle('A1:C1')->getBorders()->getTop()->setBorderStyle(Border::BORDER_THIN)->setColor($color); + $sheet->getStyle('A1:A3')->getBorders()->getLeft()->setBorderStyle(Border::BORDER_THIN)->setColor($color); + $sheet->getStyle('C1:C3')->getBorders()->getRight()->setBorderStyle(Border::BORDER_THIN)->setColor($color); + $sheet->getStyle('A3:C3')->getBorders()->getBottom()->setBorderStyle(Border::BORDER_THIN)->setColor($color); + + // upper row + $expectations = [ + // cell => Left/Right/Top/Bottom + 'A1' => 'LT', + 'B1' => 'T', + 'C1' => 'RT', + 'A2' => 'L', + 'B2' => '', + 'C2' => 'R', + 'A3' => 'LB', + 'B3' => 'B', + 'C3' => 'RB', + ]; + $sides = [ + 'L' => 'Left', + 'R' => 'Right', + 'T' => 'Top', + 'B' => 'Bottom', + ]; + + foreach ($expectations as $cell => $borders) { + $bs = $sheet->getStyle($cell)->getBorders(); + foreach ($sides as $sidekey => $side) { + $assertion = "setBorderStyle on a range of cells, $cell $side"; + $func = "get$side"; + $b = $bs->$func(); // boo + + if (strpos($borders, $sidekey) === false) { + self::assertSame(Border::BORDER_NONE, $b->getBorderStyle(), $assertion); + } else { + self::assertSame(Border::BORDER_THIN, $b->getBorderStyle(), $assertion); + self::assertSame($argb, $b->getColor()->getARGB(), $assertion); + } + } + } + } + + public function testBorderRangeDirectly() + { + // testcase for the underlying problem directly + $spreadsheet = new Spreadsheet(); + $sheet = $spreadsheet->getActiveSheet(); + $style = $sheet->getStyle('A1:C1')->getBorders()->getTop()->setBorderStyle(Border::BORDER_THIN); + self::assertSame('A1:C1', $style->getSelectedCells(), 'getSelectedCells should not change after a style operation on a border range'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Style/BorderTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Style/BorderTest.php new file mode 100644 index 0000000..7efe935 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Style/BorderTest.php @@ -0,0 +1,26 @@ +getActiveSheet()->getStyle('A1')->getBorders(); + $allBorders = $borders->getAllBorders(); + $bottom = $borders->getBottom(); + + $actual = $bottom->getBorderStyle(); + self::assertSame(Border::BORDER_NONE, $actual, 'should default to none'); + + $allBorders->setBorderStyle(Border::BORDER_THIN); + + $actual = $bottom->getBorderStyle(); + self::assertSame(Border::BORDER_THIN, $actual, 'should have been set via allBorders'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Style/ColorTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Style/ColorTest.php new file mode 100644 index 0000000..a99c899 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Style/ColorTest.php @@ -0,0 +1,73 @@ +mockAutoFilterColumnObject = $this->getMockBuilder(Column::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->testAutoFilterRuleObject = new Column\Rule( + $this->mockAutoFilterColumnObject + ); + } + + public function testGetRuleType() + { + $result = $this->testAutoFilterRuleObject->getRuleType(); + self::assertEquals(Column\Rule::AUTOFILTER_RULETYPE_FILTER, $result); + } + + public function testSetRuleType() + { + $expectedResult = Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP; + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterRuleObject->setRuleType($expectedResult); + self::assertInstanceOf(Column\Rule::class, $result); + + $result = $this->testAutoFilterRuleObject->getRuleType(); + self::assertEquals($expectedResult, $result); + } + + public function testSetValue() + { + $expectedResult = 100; + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterRuleObject->setValue($expectedResult); + self::assertInstanceOf(Column\Rule::class, $result); + + $result = $this->testAutoFilterRuleObject->getValue(); + self::assertEquals($expectedResult, $result); + } + + public function testGetOperator() + { + $result = $this->testAutoFilterRuleObject->getOperator(); + self::assertEquals(Column\Rule::AUTOFILTER_COLUMN_RULE_EQUAL, $result); + } + + public function testSetOperator() + { + $expectedResult = Column\Rule::AUTOFILTER_COLUMN_RULE_LESSTHAN; + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterRuleObject->setOperator($expectedResult); + self::assertInstanceOf(Column\Rule::class, $result); + + $result = $this->testAutoFilterRuleObject->getOperator(); + self::assertEquals($expectedResult, $result); + } + + public function testSetGrouping() + { + $expectedResult = Column\Rule::AUTOFILTER_RULETYPE_DATEGROUP_MONTH; + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterRuleObject->setGrouping($expectedResult); + self::assertInstanceOf(Column\Rule::class, $result); + + $result = $this->testAutoFilterRuleObject->getGrouping(); + self::assertEquals($expectedResult, $result); + } + + public function testGetParent() + { + $result = $this->testAutoFilterRuleObject->getParent(); + self::assertInstanceOf(Column::class, $result); + } + + public function testSetParent() + { + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterRuleObject->setParent($this->mockAutoFilterColumnObject); + self::assertInstanceOf(Column\Rule::class, $result); + } + + public function testClone() + { + $result = clone $this->testAutoFilterRuleObject; + self::assertInstanceOf(Column\Rule::class, $result); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/AutoFilter/ColumnTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/AutoFilter/ColumnTest.php new file mode 100644 index 0000000..9ce636d --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/AutoFilter/ColumnTest.php @@ -0,0 +1,176 @@ +mockAutoFilterObject = $this->getMockBuilder(AutoFilter::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockAutoFilterObject->expects($this->any()) + ->method('testColumnInRange') + ->will($this->returnValue(3)); + + $this->testAutoFilterColumnObject = new AutoFilter\Column($this->testInitialColumn, $this->mockAutoFilterObject); + } + + public function testGetColumnIndex() + { + $result = $this->testAutoFilterColumnObject->getColumnIndex(); + self::assertEquals($this->testInitialColumn, $result); + } + + public function testSetColumnIndex() + { + $expectedResult = 'L'; + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterColumnObject->setColumnIndex($expectedResult); + self::assertInstanceOf(AutoFilter\Column::class, $result); + + $result = $this->testAutoFilterColumnObject->getColumnIndex(); + self::assertEquals($expectedResult, $result); + } + + public function testGetParent() + { + $result = $this->testAutoFilterColumnObject->getParent(); + self::assertInstanceOf(AutoFilter::class, $result); + } + + public function testSetParent() + { + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterColumnObject->setParent($this->mockAutoFilterObject); + self::assertInstanceOf(AutoFilter\Column::class, $result); + } + + public function testGetFilterType() + { + $result = $this->testAutoFilterColumnObject->getFilterType(); + self::assertEquals(AutoFilter\Column::AUTOFILTER_FILTERTYPE_FILTER, $result); + } + + public function testSetFilterType() + { + $result = $this->testAutoFilterColumnObject->setFilterType(AutoFilter\Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER); + self::assertInstanceOf(AutoFilter\Column::class, $result); + + $result = $this->testAutoFilterColumnObject->getFilterType(); + self::assertEquals(AutoFilter\Column::AUTOFILTER_FILTERTYPE_DYNAMICFILTER, $result); + } + + public function testSetInvalidFilterTypeThrowsException() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $expectedResult = 'Unfiltered'; + + $this->testAutoFilterColumnObject->setFilterType($expectedResult); + } + + public function testGetJoin() + { + $result = $this->testAutoFilterColumnObject->getJoin(); + self::assertEquals(AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_OR, $result); + } + + public function testSetJoin() + { + $result = $this->testAutoFilterColumnObject->setJoin(AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND); + self::assertInstanceOf(AutoFilter\Column::class, $result); + + $result = $this->testAutoFilterColumnObject->getJoin(); + self::assertEquals(AutoFilter\Column::AUTOFILTER_COLUMN_JOIN_AND, $result); + } + + public function testSetInvalidJoinThrowsException() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $expectedResult = 'Neither'; + + $this->testAutoFilterColumnObject->setJoin($expectedResult); + } + + public function testSetAttributes() + { + $attributeSet = [ + 'val' => 100, + 'maxVal' => 200, + ]; + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterColumnObject->setAttributes($attributeSet); + self::assertInstanceOf(AutoFilter\Column::class, $result); + } + + public function testGetAttributes() + { + $attributeSet = [ + 'val' => 100, + 'maxVal' => 200, + ]; + + $this->testAutoFilterColumnObject->setAttributes($attributeSet); + + $result = $this->testAutoFilterColumnObject->getAttributes(); + self::assertInternalType('array', $result); + self::assertCount(count($attributeSet), $result); + } + + public function testSetAttribute() + { + $attributeSet = [ + 'val' => 100, + 'maxVal' => 200, + ]; + + foreach ($attributeSet as $attributeName => $attributeValue) { + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterColumnObject->setAttribute($attributeName, $attributeValue); + self::assertInstanceOf(AutoFilter\Column::class, $result); + } + } + + public function testGetAttribute() + { + $attributeSet = [ + 'val' => 100, + 'maxVal' => 200, + ]; + + $this->testAutoFilterColumnObject->setAttributes($attributeSet); + + foreach ($attributeSet as $attributeName => $attributeValue) { + $result = $this->testAutoFilterColumnObject->getAttribute($attributeName); + self::assertEquals($attributeValue, $result); + } + $result = $this->testAutoFilterColumnObject->getAttribute('nonExistentAttribute'); + self::assertNull($result); + } + + public function testClone() + { + $originalRule = $this->testAutoFilterColumnObject->createRule(); + $result = clone $this->testAutoFilterColumnObject; + self::assertInstanceOf(AutoFilter\Column::class, $result); + self::assertCount(1, $result->getRules()); + self::assertContainsOnlyInstancesOf(AutoFilter\Column\Rule::class, $result->getRules()); + $clonedRule = $result->getRules()[0]; + self::assertNotSame($originalRule, $clonedRule); + self::assertSame($result, $clonedRule->getParent()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/AutoFilterTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/AutoFilterTest.php new file mode 100644 index 0000000..6766aac --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/AutoFilterTest.php @@ -0,0 +1,336 @@ +mockWorksheetObject = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + $this->cellCollection = $this->getMockBuilder(Cells::class) + ->disableOriginalConstructor() + ->getMock(); + $this->mockWorksheetObject->expects($this->any()) + ->method('getCellCollection') + ->will($this->returnValue($this->cellCollection)); + + $this->testAutoFilterObject = new AutoFilter($this->testInitialRange, $this->mockWorksheetObject); + } + + public function testToString() + { + $expectedResult = $this->testInitialRange; + + // magic __toString should return the active autofilter range + $result = $this->testAutoFilterObject; + self::assertEquals($expectedResult, $result); + } + + public function testGetParent() + { + $result = $this->testAutoFilterObject->getParent(); + self::assertInstanceOf(Worksheet::class, $result); + } + + public function testSetParent() + { + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterObject->setParent($this->mockWorksheetObject); + self::assertInstanceOf(AutoFilter::class, $result); + } + + public function testGetRange() + { + $expectedResult = $this->testInitialRange; + + // Result should be the active autofilter range + $result = $this->testAutoFilterObject->getRange(); + self::assertEquals($expectedResult, $result); + } + + public function testSetRange() + { + $ranges = [ + 'G1:J512' => 'Worksheet1!G1:J512', + 'K1:N20' => 'K1:N20', + ]; + + foreach ($ranges as $actualRange => $fullRange) { + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterObject->setRange($fullRange); + self::assertInstanceOf(AutoFilter::class, $result); + + // Result should be the new autofilter range + $result = $this->testAutoFilterObject->getRange(); + self::assertEquals($actualRange, $result); + } + } + + public function testClearRange() + { + $expectedResult = ''; + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterObject->setRange(''); + self::assertInstanceOf(AutoFilter::class, $result); + + // Result should be a clear range + $result = $this->testAutoFilterObject->getRange(); + self::assertEquals($expectedResult, $result); + } + + public function testSetRangeInvalidRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $expectedResult = 'A1'; + + $this->testAutoFilterObject->setRange($expectedResult); + } + + public function testGetColumnsEmpty() + { + // There should be no columns yet defined + $result = $this->testAutoFilterObject->getColumns(); + self::assertInternalType('array', $result); + self::assertCount(0, $result); + } + + public function testGetColumnOffset() + { + $columnIndexes = [ + 'H' => 0, + 'K' => 3, + 'M' => 5, + ]; + + // If we request a specific column by its column ID, we should get an + // integer returned representing the column offset within the range + foreach ($columnIndexes as $columnIndex => $columnOffset) { + $result = $this->testAutoFilterObject->getColumnOffset($columnIndex); + self::assertEquals($columnOffset, $result); + } + } + + public function testGetInvalidColumnOffset() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $invalidColumn = 'G'; + + $this->testAutoFilterObject->getColumnOffset($invalidColumn); + } + + public function testSetColumnWithString() + { + $expectedResult = 'L'; + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterObject->setColumn($expectedResult); + self::assertInstanceOf(AutoFilter::class, $result); + + $result = $this->testAutoFilterObject->getColumns(); + // Result should be an array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column + // objects for each column we set indexed by the column ID + self::assertInternalType('array', $result); + self::assertCount(1, $result); + self::assertArrayHasKey($expectedResult, $result); + self::assertInstanceOf(Column::class, $result[$expectedResult]); + } + + public function testSetInvalidColumnWithString() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $invalidColumn = 'A'; + + $this->testAutoFilterObject->setColumn($invalidColumn); + } + + public function testSetColumnWithColumnObject() + { + $expectedResult = 'M'; + $columnObject = new AutoFilter\Column($expectedResult); + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterObject->setColumn($columnObject); + self::assertInstanceOf(AutoFilter::class, $result); + + $result = $this->testAutoFilterObject->getColumns(); + // Result should be an array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column + // objects for each column we set indexed by the column ID + self::assertInternalType('array', $result); + self::assertCount(1, $result); + self::assertArrayHasKey($expectedResult, $result); + self::assertInstanceOf(Column::class, $result[$expectedResult]); + } + + public function testSetInvalidColumnWithObject() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $invalidColumn = 'E'; + $this->testAutoFilterObject->setColumn($invalidColumn); + } + + public function testSetColumnWithInvalidDataType() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $invalidColumn = 123.456; + $this->testAutoFilterObject->setColumn($invalidColumn); + } + + public function testGetColumns() + { + $columnIndexes = ['L', 'M']; + + foreach ($columnIndexes as $columnIndex) { + $this->testAutoFilterObject->setColumn($columnIndex); + } + + $result = $this->testAutoFilterObject->getColumns(); + // Result should be an array of \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column + // objects for each column we set indexed by the column ID + self::assertInternalType('array', $result); + self::assertCount(count($columnIndexes), $result); + foreach ($columnIndexes as $columnIndex) { + self::assertArrayHasKey($columnIndex, $result); + self::assertInstanceOf(Column::class, $result[$columnIndex]); + } + } + + public function testGetColumn() + { + $columnIndexes = ['L', 'M']; + + foreach ($columnIndexes as $columnIndex) { + $this->testAutoFilterObject->setColumn($columnIndex); + } + + // If we request a specific column by its column ID, we should + // get a \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column object returned + foreach ($columnIndexes as $columnIndex) { + $result = $this->testAutoFilterObject->getColumn($columnIndex); + self::assertInstanceOf(Column::class, $result); + } + } + + public function testGetColumnByOffset() + { + $columnIndexes = [ + 0 => 'H', + 3 => 'K', + 5 => 'M', + ]; + + // If we request a specific column by its offset, we should + // get a \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column object returned + foreach ($columnIndexes as $columnIndex => $columnID) { + $result = $this->testAutoFilterObject->getColumnByOffset($columnIndex); + self::assertInstanceOf(Column::class, $result); + self::assertEquals($result->getColumnIndex(), $columnID); + } + } + + public function testGetColumnIfNotSet() + { + // If we request a specific column by its column ID, we should + // get a \PhpOffice\PhpSpreadsheet\Worksheet\Worksheet\AutoFilter\Column object returned + $result = $this->testAutoFilterObject->getColumn('K'); + self::assertInstanceOf(Column::class, $result); + } + + public function testGetColumnWithoutRangeSet() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + // Clear the range + $this->testAutoFilterObject->setRange(''); + $this->testAutoFilterObject->getColumn('A'); + } + + public function testClearRangeWithExistingColumns() + { + $expectedResult = ''; + + $columnIndexes = ['L', 'M', 'N']; + foreach ($columnIndexes as $columnIndex) { + $this->testAutoFilterObject->setColumn($columnIndex); + } + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterObject->setRange(''); + self::assertInstanceOf(AutoFilter::class, $result); + + // Range should be cleared + $result = $this->testAutoFilterObject->getRange(); + self::assertEquals($expectedResult, $result); + + // Column array should be cleared + $result = $this->testAutoFilterObject->getColumns(); + self::assertInternalType('array', $result); + self::assertCount(0, $result); + } + + public function testSetRangeWithExistingColumns() + { + $expectedResult = 'G1:J512'; + + // These columns should be retained + $columnIndexes1 = ['I', 'J']; + foreach ($columnIndexes1 as $columnIndex) { + $this->testAutoFilterObject->setColumn($columnIndex); + } + // These columns should be discarded + $columnIndexes2 = ['K', 'L', 'M']; + foreach ($columnIndexes2 as $columnIndex) { + $this->testAutoFilterObject->setColumn($columnIndex); + } + + // Setters return the instance to implement the fluent interface + $result = $this->testAutoFilterObject->setRange($expectedResult); + self::assertInstanceOf(AutoFilter::class, $result); + + // Range should be correctly set + $result = $this->testAutoFilterObject->getRange(); + self::assertEquals($expectedResult, $result); + + // Only columns that existed in the original range and that + // still fall within the new range should be retained + $result = $this->testAutoFilterObject->getColumns(); + self::assertInternalType('array', $result); + self::assertCount(count($columnIndexes1), $result); + } + + public function testClone() + { + $columnIndexes = ['L', 'M']; + + foreach ($columnIndexes as $columnIndex) { + $this->testAutoFilterObject->setColumn($columnIndex); + } + + $result = clone $this->testAutoFilterObject; + self::assertInstanceOf(AutoFilter::class, $result); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnCellIteratorTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnCellIteratorTest.php new file mode 100644 index 0000000..46880e2 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnCellIteratorTest.php @@ -0,0 +1,86 @@ +mockCell = $this->getMockBuilder(Cell::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestRow') + ->will($this->returnValue(5)); + $this->mockWorksheet->expects($this->any()) + ->method('getCellByColumnAndRow') + ->will($this->returnValue($this->mockCell)); + } + + public function testIteratorFullRange() + { + $iterator = new ColumnCellIterator($this->mockWorksheet, 'A'); + $ColumnCellIndexResult = 1; + self::assertEquals($ColumnCellIndexResult, $iterator->key()); + + foreach ($iterator as $key => $ColumnCell) { + self::assertEquals($ColumnCellIndexResult++, $key); + self::assertInstanceOf(Cell::class, $ColumnCell); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); + $ColumnCellIndexResult = 2; + self::assertEquals($ColumnCellIndexResult, $iterator->key()); + + foreach ($iterator as $key => $ColumnCell) { + self::assertEquals($ColumnCellIndexResult++, $key); + self::assertInstanceOf(Cell::class, $ColumnCell); + } + } + + public function testIteratorSeekAndPrev() + { + $iterator = new ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); + $columnIndexResult = 4; + $iterator->seek(4); + self::assertEquals($columnIndexResult, $iterator->key()); + + for ($i = 1; $i < $columnIndexResult - 1; ++$i) { + $iterator->prev(); + self::assertEquals($columnIndexResult - $i, $iterator->key()); + } + } + + public function testSeekOutOfRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $iterator = new ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); + $iterator->seek(1); + } + + public function testPrevOutOfRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $iterator = new ColumnCellIterator($this->mockWorksheet, 'A', 2, 4); + $iterator->prev(); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnIteratorTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnIteratorTest.php new file mode 100644 index 0000000..7285961 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnIteratorTest.php @@ -0,0 +1,85 @@ +mockColumn = $this->getMockBuilder(Column::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestColumn') + ->will($this->returnValue('E')); + } + + public function testIteratorFullRange() + { + $iterator = new ColumnIterator($this->mockWorksheet); + $columnIndexResult = 'A'; + self::assertEquals($columnIndexResult, $iterator->key()); + + foreach ($iterator as $key => $column) { + self::assertEquals($columnIndexResult++, $key); + self::assertInstanceOf(Column::class, $column); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new ColumnIterator($this->mockWorksheet, 'B', 'D'); + $columnIndexResult = 'B'; + self::assertEquals($columnIndexResult, $iterator->key()); + + foreach ($iterator as $key => $column) { + self::assertEquals($columnIndexResult++, $key); + self::assertInstanceOf(Column::class, $column); + } + } + + public function testIteratorSeekAndPrev() + { + $ranges = range('A', 'E'); + $iterator = new ColumnIterator($this->mockWorksheet, 'B', 'D'); + $columnIndexResult = 'D'; + $iterator->seek('D'); + self::assertEquals($columnIndexResult, $iterator->key()); + + for ($i = 1; $i < array_search($columnIndexResult, $ranges); ++$i) { + $iterator->prev(); + $expectedResult = $ranges[array_search($columnIndexResult, $ranges) - $i]; + self::assertEquals($expectedResult, $iterator->key()); + } + } + + public function testSeekOutOfRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $iterator = new ColumnIterator($this->mockWorksheet, 'B', 'D'); + $iterator->seek('A'); + } + + public function testPrevOutOfRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $iterator = new ColumnIterator($this->mockWorksheet, 'B', 'D'); + $iterator->prev(); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnTest.php new file mode 100644 index 0000000..b1e7b47 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/ColumnTest.php @@ -0,0 +1,48 @@ +mockWorksheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + $this->mockWorksheet->expects($this->any()) + ->method('getHighestRow') + ->will($this->returnValue(5)); + } + + public function testInstantiateColumnDefault() + { + $column = new Column($this->mockWorksheet); + self::assertInstanceOf(Column::class, $column); + $columnIndex = $column->getColumnIndex(); + self::assertEquals('A', $columnIndex); + } + + public function testInstantiateColumnSpecified() + { + $column = new Column($this->mockWorksheet, 'E'); + self::assertInstanceOf(Column::class, $column); + $columnIndex = $column->getColumnIndex(); + self::assertEquals('E', $columnIndex); + } + + public function testGetCellIterator() + { + $column = new Column($this->mockWorksheet); + $cellIterator = $column->getCellIterator(); + self::assertInstanceOf(ColumnCellIterator::class, $cellIterator); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/DrawingTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/DrawingTest.php new file mode 100644 index 0000000..32bd97f --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/DrawingTest.php @@ -0,0 +1,40 @@ +getActiveSheet(); + + $gdImage = @imagecreatetruecolor(120, 20); + $textColor = imagecolorallocate($gdImage, 255, 255, 255); + imagestring($gdImage, 1, 5, 5, 'Created with PhpSpreadsheet', $textColor); + + $drawing = new MemoryDrawing(); + $drawing->setName('In-Memory image 1'); + $drawing->setDescription('In-Memory image 1'); + $drawing->setCoordinates('A1'); + $drawing->setImageResource($gdImage); + $drawing->setRenderingFunction( + MemoryDrawing::RENDERING_JPEG + ); + $drawing->setMimeType(MemoryDrawing::MIMETYPE_DEFAULT); + $drawing->setHeight(36); + $drawing->setWorksheet($aSheet); + + $originDrawingCount = count($aSheet->getDrawingCollection()); + $clonedWorksheet = clone $aSheet; + $clonedDrawingCount = count($clonedWorksheet->getDrawingCollection()); + + self::assertEquals($originDrawingCount, $clonedDrawingCount); + self::assertNotSame($aSheet, $clonedWorksheet); + self::assertNotSame($aSheet->getDrawingCollection(), $clonedWorksheet->getDrawingCollection()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowCellIteratorTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowCellIteratorTest.php new file mode 100644 index 0000000..9346d0a --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowCellIteratorTest.php @@ -0,0 +1,88 @@ +mockCell = $this->getMockBuilder(Cell::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestColumn') + ->will($this->returnValue('E')); + $this->mockWorksheet->expects($this->any()) + ->method('getCellByColumnAndRow') + ->will($this->returnValue($this->mockCell)); + } + + public function testIteratorFullRange() + { + $iterator = new RowCellIterator($this->mockWorksheet); + $RowCellIndexResult = 'A'; + self::assertEquals($RowCellIndexResult, $iterator->key()); + + foreach ($iterator as $key => $RowCell) { + self::assertEquals($RowCellIndexResult++, $key); + self::assertInstanceOf(Cell::class, $RowCell); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); + $RowCellIndexResult = 'B'; + self::assertEquals($RowCellIndexResult, $iterator->key()); + + foreach ($iterator as $key => $RowCell) { + self::assertEquals($RowCellIndexResult++, $key); + self::assertInstanceOf(Cell::class, $RowCell); + } + } + + public function testIteratorSeekAndPrev() + { + $ranges = range('A', 'E'); + $iterator = new RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); + $RowCellIndexResult = 'D'; + $iterator->seek('D'); + self::assertEquals($RowCellIndexResult, $iterator->key()); + + for ($i = 1; $i < array_search($RowCellIndexResult, $ranges); ++$i) { + $iterator->prev(); + $expectedResult = $ranges[array_search($RowCellIndexResult, $ranges) - $i]; + self::assertEquals($expectedResult, $iterator->key()); + } + } + + public function testSeekOutOfRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $iterator = new RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); + $iterator->seek(1); + } + + public function testPrevOutOfRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $iterator = new RowCellIterator($this->mockWorksheet, 2, 'B', 'D'); + $iterator->prev(); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowIteratorTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowIteratorTest.php new file mode 100644 index 0000000..63e26b3 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowIteratorTest.php @@ -0,0 +1,83 @@ +mockRow = $this->getMockBuilder(Row::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + + $this->mockWorksheet->expects($this->any()) + ->method('getHighestRow') + ->will($this->returnValue(5)); + } + + public function testIteratorFullRange() + { + $iterator = new RowIterator($this->mockWorksheet); + $rowIndexResult = 1; + self::assertEquals($rowIndexResult, $iterator->key()); + + foreach ($iterator as $key => $row) { + self::assertEquals($rowIndexResult++, $key); + self::assertInstanceOf(Row::class, $row); + } + } + + public function testIteratorStartEndRange() + { + $iterator = new RowIterator($this->mockWorksheet, 2, 4); + $rowIndexResult = 2; + self::assertEquals($rowIndexResult, $iterator->key()); + + foreach ($iterator as $key => $row) { + self::assertEquals($rowIndexResult++, $key); + self::assertInstanceOf(Row::class, $row); + } + } + + public function testIteratorSeekAndPrev() + { + $iterator = new RowIterator($this->mockWorksheet, 2, 4); + $columnIndexResult = 4; + $iterator->seek(4); + self::assertEquals($columnIndexResult, $iterator->key()); + + for ($i = 1; $i < $columnIndexResult - 1; ++$i) { + $iterator->prev(); + self::assertEquals($columnIndexResult - $i, $iterator->key()); + } + } + + public function testSeekOutOfRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $iterator = new RowIterator($this->mockWorksheet, 2, 4); + $iterator->seek(1); + } + + public function testPrevOutOfRange() + { + $this->expectException(\PhpOffice\PhpSpreadsheet\Exception::class); + + $iterator = new RowIterator($this->mockWorksheet, 2, 4); + $iterator->prev(); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowTest.php new file mode 100644 index 0000000..0b2822c --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/RowTest.php @@ -0,0 +1,48 @@ +mockWorksheet = $this->getMockBuilder(Worksheet::class) + ->disableOriginalConstructor() + ->getMock(); + $this->mockWorksheet->expects($this->any()) + ->method('getHighestColumn') + ->will($this->returnValue('E')); + } + + public function testInstantiateRowDefault() + { + $row = new Row($this->mockWorksheet); + self::assertInstanceOf(Row::class, $row); + $rowIndex = $row->getRowIndex(); + self::assertEquals(1, $rowIndex); + } + + public function testInstantiateRowSpecified() + { + $row = new Row($this->mockWorksheet, 5); + self::assertInstanceOf(Row::class, $row); + $rowIndex = $row->getRowIndex(); + self::assertEquals(5, $rowIndex); + } + + public function testGetCellIterator() + { + $row = new Row($this->mockWorksheet); + $cellIterator = $row->getCellIterator(); + self::assertInstanceOf(RowCellIterator::class, $cellIterator); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php new file mode 100644 index 0000000..5dfa825 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Worksheet/WorksheetTest.php @@ -0,0 +1,133 @@ +setTitle($testTitle); + self::assertSame($testTitle, $worksheet->getTitle()); + } + + public function setTitleInvalidProvider() + { + return [ + [str_repeat('a', 32), 'Maximum 31 characters allowed in sheet title.'], + ['invalid*title', 'Invalid character found in sheet title'], + ]; + } + + /** + * @param string $title + * @param string $expectMessage + * @dataProvider setTitleInvalidProvider + */ + public function testSetTitleInvalid($title, $expectMessage) + { + // First, test setting title with validation disabled -- should be successful + $worksheet = new Worksheet(); + $worksheet->setTitle($title, true, false); + + // Next, test again with validation enabled -- this time we should fail + $worksheet = new Worksheet(); + $this->expectException(\Exception::class); + $this->expectExceptionMessage($expectMessage); + $worksheet->setTitle($title); + } + + public function testSetTitleDuplicate() + { + // Create a Spreadsheet with three Worksheets (the first is created automatically) + $spreadsheet = new Spreadsheet(); + $spreadsheet->createSheet(); + $spreadsheet->createSheet(); + + // Set unique title -- should be unchanged + $sheet = $spreadsheet->getSheet(0); + $sheet->setTitle('Test Title'); + self::assertSame('Test Title', $sheet->getTitle()); + + // Set duplicate title -- should have numeric suffix appended + $sheet = $spreadsheet->getSheet(1); + $sheet->setTitle('Test Title'); + self::assertSame('Test Title 1', $sheet->getTitle()); + + // Set duplicate title with validation disabled -- should be unchanged + $sheet = $spreadsheet->getSheet(2); + $sheet->setTitle('Test Title', true, false); + self::assertSame('Test Title', $sheet->getTitle()); + } + + public function testSetCodeName() + { + $testCodeName = str_repeat('a', 31); + + $worksheet = new Worksheet(); + $worksheet->setCodeName($testCodeName); + self::assertSame($testCodeName, $worksheet->getCodeName()); + } + + public function setCodeNameInvalidProvider() + { + return [ + [str_repeat('a', 32), 'Maximum 31 characters allowed in sheet code name.'], + ['invalid*code*name', 'Invalid character found in sheet code name'], + ]; + } + + /** + * @param string $codeName + * @param string $expectMessage + * @dataProvider setCodeNameInvalidProvider + */ + public function testSetCodeNameInvalid($codeName, $expectMessage) + { + // First, test setting code name with validation disabled -- should be successful + $worksheet = new Worksheet(); + $worksheet->setCodeName($codeName, false); + + // Next, test again with validation enabled -- this time we should fail + $worksheet = new Worksheet(); + $this->expectException(\Exception::class); + $this->expectExceptionMessage($expectMessage); + $worksheet->setCodeName($codeName); + } + + public function testSetCodeNameDuplicate() + { + // Create a Spreadsheet with three Worksheets (the first is created automatically) + $spreadsheet = new Spreadsheet(); + $spreadsheet->createSheet(); + $spreadsheet->createSheet(); + + // Set unique code name -- should be massaged to Snake_Case + $sheet = $spreadsheet->getSheet(0); + $sheet->setCodeName('Test Code Name'); + self::assertSame('Test_Code_Name', $sheet->getCodeName()); + + // Set duplicate code name -- should be massaged and have numeric suffix appended + $sheet = $spreadsheet->getSheet(1); + $sheet->setCodeName('Test Code Name'); + self::assertSame('Test_Code_Name_1', $sheet->getCodeName()); + + // Set duplicate code name with validation disabled -- should be unchanged, and unmassaged + $sheet = $spreadsheet->getSheet(2); + $sheet->setCodeName('Test Code Name', false); + self::assertSame('Test Code Name', $sheet->getCodeName()); + } + + public function testFreezePaneSelectedCell() + { + $worksheet = new Worksheet(); + $worksheet->freezePane('B2'); + self::assertSame('B2', $worksheet->getTopLeftCell()); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Ods/ContentTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Ods/ContentTest.php new file mode 100644 index 0000000..0c9995a --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Ods/ContentTest.php @@ -0,0 +1,98 @@ +compatibilityMode = Functions::getCompatibilityMode(); + Functions::setCompatibilityMode(Functions::COMPATIBILITY_OPENOFFICE); + } + + protected function tearDown() + { + parent::tearDown(); + Functions::setCompatibilityMode($this->compatibilityMode); + } + + public function testWriteEmptySpreadsheet() + { + $content = new Content(new Ods(new Spreadsheet())); + $xml = $content->write(); + + self::assertXmlStringEqualsXmlFile($this->samplesPath . '/content-empty.xml', $xml); + } + + public function testWriteSpreadsheet() + { + $workbook = new Spreadsheet(); + + // Worksheet 1 + $worksheet1 = $workbook->getActiveSheet(); + $worksheet1->setCellValue('A1', 1); // Number + $worksheet1->setCellValue('B1', 12345.6789); // Number + $worksheet1->setCellValue('C1', '1'); // Number without cast + $worksheet1->setCellValueExplicit('D1', '01234', DataType::TYPE_STRING); // Number casted to string + $worksheet1->setCellValue('E1', 'Lorem ipsum'); // String + + $worksheet1->setCellValue('A2', true); // Boolean + $worksheet1->setCellValue('B2', false); // Boolean + $worksheet1->setCellValueExplicit( + 'C2', + '=IF(A3, CONCATENATE(A1, " ", A2), CONCATENATE(A2, " ", A1))', + DataType::TYPE_FORMULA + ); // Formula + + $worksheet1->setCellValue('D2', Date::PHPToExcel(1488635026)); // Date + $worksheet1->getStyle('D2') + ->getNumberFormat() + ->setFormatCode(NumberFormat::FORMAT_DATE_DATETIME); + + // Styles + $worksheet1->getStyle('A1')->getFont()->setBold(true); + $worksheet1->getStyle('B1')->getFont()->setItalic(true); + $worksheet1->getStyle('C1')->getFont()->setName('Courier'); + $worksheet1->getStyle('C1')->getFont()->setSize(14); + $worksheet1->getStyle('C1')->getFont()->setColor(new Color(Color::COLOR_BLUE)); + + $worksheet1->getStyle('C1')->getFill()->setFillType(Fill::FILL_SOLID); + $worksheet1->getStyle('C1')->getFill()->setStartColor(new Color(Color::COLOR_RED)); + + $worksheet1->getStyle('C1')->getFont()->setUnderline(Font::UNDERLINE_SINGLE); + $worksheet1->getStyle('C2')->getFont()->setUnderline(Font::UNDERLINE_DOUBLE); + $worksheet1->getStyle('D2')->getFont()->setUnderline(Font::UNDERLINE_NONE); + + // Worksheet 2 + $worksheet2 = $workbook->createSheet(); + $worksheet2->setTitle('New Worksheet'); + $worksheet2->setCellValue('A1', 2); + + // Write + $content = new Content(new Ods($workbook)); + $xml = $content->write(); + + self::assertXmlStringEqualsXmlFile($this->samplesPath . '/content-with-data.xml', $xml); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Xls/WorkbookTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Xls/WorkbookTest.php new file mode 100644 index 0000000..591f48f --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Xls/WorkbookTest.php @@ -0,0 +1,143 @@ +workbook = new Workbook($spreadsheet, $strTotal, $strUnique, $str_table, $colors, $parser); + } + + /** + * @dataProvider providerAddColor + * + * @param array $testColors + * @param array $expectedResult + */ + public function testAddColor(array $testColors, array $expectedResult) + { + $workbookReflection = new \ReflectionClass(Workbook::class); + $methodAddColor = $workbookReflection->getMethod('addColor'); + $propertyPalette = $workbookReflection->getProperty('palette'); + $methodAddColor->setAccessible(true); + $propertyPalette->setAccessible(true); + + foreach ($testColors as $testColor) { + $methodAddColor->invoke($this->workbook, $testColor); + } + + $palette = $propertyPalette->getValue($this->workbook); + + self::assertEquals($expectedResult, $palette); + } + + public function providerAddColor() + { + $this->setUp(); + + $workbookReflection = new \ReflectionClass(Workbook::class); + $propertyPalette = $workbookReflection->getProperty('palette'); + $propertyPalette->setAccessible(true); + + $palette = $propertyPalette->getValue($this->workbook); + + $newColor1 = [0x00, 0x00, 0x01, 0x00]; + $newColor2 = [0x00, 0x00, 0x02, 0x00]; + $newColor3 = [0x00, 0x00, 0x03, 0x00]; + + // Add one new color + $paletteTestOne = $palette; + $paletteTestOne[8] = $newColor1; + + // Add one new color + one existing color after index 8 + $paletteTestTwo = $paletteTestOne; + + // Add one new color + one existing color before index 9 + $paletteTestThree = $paletteTestOne; + $paletteTestThree[9] = $palette[8]; + + // Add three new color + $paletteTestFour = $palette; + $paletteTestFour[8] = $newColor1; + $paletteTestFour[9] = $newColor2; + $paletteTestFour[10] = $newColor3; + + // Add all existing color + $colorsAdd = array_map([$this, 'paletteToColor'], $palette); + $paletteTestFive = $palette; + + // Add new color after all existing color + $colorsAddTwo = array_map([$this, 'paletteToColor'], $palette); + $colorsAddTwo[] = $this->paletteToColor($newColor1); + $paletteTestSix = $palette; + + // Add one existing color + $paletteTestSeven = $palette; + + // Add two existing color + $paletteTestHeight = $palette; + + // Add last existing color and add one new color + $keyPalette = array_keys($palette); + $last = end($keyPalette); + $lastColor = $this->paletteToColor($palette[$last]); + $paletteTestNine = $palette; + + return [ + [[$this->paletteToColor($newColor1)], $paletteTestOne], + [[$this->paletteToColor($newColor1), $this->paletteToColor($palette[12])], $paletteTestTwo], + [[$this->paletteToColor($newColor1), $this->paletteToColor($palette[8])], $paletteTestThree], + [[$this->paletteToColor($newColor1), $this->paletteToColor($newColor2), $this->paletteToColor($newColor3)], $paletteTestFour], + [$colorsAdd, $paletteTestFive], + [$colorsAddTwo, $paletteTestSix], + [[$this->paletteToColor($palette[8])], $paletteTestSeven], + [[$this->paletteToColor($palette[25]), $this->paletteToColor($palette[10])], $paletteTestHeight], + [[$lastColor, $this->paletteToColor($newColor1)], $paletteTestNine], + ]; + } + + /** + * Change palette color to rgb string. + * + * @param array $palette palette color + * + * @return string rgb string + */ + private function paletteToColor($palette) + { + return $this->right('00' . dechex((int) ($palette[0])), 2) + . $this->right('00' . dechex((int) ($palette[1])), 2) + . $this->right('00' . dechex((int) ($palette[2])), 2); + } + + /** + * Return n right character in string. + * + * @param string $value text to get right character + * @param int $nbchar number of char at right of string + * + * @return string + */ + private function right($value, $nbchar) + { + return mb_substr($value, mb_strlen($value) - $nbchar, $nbchar); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php new file mode 100644 index 0000000..c17d55d --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/PhpSpreadsheetTests/Writer/Xlsx/UnparsedDataTest.php @@ -0,0 +1,103 @@ +load($sampleFilename); + + $excel->getSheet(1)->setCellValue('B1', '222'); + + $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($excel); + $writer->save($resultFilename); + self::assertFileExists($resultFilename); + + $resultZip = new ZipArchive(); + $resultZip->open($resultFilename); + $resultContentTypesRaw = $resultZip->getFromName('[Content_Types].xml'); + $resultControlPropRaw = $resultZip->getFromName('xl/ctrlProps/ctrlProp1.xml'); + $resultDrawingRaw = $resultZip->getFromName('xl/drawings/drawing1.xml'); + $resultVmlDrawingRaw = $resultZip->getFromName('xl/drawings/vmlDrawing1.vml'); + $resultPrinterSettingsRaw = $resultZip->getFromName('xl/printerSettings/printerSettings1.bin'); + $resultVbaProjectRaw = $resultZip->getFromName('xl/vbaProject.bin'); + $resultWorkbookRaw = $resultZip->getFromName('xl/workbook.xml'); + $resultSheet1RelsRaw = $resultZip->getFromName('xl/worksheets/_rels/sheet1.xml.rels'); + $resultSheet1Raw = $resultZip->getFromName('xl/worksheets/sheet1.xml'); + $resultSheet2Raw = $resultZip->getFromName('xl/worksheets/sheet2.xml'); + if (false === $resultZip->close()) { + throw new Exception("Could not close zip file \"{$resultFilename}\"."); + } + unlink($resultFilename); + + // [Content_Types].xml + $this->assertTrue(strpos($resultContentTypesRaw, 'application/vnd.openxmlformats-officedocument.spreadsheetml.printerSettings') > 0, 'Content type for printerSettings not found!'); + $this->assertTrue(strpos($resultContentTypesRaw, 'application/vnd.ms-office.vbaProject') > 0, 'Content type for VbaProject not found!'); + $this->assertTrue(strpos($resultContentTypesRaw, 'application/vnd.ms-excel.controlproperties+xml') > 0, 'Content type for ctrlProp not found!'); + + // xl/ctrlProps/ctrlProp1.xml + $this->assertTrue(!empty($resultControlPropRaw), 'ctrlProp not found!'); + + // xl/drawings/drawing1.xml + $this->assertTrue(strpos($resultDrawingRaw, ' 0, 'AlternateContent at drawing.xml not found!'); + + // xl/drawings/vmlDrawing1.vml + $this->assertTrue(!empty($resultVmlDrawingRaw), 'vmlDrawing not found!'); + + // xl/printerSettings/printerSettings1.bin + $this->assertTrue(!empty($resultPrinterSettingsRaw), 'printerSettings.bin not found!'); + + // xl/vbaProject.bin + $this->assertTrue(!empty($resultVbaProjectRaw), 'vbaProject.bin not found!'); + + // xl/workbook.xml + $xmlWorkbook = simplexml_load_string($resultWorkbookRaw, 'SimpleXMLElement', Settings::getLibXmlLoaderOptions()); + if (!$xmlWorkbook->workbookProtection) { + $this->fail('workbook.xml/workbookProtection not found!'); + } else { + $this->assertEquals($xmlWorkbook->workbookProtection['workbookPassword'], 'CBEB', 'workbook.xml/workbookProtection[workbookPassword] is wrong!'); + $this->assertEquals($xmlWorkbook->workbookProtection['lockStructure'], 'true', 'workbook.xml/workbookProtection[lockStructure] is wrong!'); + + $this->assertEquals($xmlWorkbook->sheets->sheet[0]['state'], '', 'workbook.xml/sheets/sheet[0][state] is wrong!'); + $this->assertEquals($xmlWorkbook->sheets->sheet[1]['state'], 'hidden', 'workbook.xml/sheets/sheet[1][state] is wrong!'); + } + unset($xmlWorkbook); + + // xl/worksheets/_rels/sheet1.xml.rels + $this->assertTrue(strpos($resultSheet1RelsRaw, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/printerSettings') > 0, 'Sheet relation with printerSettings not found!'); + $this->assertTrue(strpos($resultSheet1RelsRaw, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/vmlDrawing') > 0, 'Sheet relation with vmlDrawing not found!'); + $this->assertTrue(strpos($resultSheet1RelsRaw, 'http://schemas.openxmlformats.org/officeDocument/2006/relationships/ctrlProp') > 0, 'Sheet relation with ctrlProp not found!'); + + // xl/worksheets/sheet1.xml + $this->assertTrue(strpos($resultSheet1Raw, ' 0, 'AlternateContent at sheet1.xml not found!'); + $xmlWorksheet = simplexml_load_string($resultSheet1Raw, 'SimpleXMLElement', Settings::getLibXmlLoaderOptions()); + $pageSetupAttributes = $xmlWorksheet->pageSetup->attributes('http://schemas.openxmlformats.org/officeDocument/2006/relationships'); + $this->assertTrue(!empty($pageSetupAttributes['id']), 'sheet1.xml/pageSetup[r:id] not found!'); + if (!$xmlWorksheet->sheetProtection) { + $this->fail('sheet1.xml/sheetProtection not found!'); + } else { + $this->assertEquals($xmlWorksheet->sheetProtection['password'], 'CBEB', 'sheet1.xml/sheetProtection[password] is wrong!'); + $this->assertEquals($xmlWorksheet->sheetProtection['sheet'], 'true', 'sheet1.xml/sheetProtection[sheet] is wrong!'); + $this->assertEquals($xmlWorksheet->sheetProtection['objects'], 'true', 'sheet1.xml/sheetProtection[objects] is wrong!'); + $this->assertEquals($xmlWorksheet->sheetProtection['scenarios'], 'true', 'sheet1.xml/sheetProtection[scenarios] is wrong!'); + } + unset($xmlWorksheet); + + // xl/worksheets/sheet2.xml + $this->assertTrue(!empty($resultSheet2Raw), 'sheet2.xml not found!'); + } +} diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/bootstrap.php b/inc/vendor/phpoffice/phpspreadsheet/tests/bootstrap.php new file mode 100644 index 0000000..f89fe40 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/bootstrap.php @@ -0,0 +1,13 @@ +"A"', + '>A', + ], + [ + '<="A"', + '<=A', + ], + [ + '>"A"', + '>A', + ], + [ + '>="A"', + '>=A', + ], + [ + '<>"A"', + '<>A', + ], + [ + '<""< PLEASE SELECT >"', + '<>< Please Select >', + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/Functions/ISFORMULA.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/Functions/ISFORMULA.php new file mode 100644 index 0000000..9e0d0d0 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/Functions/ISFORMULA.php @@ -0,0 +1,84 @@ + 0, 2 > 0, + ], + [ + true, + true, false, false, + ], + [ + true, + 1 > 0, 0 > 1, + ], + [ + true, + 0 > 1, 2 > 0, + ], + [ + false, + 0 > 1, 0 > 2, + ], + [ + false, + 1 > 0, 2 > 0, 0 > 1, 0 > 2, + ], + [ + true, + 1 > 0, 2 > 0, 3 > 0, 0 > 1, + ], + [ + false, + 'TRUE', + 1, + 0.5, + ], + [ + true, + 'FALSE', + 1.5, + 0, + ], + [ + '#VALUE!', + 'HELLO WORLD', + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/COLUMNS.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/COLUMNS.php new file mode 100644 index 0000000..3a6a587 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/COLUMNS.php @@ -0,0 +1,36 @@ + [1, 1]], + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/FORMULATEXT.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/FORMULATEXT.php new file mode 100644 index 0000000..30b2d6e --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/FORMULATEXT.php @@ -0,0 +1,34 @@ + ['R' => 1]], // Expected + // Input + [20 => ['R' => 1]], + ], + [ + '#VALUE!', // Expected + // Input + [ + 20 => ['R' => 1], + 21 => ['R' => 2], + ], + -1, + ], + [ + '#REF!', // Expected + // Input + [ + 20 => ['R' => 1], + 21 => ['R' => 2], + ], + 10, + ], + [ + [21 => ['R' => 2]], // Expected + // Input + [ + 20 => ['R' => 1], + 21 => ['R' => 2], + ], + 2, + ], + [ + [21 => ['R' => 2, 'S' => 4]], // Expected + // Input + [ + '20' => ['R' => 1, 'S' => 3], + '21' => ['R' => 2, 'S' => 4], + ], + 2, + 0, + ], + [ + '#VALUE!', // Expected + // Input + [ + '20' => ['R' => 1, 'S' => 3], + '21' => ['R' => 2, 'S' => 4], + ], + 2, + -1, + ], + [ + '#VALUE!', // Expected + // Input + [ + '20' => ['R' => 1, 'S' => 3], + '21' => ['R' => 2, 'S' => 4], + ], + 2, + 10, + ], + [ + 4, // Expected + // Input + [ + '20' => ['R' => 1, 'S' => 3], + '21' => ['R' => 2, 'S' => 4], + ], + 2, + 2, + ], + [ + 4, // Expected + // Input + [ + '20' => ['R' => 1, 'S' => 3], + '21' => ['R' => 2, 'S' => 4], + ], + [ + '21' => ['R' => 2], + ], + [ + '21' => ['R' => 2], + ], + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/MATCH.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/MATCH.php new file mode 100644 index 0000000..a82acdd --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/MATCH.php @@ -0,0 +1,99 @@ + [1, 1]], + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/VLOOKUP.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/VLOOKUP.php new file mode 100644 index 0000000..2ef64d0 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/LookupRef/VLOOKUP.php @@ -0,0 +1,294 @@ + ['A' => 0], + 2 => ['A' => 1], + 3 => ['A' => 1], + 4 => ['A' => 2], + 5 => ['A' => 3], + 6 => ['A' => 5], + 7 => ['A' => 8], + 8 => ['A' => 13], + 9 => ['A' => 21], + 10 => ['A' => 34], + 11 => ['A' => 55], + 12 => ['A' => 89], +]; + +return [ + [ + 19.3333333333333, + 1, + $baseTestData, + ], + [ + 12, + 2, + $baseTestData, + ], + [ + 12, + 3, + $baseTestData, + ], + [ + 89, + 4, + $baseTestData, + ], + [ + 0, + 5, + $baseTestData, + ], + [ + 0, + 6, + $baseTestData, + ], + [ + 27.5196899207337, + 7, + $baseTestData, + ], + [ + 26.3480971271593, + 8, + $baseTestData, + ], + [ + 232, + 9, + $baseTestData, + ], + [ + 757.3333333333330, + 10, + $baseTestData, + ], + [ + 694.2222222222220, + 11, + $baseTestData, + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUBTOTALHIDDEN.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUBTOTALHIDDEN.php new file mode 100644 index 0000000..001531f --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUBTOTALHIDDEN.php @@ -0,0 +1,74 @@ + ['A' => 0], + 2 => ['A' => 1], + 3 => ['A' => 1], + 4 => ['A' => 2], + 5 => ['A' => 3], + 6 => ['A' => 5], + 7 => ['A' => 8], + 8 => ['A' => 13], + 9 => ['A' => 21], + 10 => ['A' => 34], + 11 => ['A' => 55], + 12 => ['A' => 89], +]; + +return [ + [ + 21, + 101, + $baseTestData, + ], + [ + 5, + 102, + $baseTestData, + ], + [ + 5, + 103, + $baseTestData, + ], + [ + 55, + 104, + $baseTestData, + ], + [ + 1, + 105, + $baseTestData, + ], + [ + 48620, + 106, + $baseTestData, + ], + [ + 23.1840462387393, + 107, + $baseTestData, + ], + [ + 20.7364413533277, + 108, + $baseTestData, + ], + [ + 105, + 109, + $baseTestData, + ], + [ + 537.5, + 110, + $baseTestData, + ], + [ + 430, + 111, + $baseTestData, + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUBTOTALNESTED.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUBTOTALNESTED.php new file mode 100644 index 0000000..e1ae38f --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUBTOTALNESTED.php @@ -0,0 +1,18 @@ + ['A' => 123], + 2 => ['A' => 234], + 3 => ['A' => '=SUBTOTAL(1, A1:A2)'], + 4 => ['A' => '=ROMAN(SUBTOTAL(1, A1:A2))'], + 5 => ['A' => 'This is text containing "=" and "SUBTOTAL("'], + 6 => ['A' => '=AGGREGATE(1, A1:A2)'], +]; + +return [ + [ + 357, + 9, + $baseTestData, + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUMIF.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUMIF.php new file mode 100644 index 0000000..0b94701 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUMIF.php @@ -0,0 +1,61 @@ +=5', + ], + [ + 10, + [ + ['text'], + [2], + ], + '=text', + [ + [10], + [100], + ], + ], + [ + 10, + [ + ['"text with quotes"'], + [2], + ], + '="text with quotes"', + [ + [10], + [100], + ], + ], + [ + 10, + [ + ['"text with quotes"'], + [''], + ], + '>"', // Compare to the single characater " (double quote) + [ + [10], + [100], + ], + ], + [ + 100, + [ + [''], + ['anything'], + ], + '>"', // Compare to the single characater " (double quote) + [ + [10], + [100], + ], + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUMPRODUCT.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUMPRODUCT.php new file mode 100644 index 0000000..3a75e03 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/MathTrig/SUMPRODUCT.php @@ -0,0 +1,19 @@ + [ + "\u{0061}\u{030A}", + "\u{0061}\u{030A}", + "\u{00E5}", + 'x', + ], + 'Multibytes are supported' => [ + 'x', + "\u{00E5}", + "\u{00E5}", + 'x', + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/TextData/T.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/TextData/T.php new file mode 100644 index 0000000..8eb7095 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Calculation/TextData/T.php @@ -0,0 +1,24 @@ + 1', + true, + true, + ], + [ + '=3 > 3', + false, + false, + ], + [ + '=1 > 3', + false, + false, + ], + [ + '=3 < 1', + false, + false, + ], + [ + '=3 < 3', + false, + false, + ], + [ + '=1 < 3', + true, + true, + ], + [ + '=3 = 1', + false, + false, + ], + [ + '=3 = 3', + true, + true, + ], + [ + '=1 = 1.0', + true, + true, + ], + [ + '=3 >= 1', + true, + true, + ], + [ + '=3 >= 3', + true, + true, + ], + [ + '=1 >= 3', + false, + false, + ], + [ + '=3 <= 1', + false, + false, + ], + [ + '=3 <= 3', + true, + true, + ], + [ + '=1 <= 3', + true, + true, + ], + [ + '=3 <> 1', + true, + true, + ], + [ + '=3 <> 3', + false, + false, + ], + [ + '=1 <> 1.0', + false, + false, + ], + [ + '="a" > "a"', + false, + false, + ], + [ + '="A" > "A"', + false, + false, + ], + [ + '="A" > "a"', + false, + true, + ], + [ + '="a" > "A"', + false, + false, + ], + [ + '="a" < "a"', + false, + false, + ], + [ + '="A" < "A"', + false, + false, + ], + [ + '="A" < "a"', + false, + false, + ], + [ + '="a" < "A"', + false, + true, + ], + [ + '="a" = "a"', + true, + true, + ], + [ + '="A" = "A"', + true, + true, + ], + [ + '="A" = "a"', + true, + false, + ], + [ + '="a" = "A"', + true, + false, + ], + [ + '="a" <= "a"', + true, + true, + ], + [ + '="A" <= "A"', + true, + true, + ], + [ + '="A" <= "a"', + true, + false, + ], + [ + '="a" <= "A"', + true, + true, + ], + [ + '="a" >= "a"', + true, + true, + ], + [ + '="A" >= "A"', + true, + true, + ], + [ + '="A" >= "a"', + true, + true, + ], + [ + '="a" >= "A"', + true, + false, + ], + [ + '="a" <> "a"', + false, + false, + ], + [ + '="A" <> "A"', + false, + false, + ], + [ + '="A" <> "a"', + false, + true, + ], + [ + '="a" <> "A"', + false, + true, + ], + [ + '="A" > "b"', + false, + true, + ], + [ + '="a" > "b"', + false, + false, + ], + [ + '="b" > "a"', + true, + true, + ], + [ + '="b" > "A"', + true, + false, + ], + // Test natural sorting is not used + [ + '="a2" > "a10"', + true, + true, + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Cell/DefaultValueBinder.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Cell/DefaultValueBinder.php new file mode 100644 index 0000000..53ba628 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Cell/DefaultValueBinder.php @@ -0,0 +1,76 @@ + 'x', + 'A4' => 'y', + ], + [ + 'A1' => 'x', + 'A2' => 'x', + 'A3' => 'x', + 'A4' => 'y', + ], + ], + [ + [ + 'A1:A4' => 'x', + 'A6:A7' => 'x', + 'A9' => 'x', + ], + [ + 'A7' => 'x', + 'A1' => 'x', + 'A4' => 'x', + 'A6' => 'x', + 'A2' => 'x', + 'A9' => 'x', + 'A3' => 'x', + ], + ], + [ + [ + 'A1:A3' => 'x', + 'B1:B3' => 'x', + ], + [ + 'A1' => 'x', + 'B3' => 'x', + 'A2' => 'x', + 'B2' => 'x', + 'A3' => 'x', + 'B1' => 'x', + ], + ], + [ + [ + 'A1' => 'x', + 'A2' => 'y', + 'A3' => 'z', + ], + [ + 'A1' => 'x', + 'A2' => 'y', + 'A3' => 'z', + ], + ], + [ + [ + 'C1' => 'x', + 'A1:A3' => 'x', + 'A1:A3,C1:C3' => 'y', + ], + [ + 'C1' => 'x', + 'A1:A3' => 'x', + 'A1:A3,C1:C3' => 'y', + ], + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/CellRangeBoundaries.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/CellRangeBoundaries.php new file mode 100644 index 0000000..9e856ce --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/CellRangeBoundaries.php @@ -0,0 +1,30 @@ +Link";"Column C" \ No newline at end of file diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/csv_without_extension b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/csv_without_extension new file mode 100644 index 0000000..378dc51 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/csv_without_extension @@ -0,0 +1,3 @@ +This;Are;Headers +Cell A2;Number with comma;25,5 +Two colons and a comma;B|3;:,: diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/empty.csv b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/empty.csv new file mode 100644 index 0000000..e69de29 diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/enclosure.csv b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/enclosure.csv new file mode 100644 index 0000000..a768c63 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/enclosure.csv @@ -0,0 +1,4 @@ +"Date/Time","task","username" +"12/17/2017 14:35","viewpage","username1", +"12/17/2017 04:00","editpage","username5", +"11/29/2017 08:20","deletepage","username2",, diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/semicolon_separated.csv b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/semicolon_separated.csv new file mode 100644 index 0000000..378dc51 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/CSV/semicolon_separated.csv @@ -0,0 +1,3 @@ +This;Are;Headers +Cell A2;Number with comma;25,5 +Two colons and a comma;B|3;:,: diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/HTML/csv_with_angle_bracket.csv b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/HTML/csv_with_angle_bracket.csv new file mode 100644 index 0000000..6e1b0ab --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/HTML/csv_with_angle_bracket.csv @@ -0,0 +1 @@ +Collection Name,Number of items with weight <= 50kg diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Ods/data.ods b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Ods/data.ods new file mode 100644 index 0000000..3171eb6 Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Ods/data.ods differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/XLSX/without_cell_reference.xlsx b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/XLSX/without_cell_reference.xlsx new file mode 100644 index 0000000..99e5f1d Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/XLSX/without_cell_reference.xlsx differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/WithoutStyle.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/WithoutStyle.xml new file mode 100644 index 0000000..b8698b0 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/WithoutStyle.xml @@ -0,0 +1,47 @@ + + + + + + 3 + #000000 + + + + + 9000 + 13860 + 240 + 75 + False + False + + + + + + + + + + + + Test String 1 + + + Test for a simple colour-formatted string + + + + + 1 + + +
+ +
+
diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidSimpleXML.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidSimpleXML.xml new file mode 100644 index 0000000..9a382a7 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidSimpleXML.xml @@ -0,0 +1,8 @@ + + + R&d + R + R>d + R'd + R"d + diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16.xml new file mode 100644 index 0000000..c16bcc9 Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16.xml differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16BE.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16BE.xml new file mode 100644 index 0000000..3d04aa7 Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16BE.xml differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16LE.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16LE.xml new file mode 100644 index 0000000..63ee8c2 Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-16LE.xml differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-8.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-8.xml new file mode 100644 index 0000000..212003f --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestInvalidUTF-8.xml @@ -0,0 +1,8 @@ + + +]> + + + test: (&x0;) + \ No newline at end of file diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16.xml new file mode 100644 index 0000000..2283752 Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16.xml differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16BE.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16BE.xml new file mode 100644 index 0000000..00e7f18 Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16BE.xml differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16LE.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16LE.xml new file mode 100644 index 0000000..50eacb8 Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-16LE.xml differ diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-8.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-8.xml new file mode 100644 index 0000000..c400ae8 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Reader/Xml/XEETestValidUTF-8.xml @@ -0,0 +1,4 @@ + + + test: Valid + \ No newline at end of file diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Shared/CentimeterSizeToPixels.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Shared/CentimeterSizeToPixels.php new file mode 100644 index 0000000..6ef11d9 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Shared/CentimeterSizeToPixels.php @@ -0,0 +1,24 @@ + 19-Dec-1960 05:00:00 UTC + [ + -285102000, + 22269, + 'America/New_York', + ], + // 01-Jan-1970 00:00:00 EST => 01-Jan-1970 05:00:00 UTC PHP Base Date + [ + 18000, + 25569, + 'America/New_York', + ], + // 07-Dec-1982 00:00:00 EST => 07-Dec-1982 05:00:00 UTC + [ + 408085200, + 30292, + 'America/New_York', + ], + // 12-Jun-2008 00:00:00 EDT => 12-Jun-2008 04:00:00 UTC + [ + 1213243200, + 39611, + 'America/New_York', + ], + // 19-Jan-2038 00:00:00 EST => 19-Jan-2038 05:00:00 UTC PHP 32-bit Latest Date + [ + 2147490000, + 50424, + 'America/New_York', + ], + // 05-Mar-1961 13:37:46 EST => 05-Mar-1961 18:37:46 UTC + [ + -278486534, + 22345.56789, + 'America/New_York', + ], + // 05-Mar-1961 16:17:37 EST => 05-Mar-1961 21:17:37 UTC + [ + -278476943, + 22345.6789, + 'America/New_York', + ], + // 12:00:00 EST => 17:00:00 UTC + [ + 61200, + 0.5, + 'America/New_York', + ], + // 18:00.00 EST => 23:00:00 UTC + [ + 82800, + 0.75, + 'America/New_York', + ], + // 02:57:46 EST => 07:57:46 UTC + [ + 28666, + 0.12345, + 'America/New_York', + ], + // 02-Nov-2012 00:00:00 EDT => 02-Nov-2012 04:00:00 UTC + [ + 1351828800, + 41215, + 'America/New_York', + ], + // 19-Dec-1960 00:00:00 NZST => 18-Dec-1960 12:00:00 UTC + [ + -285163200, + 22269, + 'Pacific/Auckland', + ], + // 01-Jan-1970 00:00:00 NZST => 31-Dec-1969 12:00:00 UTC PHP Base Date + [ + -43200, + 25569, + 'Pacific/Auckland', + ], + // 07-Dec-1982 00:00:00 NZDT => 06-Dec-1982 11:00:00 UTC + [ + 408020400, + 30292, + 'Pacific/Auckland', + ], + // 12-Jun-2008 00:00:00 NZST => 11-Jun-2008 12:00:00 UTC + [ + 1213185600, + 39611, + 'Pacific/Auckland', + ], + // 18-Jan-2038 12:00:00 NZDT => 17-Jan-2038 23:00:00 UTC PHP 32-bit Latest Date + [ + 2147382000, + 50423.5, + 'Pacific/Auckland', + ], + // 05-Mar-1961 13:37:46 NZST => 05-Mar-1961 01:37:46 UTC + [ + -278547734, + 22345.56789, + 'Pacific/Auckland', + ], + // 05-Mar-1961 16:17:37 NZST => 05-Mar-1961 04:17:37 UTC + [ + -278538143, + 22345.6789, + 'Pacific/Auckland', + ], + // 12:00:00 NZST => 00:00:00 UTC + [ + 0, + 0.5, + 'Pacific/Auckland', + ], + // 18:00.00 NZST => 06:00:00 UTC + [ + 21600, + 0.75, + 'Pacific/Auckland', + ], + // 02:57:46 NZST => 14:57:46 UTC + [ + -32534, + 0.12345, + 'Pacific/Auckland', + ], + // 02-Nov-2012 00:00:00 NZDT => 01-Nov-2012 11:00:00 UTC + [ + 1351767600, + 41215, + 'Pacific/Auckland', + ], +]; diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Shared/Date/ExcelToTimestamp1904.php b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Shared/Date/ExcelToTimestamp1904.php new file mode 100644 index 0000000..e0f3075 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Shared/Date/ExcelToTimestamp1904.php @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Writer/Ods/content-with-data.xml b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Writer/Ods/content-with-data.xml new file mode 100644 index 0000000..4818438 --- /dev/null +++ b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Writer/Ods/content-with-data.xml @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 1 + + + 12345.6789 + + + 1 + + + 01234 + + + Lorem ipsum + + + + + + 1 + + + + + + 1 1 + + + 42798.572060185 + + + + + + + + + + + 2 + + + + + + + + \ No newline at end of file diff --git a/inc/vendor/phpoffice/phpspreadsheet/tests/data/Writer/XLSX/form_pass_print.xlsm b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Writer/XLSX/form_pass_print.xlsm new file mode 100644 index 0000000..9a593a9 Binary files /dev/null and b/inc/vendor/phpoffice/phpspreadsheet/tests/data/Writer/XLSX/form_pass_print.xlsm differ diff --git a/reference/stigs/.gitignore b/reference/stigs/.gitignore new file mode 100644 index 0000000..2dd3889 --- /dev/null +++ b/reference/stigs/.gitignore @@ -0,0 +1,2 @@ +/*.xml +/*.csv \ No newline at end of file