From e7d95f5b04cd0d5a522107ae292865ee52d6ba6c Mon Sep 17 00:00:00 2001 From: Patrick Dawkins Date: Mon, 25 Nov 2024 21:32:14 +0000 Subject: [PATCH] Increase PHP version requirement to 8.2 --- .github/workflows/ci.yml | 31 + .gitignore | 4 +- .travis.yml | 27 - README.md | 2 - composer.json | 9 +- composer.lock | 1875 ++++++++++++------- ecs.php | 16 + phpunit.xml | 27 +- src/Context.php | 5 +- src/Exception/ConditionalFieldException.php | 12 +- src/Exception/FieldLevelException.php | 13 +- src/Exception/InvalidValueException.php | 6 +- src/Exception/MissingValueException.php | 6 +- src/Field/ArrayField.php | 104 +- src/Field/BooleanField.php | 53 +- src/Field/EmailAddressField.php | 4 +- src/Field/Field.php | 340 ++-- src/Field/FileField.php | 53 +- src/Field/OptionsField.php | 90 +- src/Field/UrlField.php | 4 +- src/Form.php | 73 +- tests/FormTest.php | 361 ++-- tests/bootstrap.php | 2 + 23 files changed, 1840 insertions(+), 1277 deletions(-) create mode 100644 .github/workflows/ci.yml delete mode 100644 .travis.yml create mode 100644 ecs.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000..2322804 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,31 @@ +name: CI + +on: + push: + branches: + - main + pull_request: + branches: + - main + +jobs: + lint-test: + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Set up PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.2' + + - name: Install dependencies + run: composer install --no-progress --no-suggest --no-interaction + + - name: Check coding standards + run: ./vendor/bin/ecs check + + - name: Run PHPUnit tests + run: ./vendor/bin/phpunit diff --git a/.gitignore b/.gitignore index 22d0d82..0056254 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -vendor +/vendor +/.phpunit.result.cache +/.phpunit.cache diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 296db2a..0000000 --- a/.travis.yml +++ /dev/null @@ -1,27 +0,0 @@ -language: php -dist: trusty -sudo: false - -php: - - 5.6 - - 7.0 - - 7.1 - - 7.2 - - 7.3 - - nightly - -matrix: - allow_failures: - - php: nightly - fast_finish: true - -cache: - directories: - - $HOME/.composer/cache - -install: - - composer install --no-interaction - -script: - - 'curl -H "Accept: text/plain" https://security.symfony.com/check_lock -F lock=@./composer.lock' - - ./vendor/bin/phpunit -c ./phpunit.xml --coverage-text diff --git a/README.md b/README.md index 430ea58..2785b06 100644 --- a/README.md +++ b/README.md @@ -4,8 +4,6 @@ A lightweight form system for Symfony Console commands. Commands can define forms which can be used both via command-line options and via interactive input. -[![Build Status](https://travis-ci.org/platformsh/console-form.svg?branch=master)](https://travis-ci.org/platformsh/console-form) - ## Example ```php =5.5.9", - "symfony/console": "^6.0 || ^5.0 || ^4.0 || ^3.0 || ^2.6" + "php": "^8.2", + "symfony/console": "^7.0 || ^6.0" }, "require-dev": { - "phpunit/phpunit": "^5.0" + "phpunit/phpunit": "^11", + "symplify/easy-coding-standard": "^12.3" }, "autoload": { "psr-4": { @@ -21,7 +22,7 @@ ], "config": { "platform": { - "php": "5.6" + "php": "8.2" } } } diff --git a/composer.lock b/composer.lock index 118d3e1..974d343 100644 --- a/composer.lock +++ b/composer.lock @@ -4,34 +4,34 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0b4a29663149b803db29989a4117190b", + "content-hash": "000fe99f768056b7397dd3e8643dce99", "packages": [ { - "name": "psr/log", - "version": "1.1.4", + "name": "psr/container", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Container\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -44,57 +44,63 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", "keywords": [ - "log", - "psr", - "psr-3" + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "symfony/console", - "version": "v3.4.47", + "version": "v7.1.8", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81" + "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a10b1da6fc93080c180bba7219b5ff5b7518fe81", - "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81", + "url": "https://api.github.com/repos/symfony/console/zipball/ff04e5b5ba043d2badfb308197b9e6b42883fcd5", + "reference": "ff04e5b5ba043d2badfb308197b9e6b42883fcd5", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/debug": "~2.8|~3.0|~4.0", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=8.2", + "symfony/polyfill-mbstring": "~1.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^6.4|^7.0" }, "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/process": "<3.3" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.3|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~2.8|~3.0|~4.0", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.3|~4.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -119,10 +125,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], "support": { - "source": "https://github.com/symfony/console/tree/v3.4.47" + "source": "https://github.com/symfony/console/tree/v7.1.8" }, "funding": [ { @@ -138,39 +150,268 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2024-11-06T14:23:19+00:00" }, { - "name": "symfony/debug", - "version": "v3.4.47", + "name": "symfony/deprecation-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "ab42889de57fdfcfcc0759ab102e2fd4ea72dcae" + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/ab42889de57fdfcfcc0759ab102e2fd4ea72dcae", - "reference": "ab42889de57fdfcfcc0759ab102e2fd4ea72dcae", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "psr/log": "~1.0" + "php": ">=8.1" }, - "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } }, - "require-dev": { - "symfony/http-kernel": "~2.8|~3.0|~4.0" + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Debug\\": "" + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" }, - "exclude-from-classmap": [ - "/Tests/" + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-09-09T11:45:10+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.31.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "3833d7255cc303546435cb650316bff708a1c75c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -179,18 +420,26 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Debug Component", + "description": "Symfony polyfill for intl's Normalizer class and related functions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/debug/tree/v3.4.47" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -206,33 +455,33 @@ "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.19.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "b5f7b932ee6fa802fc792eabd77c4c88084517ce" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/b5f7b932ee6fa802fc792eabd77c4c88084517ce", - "reference": "b5f7b932ee6fa802fc792eabd77c4c88084517ce", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.19-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -270,7 +519,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.19.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -286,44 +535,47 @@ "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" - } - ], - "packages-dev": [ + "time": "2024-09-09T11:45:10+00:00" + }, { - "name": "doctrine/instantiator", - "version": "1.0.5", + "name": "symfony/service-contracts", + "version": "v3.5.0", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "3.5-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" } }, "autoload": { "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -331,333 +583,408 @@ ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", "keywords": [ - "constructor", - "instantiate" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/master" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, - "time": "2015-06-14T21:17:01+00:00" + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" }, { - "name": "myclabs/deep-copy", - "version": "1.7.0", + "name": "symfony/string", + "version": "v7.1.8", "source": { "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + "url": "https://github.com/symfony/string.git", + "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "url": "https://api.github.com/repos/symfony/string/zipball/591ebd41565f356fcd8b090fe64dbb5878f50281", + "reference": "591ebd41565f356fcd8b090fe64dbb5878f50281", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=8.2", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^4.1" + "symfony/emoji": "^7.1", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { "files": [ - "src/DeepCopy/deep_copy.php" + "Resources/functions.php" ], "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - } + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "Create deep copies (clones) of your objects", + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", + "homepage": "https://symfony.com", "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" ], "support": { - "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.x" + "source": "https://github.com/symfony/string/tree/v7.1.8" }, - "time": "2017-10-19T19:58:43+00:00" - }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-11-13T13:31:21+00:00" + } + ], + "packages-dev": [ { - "name": "phpdocumentor/reflection-common", - "version": "1.0.1", + "name": "myclabs/deep-copy", + "version": "1.12.1", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src" - ] + "DeepCopy\\": "src/DeepCopy/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "Create deep copies (clones) of your objects", "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" + "clone", + "copy", + "duplicate", + "object", + "object graph" ], "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/master" + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, - "time": "2017-09-11T18:02:19+00:00" + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2024-11-08T17:47:46+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "3.3.2", + "name": "nikic/php-parser", + "version": "v5.3.1", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", - "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8eea230464783aa9671db8eea6f8c6ac5285794b", + "reference": "8eea230464783aa9671db8eea6f8c6ac5285794b", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Nikita Popov" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/3.x" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.3.1" }, - "time": "2017-11-10T14:09:06+00:00" + "time": "2024-10-08T18:51:32+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "name": "phar-io/manifest", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" - }, - "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "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": { - "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/master" + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2017-07-14T14:27:02+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { - "name": "phpspec/prophecy", - "version": "v1.10.3", + "name": "phar-io/version", + "version": "3.2.1", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "451c3cd1418cf640de218914901e51b064abb093" + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/451c3cd1418cf640de218914901e51b064abb093", - "reference": "451c3cd1418cf640de218914901e51b064abb093", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.3|^7.0", - "phpdocumentor/reflection-docblock": "^2.0|^3.0.2|^4.0|^5.0", - "sebastian/comparator": "^1.2.3|^2.0|^3.0|^4.0", - "sebastian/recursion-context": "^1.0|^2.0|^3.0|^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^2.5 || ^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5 || ^7.1" + "php": "^7.2 || ^8.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10.x-dev" - } - }, "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" }, { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], + "description": "Library for handling version information and constraints", "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2020-03-05T15:02:03+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "4.0.8", + "version": "11.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f7f08030e8811582cc459871d28d6f5a1a4d35ca", + "reference": "f7f08030e8811582cc459871d28d6f5a1a4d35ca", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-xmlwriter": "*", - "php": "^5.6 || ^7.0", - "phpunit/php-file-iterator": "^1.3", - "phpunit/php-text-template": "^1.2", - "phpunit/php-token-stream": "^1.4.2 || ^2.0", - "sebastian/code-unit-reverse-lookup": "^1.0", - "sebastian/environment": "^1.3.2 || ^2.0", - "sebastian/version": "^1.0 || ^2.0" + "nikic/php-parser": "^5.3.1", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "ext-xdebug": "^2.1.4", - "phpunit/phpunit": "^5.7" + "phpunit/phpunit": "^11.4.1" }, "suggest": { - "ext-xdebug": "^2.5.1" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { @@ -672,7 +999,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -684,33 +1011,42 @@ "xunit" ], "support": { - "irc": "irc://irc.freenode.net/phpunit", "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/4.0" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.7" }, - "time": "2017-04-02T07:44:40+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-09T06:21:38+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4" + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/730b01bc3e867237eaac355e06a36b85dd93a8b4", - "reference": "730b01bc3e867237eaac355e06a36b85dd93a8b4", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -725,7 +1061,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -736,30 +1072,48 @@ "iterator" ], "support": { - "irc": "irc://irc.freenode.net/phpunit", "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/1.4.5" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" }, - "time": "2017-11-27T13:52:08+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-27T05:02:59+00:00" }, { - "name": "phpunit/php-text-template", - "version": "1.2.1", + "name": "phpunit/php-invoker", + "version": "5.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "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/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "5.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -776,41 +1130,48 @@ "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", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, - "time": "2015-06-21T13:50:34+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:07:44+00:00" }, { - "name": "phpunit/php-timer", - "version": "1.0.9", + "name": "phpunit/php-text-template", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -825,46 +1186,52 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "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/master" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, - "time": "2017-02-26T11:10:40+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:08:43+00:00" }, { - "name": "phpunit/php-token-stream", - "version": "1.4.12", + "name": "phpunit/php-timer", + "version": "7.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "ext-tokenizer": "*", - "php": ">=5.3.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -879,33 +1246,40 @@ "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/1.4" + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, - "abandoned": true, - "time": "2017-12-04T08:55:13+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:09:35+00:00" }, { "name": "phpunit/phpunit", - "version": "5.7.27", + "version": "11.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c" + "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", - "reference": "b7803aeca3ccb99ad0a506fa80b64cd6a56bbc0c", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e8e8ed1854de5d36c088ec1833beae40d2dedd76", + "reference": "e8e8ed1854de5d36c088ec1833beae40d2dedd76", "shasum": "" }, "require": { @@ -914,33 +1288,29 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "~1.3", - "php": "^5.6 || ^7.0", - "phpspec/prophecy": "^1.6.2", - "phpunit/php-code-coverage": "^4.0.4", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "^1.2.4", - "sebastian/diff": "^1.4.3", - "sebastian/environment": "^1.3.4 || ^2.0", - "sebastian/exporter": "~2.0", - "sebastian/global-state": "^1.1", - "sebastian/object-enumerator": "~2.0", - "sebastian/resource-operations": "~1.0", - "sebastian/version": "^1.0.6|^2.0.1", - "symfony/yaml": "~2.1|~3.0|~4.0" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2" - }, - "require-dev": { - "ext-pdo": "*" + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.12.0", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.7", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.1", + "sebastian/comparator": "^6.1.1", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.1.3", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2" }, "suggest": { - "ext-xdebug": "*", - "phpunit/php-invoker": "~1.1" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -948,10 +1318,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.7.x-dev" + "dev-main": "11.4-dev" } }, "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], "classmap": [ "src/" ] @@ -976,43 +1349,49 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/5.7.27" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.4.3" }, - "time": "2018-02-01T05:50:59+00:00" + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-10-28T13:07:50+00:00" }, { - "name": "phpunit/phpunit-mock-objects", - "version": "3.4.4", + "name": "sebastian/cli-parser", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", - "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.6 || ^7.0", - "phpunit/php-text-template": "^1.2", - "sebastian/exporter": "^1.2 || ^2.0" - }, - "conflict": { - "phpunit/phpunit": "<5.4.0" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^5.4" - }, - "suggest": { - "ext-soap": "*" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1027,48 +1406,106 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], - "description": "Mock Object library for PHPUnit", - "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/", - "keywords": [ - "mock", - "xunit" + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:41:36+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6bb7d09d6623567178cf54126afa9c2310114268", + "reference": "6bb7d09d6623567178cf54126afa9c2310114268", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.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": { - "irc": "irc://irc.freenode.net/phpunit", - "issues": "https://github.com/sebastianbergmann/phpunit-mock-objects/issues", - "source": "https://github.com/sebastianbergmann/phpunit-mock-objects/tree/3.4" + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.1" }, - "abandoned": true, - "time": "2017-06-30T09:13:00+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:44:28+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "1de8cd5c010cb153fcd68b8d0f64606f523f7619" + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "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/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^8.5" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1090,7 +1527,8 @@ "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" + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" }, "funding": [ { @@ -1098,34 +1536,36 @@ "type": "github" } ], - "time": "2020-11-30T08:15:22+00:00" + "time": "2024-07-03T04:45:54+00:00" }, { "name": "sebastian/comparator", - "version": "1.2.4", + "version": "6.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/43d129d6a0f81c78bee378b46688293eb7ea3739", + "reference": "43d129d6a0f81c78bee378b46688293eb7ea3739", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^11.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-main": "6.2-dev" } }, "autoload": { @@ -1138,6 +1578,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1149,14 +1593,10 @@ { "name": "Bernhard Schussek", "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" } ], "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", + "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", @@ -1164,34 +1604,100 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/1.2" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-10-31T05:30:08+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.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", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" }, - "time": "2017-01-29T09:50:25+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:49:50+00:00" }, { "name": "sebastian/diff", - "version": "1.4.3", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1204,50 +1710,63 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" } ], "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "diff" + "diff", + "udiff", + "unidiff", + "unified diff" ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/1.4" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" }, - "time": "2017-05-22T07:24:03+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:53:05+00:00" }, { "name": "sebastian/environment", - "version": "2.0.0", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^5.0" + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "7.2-dev" } }, "autoload": { @@ -1266,7 +1785,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -1274,36 +1793,43 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/master" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" }, - "time": "2016-11-26T07:53:53+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:54:44+00:00" }, { "name": "sebastian/exporter", - "version": "2.0.0", + "version": "6.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", + "reference": "c414673eee9a8f9d51bbf8d61fc9e3ef1e85b20e", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~2.0" + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^11.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -1316,6 +1842,10 @@ "BSD-3-Clause" ], "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, { "name": "Jeff Welch", "email": "whatthejeff@gmail.com" @@ -1324,58 +1854,61 @@ "name": "Volker Dusch", "email": "github@wallbash.com" }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, { "name": "Adam Harvey", "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/master" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.1.3" }, - "time": "2016-11-19T08:54:04+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:56:19+00:00" }, { "name": "sebastian/global-state", - "version": "1.1.1", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" - }, - "suggest": { - "ext-uopz": "*" + "ext-dom": "*", + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -1394,41 +1927,107 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/1.1.1" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:57:36+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" }, - "time": "2015-10-12T03:26:01+00:00" + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.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", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T04:58:38+00:00" }, { "name": "sebastian/object-enumerator", - "version": "2.0.1", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": ">=5.6", - "sebastian/recursion-context": "~2.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "~5" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1450,34 +2049,41 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/master" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, - "time": "2017-02-18T15:18:39+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:00:13+00:00" }, { - "name": "sebastian/recursion-context", - "version": "2.0.0", + "name": "sebastian/object-reflector", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1490,48 +2096,50 @@ "BSD-3-Clause" ], "authors": [ - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, - "time": "2016-11-19T07:33:16+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:01:32+00:00" }, { - "name": "sebastian/resource-operations", - "version": "1.0.0", + "name": "sebastian/recursion-context", + "version": "6.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", "shasum": "" }, "require": { - "php": ">=5.6.0" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1547,37 +2155,55 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/master" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" }, - "time": "2015-07-28T20:34:47+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-07-03T05:10:34+00:00" }, { - "name": "sebastian/version", - "version": "2.0.1", + "name": "sebastian/type", + "version": "5.1.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", - "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -1596,229 +2222,198 @@ "role": "lead" } ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", + "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/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/master" + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" }, - "time": "2016-10-03T07:35:21+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-09-17T13:12:04+00:00" }, { - "name": "symfony/polyfill-ctype", - "version": "v1.19.0", + "name": "sebastian/version", + "version": "5.0.2", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/aed596913b70fae57be53d86faa2e9ef85a2297b", - "reference": "aed596913b70fae57be53d86faa2e9ef85a2297b", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.19-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "dev-main": "5.0-dev" } }, "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.19.0" + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2020-10-23T09:01:57+00:00" + "time": "2024-10-09T05:16:32+00:00" }, { - "name": "symfony/yaml", - "version": "v3.4.47", + "name": "symplify/easy-coding-standard", + "version": "12.3.6", "source": { "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "88289caa3c166321883f67fe5130188ebbb47094" + "url": "https://github.com/easy-coding-standard/easy-coding-standard.git", + "reference": "c0f378782d06dfd21c66c3024e9d28f4e737645e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/88289caa3c166321883f67fe5130188ebbb47094", - "reference": "88289caa3c166321883f67fe5130188ebbb47094", + "url": "https://api.github.com/repos/easy-coding-standard/easy-coding-standard/zipball/c0f378782d06dfd21c66c3024e9d28f4e737645e", + "reference": "c0f378782d06dfd21c66c3024e9d28f4e737645e", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/polyfill-ctype": "~1.8" + "php": ">=7.2" }, "conflict": { - "symfony/console": "<3.4" - }, - "require-dev": { - "symfony/console": "~3.4|~4.0" + "friendsofphp/php-cs-fixer": "<3.46", + "phpcsstandards/php_codesniffer": "<3.8", + "symplify/coding-standard": "<12.1" }, "suggest": { - "symfony/console": "For validating YAML files using the lint command" + "ext-dom": "Needed to support checkstyle output format in class CheckstyleOutputFormatter" }, + "bin": [ + "bin/ecs" + ], "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } + "description": "Use Coding Standard with 0-knowledge of PHP-CS-Fixer and PHP_CodeSniffer", + "keywords": [ + "Code style", + "automation", + "fixer", + "static analysis" ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v3.4.47" + "issues": "https://github.com/easy-coding-standard/easy-coding-standard/issues", + "source": "https://github.com/easy-coding-standard/easy-coding-standard/tree/12.3.6" }, "funding": [ { - "url": "https://symfony.com/sponsor", + "url": "https://www.paypal.me/rectorphp", "type": "custom" }, { - "url": "https://github.com/fabpot", + "url": "https://github.com/tomasvotruba", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2024-10-06T08:27:28+00:00" }, { - "name": "webmozart/assert", - "version": "1.9.1", + "name": "theseer/tokenizer", + "version": "1.2.3", "source": { "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" }, "type": "library", "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" } ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.9.1" + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, - "time": "2020-07-08T17:02:28+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.5.9" + "php": "^8.2" }, - "platform-dev": [], + "platform-dev": {}, "platform-overrides": { - "php": "5.6" + "php": "8.2" }, - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.6.0" } diff --git a/ecs.php b/ecs.php new file mode 100644 index 0000000..957de29 --- /dev/null +++ b/ecs.php @@ -0,0 +1,16 @@ +withPaths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) + ->withPreparedSets( + psr12: true, + common: true, + strict: true, + ); diff --git a/phpunit.xml b/phpunit.xml index c34e68c..659c34b 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -1,13 +1,24 @@ - + - - ./tests/ + + tests - - - ./src/ - - + + + + src + + diff --git a/src/Context.php b/src/Context.php index 1753dea..7cc565a 100644 --- a/src/Context.php +++ b/src/Context.php @@ -1,5 +1,7 @@ previousValues; } diff --git a/src/Exception/FieldLevelException.php b/src/Exception/FieldLevelException.php index e7360bf..e50e68b 100644 --- a/src/Exception/FieldLevelException.php +++ b/src/Exception/FieldLevelException.php @@ -1,11 +1,14 @@ field; } } diff --git a/src/Exception/InvalidValueException.php b/src/Exception/InvalidValueException.php index 89a3872..33f68ad 100644 --- a/src/Exception/InvalidValueException.php +++ b/src/Exception/InvalidValueException.php @@ -1,5 +1,9 @@ splitPattern, $str), 'strlen'); - } - - /** - * {@inheritdoc} - */ - protected function getQuestionText() + public function getAsQuestion(): Question { - $text = $this->getQuestionHeader(false); - if (!empty($this->default)) { - $text .= "\n" . 'Default: ' . implode(', ', (array) $this->default) . ''; - } - if ($this->splitPattern === self::SPLIT_PATTERN_COMMA_NEWLINE || $this->splitPattern === self::SPLIT_PATTERN_COMMA_WHITESPACE) { - $text .= "\nEnter comma-separated values"; - if (!$this->isRequired()) { - $text .= ' (or leave this blank)'; + $question = new Question($this->getQuestionText(), $this->default ? implode(', ', $this->default) : null); + $question->setMaxAttempts($this->maxAttempts); + $question->setValidator(function ($value) { + if ($this->isEmpty($value) && $this->isRequired()) { + throw new MissingValueException("'{$this->name}' is required", $this); } - } - $text .= "\n" . $this->prompt; + $this->validate($value); - return $text; + return $value; + }); + $question->setAutocompleterValues($this->autoCompleterValues); + + return $question; } - /** - * {@inheritdoc} - */ - public function matchesCondition($userValue, $condition) + public function matchesCondition(mixed $userValue, mixed $condition): bool { if (is_callable($condition)) { return $condition($userValue); } - return !array_diff($userValue, $condition); + return ! array_diff($userValue, $condition); } - /** - * {@inheritdoc} - */ - public function getOptionMode() + public function getOptionMode(): int { return InputOption::VALUE_IS_ARRAY | InputOption::VALUE_REQUIRED; } - /** - * {@inheritdoc} - */ - public function isEmpty($value) + public function isEmpty(mixed $value): bool { return empty($value); } + public function isRequired(): bool + { + return $this->required && empty($this->default); + } + + protected function getQuestionText(): string + { + $text = $this->getQuestionHeader(false); + if (! empty($this->default)) { + $text .= "\n" . 'Default: ' . implode(', ', (array) $this->default) . ''; + } + if ($this->splitPattern === self::SPLIT_PATTERN_COMMA_NEWLINE || $this->splitPattern === self::SPLIT_PATTERN_COMMA_WHITESPACE) { + $text .= "\nEnter comma-separated values"; + if (! $this->isRequired()) { + $text .= ' (or leave this blank)'; + } + } + $text .= "\n" . $this->prompt; + + return $text; + } + /** - * {@inheritdoc} + * Split a comma or whitespace-separated string into an array. */ - public function isRequired() + private function split(string $str): array { - return $this->required && empty($this->default); + return array_filter(preg_split($this->splitPattern, $str), 'strlen'); } } diff --git a/src/Field/BooleanField.php b/src/Field/BooleanField.php index e016e1a..031100d 100644 --- a/src/Field/BooleanField.php +++ b/src/Field/BooleanField.php @@ -1,5 +1,7 @@ defaultCallback) && !isset($this->default)) { + if (! isset($this->defaultCallback) && ! isset($this->default)) { $this->default = $this->originalDefault = true; } $this->autoCompleterValues = ['true', 'false', 'yes', 'no']; } - /** - * {@inheritdoc} - */ - protected function getQuestionText() - { - return rtrim($this->getQuestionHeader(false), '?') - . '? [default: ' - . ($this->default ? 'true' : 'false') - . '] '; - } - - /** - * {@inheritdoc} - */ - public function isEmpty($value) + public function isEmpty(mixed $value): bool { // False is not empty. if ($value === false) { @@ -43,26 +31,29 @@ public function isEmpty($value) return parent::isEmpty($value); } - /** - * {@inheritdoc} - */ - protected function normalize($value) + protected function getQuestionText(): string + { + return rtrim($this->getQuestionHeader(false), '?') + . '? [default: ' + . ($this->default ? 'true' : 'false') + . '] '; + } + + protected function normalize(mixed $value): bool { if (is_bool($value)) { return $value; - } - elseif (preg_match('/^(0|false|no|n)$/i', $value)) { + } elseif (preg_match('/^(0|false|no|n)$/i', $value)) { return false; - } - elseif (preg_match('/^(1|true|yes|y)$/i', $value)) { + } elseif (preg_match('/^(1|true|yes|y)$/i', $value)) { return true; } - else { - throw new InvalidValueException(sprintf( - "Invalid value for '%s': %s (expected 1, 0, true, or false)", - $this->name, - $value - ), $this); - } + + throw new InvalidValueException(sprintf( + "Invalid value for '%s': %s (expected 1, 0, true, or false)", + $this->name, + $value + ), $this); + } } diff --git a/src/Field/EmailAddressField.php b/src/Field/EmailAddressField.php index 542f0bc..ef4f4f6 100644 --- a/src/Field/EmailAddressField.php +++ b/src/Field/EmailAddressField.php @@ -1,5 +1,7 @@ validators[] = function ($value) { - return filter_var($value, FILTER_VALIDATE_EMAIL) ? true : "Invalid email address: $value"; + return filter_var($value, FILTER_VALIDATE_EMAIL) ? true : "Invalid email address: {$value}"; }; } } diff --git a/src/Field/Field.php b/src/Field/Field.php index 7914da0..929c5de 100644 --- a/src/Field/Field.php +++ b/src/Field/Field.php @@ -1,5 +1,7 @@ '; + protected string $prompt = '> '; /** * The required value marker. - * - * @var string */ - protected $requiredMarker = '* '; + protected string $requiredMarker = '* '; /** * A callback used to calculate a dynamic default. @@ -113,31 +95,29 @@ class Field * The callback accepts an array of values entered previously for other form * fields. It returns the new default. * - * @var callable + * @var callable|null */ - protected $defaultCallback; + protected $defaultCallback = null; /** * Validator callbacks. * * @see self::validate() * - * @var callable[] $validators + * @var callable[] * An array of callbacks accepting a single value (the normalized input * from the user). Each callback should return either a string or Boolean * false if there was a validation error. Anything else is treated as * success. */ - protected $validators = []; + protected array $validators = []; /** * The number of attempts the user can make to answer a question. * * @see Question::setMaxAttempts() - * - * @var int */ - protected $maxAttempts = 5; + protected int $maxAttempts = 5; /** * Normalizer callbacks. @@ -146,7 +126,7 @@ class Field * An array of callbacks. Each callback takes one argument (the user * input) and returns it normalized. */ - protected $normalizers = []; + protected array $normalizers = []; /** * The conditions under which the field will be displayed or used. @@ -160,7 +140,7 @@ class Field * be displayed. If the condition is a callable, it will be called with * one argument (the user input) and expected to return a boolean. */ - protected $conditions = []; + protected array $conditions = []; /** * Array keys, under which the value of this field should be returned. @@ -170,25 +150,21 @@ class Field * * @var string[] */ - protected $valueKeys = []; + protected array $valueKeys = []; /** * Avoids asking the field as a question, if it already has a default or is not required. - * - * @var bool */ - protected $avoidQuestion; + protected bool $avoidQuestion = false; /** - * Constructor. - * * @param string $name * The field name. * @param array $config * Other field configuration. The keys are protected properties of this * class. */ - public function __construct($name, array $config = []) + public function __construct(string $name, array $config = []) { $this->name = $name; foreach ($config as $key => $value) { @@ -198,13 +174,8 @@ public function __construct($name, array $config = []) /** * Set or modify a configuration value. - * - * @param string $key - * @param mixed $value - * - * @return self */ - public function set($key, $value) + public function set(string $key, mixed $value): static { switch ($key) { case 'validator': @@ -220,10 +191,10 @@ public function set($key, $value) break; default: - if (!property_exists($this, $key)) { - throw new \InvalidArgumentException("Unrecognized config key: $key"); + if (! property_exists($this, $key)) { + throw new \InvalidArgumentException("Unrecognized config key: {$key}"); } - $this->$key = $value; + $this->{$key} = $value; } return $this; @@ -234,30 +205,23 @@ public function set($key, $value) * * @return string[] */ - public function getValueKeys() + public function getValueKeys(): array { return $this->valueKeys; } /** * Get the field's conditions. - * - * @return array */ - public function getConditions() + public function getConditions(): array { return $this->conditions; } /** * Test whether the user's input matches the provided condition value. - * - * @param mixed $userValue - * @param mixed $condition - * - * @return bool */ - public function matchesCondition($userValue, $condition) + public function matchesCondition(mixed $userValue, mixed $condition): bool { if (is_callable($condition)) { return $condition($userValue); @@ -266,36 +230,16 @@ public function matchesCondition($userValue, $condition) return $userValue === $condition; } - /** - * Normalize user input. - * - * @param mixed $value - * - * @return mixed - */ - protected function normalize($value) - { - if ($value === null) { - return $value; - } - foreach ($this->normalizers as $normalizer) { - $value = $normalizer($value); - } - - return $value; - } - /** * Validate the field. * - * @throws InvalidValueException if the input was invalid. - * * @param mixed $value * The user-entered value. * @param bool $fromOption * Whether the validation is from a command-line option. This changes the default error message. + *@throws InvalidValueException if the input was invalid. */ - public function validate($value, $fromOption = false) + public function validate(mixed $value, bool $fromOption = false): void { if ($value === null) { return; @@ -322,27 +266,23 @@ public function validate($value, $fromOption = false) * The option name. Either this is set via a config key (optionName), or a * sanitized version of the field name is used. */ - public function getOptionName() + public function getOptionName(): string { return $this->optionName ?: preg_replace('/[^a-z0-9-]+/', '-', strtolower($this->name)); } /** * Returns whether to include this field as a command-line option. - * - * @return bool */ - public function includeAsOption() + public function includeAsOption(): bool { return $this->includeAsOption; } /** * Get the field as a Console input option. - * - * @return InputOption */ - public function getAsOption() + public function getAsOption(): InputOption { return new InputOption( $this->getOptionName(), @@ -353,64 +293,21 @@ public function getAsOption() ); } - /** - * Get the description of the field, used in help and interactive questions. - * - * @return string - */ - protected function getDescription() - { - return $this->description ?: $this->name; - } - - /** - * Get the header text for an interactive question. - * - * @param bool $includeDefault - * - * @return string - */ - protected function getQuestionHeader($includeDefault = true) - { - $header = ''; - if ($this->isRequired()) { - $header .= $this->requiredMarker; - } - $header .= '' . $this->name . ''; - if ($this->includeAsOption) { - $header .= ' (--' . $this->getOptionName() . ')'; - } - if ($this->questionLine === null && !empty($this->description)) { - $header .= "\n" . $this->description; - } elseif (!empty($this->questionLine)) { - $header .= "\n" . $this->questionLine; - } - if ($includeDefault && $this->default !== null) { - $header .= "\n" . 'Default: ' . $this->formatDefault($this->default) . ''; - } - - return $header; - } - /** * Returns whether the field should be asked as a Console question. - * - * @return bool */ - public function shouldAskAsQuestion() + public function shouldAskAsQuestion(): bool { if ($this->avoidQuestion) { - return $this->isRequired() && !$this->hasDefault(); + return $this->isRequired() && ! $this->hasDefault(); } return true; } /** * Get the field as a Console question. - * - * @return Question */ - public function getAsQuestion() + public function getAsQuestion(): Question { $question = new Question($this->getQuestionText(), $this->default); $question->setMaxAttempts($this->maxAttempts); @@ -427,70 +324,25 @@ public function getAsQuestion() return $question; } - /** - * Get the text of the interactive question. - * - * @return string - */ - protected function getQuestionText() - { - return $this->getQuestionHeader() . "\n" . $this->prompt; - } - - /** - * Get the default as a string. - * - * Borrowed from \Symfony\Component\Console\Descriptor::formatDefaultValue(). - * - * @param mixed $default - * - * @return string - */ - protected function formatDefault($default) - { - if (is_string($default)) { - return $default; - } - - return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); - } - - /** - * Get the Console option mode for the field. - * - * @return int - */ - protected function getOptionMode() - { - return InputOption::VALUE_REQUIRED; - } - /** * Test whether a value is empty. - * - * @param mixed $value - * - * @return bool */ - public function isEmpty($value) + public function isEmpty(mixed $value): bool { - return empty($value) && (!is_string($value) || !strlen($value)); + return empty($value) && (! is_string($value) || ! strlen($value)); } /** * Get the value the user entered for this field. * - * @param InputInterface $input - * @param bool $normalize - * * @return mixed|null * The raw value, or null if the user did not enter anything. The value * will be normalized if $normalize is set. */ - public function getValueFromInput(InputInterface $input, $normalize = true) + public function getValueFromInput(InputInterface $input, bool $normalize = true): mixed { $optionName = $this->getOptionName(); - if (!$input->hasOption($optionName)) { + if (! $input->hasOption($optionName)) { return null; } $value = $input->getOption($optionName); @@ -506,12 +358,8 @@ public function getValueFromInput(InputInterface $input, $normalize = true) /** * Get the default value of this field, or the normalized user's value. - * - * @param mixed $userValue - * - * @return mixed */ - public function getFinalValue($userValue) + public function getFinalValue(mixed $userValue): mixed { return $this->isEmpty($userValue) ? $this->default : $this->normalize($userValue); @@ -519,44 +367,114 @@ public function getFinalValue($userValue) /** * Check whether the user must enter a value for this field. - * - * @return bool */ - public function isRequired() + public function isRequired(): bool { return $this->required; } /** * Check whether a default is set for the field. - * - * @return bool */ - public function hasDefault() + public function hasDefault(): bool { return isset($this->default); } /** * Get the name of the field. - * - * @return string */ - public function getName() + public function getName(): string { return $this->name; } /** * React to a change in user input. + */ + public function onChange(array $previousValues): void + { + if (isset($this->defaultCallback)) { + $callback = $this->defaultCallback; + $this->default = $callback($previousValues); + } + } + + /** + * Normalize user input. + */ + protected function normalize(mixed $value): mixed + { + if ($value === null) { + return null; + } + foreach ($this->normalizers as $normalizer) { + $value = $normalizer($value); + } + + return $value; + } + + /** + * Get the description of the field, used in help and interactive questions. + */ + protected function getDescription(): string + { + return $this->description ?: $this->name; + } + + /** + * Get the header text for an interactive question. + */ + protected function getQuestionHeader(bool $includeDefault = true): string + { + $header = ''; + if ($this->isRequired()) { + $header .= $this->requiredMarker; + } + $header .= '' . $this->name . ''; + if ($this->includeAsOption) { + $header .= ' (--' . $this->getOptionName() . ')'; + } + if ($this->questionLine === null && ! empty($this->description)) { + $header .= "\n" . $this->description; + } elseif (! empty($this->questionLine)) { + $header .= "\n" . $this->questionLine; + } + if ($includeDefault && $this->default !== null) { + $header .= "\n" . 'Default: ' . $this->formatDefault($this->default) . ''; + } + + return $header; + } + + /** + * Get the text of the interactive question. + */ + protected function getQuestionText(): string + { + return $this->getQuestionHeader() . "\n" . $this->prompt; + } + + /** + * Get the default as a string. * - * @param array $previousValues + * Borrowed from \Symfony\Component\Console\Descriptor::formatDefaultValue(). */ - public function onChange(array $previousValues) + protected function formatDefault(mixed $default): string { - if (isset($this->defaultCallback)) { - $callback = $this->defaultCallback; - $this->default = $callback($previousValues); - } + if (is_string($default)) { + return $default; + } + + return json_encode($default, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE); + } + + /** + * Get the Console option mode for the field. + */ + protected function getOptionMode(): int + { + return InputOption::VALUE_REQUIRED; } } diff --git a/src/Field/FileField.php b/src/Field/FileField.php index 39505ab..11fd145 100644 --- a/src/Field/FileField.php +++ b/src/Field/FileField.php @@ -1,51 +1,54 @@ validators[] = function ($value) { - if ($this->requireExists && !file_exists($value)) { - return "File not found: $value"; + if ($this->requireExists && ! file_exists($value)) { + return "File not found: {$value}"; } if (is_dir($value)) { - return "The file is a directory: $value"; + return "The file is a directory: {$value}"; } - if ($this->requireExists && $this->requireReadable && !is_readable($value)) { - return "File not readable: $value"; + if ($this->requireExists && $this->requireReadable && ! is_readable($value)) { + return "File not readable: {$value}"; } - if ($this->requireExists && $this->requireWritable && !is_writable($value)) { - return "File not writable: $value"; + if ($this->requireExists && $this->requireWritable && ! is_writable($value)) { + return "File not writable: {$value}"; } - if (!$this->matchesAllowedExtension($value)) { - return "Invalid file extension (allowed: " . implode(', ', $this->allowedExtensions) . ")"; + if (! $this->matchesAllowedExtension($value)) { + return 'Invalid file extension (allowed: ' . implode(', ', $this->allowedExtensions) . ')'; } return true; }; } - /** - * {@inheritDoc} - */ - public function getFinalValue($userValue) + public function getFinalValue(mixed $userValue): mixed { $value = parent::getFinalValue($userValue); - if (!empty($value) && $this->contentsAsValue) { + if (! empty($value) && $this->contentsAsValue) { $contents = file_get_contents($value); if ($contents === false) { throw new \RuntimeException('Failed to read file: ' . $value); @@ -59,23 +62,19 @@ public function getFinalValue($userValue) /** * Checks whether the filename matches an allowed extension. - * - * @param string $filename - * - * @return bool */ - private function matchesAllowedExtension($filename) + private function matchesAllowedExtension(string $filename): bool { if (empty($this->allowedExtensions)) { return true; } foreach ($this->allowedExtensions as $allowedExtension) { $normalized = '.' . ltrim($allowedExtension, '.'); - if (substr($filename, - strlen($normalized)) === $normalized) { + if (str_ends_with($filename, $normalized)) { return true; } } - if (in_array('', $this->allowedExtensions, true) && strpos($filename, '.') === false) { + if (in_array('', $this->allowedExtensions, true) && ! str_contains($filename, '.')) { return true; } diff --git a/src/Field/OptionsField.php b/src/Field/OptionsField.php index 2009dba..316bc4a 100644 --- a/src/Field/OptionsField.php +++ b/src/Field/OptionsField.php @@ -1,18 +1,23 @@ validOptions(); - return array_search($value, $options, true) !== false - ? true : "$value is not one of: " . implode(', ', $options); + return in_array($value, $options, true) + ? true : "{$value} is not one of: " . implode(', ', $options); }; } - /** - * Return a list of valid option values. - * - * @return array - */ - private function validOptions() - { - return $this->isNumeric() ? $this->options : array_keys($this->options); - } - - /** - * {@inheritdoc} - */ - public function matchesCondition($userValue, $condition) + public function matchesCondition(mixed $userValue, mixed $condition): bool { if (is_callable($condition)) { return $condition($userValue); } return is_array($condition) - ? in_array($userValue, $condition) + ? in_array($userValue, $condition, true) : $userValue === $condition; } - /** - * {@inheritdoc} - */ - public function getAsQuestion() + public function getAsQuestion(): ChoiceQuestion|\Symfony\Component\Console\Question\Question { if ($this->asChoice) { $question = $this->getChoiceQuestion(); - } - else { + } else { $question = parent::getAsQuestion(); $question->setAutocompleterValues($this->options); } @@ -81,10 +66,16 @@ public function getAsQuestion() return $question; } - /** - * {@inheritdoc} - */ - protected function getChoiceQuestion() + public function onChange(array $previousValues): void + { + parent::onChange($previousValues); + if (isset($this->optionsCallback)) { + $callback = $this->optionsCallback; + $this->options = $callback($previousValues); + } + } + + protected function getChoiceQuestion(): ChoiceQuestion { $numeric = $this->isNumeric(); $text = $this->getQuestionHeader(); @@ -98,7 +89,7 @@ protected function getChoiceQuestion() ); $question->setPrompt($this->prompt); $question->setMaxAttempts($this->maxAttempts); - if (!$numeric) { + if (! $numeric) { $question->setAutocompleterValues(array_keys($this->options)); } $question->setValidator(function ($userInput) use ($numeric) { @@ -126,16 +117,13 @@ protected function getChoiceQuestion() return $question; } - /** - * @return string - */ - protected function getDescription() + protected function getDescription(): string { $description = parent::getDescription(); $validOptions = $this->validOptions(); - if (!empty($validOptions) && $this->autoDescribe) { + if (! empty($validOptions) && $this->autoDescribe) { $separator = count($validOptions) === 2 ? ' or ' : ', '; - $optionsString = "'" . implode("'$separator'", $this->validOptions()) . "'"; + $optionsString = "'" . implode("'{$separator}'", $this->validOptions()) . "'"; if (strlen($optionsString) < 255) { $description .= ' ('; if ($this->allowOther) { @@ -149,26 +137,20 @@ protected function getDescription() } /** - * {@inheritdoc} + * Return a list of valid option values. */ - public function onChange(array $previousValues) + private function validOptions(): array { - parent::onChange($previousValues); - if (isset($this->optionsCallback)) { - $callback = $this->optionsCallback; - $this->options = $callback($previousValues); - } + return $this->isNumeric() ? $this->options : array_keys($this->options); } /** * Check if this is numeric, rather than associative. - * - * @return bool */ - private function isNumeric() + private function isNumeric(): bool { foreach (array_keys($this->options) as $key) { - if (!is_int($key)) { + if (! is_int($key)) { return false; } } diff --git a/src/Field/UrlField.php b/src/Field/UrlField.php index 4454a8b..8f49f00 100644 --- a/src/Field/UrlField.php +++ b/src/Field/UrlField.php @@ -1,5 +1,7 @@ validators[] = function ($value) { - return parse_url($value, PHP_URL_HOST) ? true : "Invalid URL: $value"; + return parse_url($value, PHP_URL_HOST) ? true : "Invalid URL: {$value}"; }; } } diff --git a/src/Form.php b/src/Form.php index 561ff56..4afb63a 100644 --- a/src/Form.php +++ b/src/Form.php @@ -1,5 +1,7 @@ fields[$key] = $field; @@ -34,14 +35,10 @@ public function addField(Field $field, $key = null) /** * Get a single form field. - * - * @param string $key - * - * @return Field|false */ - public function getField($key) + public function getField(string $key): false|Field { - if (!isset($this->fields[$key])) { + if (! isset($this->fields[$key])) { return false; } @@ -52,10 +49,8 @@ public function getField($key) * Create a form from an array of fields. * * @param Field[] $fields - * - * @return static */ - public static function fromArray(array $fields) + public static function fromArray(array $fields): static { $form = new static(); foreach ($fields as $key => $field) { @@ -67,10 +62,8 @@ public static function fromArray(array $fields) /** * Add options to a Symfony Console input definition. - * - * @param InputDefinition $definition */ - public function configureInputDefinition(InputDefinition $definition) + public function configureInputDefinition(InputDefinition $definition): void { foreach ($this->fields as $field) { if ($field->includeAsOption()) { @@ -84,25 +77,21 @@ public function configureInputDefinition(InputDefinition $definition) * * @return Field[] */ - public function getFields() + public function getFields(): array { return $this->fields; } /** * Validates command-line input, partially, without using interaction. - * - * @param InputInterface $input - * - * @return void */ - public function validateInputBeforeInteraction(InputInterface $input) + public function validateInputBeforeInteraction(InputInterface $input): void { $values = []; foreach ($this->fields as $key => $field) { $field->onChange($values); - if (!$this->includeField($field, $values, true)) { + if (! $this->includeField($field, $values, true)) { if ($field->getValueFromInput($input, false) !== null) { throw new ConditionalFieldException('--' . $field->getOptionName() . ' is not applicable', $field, $values); } @@ -131,18 +120,13 @@ public function validateInputBeforeInteraction(InputInterface $input) * - defaults * - interactive questions * - * @param InputInterface $input - * @param OutputInterface $output - * @param QuestionHelper $helper - * @param Context|null $context - * * @throws InvalidValueException if any of the input was invalid. * * @return array * An array of normalized field values. The array keys match those * provided as the second argument to self::addField(). */ - public function resolveOptions(InputInterface $input, OutputInterface $output, QuestionHelper $helper, Context $context = null) + public function resolveOptions(InputInterface $input, OutputInterface $output, QuestionHelper $helper, Context $context = null): array { $context = $context ?: new Context(); try { @@ -157,7 +141,7 @@ public function resolveOptions(InputInterface $input, OutputInterface $output, Q foreach ($this->fields as $key => $field) { $field->onChange($values); - if (!$this->includeField($field, $values)) { + if (! $this->includeField($field, $values)) { if ($field->getValueFromInput($input, false) !== null) { throw new ConditionalFieldException('--' . $field->getOptionName() . ' is not applicable', $field, $values); } @@ -172,7 +156,7 @@ public function resolveOptions(InputInterface $input, OutputInterface $output, Q // Get the value interactively. $value = $helper->ask($input, $stdErr, $field->getAsQuestion()); $stdErr->writeln(''); - } elseif ($field->isRequired() && !$field->hasDefault()) { + } elseif ($field->isRequired() && ! $field->hasDefault()) { throw new MissingValueException('--' . $field->getOptionName() . ' is required', $field); } @@ -189,24 +173,18 @@ public function resolveOptions(InputInterface $input, OutputInterface $output, Q /** * Determine whether the field should be included. - * - * @param Field $field - * @param array $previousValues - * @param bool $ignoreUnsetValues - * - * @return bool */ - public function includeField(Field $field, array $previousValues, $ignoreUnsetValues = false) + public function includeField(Field $field, array $previousValues, bool $ignoreUnsetValues = false): bool { foreach ($field->getConditions() as $previousField => $condition) { $previousFieldObject = $this->getField($previousField); - if ($previousFieldObject === false || !isset($previousValues[$previousField])) { + if ($previousFieldObject === false || ! isset($previousValues[$previousField])) { if ($ignoreUnsetValues) { continue; } return false; } - if (!$previousFieldObject->matchesCondition($previousValues[$previousField], $condition)) { + if (! $previousFieldObject->matchesCondition($previousValues[$previousField], $condition)) { return false; } } @@ -217,20 +195,15 @@ public function includeField(Field $field, array $previousValues, $ignoreUnsetVa /** * Set a nested value in an array. * - * @see Copied from \Drupal\Component\Utility\NestedArray::setValue() - * - * @param array &$array - * @param array $parents - * @param mixed $value - * @param bool $force + *@see Copied from \Drupal\Component\Utility\NestedArray::setValue() */ - public static function setNestedArrayValue(array &$array, array $parents, $value, $force = false) + public static function setNestedArrayValue(array &$array, array $parents, mixed $value, bool $force = false): void { $ref = &$array; foreach ($parents as $parent) { // PHP auto-creates container arrays and NULL entries without error if $ref // is NULL, but throws an error if $ref is set, but not an array. - if ($force && isset($ref) && !is_array($ref)) { + if ($force && isset($ref) && ! is_array($ref)) { $ref = []; } $ref = &$ref[$parent]; diff --git a/tests/FormTest.php b/tests/FormTest.php index 4107b01..77ba712 100644 --- a/tests/FormTest.php +++ b/tests/FormTest.php @@ -1,5 +1,7 @@ fields = [ - 'test_field' => new Field('Test field', [ - 'optionName' => 'test', - 'validator' => function ($value) { - return $value === $this->validString; - }, - ]), - 'email' => new EmailAddressField('Email address', [ - 'optionName' => 'mail', - ]), - 'non_option_field' => new Field('Form-only field not being included as an option', [ - 'optionName' => 'non-option-field', - 'includeAsOption' => false, - 'required' => false, - ]), - 'with_default' => new Field('Field with default', [ - 'default' => 'defaultValue', - ]), - 'with_dynamic_default' => new Field('Field with dynamic default', [ - 'defaultCallback' => function (array $values) { - return $values['test_field']; - }, - ]), - 'options_with_dynamic_default' => new OptionsField('Options with dynamic default', [ - 'optionName' => 'options-dyn-default', - 'options' => ['foo', 'bar', 'baz'], - 'defaultCallback' => function () { - return $this->validOptionsDynamicDefault; - }, - ]), - 'bool' => new BooleanField('Boolean field', [ - 'optionName' => 'bool', - 'required' => false, - ]), - 'array' => new ArrayField('Array field', [ - 'optionName' => 'array', - 'required' => false, - ]), - 'url' => new UrlField('URL field', [ - 'optionName' => 'url', - 'required' => false, - ]), - 'file' => new FileField('JSON file', [ - 'optionName' => 'file', - 'required' => false, - 'requireExists' => false, - 'allowedExtensions' => ['json', ''], - ]), - 'custom_value_keys1' => new BooleanField('Field with custom value keys 1', [ - 'optionName' => 'custom-keys-1', - 'default' => false, - 'valueKeys' => ['foo1'], - ]), - 'custom_value_keys2' => new BooleanField('Field with custom value keys 2', [ - 'optionName' => 'custom-keys-2', - 'default' => true, - 'valueKeys' => ['foo2', 'bar'], - ]), + 'test_field' => new Field('Test field', [ + 'optionName' => 'test', + 'validator' => function ($value) { + return $value === $this->validString; + }, + ]), + 'email' => new EmailAddressField('Email address', [ + 'optionName' => 'mail', + ]), + 'non_option_field' => new Field('Form-only field not being included as an option', [ + 'optionName' => 'non-option-field', + 'includeAsOption' => false, + 'required' => false, + ]), + 'with_default' => new Field('Field with default', [ + 'default' => 'defaultValue', + ]), + 'with_dynamic_default' => new Field('Field with dynamic default', [ + 'defaultCallback' => function (array $values) { + return $values['test_field']; + }, + ]), + 'options_with_dynamic_default' => new OptionsField('Options with dynamic default', [ + 'optionName' => 'options-dyn-default', + 'options' => ['foo', 'bar', 'baz'], + 'defaultCallback' => function () { + return $this->validOptionsDynamicDefault; + }, + ]), + 'bool' => new BooleanField('Boolean field', [ + 'optionName' => 'bool', + 'required' => false, + ]), + 'array' => new ArrayField('Array field', [ + 'optionName' => 'array', + 'required' => false, + ]), + 'url' => new UrlField('URL field', [ + 'optionName' => 'url', + 'required' => false, + ]), + 'file' => new FileField('JSON file', [ + 'optionName' => 'file', + 'required' => false, + 'requireExists' => false, + 'allowedExtensions' => ['json', ''], + ]), + 'custom_value_keys1' => new BooleanField('Field with custom value keys 1', [ + 'optionName' => 'custom-keys-1', + 'default' => false, + 'valueKeys' => ['foo1'], + ]), + 'custom_value_keys2' => new BooleanField('Field with custom value keys 2', [ + 'optionName' => 'custom-keys-2', + 'default' => true, + 'valueKeys' => ['foo2', 'bar'], + ]), ]; $this->form = Form::fromArray($this->fields); $this->validResult = [ - 'test_field' => $this->validString, - 'email' => $this->validMail, - 'bool' => true, - 'array' => [], - 'url' => null, - 'with_default' => 'defaultValue', - 'with_dynamic_default' => $this->validString, - 'options_with_dynamic_default' => $this->validOptionsDynamicDefault, - 'foo1' => false, - 'foo2' => ['bar' => true], - 'file' => null, - 'non_option_field' => null, + 'test_field' => $this->validString, + 'email' => $this->validMail, + 'bool' => true, + 'array' => [], + 'url' => null, + 'with_default' => 'defaultValue', + 'with_dynamic_default' => $this->validString, + 'options_with_dynamic_default' => $this->validOptionsDynamicDefault, + 'foo1' => false, + 'foo2' => [ + 'bar' => true, + ], + 'file' => null, + 'non_option_field' => null, ]; } @@ -138,8 +154,8 @@ public function testNonInteractiveInput() $this->assertEquals($this->validResult, $result, 'Valid input passes'); $input = new ArrayInput([ - '--test' => 'invalidString', - '--mail' => 'invalidMail', + '--test' => 'invalidString', + '--mail' => 'invalidMail', ], $definition); $input->setInteractive(false); $this->expectException('\\Platformsh\\ConsoleForm\\Exception\\InvalidValueException'); @@ -193,18 +209,22 @@ public function testMixedInput() $this->form->configureInputDefinition($definition); $output = new NullOutput(); - $input = new ArrayInput(['--mail' => $this->validMail], $definition); + $input = new ArrayInput([ + '--mail' => $this->validMail, + ], $definition); $input->setStream($this->getInputStream( - "{$this->validString}\n" . str_repeat("\n", count($this->form->getFields()) - 1) + "{$this->validString}\n" . str_repeat("\n", count($this->form->getFields()) - 1) )); $result = $this->form->resolveOptions($input, $output, $helper); $this->assertEquals($this->validResult, $result, 'Valid input passes'); $this->expectException(InvalidValueException::class); - $input = new ArrayInput(['--test' => 'invalidString'], $definition); + $input = new ArrayInput([ + '--test' => 'invalidString', + ], $definition); $input->setStream($this->getInputStream("{$this->validMail}\n")); $result = $this->form->resolveOptions($input, $output, $helper); - $this->assertEquals(false, $result, 'Invalid input fails'); + $this->assertFalse($result, 'Invalid input fails'); } public function testNormalizedInput() @@ -221,13 +241,15 @@ public function testNormalizedInput() $output = new NullOutput(); $input = new ArrayInput([ - '--test' => $this->validString, - '--mail' => $this->validMail, - '--to-upper' => 'testString', + '--test' => $this->validString, + '--mail' => $this->validMail, + '--to-upper' => 'testString', ], $definition); $input->setInteractive(false); $result = $this->form->resolveOptions($input, $output, $helper); - $validResult = $this->validResult + ['to_upper' => 'TESTSTRING']; + $validResult = $this->validResult + [ + 'to_upper' => 'TESTSTRING', + ]; $this->assertEquals($validResult, $result, 'Input has been normalized'); } @@ -237,7 +259,9 @@ public function testDependentField() $definition = new InputDefinition(); $this->form->addField(new Field('Dependency'), 'dependency'); $this->form->addField(new Field('Dependent', [ - 'conditions' => ['dependency' => 'doTrigger'], + 'conditions' => [ + 'dependency' => 'doTrigger', + ], ]), 'dependent'); $this->form->configureInputDefinition($definition); $output = new NullOutput(); @@ -251,7 +275,7 @@ public function testDependentField() $input->setInteractive(false); $result = $this->form->resolveOptions($input, $output, $helper); $validResult = $this->validResult + [ - 'dependency' => 'doNotTrigger' + 'dependency' => 'doNotTrigger', ]; $this->assertEquals($validResult, $result, 'Dependent field does not appear'); @@ -290,7 +314,9 @@ public function testDependentOnOptionsField() 'options' => ['doTrigger', 'doTrigger2', 'doNotTrigger'], ]), 'dependency'); $this->form->addField(new Field('Dependent', [ - 'conditions' => ['dependency' => ['doTrigger', 'doTrigger2']], + 'conditions' => [ + 'dependency' => ['doTrigger', 'doTrigger2'], + ], ]), 'dependent'); $this->form->configureInputDefinition($definition); $output = new NullOutput(); @@ -303,7 +329,9 @@ public function testDependentOnOptionsField() ], $definition); $input->setInteractive(false); $result = $this->form->resolveOptions($input, $output, $helper); - $validResult = $this->validResult + ['dependency' => 'doNotTrigger']; + $validResult = $this->validResult + [ + 'dependency' => 'doNotTrigger', + ]; $this->assertEquals($validResult, $result, 'Dependent field does not appear'); // Test triggering the dependent field and providing a value. @@ -316,9 +344,9 @@ public function testDependentOnOptionsField() $input->setInteractive(false); $result = $this->form->resolveOptions($input, $output, $helper); $validResult = $this->validResult + [ - 'dependency' => 'doTrigger', - 'dependent' => 'value', - ]; + 'dependency' => 'doTrigger', + 'dependent' => 'value', + ]; $this->assertEquals($validResult, $result, 'Dependent field does appear'); // Test providing a value for the dependent field, without making it @@ -356,17 +384,25 @@ public function testOptionsField() 'optionName' => 'options-allow-other', ]), 'options_non_strict'); $this->form->addField(new OptionsField('Associative options', [ - 'options' => ['option1' => 'Option 1', 'option2' => 'Option 2', 'option3' => 'Option 3'], + 'options' => [ + 'option1' => 'Option 1', + 'option2' => 'Option 2', + 'option3' => 'Option 3', + ], 'optionName' => 'options-assoc', ]), 'options-assoc'); $customValidatorLastValue = null; $this->form->addField(new OptionsField('Associative options with custom validator', [ - 'options' => ['option1' => 'Option 1', 'option2' => 'Option 2', 'option3' => 'Option 3'], - 'optionName' => 'options-assoc-custom-validator', - 'validator' => function ($value) use (&$customValidatorLastValue) { - $customValidatorLastValue = $value; - return true; - }, + 'options' => [ + 'option1' => 'Option 1', + 'option2' => 'Option 2', + 'option3' => 'Option 3', + ], + 'optionName' => 'options-assoc-custom-validator', + 'validator' => function ($value) use (&$customValidatorLastValue) { + $customValidatorLastValue = $value; + return true; + }, ]), 'options-assoc-custom-validator'); $this->form->configureInputDefinition($definition); @@ -397,7 +433,11 @@ public function testOptionsField() // filled in. $output = new NullOutput(); $this->form->addField(new OptionsField('Associative options, choosing with number', [ - 'options' => ['option1' => 'Option 1', 'option2' => 'Option 2', 'option3' => 'Option 3'], + 'options' => [ + 'option1' => 'Option 1', + 'option2' => 'Option 2', + 'option3' => 'Option 3', + ], 'chooseWithNumber' => true, ]), 'options-assoc-number'); $input = new ArrayInput([ @@ -441,19 +481,32 @@ public function testAvoidQuestion() { $definition = new InputDefinition(); $defaultValue = 'default value for avoided question'; - $this->form->addField(new Field('Field avoiding unnecessary question', ['avoidQuestion' => true, 'default' => $defaultValue]), 'avoid_question'); + $this->form->addField(new Field('Field avoiding unnecessary question', [ + 'avoidQuestion' => true, + 'default' => $defaultValue, + ]), 'avoid_question'); $this->form->configureInputDefinition($definition); - $input = new ArrayInput(['--test' => $this->validString, '--mail' => $this->validMail], $definition); + $input = new ArrayInput([ + '--test' => $this->validString, + '--mail' => $this->validMail, + ], $definition); $input->setStream($this->getInputStream(str_repeat("\n", count($this->form->getFields())))); $output = new BufferedOutput(OutputInterface::VERBOSITY_NORMAL, true); $result = $this->form->resolveOptions($input, $output, $this->getQuestionHelper()); - $this->assertNotContains('avoiding', $output->fetch()); - $this->assertEquals($this->validResult + ['avoid_question' => $defaultValue], $result); + $this->assertStringNotContainsString('avoiding', $output->fetch()); + $this->assertEquals($this->validResult + [ + 'avoid_question' => $defaultValue, + ], $result); $definition = new InputDefinition(); - $this->form->addField(new Field('Field with avoidQuestion needing question', ['avoidQuestion' => true]), 'trigger_question'); + $this->form->addField(new Field('Field with avoidQuestion needing question', [ + 'avoidQuestion' => true, + ]), 'trigger_question'); $this->form->configureInputDefinition($definition); - $input = new ArrayInput(['--test' => $this->validString, '--mail' => $this->validMail], $definition); + $input = new ArrayInput([ + '--test' => $this->validString, + '--mail' => $this->validMail, + ], $definition); $input->setStream($this->getInputStream(str_repeat("\n", count($this->form->getFields())))); $this->expectExceptionMessage("'Field with avoidQuestion needing question' is required"); $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); @@ -479,7 +532,9 @@ public function testCustomValidator() ], $definition); $input->setInteractive(false); $result = $this->form->resolveOptions($input, $output, $helper); - $validResult = $this->validResult + ['custom_validated' => 'valid']; + $validResult = $this->validResult + [ + 'custom_validated' => 'valid', + ]; $this->assertEquals($validResult, $result); $input = new ArrayInput([ @@ -496,27 +551,29 @@ public function testCustomValidator() public function testInvalidConfig() { $this->expectException('InvalidArgumentException'); - new Field('Test field', ['invalid' => 'invalid']); + new Field('Test field', [ + 'invalid' => 'invalid', + ]); } public function testOverrideField() { - $fields = $this->fields; - $validResult = $this->validResult; - $validResult['test_field'] = 'Default result for test_field'; - $validResult['with_dynamic_default'] = $validResult['test_field']; - $validResult['email'] = 'test-default@example.com'; - $fields['test_field']->set('default', $validResult['test_field']); - $fields['email']->set('default', $validResult['email']); - - $definition = new InputDefinition(); - $this->form = Form::fromArray($fields); - $this->form->configureInputDefinition($definition); - - $input = new ArrayInput([], $definition); - $input->setInteractive(false); - $result = $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); - $this->assertEquals($validResult, $result, 'Empty input passes'); + $fields = $this->fields; + $validResult = $this->validResult; + $validResult['test_field'] = 'Default result for test_field'; + $validResult['with_dynamic_default'] = $validResult['test_field']; + $validResult['email'] = 'test-default@example.com'; + $fields['test_field']->set('default', $validResult['test_field']); + $fields['email']->set('default', $validResult['email']); + + $definition = new InputDefinition(); + $this->form = Form::fromArray($fields); + $this->form->configureInputDefinition($definition); + + $input = new ArrayInput([], $definition); + $input->setInteractive(false); + $result = $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); + $this->assertEquals($validResult, $result, 'Empty input passes'); } public function testCommandLineCommaSeparatedArrayOptions() @@ -554,32 +611,32 @@ public function testCommandLineCommaSeparatedArrayOptions() public function testUrlField() { - $definition = new InputDefinition(); - $this->form->configureInputDefinition($definition); - - $validResult = $this->validResult; - $validResult['url'] = 'https://example.com'; - - $input = new ArgvInput([ - 'commandName', - '--test', $this->validString, - '--mail', $this->validMail, - '--url', 'https://example.com', - ], $definition); - $input->setInteractive(false); - $result = $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); - $this->assertEquals($validResult, $result, 'URL input with valid URL passes'); - - $input = new ArgvInput([ - 'commandName', - '--test', $this->validString, - '--mail', $this->validMail, - '--url', 'example.com', - ], $definition); - $input->setInteractive(false); - $this->expectException(InvalidValueException::class); - $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); - $this->assertEquals($validResult, $result, 'URL input with invalid URL fails'); + $definition = new InputDefinition(); + $this->form->configureInputDefinition($definition); + + $validResult = $this->validResult; + $validResult['url'] = 'https://example.com'; + + $input = new ArgvInput([ + 'commandName', + '--test', $this->validString, + '--mail', $this->validMail, + '--url', 'https://example.com', + ], $definition); + $input->setInteractive(false); + $result = $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); + $this->assertEquals($validResult, $result, 'URL input with valid URL passes'); + + $input = new ArgvInput([ + 'commandName', + '--test', $this->validString, + '--mail', $this->validMail, + '--url', 'example.com', + ], $definition); + $input->setInteractive(false); + $this->expectException(InvalidValueException::class); + $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); + $this->assertEquals($validResult, $result, 'URL input with invalid URL fails'); } public function testPresetInputOptions() @@ -667,8 +724,6 @@ public function testFileContentsAsValue() '--file', $tmpFilename, ], $definition); - $validResult['file'] = ''; - $input->setInteractive(false); $result = $this->form->resolveOptions($input, new NullOutput(), $this->getQuestionHelper()); $this->assertEquals($testContents, $result['file'], "Value for file is returned as the file's contents"); diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1f5d80b..bd35eb5 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,4 +1,6 @@