From 2cced1cbb487761e9177605eb32c67f74bc00634 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 2 Sep 2021 15:44:40 -0500 Subject: [PATCH 1/8] feat: prepare for PHP 8.1 support - Adds 8.1 to list of PHP constraints - Modifies how package replaces zend-mime: - Changes "replace" section to "conflict", and changes zend-mime constraint in that section to "*" - Removes laminas-zendframework-bridge as requirement - Bumps laminas-coding-standard to 2.2 series Signed-off-by: Matthew Weier O'Phinney --- composer.json | 11 +- composer.lock | 1456 ++++++++++++++++++++++++++++++++++-------------- phpcs.xml | 8 - phpcs.xml.dist | 21 + 4 files changed, 1067 insertions(+), 429 deletions(-) delete mode 100644 phpcs.xml create mode 100644 phpcs.xml.dist diff --git a/composer.json b/composer.json index 310b5bca..4826db64 100644 --- a/composer.json +++ b/composer.json @@ -19,12 +19,11 @@ "sort-packages": true }, "require": { - "php": "^7.3 || ~8.0.0", - "laminas/laminas-stdlib": "^2.7 || ^3.0", - "laminas/laminas-zendframework-bridge": "^1.0" + "php": "^7.3 || ~8.0.0 || ~8.1.0", + "laminas/laminas-stdlib": "^2.7 || ^3.0" }, "require-dev": { - "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-coding-standard": "~2.2.1", "laminas/laminas-mail": "^2.6", "phpunit/phpunit": "^9.3" }, @@ -51,7 +50,7 @@ "test": "phpunit --colors=always", "test-coverage": "phpunit --colors=always --coverage-clover clover.xml" }, - "replace": { - "zendframework/zend-mime": "^2.7.2" + "conflict": { + "zendframework/zend-mime": "*" } } diff --git a/composer.lock b/composer.lock index bf9069d7..bc3f6897 100644 --- a/composer.lock +++ b/composer.lock @@ -4,33 +4,34 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "bd9df1e2e68c12fb4ef0af0121222752", + "content-hash": "1828c98cd3463d06400585e13392c0dd", "packages": [ { "name": "laminas/laminas-stdlib", - "version": "3.3.1", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-stdlib.git", - "reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe" + "reference": "c53d8537f108fac3fae652677a19735db730ba46" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/d81c7ffe602ed0e6ecb18691019111c0f4bf1efe", - "reference": "d81c7ffe602ed0e6ecb18691019111c0f4bf1efe", + "url": "https://api.github.com/repos/laminas/laminas-stdlib/zipball/c53d8537f108fac3fae652677a19735db730ba46", + "reference": "c53d8537f108fac3fae652677a19735db730ba46", "shasum": "" }, "require": { - "laminas/laminas-zendframework-bridge": "^1.0", - "php": "^7.3 || ^8.0" + "php": "^7.3 || ~8.0.0 || ~8.1.0" }, - "replace": { - "zendframework/zend-stdlib": "^3.2.1" + "conflict": { + "zendframework/zend-stdlib": "*" }, "require-dev": { - "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-coding-standard": "~2.3.0", "phpbench/phpbench": "^0.17.1", - "phpunit/phpunit": "~9.3.7" + "phpunit/phpunit": "~9.3.7", + "psalm/plugin-phpunit": "^0.16.0", + "vimeo/psalm": "^4.7" }, "type": "library", "autoload": { @@ -62,105 +63,115 @@ "type": "community_bridge" } ], - "time": "2020-11-19T20:18:59+00:00" - }, + "time": "2021-09-02T16:11:32+00:00" + } + ], + "packages-dev": [ { - "name": "laminas/laminas-zendframework-bridge", - "version": "1.1.1", + "name": "container-interop/container-interop", + "version": "1.2.0", "source": { "type": "git", - "url": "https://github.com/laminas/laminas-zendframework-bridge.git", - "reference": "6ede70583e101030bcace4dcddd648f760ddf642" + "url": "https://github.com/container-interop/container-interop.git", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/6ede70583e101030bcace4dcddd648f760ddf642", - "reference": "6ede70583e101030bcace4dcddd648f760ddf642", + "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", - "squizlabs/php_codesniffer": "^3.5" + "psr/container": "^1.0" }, "type": "library", - "extra": { - "laminas": { - "module": "Laminas\\ZendFrameworkBridge" - } - }, "autoload": { - "files": [ - "src/autoload.php" - ], "psr-4": { - "Laminas\\ZendFrameworkBridge\\": "src//" + "Interop\\Container\\": "src/Interop/Container/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" - ], - "description": "Alias legacy ZF class names to Laminas Project equivalents.", - "keywords": [ - "ZendFramework", - "autoloading", - "laminas", - "zf" + "MIT" ], + "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", + "homepage": "https://github.com/container-interop/container-interop", "support": { - "forum": "https://discourse.laminas.dev/", - "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues", - "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom", - "source": "https://github.com/laminas/laminas-zendframework-bridge" + "issues": "https://github.com/container-interop/container-interop/issues", + "source": "https://github.com/container-interop/container-interop/tree/master" }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2020-09-14T14:23:00+00:00" - } - ], - "packages-dev": [ + "abandoned": "psr/container", + "time": "2017-02-14T19:40:03+00:00" + }, { - "name": "container-interop/container-interop", - "version": "1.2.0", + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.7.1", "source": { "type": "git", - "url": "https://github.com/container-interop/container-interop.git", - "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8" + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "fe390591e0241955f22eb9ba327d137e501c771c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8", - "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", + "reference": "fe390591e0241955f22eb9ba327d137e501c771c", "shasum": "" }, "require": { - "psr/container": "^1.0" + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" + }, + "require-dev": { + "composer/composer": "*", + "phpcompatibility/php-compatibility": "^9.0", + "sensiolabs/security-checker": "^4.1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, - "type": "library", "autoload": { "psr-4": { - "Interop\\Container\\": "src/Interop/Container/" + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Promoting the interoperability of container objects (DIC, SL, etc.)", - "homepage": "https://github.com/container-interop/container-interop", + "authors": [ + { + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" + } + ], + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", + "keywords": [ + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], "support": { - "issues": "https://github.com/container-interop/container-interop/issues", - "source": "https://github.com/container-interop/container-interop/tree/master" + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" }, - "abandoned": "psr/container", - "time": "2017-02-14T19:40:03+00:00" + "time": "2020-12-07T18:04:37+00:00" }, { "name": "doctrine/instantiator", @@ -233,31 +244,36 @@ }, { "name": "laminas/laminas-coding-standard", - "version": "1.0.0", + "version": "2.2.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-coding-standard.git", - "reference": "08880ce2fbfe62d471cd3cb766a91da630b32539" + "reference": "c953ecb1d37034f4aa326046e2c24a10fe0a2845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/08880ce2fbfe62d471cd3cb766a91da630b32539", - "reference": "08880ce2fbfe62d471cd3cb766a91da630b32539", + "url": "https://api.github.com/repos/laminas/laminas-coding-standard/zipball/c953ecb1d37034f4aa326046e2c24a10fe0a2845", + "reference": "c953ecb1d37034f4aa326046e2c24a10fe0a2845", "shasum": "" }, "require": { - "laminas/laminas-zendframework-bridge": "^1.0", - "squizlabs/php_codesniffer": "^2.7" + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "php": "^7.3 || ~8.0.0", + "slevomat/coding-standard": "^6.4.1", + "squizlabs/php_codesniffer": "^3.5.8", + "webimpress/coding-standard": "^1.1.6" }, - "replace": { - "zendframework/zend-coding-standard": "self.version" + "type": "phpcodesniffer-standard", + "autoload": { + "psr-4": { + "LaminasCodingStandard\\": "src/LaminasCodingStandard/" + } }, - "type": "library", "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], - "description": "Laminas coding standard", + "description": "Laminas Coding Standard", "homepage": "https://laminas.dev", "keywords": [ "Coding Standard", @@ -271,31 +287,36 @@ "rss": "https://github.com/laminas/laminas-coding-standard/releases.atom", "source": "https://github.com/laminas/laminas-coding-standard" }, - "time": "2019-12-31T16:28:26+00:00" + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2021-05-17T17:39:41+00:00" }, { "name": "laminas/laminas-loader", - "version": "2.7.0", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/laminas/laminas-loader.git", - "reference": "bcf8a566cb9925a2e7cc41a16db09235ec9fb616" + "reference": "d0589ec9dd48365fd95ad10d1c906efd7711c16b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/bcf8a566cb9925a2e7cc41a16db09235ec9fb616", - "reference": "bcf8a566cb9925a2e7cc41a16db09235ec9fb616", + "url": "https://api.github.com/repos/laminas/laminas-loader/zipball/d0589ec9dd48365fd95ad10d1c906efd7711c16b", + "reference": "d0589ec9dd48365fd95ad10d1c906efd7711c16b", "shasum": "" }, "require": { - "laminas/laminas-zendframework-bridge": "^1.0", - "php": "^7.3 || ~8.0.0" + "php": "^7.3 || ~8.0.0 || ~8.1.0" }, - "replace": { - "zendframework/zend-loader": "^2.6.1" + "conflict": { + "zendframework/zend-loader": "*" }, "require-dev": { - "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-coding-standard": "~2.2.1", "phpunit/phpunit": "^9.3" }, "type": "library", @@ -328,20 +349,20 @@ "type": "community_bridge" } ], - "time": "2021-02-12T16:08:18+00:00" + "time": "2021-09-02T18:30:53+00:00" }, { "name": "laminas/laminas-mail", - "version": "2.13.1", + "version": "2.14.1", "source": { "type": "git", "url": "https://github.com/laminas/laminas-mail.git", - "reference": "6f6fb7c6f332abea25461eefb3da15e104edfd56" + "reference": "180c6c7baa37cba16fe9fd34af0f346e796cf1a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-mail/zipball/6f6fb7c6f332abea25461eefb3da15e104edfd56", - "reference": "6f6fb7c6f332abea25461eefb3da15e104edfd56", + "url": "https://api.github.com/repos/laminas/laminas-mail/zipball/180c6c7baa37cba16fe9fd34af0f346e796cf1a1", + "reference": "180c6c7baa37cba16fe9fd34af0f346e796cf1a1", "shasum": "" }, "require": { @@ -363,7 +384,9 @@ "laminas/laminas-config": "^3.4", "laminas/laminas-crypt": "^2.6 || ^3.0", "laminas/laminas-servicemanager": "^3.2.1", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.3", + "psalm/plugin-phpunit": "^0.15.1", + "vimeo/psalm": "^4.7" }, "suggest": { "laminas/laminas-crypt": "Crammd5 support in SMTP Auth", @@ -405,20 +428,20 @@ "type": "community_bridge" } ], - "time": "2021-02-12T17:56:28+00:00" + "time": "2021-05-20T04:00:23+00:00" }, { "name": "laminas/laminas-validator", - "version": "2.14.4", + "version": "2.14.5", "source": { "type": "git", "url": "https://github.com/laminas/laminas-validator.git", - "reference": "e370c4695db1c81e6dfad38d8c4dbdb37b23d776" + "reference": "4680bc4241cb5b3ff78954c421fe43105ca413b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/e370c4695db1c81e6dfad38d8c4dbdb37b23d776", - "reference": "e370c4695db1c81e6dfad38d8c4dbdb37b23d776", + "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/4680bc4241cb5b3ff78954c421fe43105ca413b7", + "reference": "4680bc4241cb5b3ff78954c421fe43105ca413b7", "shasum": "" }, "require": { @@ -432,7 +455,7 @@ }, "require-dev": { "laminas/laminas-cache": "^2.6.1", - "laminas/laminas-coding-standard": "~1.0.0", + "laminas/laminas-coding-standard": "~2.2.1", "laminas/laminas-config": "^2.6", "laminas/laminas-db": "^2.7", "laminas/laminas-filter": "^2.6", @@ -497,7 +520,69 @@ "type": "community_bridge" } ], - "time": "2021-01-24T20:45:49+00:00" + "time": "2021-07-14T13:59:23+00:00" + }, + { + "name": "laminas/laminas-zendframework-bridge", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/laminas/laminas-zendframework-bridge.git", + "reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/laminas/laminas-zendframework-bridge/zipball/13af2502d9bb6f7d33be2de4b51fb68c6cdb476e", + "reference": "13af2502d9bb6f7d33be2de4b51fb68c6cdb476e", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^5.7 || ^6.5 || ^7.5 || ^8.1 || ^9.3", + "psalm/plugin-phpunit": "^0.15.1", + "squizlabs/php_codesniffer": "^3.5", + "vimeo/psalm": "^4.6" + }, + "type": "library", + "extra": { + "laminas": { + "module": "Laminas\\ZendFrameworkBridge" + } + }, + "autoload": { + "files": [ + "src/autoload.php" + ], + "psr-4": { + "Laminas\\ZendFrameworkBridge\\": "src//" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "Alias legacy ZF class names to Laminas Project equivalents.", + "keywords": [ + "ZendFramework", + "autoloading", + "laminas", + "zf" + ], + "support": { + "forum": "https://discourse.laminas.dev/", + "issues": "https://github.com/laminas/laminas-zendframework-bridge/issues", + "rss": "https://github.com/laminas/laminas-zendframework-bridge/releases.atom", + "source": "https://github.com/laminas/laminas-zendframework-bridge" + }, + "funding": [ + { + "url": "https://funding.communitybridge.org/projects/laminas-project", + "type": "community_bridge" + } + ], + "time": "2021-06-24T12:49:22+00:00" }, { "name": "myclabs/deep-copy", @@ -557,30 +642,87 @@ ], "time": "2020-11-13T09:40:50+00:00" }, + { + "name": "nikic/php-parser", + "version": "v4.12.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "6608f01670c3cc5079e18c1dab1104e002579143" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/6608f01670c3cc5079e18c1dab1104e002579143", + "reference": "6608f01670c3cc5079e18c1dab1104e002579143", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.12.0" + }, + "time": "2021-07-21T10:44:31+00:00" + }, { "name": "phar-io/manifest", - "version": "1.0.3", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4" + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", - "reference": "7761fcacf03b4d4f16e7ccb606d4879ca431fcf4", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", "shasum": "" }, "require": { "ext-dom": "*", "ext-phar": "*", - "phar-io/version": "^2.0", - "php": "^5.6 || ^7.0" + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -612,26 +754,26 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/master" + "source": "https://github.com/phar-io/manifest/tree/2.0.3" }, - "time": "2018-07-08T19:23:20+00:00" + "time": "2021-07-20T11:28:43+00:00" }, { "name": "phar-io/version", - "version": "2.0.1", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6" + "reference": "bae7c545bef187884426f042434e561ab1ddb182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/45a2ec53a73c70ce41d55cedef9063630abaf1b6", - "reference": "45a2ec53a73c70ce41d55cedef9063630abaf1b6", + "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", + "reference": "bae7c545bef187884426f042434e561ab1ddb182", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { @@ -663,9 +805,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/master" + "source": "https://github.com/phar-io/version/tree/3.1.0" }, - "time": "2018-07-08T19:19:57+00:00" + "time": "2021-02-23T14:00:09+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -827,16 +969,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.12.2", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "245710e971a030f42e08f4912863805570f23d39" + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", - "reference": "245710e971a030f42e08f4912863805570f23d39", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be1996ed8adc35c3fd795488a653f4b518be70ea", + "reference": "be1996ed8adc35c3fd795488a653f4b518be70ea", "shasum": "" }, "require": { @@ -888,46 +1030,103 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.12.2" + "source": "https://github.com/phpspec/prophecy/tree/1.13.0" }, - "time": "2020-12-19T10:15:11+00:00" + "time": "2021-03-17T13:42:18+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "0.4.9", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "98a088b17966bdf6ee25c8a4b634df313d8aa531" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/98a088b17966bdf6ee25c8a4b634df313d8aa531", + "reference": "98a088b17966bdf6ee25c8a4b634df313d8aa531", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "consistence/coding-standard": "^3.5", + "ergebnis/composer-normalize": "^2.0.2", + "jakub-onderka/php-parallel-lint": "^0.9.2", + "phing/phing": "^2.16.0", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^0.12.26", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^6.3", + "slevomat/coding-standard": "^4.7.2", + "symfony/process": "^4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.4-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/master" + }, + "time": "2020-08-03T20:32:43+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "6.1.4", + "version": "9.2.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d" + "reference": "f6293e1b30a2354e8428e004689671b83871edde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", - "reference": "807e6013b00af69b6c5d9ceb4282d0393dbb9d8d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f6293e1b30a2354e8428e004689671b83871edde", + "reference": "f6293e1b30a2354e8428e004689671b83871edde", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "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 || ^4.0", - "sebastian/version": "^2.0.1", - "theseer/tokenizer": "^1.1" + "nikic/php-parser": "^4.10.2", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0.3", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-xdebug": "^2.6.0" + "ext-pcov": "*", + "ext-xdebug": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "6.1-dev" + "dev-master": "9.2-dev" } }, "autoload": { @@ -955,34 +1154,40 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/master" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.6" }, - "time": "2018-10-31T16:06:48+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-03-28T07:26:59+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "2.0.3", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357" + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/4b49fb70f067272b659ef0174ff9ca40fdaa6357", - "reference": "4b49fb70f067272b659ef0174ff9ca40fdaa6357", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", + "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1009,7 +1214,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.3" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" }, "funding": [ { @@ -1017,26 +1222,38 @@ "type": "github" } ], - "time": "2020-11-30T08:25:21+00:00" + "time": "2020-09-28T05:57:25+00:00" }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", + "name": "phpunit/php-invoker", + "version": "3.1.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.3" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -1053,41 +1270,47 @@ "role": "lead" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ - "template" + "process" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" }, - "time": "2015-06-21T13:50:34+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" }, { - "name": "phpunit/php-timer", - "version": "2.1.3", + "name": "phpunit/php-text-template", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/2454ae1765516d20c4ffe103d85a58a9a3bd5662", - "reference": "2454ae1765516d20c4ffe103d85a58a9a3bd5662", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1106,14 +1329,14 @@ "role": "lead" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "timer" + "template" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.3" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" }, "funding": [ { @@ -1121,33 +1344,32 @@ "type": "github" } ], - "time": "2020-11-30T08:20:02+00:00" + "time": "2020-10-26T05:33:50+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "3.1.2", + "name": "phpunit/php-timer", + "version": "5.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "472b687829041c24b25f475e14c2f38a09edf1c2" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/472b687829041c24b25f475e14c2f38a09edf1c2", - "reference": "472b687829041c24b25f475e14c2f38a09edf1c2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1162,17 +1384,18 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Wrapper around PHP's tokenizer extension.", - "homepage": "https://github.com/sebastianbergmann/php-token-stream/", + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ - "tokenizer" + "timer" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", - "source": "https://github.com/sebastianbergmann/php-token-stream/tree/3.1.2" + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" }, "funding": [ { @@ -1180,58 +1403,59 @@ "type": "github" } ], - "abandoned": true, - "time": "2020-11-30T08:38:46+00:00" + "time": "2020-10-26T13:16:10+00:00" }, { "name": "phpunit/phpunit", - "version": "7.5.20", + "version": "9.5.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c" + "reference": "ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/9467db479d1b0487c99733bb1e7944d32deded2c", - "reference": "9467db479d1b0487c99733bb1e7944d32deded2c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b", + "reference": "ea8c2dfb1065eb35a79b3681eee6e6fb0a6f273b", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.1", + "doctrine/instantiator": "^1.3.1", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "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": "^6.0.7", - "phpunit/php-file-iterator": "^2.0.1", - "phpunit/php-text-template": "^1.2.1", - "phpunit/php-timer": "^2.1", - "sebastian/comparator": "^3.0", - "sebastian/diff": "^3.0", - "sebastian/environment": "^4.0", - "sebastian/exporter": "^3.1", - "sebastian/global-state": "^2.0", - "sebastian/object-enumerator": "^3.0.3", - "sebastian/resource-operations": "^2.0", - "sebastian/version": "^2.0.1" - }, - "conflict": { - "phpunit/phpunit-mock-objects": "*" + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=7.3", + "phpspec/prophecy": "^1.12.1", + "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.3", + "phpunit/php-timer": "^5.0.2", + "sebastian/cli-parser": "^1.0.1", + "sebastian/code-unit": "^1.0.6", + "sebastian/comparator": "^4.0.5", + "sebastian/diff": "^4.0.3", + "sebastian/environment": "^5.1.3", + "sebastian/exporter": "^4.0.3", + "sebastian/global-state": "^5.0.1", + "sebastian/object-enumerator": "^4.0.3", + "sebastian/resource-operations": "^3.0.3", + "sebastian/type": "^2.3.4", + "sebastian/version": "^3.0.2" }, "require-dev": { - "ext-pdo": "*" + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" }, "suggest": { "ext-soap": "*", - "ext-xdebug": "*", - "phpunit/php-invoker": "^2.0" + "ext-xdebug": "*" }, "bin": [ "phpunit" @@ -1239,12 +1463,15 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "7.5-dev" + "dev-master": "9.5-dev" } }, "autoload": { "classmap": [ "src/" + ], + "files": [ + "src/Framework/Assert/Functions.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1267,33 +1494,38 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/7.5.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.9" }, - "time": "2020-01-08T08:45:45+00:00" + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-08-31T06:47:40+00:00" }, { "name": "psr/container", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", + "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.2.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -1306,7 +1538,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common Container Interface (PHP FIG PSR-11)", @@ -1318,36 +1550,148 @@ "container-interop", "psr" ], - "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/master" - }, - "time": "2017-02-14T16:28:37+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.1" + }, + "time": "2021-03-05T17:36:06+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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 for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:08:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/1de8cd5c010cb153fcd68b8d0f64606f523f7619", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1369,7 +1713,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.2" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" }, "funding": [ { @@ -1377,34 +1721,34 @@ "type": "github" } ], - "time": "2020-11-30T08:15:22+00:00" + "time": "2020-09-28T05:30:19+00:00" }, { "name": "sebastian/comparator", - "version": "3.0.3", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758" + "reference": "55f4261989e546dc112258c7a75935a81a7ce382" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1071dfcef776a57013124ff35e1fc41ccd294758", - "reference": "1071dfcef776a57013124ff35e1fc41ccd294758", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", + "reference": "55f4261989e546dc112258c7a75935a81a7ce382", "shasum": "" }, "require": { - "php": ">=7.1", - "sebastian/diff": "^3.0", - "sebastian/exporter": "^3.1" + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1443,7 +1787,64 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T15:49:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", + "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "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": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" }, "funding": [ { @@ -1451,33 +1852,33 @@ "type": "github" } ], - "time": "2020-11-30T08:04:30+00:00" + "time": "2020-10-26T15:52:27+00:00" }, { "name": "sebastian/diff", - "version": "3.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211" + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/14f72dd46eaf2f2293cbe79c93cc0bc43161a211", - "reference": "14f72dd46eaf2f2293cbe79c93cc0bc43161a211", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.5 || ^8.0", - "symfony/process": "^2 || ^3.3 || ^4" + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1509,7 +1910,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" }, "funding": [ { @@ -1517,27 +1918,27 @@ "type": "github" } ], - "time": "2020-11-30T07:59:04+00:00" + "time": "2020-10-26T13:10:38+00:00" }, { "name": "sebastian/environment", - "version": "4.2.4", + "version": "5.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0" + "reference": "388b6ced16caa751030f6a69e588299fa09200ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", - "reference": "d47bbbad83711771f167c72d4e3f25f7fcc1f8b0", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", + "reference": "388b6ced16caa751030f6a69e588299fa09200ac", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^7.5" + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-posix": "*" @@ -1545,7 +1946,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -1572,7 +1973,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/4.2.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" }, "funding": [ { @@ -1580,34 +1981,34 @@ "type": "github" } ], - "time": "2020-11-30T07:53:42+00:00" + "time": "2020-09-28T05:52:38+00:00" }, { "name": "sebastian/exporter", - "version": "3.1.3", + "version": "4.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e" + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/6b853149eab67d4da22291d36f5b0631c0fd856e", - "reference": "6b853149eab67d4da22291d36f5b0631c0fd856e", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", "shasum": "" }, "require": { - "php": ">=7.0", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1649,7 +2050,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.3" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.3" }, "funding": [ { @@ -1657,27 +2058,30 @@ "type": "github" } ], - "time": "2020-11-30T07:47:53+00:00" + "time": "2020-09-28T05:24:23+00:00" }, { "name": "sebastian/global-state", - "version": "2.0.0", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4" + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", - "reference": "e8ba02eed7bbbb9e59e43dedd3dddeff4a56b0c4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", "shasum": "" }, "require": { - "php": "^7.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "ext-dom": "*", + "phpunit/phpunit": "^9.3" }, "suggest": { "ext-uopz": "*" @@ -1685,7 +2089,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -1710,36 +2114,99 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" }, - "time": "2017-04-27T15:39:26+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-06-11T13:31:12+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.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 for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-11-28T06:42:11+00:00" }, { "name": "sebastian/object-enumerator", - "version": "3.0.4", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2" + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", - "reference": "e67f6d32ebd0c749cf9d1dbd9f226c727043cdf2", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", "shasum": "" }, "require": { - "php": ">=7.0", - "sebastian/object-reflector": "^1.1.1", - "sebastian/recursion-context": "^3.0" + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1761,7 +2228,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.4" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" }, "funding": [ { @@ -1769,32 +2236,32 @@ "type": "github" } ], - "time": "2020-11-30T07:40:27+00:00" + "time": "2020-10-26T13:12:34+00:00" }, { "name": "sebastian/object-reflector", - "version": "1.1.2", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d" + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", - "reference": "9b8772b9cbd456ab45d4a598d2dd1a1bced6363d", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", "shasum": "" }, "require": { - "php": ">=7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1816,7 +2283,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.2" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" }, "funding": [ { @@ -1824,32 +2291,32 @@ "type": "github" } ], - "time": "2020-11-30T07:37:18+00:00" + "time": "2020-10-26T13:14:26+00:00" }, { "name": "sebastian/recursion-context", - "version": "3.0.1", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb" + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/367dcba38d6e1977be014dc4b22f47a484dac7fb", - "reference": "367dcba38d6e1977be014dc4b22f47a484dac7fb", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", + "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", "shasum": "" }, "require": { - "php": ">=7.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^6.0" + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0.x-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1879,7 +2346,7 @@ "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" }, "funding": [ { @@ -1887,29 +2354,32 @@ "type": "github" } ], - "time": "2020-11-30T07:34:24+00:00" + "time": "2020-10-26T13:17:30+00:00" }, { "name": "sebastian/resource-operations", - "version": "2.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3" + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/31d35ca87926450c44eae7e2611d45a7a65ea8b3", - "reference": "31d35ca87926450c44eae7e2611d45a7a65ea8b3", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1931,7 +2401,63 @@ "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:45:17+00:00" + }, + { + "name": "sebastian/type", + "version": "2.3.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-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": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" }, "funding": [ { @@ -1939,29 +2465,29 @@ "type": "github" } ], - "time": "2020-11-30T07:30:19+00:00" + "time": "2021-06-15T12:49:02+00:00" }, { "name": "sebastian/version", - "version": "2.0.1", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "reference": "c6c1022351a901512170118436c764e473f6de8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1984,70 +2510,110 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/master" + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "slevomat/coding-standard", + "version": "6.4.1", + "source": { + "type": "git", + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "696dcca217d0c9da2c40d02731526c1e25b65346" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/696dcca217d0c9da2c40d02731526c1e25b65346", + "reference": "696dcca217d0c9da2c40d02731526c1e25b65346", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "php": "^7.1 || ^8.0", + "phpstan/phpdoc-parser": "0.4.5 - 0.4.9", + "squizlabs/php_codesniffer": "^3.5.6" + }, + "require-dev": { + "phing/phing": "2.16.3", + "php-parallel-lint/php-parallel-lint": "1.2.0", + "phpstan/phpstan": "0.12.48", + "phpstan/phpstan-deprecation-rules": "0.12.5", + "phpstan/phpstan-phpunit": "0.12.16", + "phpstan/phpstan-strict-rules": "0.12.5", + "phpunit/phpunit": "7.5.20|8.5.5|9.4.0" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-master": "6.x-dev" + } + }, + "autoload": { + "psr-4": { + "SlevomatCodingStandard\\": "SlevomatCodingStandard" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/6.4.1" }, - "time": "2016-10-03T07:35:21+00:00" + "funding": [ + { + "url": "https://github.com/kukulich", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", + "type": "tidelift" + } + ], + "time": "2020-10-05T12:39:37+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "2.9.2", + "version": "3.6.0", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "2acf168de78487db620ab4bc524135a13cfe6745" + "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/2acf168de78487db620ab4bc524135a13cfe6745", - "reference": "2acf168de78487db620ab4bc524135a13cfe6745", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ffced0d2c8fa8e6cdc4d695a743271fab6c38625", + "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625", "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" @@ -2059,7 +2625,7 @@ } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", "standards" @@ -2069,20 +2635,20 @@ "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "time": "2018-11-07T22:31:41+00:00" + "time": "2021-04-09T00:54:41+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.1", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { @@ -2094,7 +2660,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2132,7 +2698,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" }, "funding": [ { @@ -2148,20 +2714,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.22.1", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", - "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "shasum": "" }, "require": { @@ -2173,7 +2739,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2212,7 +2778,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.22.1" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" }, "funding": [ { @@ -2228,20 +2794,20 @@ "type": "tidelift" } ], - "time": "2021-01-22T09:19:47+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { @@ -2270,7 +2836,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/master" + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" }, "funding": [ { @@ -2278,7 +2844,7 @@ "type": "github" } ], - "time": "2020-07-12T23:59:07+00:00" + "time": "2021-07-28T10:34:58+00:00" }, { "name": "true/punycode", @@ -2330,32 +2896,92 @@ }, "time": "2016-11-16T10:37:54+00:00" }, + { + "name": "webimpress/coding-standard", + "version": "1.2.2", + "source": { + "type": "git", + "url": "https://github.com/webimpress/coding-standard.git", + "reference": "8f4a220de33f471a8101836f7ec72b852c3f9f03" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webimpress/coding-standard/zipball/8f4a220de33f471a8101836f7ec72b852c3f9f03", + "reference": "8f4a220de33f471a8101836f7ec72b852c3f9f03", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0", + "squizlabs/php_codesniffer": "^3.6" + }, + "require-dev": { + "phpunit/phpunit": "^9.5.4" + }, + "type": "phpcodesniffer-standard", + "extra": { + "dev-master": "1.2.x-dev", + "dev-develop": "1.3.x-dev" + }, + "autoload": { + "psr-4": { + "WebimpressCodingStandard\\": "src/WebimpressCodingStandard/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-2-Clause" + ], + "description": "Webimpress Coding Standard", + "keywords": [ + "Coding Standard", + "PSR-2", + "phpcs", + "psr-12", + "webimpress" + ], + "support": { + "issues": "https://github.com/webimpress/coding-standard/issues", + "source": "https://github.com/webimpress/coding-standard/tree/1.2.2" + }, + "funding": [ + { + "url": "https://github.com/michalbundyra", + "type": "github" + } + ], + "time": "2021-04-12T12:51:27+00:00" + }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -2379,9 +3005,9 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.9.1" + "source": "https://github.com/webmozarts/assert/tree/1.10.0" }, - "time": "2020-07-08T17:02:28+00:00" + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], @@ -2390,7 +3016,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "^5.6 || ^7.0" + "php": "^7.3 || ~8.0.0 || ~8.1.0" }, "platform-dev": [], "plugin-api-version": "2.0.0" diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index c6e76749..00000000 --- a/phpcs.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - src - test - diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 00000000..7f391d80 --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,21 @@ + + + + + + + + + + + + + + src + test + + + + From 7d3b879146cafc571500b622a8113e6badfb7529 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 2 Sep 2021 16:46:14 -0500 Subject: [PATCH 2/8] qa: applies laminas-coding-standard 2.2 rules Also includes removal of file-level docblocks Signed-off-by: Matthew Weier O'Phinney --- .gitignore | 1 + src/Decode.php | 58 ++- src/Exception/ExceptionInterface.php | 6 - src/Exception/InvalidArgumentException.php | 6 - src/Exception/RuntimeException.php | 6 - src/Message.php | 61 +-- src/Mime.php | 475 +++++++++++++++++---- src/Part.php | 96 ++++- test/DecodeTest.php | 6 - test/MessageTest.php | 49 +-- test/MimeTest.php | 160 +++---- test/PartTest.php | 78 ++-- 12 files changed, 697 insertions(+), 305 deletions(-) diff --git a/.gitignore b/.gitignore index a0c8ed86..f6f6e633 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +/.phpcs-cache /.phpunit.result.cache /clover.xml /coveralls-upload.json diff --git a/src/Decode.php b/src/Decode.php index ecb3550a..dc6d0eb5 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -1,16 +1,28 @@ - $name) { $name = strtolower($name); - if ($matches[2][$key][0] == '"') { + if ($matches[2][$key][0] === '"') { $split[$name] = substr($matches[2][$key], 1, -1); } else { $split[$name] = $matches[2][$key]; diff --git a/src/Exception/ExceptionInterface.php b/src/Exception/ExceptionInterface.php index 5217cb08..762e2c00 100644 --- a/src/Exception/ExceptionInterface.php +++ b/src/Exception/ExceptionInterface.php @@ -1,11 +1,5 @@ getParts() as $key => $row) { - if ($part == $row) { + foreach ($this->getParts() as $row) { + if ($part === $row) { throw new Exception\InvalidArgumentException(sprintf( 'Provided part %s already defined.', $part->getId() @@ -65,7 +77,7 @@ public function addPart(Part $part) */ public function isMultiPart() { - return (count($this->parts) > 1); + return count($this->parts) > 1; } /** @@ -74,7 +86,6 @@ public function isMultiPart() * This can be used to set the boundary specifically or to use a subclass of * Laminas\Mime for generating the boundary. * - * @param \Laminas\Mime\Mime $mime * @return self */ public function setMime(Mime $mime) @@ -89,7 +100,7 @@ public function setMime(Mime $mime) * If the object was not present, it is created and returned. Can be used to * determine the boundary used in this message. * - * @return \Laminas\Mime\Mime + * @return Mime */ public function getMime() { @@ -127,7 +138,7 @@ public function generateMessage($EOL = Mime::LINEEND) $mime = $this->getMime(); $boundaryLine = $mime->boundaryLine($EOL); - $body = 'This is a message in Mime Format. If you see this, ' + $body = 'This is a message in Mime Format. If you see this, ' . "your mail reader does not support this format." . $EOL; foreach (array_keys($this->parts) as $p) { @@ -188,16 +199,14 @@ public function getPartContent($partnum, $EOL = Mime::LINEEND) * @throws Exception\RuntimeException * @return array */ - // @codingStandardsIgnoreStart protected static function _disassembleMime($body, $boundary) { - // @codingStandardsIgnoreEnd - $start = 0; - $res = []; + $start = 0; + $res = []; // find every mime part limiter and cut out the // string before it. // the part before the first boundary string is discarded: - $p = strpos($body, '--' . $boundary."\n", $start); + $p = strpos($body, '--' . $boundary . "\n", $start); if ($p === false) { // no parts found! return []; @@ -239,10 +248,12 @@ public static function createFromMessage($message, $boundary = null, $EOL = Mime $parts = Decode::splitMessageStruct($message, $boundary, $EOL); } else { Decode::splitMessage($message, $headers, $body, $EOL); - $parts = [[ - 'header' => $headers, - 'body' => $body, - ]]; + $parts = [ + [ + 'header' => $headers, + 'body' => $body, + ], + ]; } $res = new static(); @@ -250,7 +261,7 @@ public static function createFromMessage($message, $boundary = null, $EOL = Mime // now we build a new MimePart for the current Message Part: $properties = []; foreach ($part['header'] as $header) { - /** @var \Laminas\Mail\Header\HeaderInterface $header */ + /** @var HeaderInterface $header */ /** * @todo check for characterset and filename */ diff --git a/src/Mime.php b/src/Mime.php index 627dfe2d..70f08fa0 100644 --- a/src/Mime.php +++ b/src/Mime.php @@ -1,92 +1,395 @@ [\x21\x23-\x26\x2a\x2b\x2d\x5e\5f\60\x7b-\x7ea-zA-Z0-9]+)\?(?P[\x21\x23-\x26\x2a\x2b\x2d\x5e\5f\60\x7b-\x7ea-zA-Z0-9]+)\?(?P[\x21-\x3e\x40-\x7e]+)#'; - // @codingStandardsIgnoreEnd - + // phpcs:disable Generic.Files.LineLength.TooLong + public const TYPE_OCTETSTREAM = 'application/octet-stream'; + public const TYPE_TEXT = 'text/plain'; + public const TYPE_HTML = 'text/html'; + public const TYPE_ENRICHED = 'text/enriched'; + public const TYPE_XML = 'text/xml'; + public const ENCODING_7BIT = '7bit'; + public const ENCODING_8BIT = '8bit'; + public const ENCODING_QUOTEDPRINTABLE = 'quoted-printable'; + public const ENCODING_BASE64 = 'base64'; + public const DISPOSITION_ATTACHMENT = 'attachment'; + public const DISPOSITION_INLINE = 'inline'; + public const LINELENGTH = 72; + public const LINEEND = "\n"; + public const MULTIPART_ALTERNATIVE = 'multipart/alternative'; + public const MULTIPART_MIXED = 'multipart/mixed'; + public const MULTIPART_RELATED = 'multipart/related'; + public const MULTIPART_RELATIVE = 'multipart/relative'; + public const MULTIPART_REPORT = 'multipart/report'; + public const MESSAGE_RFC822 = 'message/rfc822'; + public const MESSAGE_DELIVERY_STATUS = 'message/delivery-status'; + public const CHARSET_REGEX = '#=\?(?P[\x21\x23-\x26\x2a\x2b\x2d\x5e\5f\60\x7b-\x7ea-zA-Z0-9]+)\?(?P[\x21\x23-\x26\x2a\x2b\x2d\x5e\5f\60\x7b-\x7ea-zA-Z0-9]+)\?(?P[\x21-\x3e\x40-\x7e]+)#'; + // phpcs:enable + + /** @var null|string */ protected $boundary; + + /** @var int */ protected static $makeUnique = 0; - // lookup-Tables for QuotedPrintable + /** + * Lookup-tables for QuotedPrintable + * + * @var string[] + */ public static $qpKeys = [ - "\x00","\x01","\x02","\x03","\x04","\x05","\x06","\x07", - "\x08","\x09","\x0A","\x0B","\x0C","\x0D","\x0E","\x0F", - "\x10","\x11","\x12","\x13","\x14","\x15","\x16","\x17", - "\x18","\x19","\x1A","\x1B","\x1C","\x1D","\x1E","\x1F", - "\x7F","\x80","\x81","\x82","\x83","\x84","\x85","\x86", - "\x87","\x88","\x89","\x8A","\x8B","\x8C","\x8D","\x8E", - "\x8F","\x90","\x91","\x92","\x93","\x94","\x95","\x96", - "\x97","\x98","\x99","\x9A","\x9B","\x9C","\x9D","\x9E", - "\x9F","\xA0","\xA1","\xA2","\xA3","\xA4","\xA5","\xA6", - "\xA7","\xA8","\xA9","\xAA","\xAB","\xAC","\xAD","\xAE", - "\xAF","\xB0","\xB1","\xB2","\xB3","\xB4","\xB5","\xB6", - "\xB7","\xB8","\xB9","\xBA","\xBB","\xBC","\xBD","\xBE", - "\xBF","\xC0","\xC1","\xC2","\xC3","\xC4","\xC5","\xC6", - "\xC7","\xC8","\xC9","\xCA","\xCB","\xCC","\xCD","\xCE", - "\xCF","\xD0","\xD1","\xD2","\xD3","\xD4","\xD5","\xD6", - "\xD7","\xD8","\xD9","\xDA","\xDB","\xDC","\xDD","\xDE", - "\xDF","\xE0","\xE1","\xE2","\xE3","\xE4","\xE5","\xE6", - "\xE7","\xE8","\xE9","\xEA","\xEB","\xEC","\xED","\xEE", - "\xEF","\xF0","\xF1","\xF2","\xF3","\xF4","\xF5","\xF6", - "\xF7","\xF8","\xF9","\xFA","\xFB","\xFC","\xFD","\xFE", - "\xFF" + "\x00", + "\x01", + "\x02", + "\x03", + "\x04", + "\x05", + "\x06", + "\x07", + "\x08", + "\x09", + "\x0A", + "\x0B", + "\x0C", + "\x0D", + "\x0E", + "\x0F", + "\x10", + "\x11", + "\x12", + "\x13", + "\x14", + "\x15", + "\x16", + "\x17", + "\x18", + "\x19", + "\x1A", + "\x1B", + "\x1C", + "\x1D", + "\x1E", + "\x1F", + "\x7F", + "\x80", + "\x81", + "\x82", + "\x83", + "\x84", + "\x85", + "\x86", + "\x87", + "\x88", + "\x89", + "\x8A", + "\x8B", + "\x8C", + "\x8D", + "\x8E", + "\x8F", + "\x90", + "\x91", + "\x92", + "\x93", + "\x94", + "\x95", + "\x96", + "\x97", + "\x98", + "\x99", + "\x9A", + "\x9B", + "\x9C", + "\x9D", + "\x9E", + "\x9F", + "\xA0", + "\xA1", + "\xA2", + "\xA3", + "\xA4", + "\xA5", + "\xA6", + "\xA7", + "\xA8", + "\xA9", + "\xAA", + "\xAB", + "\xAC", + "\xAD", + "\xAE", + "\xAF", + "\xB0", + "\xB1", + "\xB2", + "\xB3", + "\xB4", + "\xB5", + "\xB6", + "\xB7", + "\xB8", + "\xB9", + "\xBA", + "\xBB", + "\xBC", + "\xBD", + "\xBE", + "\xBF", + "\xC0", + "\xC1", + "\xC2", + "\xC3", + "\xC4", + "\xC5", + "\xC6", + "\xC7", + "\xC8", + "\xC9", + "\xCA", + "\xCB", + "\xCC", + "\xCD", + "\xCE", + "\xCF", + "\xD0", + "\xD1", + "\xD2", + "\xD3", + "\xD4", + "\xD5", + "\xD6", + "\xD7", + "\xD8", + "\xD9", + "\xDA", + "\xDB", + "\xDC", + "\xDD", + "\xDE", + "\xDF", + "\xE0", + "\xE1", + "\xE2", + "\xE3", + "\xE4", + "\xE5", + "\xE6", + "\xE7", + "\xE8", + "\xE9", + "\xEA", + "\xEB", + "\xEC", + "\xED", + "\xEE", + "\xEF", + "\xF0", + "\xF1", + "\xF2", + "\xF3", + "\xF4", + "\xF5", + "\xF6", + "\xF7", + "\xF8", + "\xF9", + "\xFA", + "\xFB", + "\xFC", + "\xFD", + "\xFE", + "\xFF", ]; + /** @var string[] */ public static $qpReplaceValues = [ - "=00","=01","=02","=03","=04","=05","=06","=07", - "=08","=09","=0A","=0B","=0C","=0D","=0E","=0F", - "=10","=11","=12","=13","=14","=15","=16","=17", - "=18","=19","=1A","=1B","=1C","=1D","=1E","=1F", - "=7F","=80","=81","=82","=83","=84","=85","=86", - "=87","=88","=89","=8A","=8B","=8C","=8D","=8E", - "=8F","=90","=91","=92","=93","=94","=95","=96", - "=97","=98","=99","=9A","=9B","=9C","=9D","=9E", - "=9F","=A0","=A1","=A2","=A3","=A4","=A5","=A6", - "=A7","=A8","=A9","=AA","=AB","=AC","=AD","=AE", - "=AF","=B0","=B1","=B2","=B3","=B4","=B5","=B6", - "=B7","=B8","=B9","=BA","=BB","=BC","=BD","=BE", - "=BF","=C0","=C1","=C2","=C3","=C4","=C5","=C6", - "=C7","=C8","=C9","=CA","=CB","=CC","=CD","=CE", - "=CF","=D0","=D1","=D2","=D3","=D4","=D5","=D6", - "=D7","=D8","=D9","=DA","=DB","=DC","=DD","=DE", - "=DF","=E0","=E1","=E2","=E3","=E4","=E5","=E6", - "=E7","=E8","=E9","=EA","=EB","=EC","=ED","=EE", - "=EF","=F0","=F1","=F2","=F3","=F4","=F5","=F6", - "=F7","=F8","=F9","=FA","=FB","=FC","=FD","=FE", - "=FF" + "=00", + "=01", + "=02", + "=03", + "=04", + "=05", + "=06", + "=07", + "=08", + "=09", + "=0A", + "=0B", + "=0C", + "=0D", + "=0E", + "=0F", + "=10", + "=11", + "=12", + "=13", + "=14", + "=15", + "=16", + "=17", + "=18", + "=19", + "=1A", + "=1B", + "=1C", + "=1D", + "=1E", + "=1F", + "=7F", + "=80", + "=81", + "=82", + "=83", + "=84", + "=85", + "=86", + "=87", + "=88", + "=89", + "=8A", + "=8B", + "=8C", + "=8D", + "=8E", + "=8F", + "=90", + "=91", + "=92", + "=93", + "=94", + "=95", + "=96", + "=97", + "=98", + "=99", + "=9A", + "=9B", + "=9C", + "=9D", + "=9E", + "=9F", + "=A0", + "=A1", + "=A2", + "=A3", + "=A4", + "=A5", + "=A6", + "=A7", + "=A8", + "=A9", + "=AA", + "=AB", + "=AC", + "=AD", + "=AE", + "=AF", + "=B0", + "=B1", + "=B2", + "=B3", + "=B4", + "=B5", + "=B6", + "=B7", + "=B8", + "=B9", + "=BA", + "=BB", + "=BC", + "=BD", + "=BE", + "=BF", + "=C0", + "=C1", + "=C2", + "=C3", + "=C4", + "=C5", + "=C6", + "=C7", + "=C8", + "=C9", + "=CA", + "=CB", + "=CC", + "=CD", + "=CE", + "=CF", + "=D0", + "=D1", + "=D2", + "=D3", + "=D4", + "=D5", + "=D6", + "=D7", + "=D8", + "=D9", + "=DA", + "=DB", + "=DC", + "=DD", + "=DE", + "=DF", + "=E0", + "=E1", + "=E2", + "=E3", + "=E4", + "=E5", + "=E6", + "=E7", + "=E8", + "=E9", + "=EA", + "=EB", + "=EC", + "=ED", + "=EE", + "=EF", + "=F0", + "=F1", + "=F2", + "=F3", + "=F4", + "=F5", + "=F6", + "=F7", + "=F8", + "=F9", + "=FA", + "=FB", + "=FC", + "=FD", + "=FE", + "=FF", ]; // @codingStandardsIgnoreStart public static $qpKeysString = @@ -104,7 +407,7 @@ class Mime */ public static function isPrintable($str) { - return (strcspn($str, static::$qpKeysString) == strlen($str)); + return strcspn($str, static::$qpKeysString) === strlen($str); } /** @@ -125,7 +428,7 @@ public static function encodeQuotedPrintable( // Split encoded text into separate lines $initialPtr = 0; - $strLength = strlen($str); + $strLength = strlen($str); while ($initialPtr < $strLength) { $continueAt = $strLength - $initialPtr; @@ -138,11 +441,11 @@ public static function encodeQuotedPrintable( // Ensure we are not splitting across an encoded character $endingMarkerPos = strrpos($chunk, '='); if ($endingMarkerPos !== false && $endingMarkerPos >= strlen($chunk) - 2) { - $chunk = substr($chunk, 0, $endingMarkerPos); + $chunk = substr($chunk, 0, $endingMarkerPos); $continueAt = $endingMarkerPos; } - if (ord($chunk[0]) == 0x2E) { // 0x2E is a dot + if (ord($chunk[0]) === 0x2E) { // 0x2E is a dot $chunk = '=2E' . substr($chunk, 1); } @@ -157,7 +460,7 @@ public static function encodeQuotedPrintable( } // Add string and continue - $out .= $chunk . '=' . $lineEnd; + $out .= $chunk . '=' . $lineEnd; $initialPtr += $continueAt; } @@ -201,7 +504,7 @@ public static function encodeQuotedPrintableHeader( $lineEnd = self::LINEEND ) { // Reduce line-length by the length of the required delimiter, charsets and encoding - $prefix = sprintf('=?%s?Q?', $charset); + $prefix = sprintf('=?%s?Q?', $charset); $lineLength = $lineLength - strlen($prefix) - 3; $str = self::_encodeQuotedPrintable($str); @@ -218,16 +521,16 @@ public static function encodeQuotedPrintableHeader( $currentLine = max(count($lines) - 1, 0); $token = static::getNextQuotedPrintableToken($str); $substr = substr($str, strlen($token)); - $str = (false === $substr) ? '' : $substr; + $str = false === $substr ? '' : $substr; $tmp .= $token; if ($token === '=20') { // only if we have a single char token or space, we can append the // tempstring it to the current line or start a new line if necessary. - $lineLimitReached = (strlen($lines[$currentLine] . $tmp) > $lineLength); - $noCurrentLine = ($lines[$currentLine] === ''); + $lineLimitReached = strlen($lines[$currentLine] . $tmp) > $lineLength; + $noCurrentLine = $lines[$currentLine] === ''; if ($noCurrentLine && $lineLimitReached) { - $lines[$currentLine] = $tmp; + $lines[$currentLine] = $tmp; $lines[$currentLine + 1] = ''; } elseif ($lineLimitReached) { $lines[$currentLine + 1] = $tmp; @@ -281,8 +584,8 @@ public static function encodeBase64Header( $lineLength = self::LINELENGTH, $lineEnd = self::LINEEND ) { - $prefix = '=?' . $charset . '?B?'; - $suffix = '?='; + $prefix = '=?' . $charset . '?B?'; + $suffix = '?='; $remainingLength = $lineLength - strlen($prefix) - strlen($suffix); $encodedValue = static::encodeBase64($str, $remainingLength, $lineEnd); @@ -325,6 +628,8 @@ public function __construct($boundary = null) } } + // phpcs:disable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps + /** * Encode the given string with the given encoding. * diff --git a/src/Part.php b/src/Part.php index 1760e016..541da9c0 100644 --- a/src/Part.php +++ b/src/Part.php @@ -1,30 +1,68 @@ */ protected $filters = []; /** @@ -47,6 +85,7 @@ public function __construct($content = '') /** * Set type + * * @param string $type * @return self */ @@ -58,6 +97,7 @@ public function setType($type = Mime::TYPE_OCTETSTREAM) /** * Get type + * * @return string */ public function getType() @@ -67,6 +107,7 @@ public function getType() /** * Set encoding + * * @param string $encoding * @return self */ @@ -78,6 +119,7 @@ public function setEncoding($encoding = Mime::ENCODING_8BIT) /** * Get encoding + * * @return string */ public function getEncoding() @@ -87,6 +129,7 @@ public function getEncoding() /** * Set id + * * @param string $id * @return self */ @@ -98,6 +141,7 @@ public function setId($id) /** * Get id + * * @return string */ public function getId() @@ -107,6 +151,7 @@ public function getId() /** * Set disposition + * * @param string $disposition * @return self */ @@ -118,6 +163,7 @@ public function setDisposition($disposition) /** * Get disposition + * * @return string */ public function getDisposition() @@ -127,6 +173,7 @@ public function getDisposition() /** * Set description + * * @param string $description * @return self */ @@ -138,6 +185,7 @@ public function setDescription($description) /** * Get description + * * @return string */ public function getDescription() @@ -147,6 +195,7 @@ public function getDescription() /** * Set filename + * * @param string $fileName * @return self */ @@ -158,6 +207,7 @@ public function setFileName($fileName) /** * Get filename + * * @return string */ public function getFileName() @@ -167,7 +217,8 @@ public function getFileName() /** * Set charset - * @param string $type + * + * @param string $charset * @return self */ public function setCharset($charset) @@ -178,6 +229,7 @@ public function setCharset($charset) /** * Get charset + * * @return string */ public function getCharset() @@ -187,6 +239,7 @@ public function getCharset() /** * Set boundary + * * @param string $boundary * @return self */ @@ -198,6 +251,7 @@ public function setBoundary($boundary) /** * Get boundary + * * @return string */ public function getBoundary() @@ -207,6 +261,7 @@ public function getBoundary() /** * Set location + * * @param string $location * @return self */ @@ -218,6 +273,7 @@ public function setLocation($location) /** * Get location + * * @return string */ public function getLocation() @@ -227,6 +283,7 @@ public function getLocation() /** * Set language + * * @param string $language * @return self */ @@ -238,6 +295,7 @@ public function setLanguage($language) /** * Get language + * * @return string */ public function getLanguage() @@ -247,6 +305,7 @@ public function getLanguage() /** * Set content + * * @param mixed $content String or Stream containing the content * @throws Exception\InvalidArgumentException * @return self @@ -269,6 +328,7 @@ public function setContent($content) /** * Set isStream + * * @param bool $isStream * @return self */ @@ -280,6 +340,7 @@ public function setIsStream($isStream = false) /** * Get isStream + * * @return bool */ public function getIsStream() @@ -289,7 +350,8 @@ public function getIsStream() /** * Set filters - * @param array $filters + * + * @param array $filters * @return self */ public function setFilters($filters = []) @@ -300,7 +362,8 @@ public function setFilters($filters = []) /** * Get Filters - * @return array + * + * @return array */ public function getFilters() { @@ -320,13 +383,15 @@ public function isStream() return $this->isStream; } + // phpcs:disable WebimpressCodingStandard.NamingConventions.ValidVariableName.NotCamelCaps + /** * if this was created with a stream, return a filtered stream for * reading the content. very useful for large file attachments. * * @param string $EOL * @return resource - * @throws Exception\RuntimeException if not a stream or unable to append filter + * @throws Exception\RuntimeException If not a stream or unable to append filter. */ public function getEncodedStream($EOL = Mime::LINEEND) { @@ -340,13 +405,13 @@ public function getEncodedStream($EOL = Mime::LINEEND) if (array_key_exists(Mime::ENCODING_QUOTEDPRINTABLE, $this->filters)) { stream_filter_remove($this->filters[Mime::ENCODING_QUOTEDPRINTABLE]); } - $filter = stream_filter_append( + $filter = stream_filter_append( $this->content, 'convert.quoted-printable-encode', STREAM_FILTER_READ, [ 'line-length' => 76, - 'line-break-chars' => $EOL + 'line-break-chars' => $EOL, ] ); $this->filters[Mime::ENCODING_QUOTEDPRINTABLE] = $filter; @@ -358,13 +423,13 @@ public function getEncodedStream($EOL = Mime::LINEEND) if (array_key_exists(Mime::ENCODING_BASE64, $this->filters)) { stream_filter_remove($this->filters[Mime::ENCODING_BASE64]); } - $filter = stream_filter_append( + $filter = stream_filter_append( $this->content, 'convert.base64-encode', STREAM_FILTER_READ, [ 'line-length' => 76, - 'line-break-chars' => $EOL + 'line-break-chars' => $EOL, ] ); $this->filters[Mime::ENCODING_BASE64] = $filter; @@ -401,6 +466,7 @@ public function getContent($EOL = Mime::LINEEND) /** * Get the RAW unencoded content from this part + * * @return string */ public function getRawContent() @@ -439,7 +505,7 @@ public function getHeadersArray($EOL = Mime::LINEEND) } if ($this->id) { - $headers[] = ['Content-ID', '<' . $this->id . '>']; + $headers[] = ['Content-ID', '<' . $this->id . '>']; } if ($this->disposition) { diff --git a/test/DecodeTest.php b/test/DecodeTest.php index d6e24808..197ba38e 100644 --- a/test/DecodeTest.php +++ b/test/DecodeTest.php @@ -1,11 +1,5 @@ getParts(); + $p = $msg->getParts(); $this->assertIsArray($p); $this->assertEmpty($p); - $p2 = []; + $p2 = []; $p2[] = new Mime\Part('This is a test'); $p2[] = new Mime\Part('This is another test'); $msg->setParts($p2); @@ -42,28 +41,28 @@ public function testSetGetParts() public function testGetMime() { $msg = new Mime\Message(); // No Parts - $m = $msg->getMime(); - $this->assertInstanceOf('Laminas\\Mime\\Mime', $m); + $m = $msg->getMime(); + $this->assertInstanceOf(\Laminas\Mime\Mime::class, $m); - $msg = new Mime\Message(); // No Parts + $msg = new Mime\Message(); // No Parts $mime = new Mime\Mime('1234'); $msg->setMime($mime); $m2 = $msg->getMime(); - $this->assertInstanceOf('Laminas\\Mime\\Mime', $m2); + $this->assertInstanceOf(\Laminas\Mime\Mime::class, $m2); $this->assertEquals('1234', $m2->boundary()); } public function testGenerate() { $msg = new Mime\Message(); // No Parts - $p1 = new Mime\Part('This is a test'); - $p2 = new Mime\Part('This is another test'); + $p1 = new Mime\Part('This is a test'); + $p2 = new Mime\Part('This is another test'); $msg->addPart($p1); $msg->addPart($p2); - $res = $msg->generateMessage(); - $mime = $msg->getMime(); + $res = $msg->generateMessage(); + $mime = $msg->getMime(); $boundary = $mime->boundary(); - $p1 = strpos($res, $boundary); + $p1 = strpos($res, $boundary); // $boundary must appear once for every mime part $this->assertNotFalse($p1); if ($p1) { @@ -78,7 +77,6 @@ public function testGenerate() /** * check if decoding a string into a \Laminas\Mime\Message object works - * */ public function testDecodeMimeMessage() { @@ -98,7 +96,7 @@ public function testDecodeMimeMessage() This is another test --=_af4357ef34b786aae1491b0a2d14399f-- EOD; - $res = Mime\Message::createFromMessage($text, '=_af4357ef34b786aae1491b0a2d14399f'); + $res = Mime\Message::createFromMessage($text, '=_af4357ef34b786aae1491b0a2d14399f'); $parts = $res->getParts(); $this->assertEquals(2, count($parts)); @@ -115,7 +113,6 @@ public function testDecodeMimeMessage() /** * check if decoding a string into a \Laminas\Mime\Message object works - * */ public function testDecodeMimeMessageNoHeader() { @@ -134,12 +131,12 @@ public function testDecodeMimeMessageNoHeader() This is a test --=_af4357ef34b786aae1491b0a2d14399f-- EOD; - $res = Mime\Message::createFromMessage($text, '=_af4357ef34b786aae1491b0a2d14399f'); + $res = Mime\Message::createFromMessage($text, '=_af4357ef34b786aae1491b0a2d14399f'); $parts = $res->getParts(); $this->assertEquals(2, count($parts)); - $part1 = $parts[0]; + $part1 = $parts[0]; $part1Content = $part1->getRawContent(); $this->assertStringContainsString('The original message', $part1Content); $this->assertStringContainsString('End content', $part1Content); @@ -158,12 +155,12 @@ public function testDecodeNonMultipartMimeMessage() This is a test EOD; - $res = Mime\Message::createFromMessage($text); + $res = Mime\Message::createFromMessage($text); $parts = $res->getParts(); $this->assertEquals(1, count($parts)); - $part1 = $parts[0]; + $part1 = $parts[0]; $part1Content = $part1->getRawContent(); $this->assertEquals('This is a test', $part1Content); $this->assertEquals('image/gif', $part1->type); @@ -206,7 +203,7 @@ public function testFromStringWithCrlfAndRfc2822FoldedHeaders() { // This is a fixture as provided by many mailservers // e.g. cyrus or dovecot - $eol = "\r\n"; + $eol = "\r\n"; $fixture = 'This is a MIME-encapsulated message' . $eol . $eol . '--=_af4357ef34b786aae1491b0a2d14399f' . $eol . 'Content-Type: text/plain' . $eol @@ -217,7 +214,7 @@ public function testFromStringWithCrlfAndRfc2822FoldedHeaders() . '--=_af4357ef34b786aae1491b0a2d14399f--'; $message = Message::createFromMessage($fixture, '=_af4357ef34b786aae1491b0a2d14399f', $eol); - $parts = $message->getParts(); + $parts = $message->getParts(); $this->assertEquals(1, count($parts)); $this->assertEquals('attachment; filename="test.txt"', $parts[0]->getDisposition()); diff --git a/test/MimeTest.php b/test/MimeTest.php index fb25a313..45e2be8d 100644 --- a/test/MimeTest.php +++ b/test/MimeTest.php @@ -1,36 +1,38 @@ _originaltimezone = date_default_timezone_get(); + $this->originalTimezone = date_default_timezone_get(); } /** @@ -38,7 +40,7 @@ protected function setUp(): void */ protected function tearDown(): void { - date_default_timezone_set($this->_originaltimezone); + date_default_timezone_set($this->originalTimezone); } public function testBoundary() @@ -54,17 +56,13 @@ public function testBoundary() $this->assertEquals($m3->boundary(), $myBoundary); } - // @codingStandardsIgnoreStart - public function testIsPrintable_notPrintable() + public function testIsNotPrintable() { - // @codingStandardsIgnoreEnd $this->assertFalse(Mime\Mime::isPrintable('Test with special chars: �����')); } - // @codingStandardsIgnoreStart - public function testIsPrintable_isPrintable() + public function testIsPrintable() { - // @codingStandardsIgnoreEnd $this->assertTrue(Mime\Mime::isPrintable('Test without special chars')); } @@ -84,7 +82,7 @@ public function testQP() public function testQuotedPrintableNoDotAtBeginningOfLine() { $text = str_repeat('a', Mime\Mime::LINELENGTH) . '.bbb'; - $qp = Mime\Mime::encodeQuotedPrintable($text); + $qp = Mime\Mime::encodeQuotedPrintable($text); $expected = str_repeat('a', Mime\Mime::LINELENGTH) . "=\n=2Ebbb"; @@ -94,7 +92,7 @@ public function testQuotedPrintableNoDotAtBeginningOfLine() public function testQuotedPrintableSpacesAndDots() { $text = str_repeat(' ', Mime\Mime::LINELENGTH) . str_repeat('.', Mime\Mime::LINELENGTH); - $qp = Mime\Mime::encodeQuotedPrintable($text); + $qp = Mime\Mime::encodeQuotedPrintable($text); $expected = str_repeat(' ', Mime\Mime::LINELENGTH - 1) . "=20=\n=2E" @@ -106,7 +104,7 @@ public function testQuotedPrintableSpacesAndDots() public function testQuotedPrintableDoesNotBreakOctets() { $text = str_repeat('a', Mime\Mime::LINELENGTH - 2) . '=.bbb'; - $qp = Mime\Mime::encodeQuotedPrintable($text); + $qp = Mime\Mime::encodeQuotedPrintable($text); $expected = str_repeat('a', Mime\Mime::LINELENGTH - 2) . "=\n=3D.bbb"; @@ -131,14 +129,15 @@ public function testLaminas1058WhitespaceAtEndOfBodyCausesInfiniteLoop() * @group Laminas-1688 * @dataProvider dataTestEncodeMailHeaderQuotedPrintable */ - public function testEncodeMailHeaderQuotedPrintable($str, $charset, $result) + public function testEncodeMailHeaderQuotedPrintable(string $str, string $charset, string $result): void { $this->assertEquals($result, Mime\Mime::encodeQuotedPrintableHeader($str, $charset)); } - public static function dataTestEncodeMailHeaderQuotedPrintable() + /** @psalm-return array */ + public static function dataTestEncodeMailHeaderQuotedPrintable(): array { - // @codingStandardsIgnoreStart + // phpcs:disable Generic.Files.LineLength.TooLong return [ ["äöü", "UTF-8", "=?UTF-8?Q?=C3=A4=C3=B6=C3=BC?="], ["äöü ", "UTF-8", "=?UTF-8?Q?=C3=A4=C3=B6=C3=BC?="], @@ -150,36 +149,42 @@ public static function dataTestEncodeMailHeaderQuotedPrintable() ["äääääääääääääää äääääääääääääää", "UTF-8", "=?UTF-8?Q?=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=20?=\n =?UTF-8?Q?=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4?="], ["ä äääääääääääääää", "UTF-8", "=?UTF-8?Q?=C3=A4=20=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4=C3=A4?="], ]; - // @codingStandardsIgnoreEnd + // phpcs:enable } /** * @group Laminas-1688 * @dataProvider dataTestEncodeMailHeaderBase64 */ - public function testEncodeMailHeaderBase64($str, $charset, $result) + public function testEncodeMailHeaderBase64(string $str, string $charset, string $result): void { $this->assertEquals($result, Mime\Mime::encodeBase64Header($str, $charset)); } - public static function dataTestEncodeMailHeaderBase64() + /** @psalm-return array */ + public static function dataTestEncodeMailHeaderBase64(): array { + // phpcs:disable Generic.Files.LineLength.TooLong return [ ["äöü", "UTF-8", "=?UTF-8?B?w6TDtsO8?="], - // @codingStandardsIgnoreStart - ["Alle meine Entchen schwimmen in dem See, schwimmen in dem See, Köpfchen in das Wasser, Schwänzchen in die Höh!", "UTF-8", "=?UTF-8?B?QWxsZSBtZWluZSBFbnRjaGVuIHNjaHdpbW1lbiBpbiBkZW0gU2VlLCBzY2h3?= + [ + "Alle meine Entchen schwimmen in dem See, schwimmen in dem See, Köpfchen in das Wasser, Schwänzchen in die Höh!", + "UTF-8", + "=?UTF-8?B?QWxsZSBtZWluZSBFbnRjaGVuIHNjaHdpbW1lbiBpbiBkZW0gU2VlLCBzY2h3?= =?UTF-8?B?aW1tZW4gaW4gZGVtIFNlZSwgS8O2cGZjaGVuIGluIGRhcyBXYXNzZXIsIFNj?= - =?UTF-8?B?aHfDpG56Y2hlbiBpbiBkaWUgSMO2aCE=?="], - // @codingStandardsIgnoreEnd + =?UTF-8?B?aHfDpG56Y2hlbiBpbiBkaWUgSMO2aCE=?=", + ], ]; + // phpcs:enable } /** * base64 chunk are 4 chars long * try to encode/decode with 4 line length + * * @dataProvider dataTestEncodeMailHeaderBase64wrap */ - public function testEncodeMailHeaderBase64wrap($str) + public function testEncodeMailHeaderBase64wrap(string $str): void { $this->assertEquals($str, Mime\Decode::decodeQuotedPrintable(Mime\Mime::encodeBase64Header($str, "UTF-8", 20))); $this->assertEquals($str, Mime\Decode::decodeQuotedPrintable(Mime\Mime::encodeBase64Header($str, "UTF-8", 21))); @@ -187,72 +192,80 @@ public function testEncodeMailHeaderBase64wrap($str) $this->assertEquals($str, Mime\Decode::decodeQuotedPrintable(Mime\Mime::encodeBase64Header($str, "UTF-8", 23))); } - public static function dataTestEncodeMailHeaderBase64wrap() + /** @psalm-return array */ + public static function dataTestEncodeMailHeaderBase64wrap(): array { return [ ["äöüäöüäöüäöüäöüäöüäöü"], - ["Alle meine Entchen schwimmen in dem See, schwimmen in dem See, " - . "Köpfchen in das Wasser, Schwänzchen in die Höh!"] + [ + "Alle meine Entchen schwimmen in dem See, schwimmen in dem See, " + . "Köpfchen in das Wasser, Schwänzchen in die Höh!", + ], ]; } public function testFromMessageMultiPart() { $message = Mime\Message::createFromMessage( - '--089e0141a1902f83ee04e0a07b7a'."\r\n" - .'Content-Type: multipart/alternative; boundary=089e0141a1902f83e904e0a07b78'."\r\n" - ."\r\n" - .'--089e0141a1902f83e904e0a07b78'."\r\n" - .'Content-Type: text/plain; charset=UTF-8'."\r\n" - ."\r\n" - .'Foo'."\r\n" - ."\r\n" - .'--089e0141a1902f83e904e0a07b78'."\r\n" - .'Content-Type: text/html; charset=UTF-8'."\r\n" - ."\r\n" - .'

Foo

'."\r\n" - ."\r\n" - .'--089e0141a1902f83e904e0a07b78--'."\r\n" - .'--089e0141a1902f83ee04e0a07b7a'."\r\n" - .'Content-Type: image/png; name="1.png"'."\r\n" - .'Content-Disposition: attachment; filename="1.png"'."\r\n" - .'Content-Transfer-Encoding: base64'."\r\n" - .'X-Attachment-Id: barquux'."\r\n" - ."\r\n" - .'Zm9vCg=='."\r\n" - .'--089e0141a1902f83ee04e0a07b7a--', + '--089e0141a1902f83ee04e0a07b7a' . "\r\n" + . 'Content-Type: multipart/alternative; boundary=089e0141a1902f83e904e0a07b78' . "\r\n" + . "\r\n" + . '--089e0141a1902f83e904e0a07b78' . "\r\n" + . 'Content-Type: text/plain; charset=UTF-8' . "\r\n" + . "\r\n" + . 'Foo' . "\r\n" + . "\r\n" + . '--089e0141a1902f83e904e0a07b78' . "\r\n" + . 'Content-Type: text/html; charset=UTF-8' . "\r\n" + . "\r\n" + . '

Foo

' . "\r\n" + . "\r\n" + . '--089e0141a1902f83e904e0a07b78--' . "\r\n" + . '--089e0141a1902f83ee04e0a07b7a' . "\r\n" + . 'Content-Type: image/png; name="1.png"' . "\r\n" + . 'Content-Disposition: attachment; filename="1.png"' . "\r\n" + . 'Content-Transfer-Encoding: base64' . "\r\n" + . 'X-Attachment-Id: barquux' . "\r\n" + . "\r\n" + . 'Zm9vCg==' . "\r\n" + . '--089e0141a1902f83ee04e0a07b7a--', '089e0141a1902f83ee04e0a07b7a' ); $this->assertSame(2, count($message->getParts())); } - public static function dataTestFromMessageDecode() + /** @psalm-return array */ + public static function dataTestFromMessageDecode(): array { + // phpcs:disable Generic.Files.LineLength.TooLong return [ ['äöü', 'quoted-printable', '=C3=A4=C3=B6=C3=BC'], - // @codingStandardsIgnoreStart - ['Alle meine Entchen schwimmen in dem See, schwimmen in dem See, Köpfchen in das Wasser, Schwänzchen in die Höh!', 'quoted-printable', 'Alle meine Entchen schwimmen in dem See, schwimmen in dem See, K=C3=B6pfche= -n in das Wasser, Schw=C3=A4nzchen in die H=C3=B6h!'], - // @codingStandardsIgnoreEnd + [ + 'Alle meine Entchen schwimmen in dem See, schwimmen in dem See, Köpfchen in das Wasser, Schwänzchen in die Höh!', + 'quoted-printable', + 'Alle meine Entchen schwimmen in dem See, schwimmen in dem See, K=C3=B6pfche= +n in das Wasser, Schw=C3=A4nzchen in die H=C3=B6h!', + ], ['foobar', 'base64', 'Zm9vYmFyCg=='], ]; + // phpcs:enable } /** * @dataProvider dataTestFromMessageDecode */ - public function testFromMessageDecode($input, $encoding, $result) + public function testFromMessageDecode(string $input, string $encoding, string $result): void { $parts = Mime\Message::createFromMessage( - '--089e0141a1902f83ee04e0a07b7a'."\r\n" - .'Content-Type: text/plain; charset=UTF-8'."\r\n" - .'Content-Transfer-Encoding: '.$encoding."\r\n" - ."\r\n" - .$result."\r\n" - .'--089e0141a1902f83ee04e0a07b7a--', + '--089e0141a1902f83ee04e0a07b7a' . "\r\n" + . 'Content-Type: text/plain; charset=UTF-8' . "\r\n" + . 'Content-Transfer-Encoding: ' . $encoding . "\r\n" + . "\r\n" + . $result . "\r\n" + . '--089e0141a1902f83ee04e0a07b7a--', '089e0141a1902f83ee04e0a07b7a' )->getParts(); - $this->assertSame($input."\n", $parts[0]->getRawContent()); + $this->assertSame($input . "\n", $parts[0]->getRawContent()); } /** @@ -280,28 +293,29 @@ public function testLineLengthInQuotedPrintableHeaderEncoding() } } - public function dataTestCharsetDetection() + /** @psalm-return array */ + public function dataTestCharsetDetection(): array { return [ ["ASCII", "test"], ["ASCII", "=?ASCII?Q?test?="], ["UTF-8", "=?UTF-8?Q?test?="], ["ISO-8859-1", "=?ISO-8859-1?Q?Pr=FCfung_f=FCr?= Entwerfen von einer MIME kopfzeile"], - ["UTF-8", "=?UTF-8?Q?Pr=C3=BCfung=20Pr=C3=BCfung?="] + ["UTF-8", "=?UTF-8?Q?Pr=C3=BCfung=20Pr=C3=BCfung?="], ]; } /** * @dataProvider dataTestCharsetDetection */ - public function testCharsetDetection($expected, $string) + public function testCharsetDetection(string $expected, string $string): void { $this->assertEquals($expected, Mime\Mime::mimeDetectCharset($string)); } public function testEncodeQuotedPrintableShouldBeFastEnoughForLongInputStrings() { - $str = str_repeat('this could be anything, ', 200000); + $str = str_repeat('this could be anything, ', 200000); $time = microtime(true); Mime\Mime::encodeQuotedPrintable($str); $this->assertLessThan(5, microtime(true) - $time); diff --git a/test/PartTest.php b/test/PartTest.php index 9a5aa4b5..0d25b9ea 100644 --- a/test/PartTest.php +++ b/test/PartTest.php @@ -1,16 +1,18 @@ testText = 'safdsafsa�lg ��gd�� sd�jg�sdjg�ld�gksd�gj�sdfg�dsj' - .'�gjsd�gj�dfsjg�dsfj�djs�g kjhdkj fgaskjfdh gksjhgjkdh gjhfsdghdhgksdjhg'; - $this->part = new Mime\Part($this->testText); - $this->part->encoding = Mime\Mime::ENCODING_BASE64; - $this->part->type = "text/plain"; - $this->part->filename = 'test.txt'; + $this->testText = 'safdsafsa�lg ��gd�� sd�jg�sdjg�ld�gksd�gj�sdfg�dsj' + . '�gjsd�gj�dfsjg�dsfj�djs�g kjhdkj fgaskjfdh gksjhgjkdh gjhfsdghdhgksdjhg'; + $this->part = new Mime\Part($this->testText); + $this->part->encoding = Mime\Mime::ENCODING_BASE64; + $this->part->type = "text/plain"; + $this->part->filename = 'test.txt'; $this->part->disposition = 'attachment'; - $this->part->charset = 'iso8859-1'; - $this->part->id = '4711'; + $this->part->charset = 'iso8859-1'; + $this->part->id = '4711'; } public function testHeaders() { - $expectedHeaders = ['Content-Type: text/plain', - 'Content-Transfer-Encoding: ' . Mime\Mime::ENCODING_BASE64, - 'Content-Disposition: attachment', - 'filename="test.txt"', - 'charset=iso8859-1', - 'Content-ID: <4711>']; + $expectedHeaders = [ + 'Content-Type: text/plain', + 'Content-Transfer-Encoding: ' . Mime\Mime::ENCODING_BASE64, + 'Content-Disposition: attachment', + 'filename="test.txt"', + 'charset=iso8859-1', + 'Content-ID: <4711>', + ]; $actual = $this->part->getHeaders(); @@ -60,11 +66,11 @@ public function testContentEncoding() $this->assertEquals($this->testText, base64_decode($content)); // Test with quotedPrintable Encoding: $this->part->encoding = Mime\Mime::ENCODING_QUOTEDPRINTABLE; - $content = $this->part->getContent(); + $content = $this->part->getContent(); $this->assertEquals($this->testText, quoted_printable_decode($content)); // Test with 8Bit encoding $this->part->encoding = Mime\Mime::ENCODING_8BIT; - $content = $this->part->getContent(); + $content = $this->part->getContent(); $this->assertEquals($this->testText, $content); } @@ -76,9 +82,9 @@ public function testStreamEncoding() // Test Base64 $fp = fopen($testfile, 'rb'); $this->assertIsResource($fp); - $part = new Mime\Part($fp); + $part = new Mime\Part($fp); $part->encoding = Mime\Mime::ENCODING_BASE64; - $fp2 = $part->getEncodedStream(); + $fp2 = $part->getEncodedStream(); $this->assertIsResource($fp2); $encoded = stream_get_contents($fp2); fclose($fp); @@ -87,9 +93,9 @@ public function testStreamEncoding() // test QuotedPrintable $fp = fopen($testfile, 'rb'); $this->assertIsResource($fp); - $part = new Mime\Part($fp); + $part = new Mime\Part($fp); $part->encoding = Mime\Mime::ENCODING_QUOTEDPRINTABLE; - $fp2 = $part->getEncodedStream(); + $fp2 = $part->getEncodedStream(); $this->assertIsResource($fp2); $encoded = stream_get_contents($fp2); fclose($fp); @@ -106,6 +112,7 @@ public function testGetRawContentFromPart() /** * @link https://github.com/zendframework/zf2/issues/5428 + * * @group 5428 */ public function testContentEncodingWithStreamReadTwiceINaRow() @@ -113,17 +120,17 @@ public function testContentEncodingWithStreamReadTwiceINaRow() $testfile = realpath(__FILE__); $original = file_get_contents($testfile); - $fp = fopen($testfile, 'rb'); - $part = new Mime\Part($fp); - $part->encoding = Mime\Mime::ENCODING_BASE64; + $fp = fopen($testfile, 'rb'); + $part = new Mime\Part($fp); + $part->encoding = Mime\Mime::ENCODING_BASE64; $contentEncodedFirstTime = $part->getContent(); $contentEncodedSecondTime = $part->getContent(); $this->assertEquals($contentEncodedFirstTime, $contentEncodedSecondTime); fclose($fp); - $fp = fopen($testfile, 'rb'); - $part = new Mime\Part($fp); - $part->encoding = Mime\Mime::ENCODING_QUOTEDPRINTABLE; + $fp = fopen($testfile, 'rb'); + $part = new Mime\Part($fp); + $part->encoding = Mime\Mime::ENCODING_QUOTEDPRINTABLE; $contentEncodedFirstTime = $part->getContent(); $contentEncodedSecondTime = $part->getContent(); $this->assertEquals($contentEncodedFirstTime, $contentEncodedSecondTime); @@ -162,7 +169,8 @@ public function testSettersGetters() $this->assertEquals('foobar', $part->getDescription()); } - public function invalidContentTypes() + /** @psalm-return array */ + public function invalidContentTypes(): array { return [ 'null' => [null], @@ -179,6 +187,7 @@ public function invalidContentTypes() /** * @dataProvider invalidContentTypes + * @param mixed $content */ public function testConstructorRaisesInvalidArgumentExceptionForInvalidContentTypes($content) { @@ -188,6 +197,7 @@ public function testConstructorRaisesInvalidArgumentExceptionForInvalidContentTy /** * @dataProvider invalidContentTypes + * @param mixed $content */ public function testSetContentRaisesInvalidArgumentExceptionForInvalidContentTypes($content) { From bb704381c5c6cfaf1e74d6bfef473fd262ff04e6 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 2 Sep 2021 17:20:56 -0500 Subject: [PATCH 3/8] qa: inline Headers class from laminas-mail We have a circular dependency scenario between laminas-mail and laminas-mime. laminas-mail depends on laminas-mime for its MIME parsing capabilities. laminas-mime decodes headers to a laminas-mail `Headers` instance. Unfortunately the `Headers` class implements `Iterator`, and, as such, we get deprecations under 8.1 unless the `#[ReturnTypeWillChange]` attribute to affected methods. The solution here is to temporarily inline the `Headers` class as a test asset until laminas-mail is updated to work on PHP 8.1. Signed-off-by: Matthew Weier O'Phinney --- composer.json | 3 +- test/TestAsset/Mail/Headers.php | 626 ++++++++++++++++++++++++++++++++ 2 files changed, 628 insertions(+), 1 deletion(-) create mode 100644 test/TestAsset/Mail/Headers.php diff --git a/composer.json b/composer.json index 4826db64..4ae9fff3 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,8 @@ }, "autoload-dev": { "psr-4": { - "LaminasTest\\Mime\\": "test/" + "LaminasTest\\Mime\\": "test/", + "Laminas\\Mail\\": "test/TestAsset/Mail/" } }, "scripts": { diff --git a/test/TestAsset/Mail/Headers.php b/test/TestAsset/Mail/Headers.php new file mode 100644 index 00000000..321f6941 --- /dev/null +++ b/test/TestAsset/Mail/Headers.php @@ -0,0 +1,626 @@ + 2) { + throw new Exception\RuntimeException('Malformed header detected'); + } + continue; + } elseif (preg_match('/^\s*$/', $line)) { + // skip empty continuation line + continue; + } + + if ($emptyLine > 1) { + throw new Exception\RuntimeException('Malformed header detected'); + } + + // check if a header name is present + if (preg_match('/^[\x21-\x39\x3B-\x7E]+:.*$/', $line)) { + if ($currentLine) { + // a header name was present, then store the current complete line + $headers->addHeaderLine($currentLine); + } + $currentLine = trim($line); + continue; + } + + // continuation: append to current line + // recover the whitespace that break the line (unfolding, rfc2822#section-2.2.3) + if (preg_match('/^\s+.*$/', $line)) { + $currentLine .= ' ' . trim($line); + continue; + } + + // Line does not match header format! + throw new Exception\RuntimeException(sprintf( + 'Line "%s" does not match header format!', + $line + )); + } + if ($currentLine) { + $headers->addHeaderLine($currentLine); + } + return $headers; + } + + /** + * Set an alternate PluginClassLocator implementation for loading header classes. + * + * @deprecated since 2.12.0 + * + * @todo Remove for version 3.0.0 + * @return $this + */ + public function setPluginClassLoader(PluginClassLocator $pluginClassLoader) + { + // Silenced; can be caught in custom error handlers. + @trigger_error(sprintf( + 'Since laminas/laminas-mail 2.12.0: Usage of %s is deprecated; use %s::setHeaderLocator() instead', + __METHOD__, + self::class + ), E_USER_DEPRECATED); + + $this->pluginClassLoader = $pluginClassLoader; + return $this; + } + + /** + * Return a PluginClassLocator instance for customizing headers. + * + * Lazyloads a Header\HeaderLoader if necessary. + * + * @deprecated since 2.12.0 + * + * @todo Remove for version 3.0.0 + * @return PluginClassLocator + */ + public function getPluginClassLoader() + { + // Silenced; can be caught in custom error handlers. + @trigger_error(sprintf( + 'Since laminas/laminas-mail 2.12.0: Usage of %s is deprecated; use %s::getHeaderLocator() instead', + __METHOD__, + self::class + ), E_USER_DEPRECATED); + + if (! $this->pluginClassLoader) { + $this->pluginClassLoader = new Header\HeaderLoader(); + } + + return $this->pluginClassLoader; + } + + /** + * Retrieve the header class locator for customizing headers. + * + * Lazyloads a Header\HeaderLocator instance if necessary. + */ + public function getHeaderLocator(): Header\HeaderLocatorInterface + { + if (! $this->headerLocator) { + $this->setHeaderLocator(new Header\HeaderLocator()); + } + return $this->headerLocator; + } + + /** + * @todo Return self when we update to 7.4 or later as minimum PHP version. + * @return $this + */ + public function setHeaderLocator(Header\HeaderLocatorInterface $headerLocator) + { + $this->headerLocator = $headerLocator; + return $this; + } + + /** + * Set the header encoding + * + * @param string $encoding + * @return Headers + */ + public function setEncoding($encoding) + { + $this->encoding = $encoding; + foreach ($this as $header) { + $header->setEncoding($encoding); + } + return $this; + } + + /** + * Get the header encoding + * + * @return string + */ + public function getEncoding() + { + return $this->encoding; + } + + /** + * Add many headers at once + * + * Expects an array (or Traversable object) of type/value pairs. + * + * @param array|Traversable $headers + * @throws Exception\InvalidArgumentException + * @return Headers + */ + public function addHeaders($headers) + { + if (! is_array($headers) && ! $headers instanceof Traversable) { + throw new Exception\InvalidArgumentException(sprintf( + 'Expected array or Traversable; received "%s"', + is_object($headers) ? get_class($headers) : gettype($headers) + )); + } + + foreach ($headers as $name => $value) { + if (is_int($name)) { + if (is_string($value)) { + $this->addHeaderLine($value); + } elseif (is_array($value) && count($value) === 1) { + $this->addHeaderLine(key($value), current($value)); + } elseif (is_array($value) && count($value) === 2) { + $this->addHeaderLine($value[0], $value[1]); + } elseif ($value instanceof Header\HeaderInterface) { + $this->addHeader($value); + } + } elseif (is_string($name)) { + $this->addHeaderLine($name, $value); + } + } + + return $this; + } + + /** + * Add a raw header line, either in name => value, or as a single string 'name: value' + * + * This method allows for lazy-loading in that the parsing and instantiation of HeaderInterface object + * will be delayed until they are retrieved by either get() or current() + * + * @throws Exception\InvalidArgumentException + * @param string $headerFieldNameOrLine + * @param string $fieldValue optional + * @return Headers + */ + public function addHeaderLine($headerFieldNameOrLine, $fieldValue = null) + { + if (! is_string($headerFieldNameOrLine)) { + throw new Exception\InvalidArgumentException(sprintf( + '%s expects its first argument to be a string; received "%s"', + __METHOD__, + is_object($headerFieldNameOrLine) + ? get_class($headerFieldNameOrLine) + : gettype($headerFieldNameOrLine) + )); + } + + if ($fieldValue === null) { + $headers = $this->loadHeader($headerFieldNameOrLine); + $headers = is_array($headers) ? $headers : [$headers]; + foreach ($headers as $header) { + $this->addHeader($header); + } + } elseif (is_array($fieldValue)) { + foreach ($fieldValue as $i) { + $this->addHeader(Header\GenericMultiHeader::fromString($headerFieldNameOrLine . ':' . $i)); + } + } else { + $this->addHeader(GenericHeader::fromString($headerFieldNameOrLine . ':' . $fieldValue)); + } + + return $this; + } + + /** + * Add a Header\Interface to this container, for raw values see {@link addHeaderLine()} and {@link addHeaders()} + * + * @return Headers + */ + public function addHeader(HeaderInterface $header) + { + $key = $this->normalizeFieldName($header->getFieldName()); + $this->headersKeys[] = $key; + $this->headers[] = $header; + if ($this->getEncoding() !== 'ASCII') { + $header->setEncoding($this->getEncoding()); + } + return $this; + } + + /** + * Remove a Header from the container + * + * @param string|HeaderInterface $instanceOrFieldName field name or specific header instance to remove + * @return bool + */ + public function removeHeader($instanceOrFieldName) + { + if (! $instanceOrFieldName instanceof Header\HeaderInterface && ! is_string($instanceOrFieldName)) { + throw new Exception\InvalidArgumentException(sprintf( + '%s requires a string or %s instance; received %s', + __METHOD__, + HeaderInterface::class, + is_object($instanceOrFieldName) ? get_class($instanceOrFieldName) : gettype($instanceOrFieldName) + )); + } + + if ($instanceOrFieldName instanceof Header\HeaderInterface) { + $indexes = array_keys($this->headers, $instanceOrFieldName, true); + } + + if (is_string($instanceOrFieldName)) { + $key = $this->normalizeFieldName($instanceOrFieldName); + $indexes = array_keys($this->headersKeys, $key, true); + } + + if (! empty($indexes)) { + foreach ($indexes as $index) { + unset($this->headersKeys[$index]); + unset($this->headers[$index]); + } + return true; + } + + return false; + } + + /** + * Clear all headers + * + * Removes all headers from queue + * + * @return Headers + */ + public function clearHeaders() + { + $this->headers = $this->headersKeys = []; + return $this; + } + + /** + * Get all headers of a certain name/type + * + * @param string $name + * @return bool|ArrayIterator|HeaderInterface Returns false if there is no headers with $name in this + * contain, an ArrayIterator if the header is a MultipleHeadersInterface instance and finally returns + * HeaderInterface for the rest of cases. + */ + public function get($name) + { + $key = $this->normalizeFieldName($name); + $results = []; + + foreach (array_keys($this->headersKeys, $key, true) as $index) { + if ($this->headers[$index] instanceof Header\GenericHeader) { + $results[] = $this->lazyLoadHeader($index); + } else { + $results[] = $this->headers[$index]; + } + } + + switch (count($results)) { + case 0: + return false; + case 1: + if ($results[0] instanceof Header\MultipleHeadersInterface) { + return new ArrayIterator($results); + } + return $results[0]; + default: + return new ArrayIterator($results); + } + } + + /** + * Test for existence of a type of header + * + * @param string $name + * @return bool + */ + public function has($name) + { + $name = $this->normalizeFieldName($name); + return in_array($name, $this->headersKeys, true); + } + + /** + * Advance the pointer for this object as an iterator + */ + #[ReturnTypeWillChange] + public function next() + { + next($this->headers); + } + + /** + * Return the current key for this object as an iterator + * + * @return mixed + */ + #[ReturnTypeWillChange] + public function key() + { + return key($this->headers); + } + + /** + * Is this iterator still valid? + * + * @return bool + */ + #[ReturnTypeWillChange] + public function valid() + { + return current($this->headers) !== false; + } + + /** + * Reset the internal pointer for this object as an iterator + */ + #[ReturnTypeWillChange] + public function rewind() + { + reset($this->headers); + } + + /** + * Return the current value for this iterator, lazy loading it if need be + * + * @return HeaderInterface + */ + #[ReturnTypeWillChange] + public function current() + { + $current = current($this->headers); + if ($current instanceof Header\GenericHeader) { + $current = $this->lazyLoadHeader(key($this->headers)); + } + return $current; + } + + /** + * Return the number of headers in this contain, if all headers have not been parsed, actual count could + * increase if MultipleHeader objects exist in the Request/Response. If you need an exact count, iterate + * + * @return int count of currently known headers + */ + #[ReturnTypeWillChange] + public function count() + { + return count($this->headers); + } + + /** + * Render all headers at once + * + * This method handles the normal iteration of headers; it is up to the + * concrete classes to prepend with the appropriate status/request line. + * + * @return string + */ + public function toString() + { + $headers = ''; + foreach ($this as $header) { + if ($str = $header->toString()) { + $headers .= $str . self::EOL; + } + } + + return $headers; + } + + /** + * Return the headers container as an array + * + * @param bool $format Return the values in Mime::Encoded or in Raw format + * @return array + * @todo determine how to produce single line headers, if they are supported + */ + public function toArray($format = HeaderInterface::FORMAT_RAW) + { + $headers = []; + /** @var HeaderInterface $header */ + foreach ($this->headers as $header) { + if ($header instanceof Header\MultipleHeadersInterface) { + $name = $header->getFieldName(); + if (! isset($headers[$name])) { + $headers[$name] = []; + } + $headers[$name][] = $header->getFieldValue($format); + } else { + $headers[$header->getFieldName()] = $header->getFieldValue($format); + } + } + return $headers; + } + + /** + * By calling this, it will force parsing and loading of all headers, after this count() will be accurate + * + * @return bool + */ + public function forceLoading() + { + // phpcs:ignore Generic.CodeAnalysis.EmptyStatement.DetectedForeach + foreach ($this as $item) { + // $item should now be loaded + } + return true; + } + + /** + * Create Header object from header line + * + * @param string $headerLine + * @return HeaderInterface|HeaderInterface[] + */ + public function loadHeader($headerLine) + { + [$name] = GenericHeader::splitHeaderLine($headerLine); + + /** @var HeaderInterface $class */ + $class = $this->resolveHeaderClass($name); + return $class::fromString($headerLine); + } + + /** + * @param int $index + * @return mixed + */ + protected function lazyLoadHeader($index) + { + $current = $this->headers[$index]; + + $key = $this->headersKeys[$index]; + + /** @var GenericHeader $class */ + $class = $this->resolveHeaderClass($key); + + $encoding = $current->getEncoding(); + $headers = $class::fromString($current->toString()); + if (is_array($headers)) { + $current = array_shift($headers); + $current->setEncoding($encoding); + $this->headers[$index] = $current; + foreach ($headers as $header) { + $header->setEncoding($encoding); + $this->headersKeys[] = $key; + $this->headers[] = $header; + } + return $current; + } + + $current = $headers; + $current->setEncoding($encoding); + $this->headers[$index] = $current; + return $current; + } + + /** + * Normalize a field name + * + * @param string $fieldName + * @return string + */ + protected function normalizeFieldName($fieldName) + { + return str_replace(['-', '_', ' ', '.'], '', strtolower($fieldName)); + } + + /** + * @param string $key + * @return string + */ + private function resolveHeaderClass($key) + { + if ($this->pluginClassLoader) { + return $this->pluginClassLoader->load($key) ?: GenericHeader::class; + } + return $this->getHeaderLocator()->get($key, GenericHeader::class); + } +} From 09d058380011be5f8579c232c1c420cfbeb0f85a Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 2 Sep 2021 17:23:47 -0500 Subject: [PATCH 4/8] qa: update CI config - We no longer need to exclude builds, as those PHP versions are no longer supported. - We DO need to ignore platform PHP requirements for PHP 8.1. Signed-off-by: Matthew Weier O'Phinney --- .laminas-ci.json | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.laminas-ci.json b/.laminas-ci.json index 4cf251ab..bce3fa21 100644 --- a/.laminas-ci.json +++ b/.laminas-ci.json @@ -1,8 +1,5 @@ { - "exclude": [ - {"name": "PHPUnit on PHP 5.6 with locked dependencies"}, - {"name": "PHPUnit on PHP 7.0 with locked dependencies"}, - {"name": "PHPUnit on PHP 7.1 with locked dependencies"}, - {"name": "PHPUnit on PHP 7.2 with locked dependencies"} - ] + "ignore_php_platform_requirements": { + "8.1": true + } } From 14bb81e8e5f281a08fab7d7f6e41a856bcf50d16 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 2 Sep 2021 17:32:40 -0500 Subject: [PATCH 5/8] qa: bump minimum supported laminas-mail version to 2.12 First version providing HeaderLocator class Signed-off-by: Matthew Weier O'Phinney --- composer.json | 2 +- composer.lock | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index 4ae9fff3..ea0b1955 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,7 @@ }, "require-dev": { "laminas/laminas-coding-standard": "~2.2.1", - "laminas/laminas-mail": "^2.6", + "laminas/laminas-mail": "^2.12", "phpunit/phpunit": "^9.3" }, "suggest": { diff --git a/composer.lock b/composer.lock index bc3f6897..aeeb2d37 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1828c98cd3463d06400585e13392c0dd", + "content-hash": "77a8daa5c98d4a651b4fab53280b68e4", "packages": [ { "name": "laminas/laminas-stdlib", From 1cac0dced7cd31c742a501f9c88b982a27a68fb1 Mon Sep 17 00:00:00 2001 From: Matthew Weier O'Phinney Date: Thu, 2 Sep 2021 17:41:22 -0500 Subject: [PATCH 6/8] fix: ensure local Headers implementation is loaded in favor of laminas-mail implementation - Use `files` autoloader to load the local `Headers` version - Ensure that the import for `ReturnTypeWillChange` attribute is not removed by phpcs Signed-off-by: Matthew Weier O'Phinney --- composer.json | 6 ++++-- test/TestAsset/Mail/Headers.php | 3 ++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/composer.json b/composer.json index ea0b1955..abd18699 100644 --- a/composer.json +++ b/composer.json @@ -36,9 +36,11 @@ } }, "autoload-dev": { + "files": [ + "test/TestAsset/Mail/Headers.php" + ], "psr-4": { - "LaminasTest\\Mime\\": "test/", - "Laminas\\Mail\\": "test/TestAsset/Mail/" + "LaminasTest\\Mime\\": "test/" } }, "scripts": { diff --git a/test/TestAsset/Mail/Headers.php b/test/TestAsset/Mail/Headers.php index 321f6941..93c3e01b 100644 --- a/test/TestAsset/Mail/Headers.php +++ b/test/TestAsset/Mail/Headers.php @@ -1,4 +1,4 @@ - Date: Mon, 20 Sep 2021 16:12:25 -0500 Subject: [PATCH 7/8] fix: do not pass null value to strtolower Found this while testing laminas-mail; $wantedName has a default `null` value, which means that when calling `strtolower()` on that value, we may raise a deprecation notice under 8.1 as `null` values are no longer allowed to that function. Signed-off-by: Matthew Weier O'Phinney --- src/Decode.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Decode.php b/src/Decode.php index dc6d0eb5..5afdeab2 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -185,7 +185,7 @@ public static function splitContentType($type, $wantedPart = null) */ public static function splitHeaderField($field, $wantedPart = null, $firstName = '0') { - $wantedPart = strtolower($wantedPart); + $wantedPart = strtolower($wantedPart ?? ''); $firstName = strtolower($firstName); // special case - a bit optimized From aa8b5563ce685554a0a8aaa91aa8a45c278de895 Mon Sep 17 00:00:00 2001 From: Alexandr Penkin Date: Thu, 20 Jan 2022 16:07:50 +0300 Subject: [PATCH 8/8] zoonru changes --- composer.json | 2 +- src/Decode.php | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index abd18699..f97f30bc 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name": "laminas/laminas-mime", + "name": "zoonru/laminas-mime", "description": "Create and parse MIME messages and parts", "license": "BSD-3-Clause", "keywords": [ diff --git a/src/Decode.php b/src/Decode.php index 5afdeab2..1bd972db 100644 --- a/src/Decode.php +++ b/src/Decode.php @@ -62,7 +62,8 @@ public static function splitMime($body, $boundary) // no more parts, find end boundary $p = strpos($body, '--' . $boundary . '--', $start); if ($p === false) { - throw new Exception\RuntimeException('Not a valid Mime Message: End Missing'); + $p = strlen($body); + //throw new Exception\RuntimeException('Not a valid Mime Message: End Missing'); } // the remaining part also needs to be parsed: