From 299fe7699f44aa22a1a4279f1a9dc6f1923ddfab Mon Sep 17 00:00:00 2001 From: "A. Stewart" Date: Sat, 8 Mar 2025 11:47:49 -0500 Subject: [PATCH 1/6] Implement Subscriptions + Created subscription related models + Integrated subscription actions into the main Client class + Added a convenience const to Env class for BitPay's datetime format + Added functional Subscription tests + Updated dependencies --- .gitignore | 5 +- composer.lock | 645 ++++++++---------- src/BitPaySDK/Client.php | 83 ++- src/BitPaySDK/Client/SubscriptionClient.php | 172 +++++ src/BitPaySDK/Env.php | 1 + src/BitPaySDK/Model/Subscription/BillData.php | 483 +++++++++++++ src/BitPaySDK/Model/Subscription/Item.php | 153 +++++ .../Model/Subscription/Subscription.php | 270 ++++++++ .../Subscription/SubscriptionSchedule.php | 44 ++ .../Model/Subscription/SubscriptionStatus.php | 28 + .../BitPaySDK/SubscriptionClientTest.php | 99 +++ 11 files changed, 1632 insertions(+), 351 deletions(-) create mode 100644 src/BitPaySDK/Client/SubscriptionClient.php create mode 100644 src/BitPaySDK/Model/Subscription/BillData.php create mode 100644 src/BitPaySDK/Model/Subscription/Item.php create mode 100644 src/BitPaySDK/Model/Subscription/Subscription.php create mode 100644 src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php create mode 100644 src/BitPaySDK/Model/Subscription/SubscriptionStatus.php create mode 100644 test/functional/BitPaySDK/SubscriptionClientTest.php diff --git a/.gitignore b/.gitignore index aa9bf3d2..dcdaa3a6 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ composer.phar .phpunit.result.cache test/unit/_html -PrivateKey.key \ No newline at end of file +PrivateKey.key + +# Local development +.lando.yml \ No newline at end of file diff --git a/composer.lock b/composer.lock index 25325b48..8334bcd4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6c7eb342f7b7b810ebc95d10637af351", + "content-hash": "4f68715b4e44f1e44f349ed4722fa2ed", "packages": [ { "name": "bitpay/key-utils", @@ -1254,20 +1254,20 @@ }, { "name": "symfony/string", - "version": "v6.4.15", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", - "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -1277,11 +1277,12 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/intl": "^6.2|^7.0", + "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": "^5.4|^6.0|^7.0" + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -1320,7 +1321,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.15" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -1336,32 +1337,32 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:12+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.18", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5" + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5", - "reference": "bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ac238f173df0c9c1120f862d0f599e17535a87ec", + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "symfony/console": "^6.4|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -1392,7 +1393,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.18" + "source": "https://github.com/symfony/yaml/tree/v7.2.3" }, "funding": [ { @@ -1408,22 +1409,22 @@ "type": "tidelift" } ], - "time": "2025-01-07T09:44:41+00:00" + "time": "2025-01-07T12:55:42+00:00" } ], "packages-dev": [ { "name": "myclabs/deep-copy", - "version": "1.12.1", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + "reference": "024473a478be9df5fdaca2c793f2232fe788e414" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", + "reference": "024473a478be9df5fdaca2c793f2232fe788e414", "shasum": "" }, "require": { @@ -1462,7 +1463,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" }, "funding": [ { @@ -1470,7 +1471,7 @@ "type": "tidelift" } ], - "time": "2024-11-08T17:47:46+00:00" + "time": "2025-02-12T12:17:51+00:00" }, { "name": "nikic/php-parser", @@ -1650,35 +1651,34 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.16", + "version": "12.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + "reference": "79e5ef5897068689c7c325554d6df905480ce942" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/79e5ef5897068689c7c325554d6df905480ce942", + "reference": "79e5ef5897068689c7c325554d6df905480ce942", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-text-template": "^3.0.1", - "sebastian/code-unit-reverse-lookup": "^3.0.0", - "sebastian/complexity": "^3.2.0", - "sebastian/environment": "^6.1.0", - "sebastian/lines-of-code": "^2.0.2", - "sebastian/version": "^4.0.1", + "nikic/php-parser": "^5.4.0", + "php": ">=8.3", + "phpunit/php-file-iterator": "^6.0", + "phpunit/php-text-template": "^5.0", + "sebastian/complexity": "^5.0", + "sebastian/environment": "^8.0", + "sebastian/lines-of-code": "^4.0", + "sebastian/version": "^6.0", "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -1687,7 +1687,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1.x-dev" + "dev-main": "12.0.x-dev" } }, "autoload": { @@ -1716,7 +1716,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.0.4" }, "funding": [ { @@ -1724,32 +1724,32 @@ "type": "github" } ], - "time": "2024-08-22T04:31:57+00:00" + "time": "2025-02-25T13:27:48+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "4.1.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + "reference": "961bc913d42fe24a257bfff826a5068079ac7782" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/961bc913d42fe24a257bfff826a5068079ac7782", + "reference": "961bc913d42fe24a257bfff826a5068079ac7782", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1777,7 +1777,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.0" }, "funding": [ { @@ -1785,28 +1785,28 @@ "type": "github" } ], - "time": "2023-08-31T06:24:48+00:00" + "time": "2025-02-07T04:58:37+00:00" }, { "name": "phpunit/php-invoker", - "version": "4.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-pcntl": "*" @@ -1814,7 +1814,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1840,7 +1840,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/6.0.0" }, "funding": [ { @@ -1848,32 +1849,32 @@ "type": "github" } ], - "time": "2023-02-03T06:56:09+00:00" + "time": "2025-02-07T04:58:58+00:00" }, { "name": "phpunit/php-text-template", - "version": "3.0.1", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1900,7 +1901,7 @@ "support": { "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/3.0.1" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/5.0.0" }, "funding": [ { @@ -1908,32 +1909,32 @@ "type": "github" } ], - "time": "2023-08-31T14:07:24+00:00" + "time": "2025-02-07T04:59:16+00:00" }, { "name": "phpunit/php-timer", - "version": "6.0.0", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -1959,7 +1960,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/8.0.0" }, "funding": [ { @@ -1967,20 +1969,20 @@ "type": "github" } ], - "time": "2023-02-03T06:57:52+00:00" + "time": "2025-02-07T04:59:38+00:00" }, { "name": "phpunit/phpunit", - "version": "10.5.45", + "version": "12.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" + "reference": "0f177d7316ba155d36337c3811b11993b54dae32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0f177d7316ba155d36337c3811b11993b54dae32", + "reference": "0f177d7316ba155d36337c3811b11993b54dae32", "shasum": "" }, "require": { @@ -1990,29 +1992,25 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.1", + "myclabs/deep-copy": "^1.13.0", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.16", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-invoker": "^4.0.0", - "phpunit/php-text-template": "^3.0.1", - "phpunit/php-timer": "^6.0.0", - "sebastian/cli-parser": "^2.0.1", - "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.3", - "sebastian/diff": "^5.1.1", - "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.2", - "sebastian/global-state": "^6.0.2", - "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.0", - "sebastian/type": "^4.0.0", - "sebastian/version": "^4.0.1" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" + "php": ">=8.3", + "phpunit/php-code-coverage": "^12.0.3", + "phpunit/php-file-iterator": "^6.0.0", + "phpunit/php-invoker": "^6.0.0", + "phpunit/php-text-template": "^5.0.0", + "phpunit/php-timer": "^8.0.0", + "sebastian/cli-parser": "^4.0.0", + "sebastian/comparator": "^7.0.0", + "sebastian/diff": "^7.0.0", + "sebastian/environment": "^8.0.0", + "sebastian/exporter": "^7.0.0", + "sebastian/global-state": "^8.0.0", + "sebastian/object-enumerator": "^7.0.0", + "sebastian/type": "^6.0.0", + "sebastian/version": "^6.0.0", + "staabm/side-effects-detector": "^1.0.5" }, "bin": [ "phpunit" @@ -2020,7 +2018,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.5-dev" + "dev-main": "12.0-dev" } }, "autoload": { @@ -2052,7 +2050,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.0.5" }, "funding": [ { @@ -2068,32 +2066,32 @@ "type": "tidelift" } ], - "time": "2025-02-06T16:08:12+00:00" + "time": "2025-02-25T06:13:04+00:00" }, { "name": "sebastian/cli-parser", - "version": "2.0.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/6d584c727d9114bcdc14c86711cd1cad51778e7c", + "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2117,118 +2115,7 @@ "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/2.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T07:12:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:43+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.0.0" }, "funding": [ { @@ -2236,36 +2123,39 @@ "type": "github" } ], - "time": "2023-02-03T06:59:15+00:00" + "time": "2025-02-07T04:53:50+00:00" }, { "name": "sebastian/comparator", - "version": "5.0.3", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" + "reference": "18eb5a4f854dbd1d6512c459b605de2edb5a0b47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/18eb5a4f854dbd1d6512c459b605de2edb5a0b47", + "reference": "18eb5a4f854dbd1d6512c459b605de2edb5a0b47", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" + "php": ">=8.3", + "sebastian/diff": "^7.0", + "sebastian/exporter": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^12.0" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2305,7 +2195,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/7.0.0" }, "funding": [ { @@ -2313,33 +2203,33 @@ "type": "github" } ], - "time": "2024-10-18T14:56:07+00:00" + "time": "2025-02-07T04:54:52+00:00" }, { "name": "sebastian/complexity", - "version": "3.2.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2363,7 +2253,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" }, "funding": [ { @@ -2371,33 +2261,33 @@ "type": "github" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2025-02-07T04:55:25+00:00" }, { "name": "sebastian/diff", - "version": "5.1.1", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2430,7 +2320,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" }, "funding": [ { @@ -2438,27 +2328,27 @@ "type": "github" } ], - "time": "2024-03-02T07:15:17+00:00" + "time": "2025-02-07T04:55:46+00:00" }, { "name": "sebastian/environment", - "version": "6.1.0", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + "reference": "8afe311eca49171bf95405cc0078be9a3821f9f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8afe311eca49171bf95405cc0078be9a3821f9f2", + "reference": "8afe311eca49171bf95405cc0078be9a3821f9f2", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-posix": "*" @@ -2466,7 +2356,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -2494,7 +2384,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/8.0.0" }, "funding": [ { @@ -2502,34 +2392,34 @@ "type": "github" } ], - "time": "2024-03-23T08:47:14+00:00" + "time": "2025-02-07T04:56:08+00:00" }, { "name": "sebastian/exporter", - "version": "5.1.2", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + "reference": "76432aafc58d50691a00d86d0632f1217a47b688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/76432aafc58d50691a00d86d0632f1217a47b688", + "reference": "76432aafc58d50691a00d86d0632f1217a47b688", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/recursion-context": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2572,7 +2462,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.0" }, "funding": [ { @@ -2580,35 +2470,35 @@ "type": "github" } ], - "time": "2024-03-02T07:17:12+00:00" + "time": "2025-02-07T04:56:42+00:00" }, { "name": "sebastian/global-state", - "version": "6.0.2", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/570a2aeb26d40f057af686d63c4e99b075fb6cbc", + "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -2634,7 +2524,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.0" }, "funding": [ { @@ -2642,33 +2532,33 @@ "type": "github" } ], - "time": "2024-03-02T07:19:19+00:00" + "time": "2025-02-07T04:56:59+00:00" }, { "name": "sebastian/lines-of-code", - "version": "2.0.2", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2692,7 +2582,7 @@ "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/2.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.0" }, "funding": [ { @@ -2700,34 +2590,34 @@ "type": "github" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2025-02-07T04:57:28+00:00" }, { "name": "sebastian/object-enumerator", - "version": "5.0.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2749,7 +2639,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" }, "funding": [ { @@ -2757,32 +2648,32 @@ "type": "github" } ], - "time": "2023-02-03T07:08:32+00:00" + "time": "2025-02-07T04:57:48+00:00" }, { "name": "sebastian/object-reflector", - "version": "3.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + "reference": "4bfa827c969c98be1e527abd576533293c634f6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2804,7 +2695,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0" }, "funding": [ { @@ -2812,32 +2704,32 @@ "type": "github" } ], - "time": "2023-02-03T07:06:18+00:00" + "time": "2025-02-07T04:58:17+00:00" }, { "name": "sebastian/recursion-context", - "version": "5.0.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + "reference": "c405ae3a63e01b32eb71577f8ec1604e39858a7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/c405ae3a63e01b32eb71577f8ec1604e39858a7c", + "reference": "c405ae3a63e01b32eb71577f8ec1604e39858a7c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2867,7 +2759,8 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.0" }, "funding": [ { @@ -2875,32 +2768,32 @@ "type": "github" } ], - "time": "2023-02-03T07:05:40+00:00" + "time": "2025-02-07T05:00:01+00:00" }, { "name": "sebastian/type", - "version": "4.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + "reference": "533fe082889a616f330bcba6f50965135f4f2fab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/533fe082889a616f330bcba6f50965135f4f2fab", + "reference": "533fe082889a616f330bcba6f50965135f4f2fab", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2923,7 +2816,8 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/6.0.0" }, "funding": [ { @@ -2931,29 +2825,29 @@ "type": "github" } ], - "time": "2023-02-03T07:10:45+00:00" + "time": "2025-02-07T05:00:19+00:00" }, { "name": "sebastian/version", - "version": "4.0.1", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2976,7 +2870,8 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/6.0.0" }, "funding": [ { @@ -2984,7 +2879,59 @@ "type": "github" } ], - "time": "2023-02-07T11:34:05+00:00" + "time": "2025-02-07T05:00:38+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" }, { "name": "theseer/tokenizer", @@ -3039,7 +2986,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3047,6 +2994,6 @@ "ext-json": "*", "ext-reflection": "*" }, - "platform-dev": {}, - "plugin-api-version": "2.6.0" + "platform-dev": [], + "plugin-api-version": "2.2.0" } diff --git a/src/BitPaySDK/Client.php b/src/BitPaySDK/Client.php index cb91d1e2..4fb9403e 100644 --- a/src/BitPaySDK/Client.php +++ b/src/BitPaySDK/Client.php @@ -18,6 +18,7 @@ use BitPaySDK\Client\RateClient; use BitPaySDK\Client\RefundClient; use BitPaySDK\Client\SettlementClient; +use BitPaySDK\Client\SubscriptionClient; use BitPaySDK\Client\TokenClient; use BitPaySDK\Client\WalletClient; use BitPaySDK\Exceptions\BitPayApiException; @@ -36,6 +37,7 @@ use BitPaySDK\Model\Rate\Rate; use BitPaySDK\Model\Rate\Rates; use BitPaySDK\Model\Settlement\Settlement; +use BitPaySDK\Model\Subscription\Subscription; use BitPaySDK\Model\Wallet\Wallet; use BitPaySDK\Util\RESTcli\RESTcli; use Exception; @@ -576,7 +578,7 @@ public function getBill(string $billId, string $facade = Facade::MERCHANT, bool * * @see https://developer.bitpay.com/reference/retrieve-bills-by-status Retrieve Bills by Status * - * @param string|null The status to filter the bills. + * @param $status string|null The status to filter the bills. * @return Bill[] * @throws BitPayApiException * @throws BitPayGenericException @@ -625,6 +627,75 @@ public function deliverBill(string $billId, string $billToken, bool $signRequest return $billClient->deliver($billId, $billToken, $signRequest); } + /** + * Create a BitPay Subscription. + * + * @see https://developer.bitpay.com/reference/create-a-subscription Create a Subscription + * + * @param Subscription $subscription A Subscription object with request parameters defined. + * @return Subscription Created Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function createSubscription(Subscription $subscription): Subscription + { + $subscriptionClient = $this->getSubscriptionClient(); + + return $subscriptionClient->create($subscription); + } + + /** + * Retrieve a BitPay subscription by its ID. + * + * @see https://developer.bitpay.com/reference/retrieve-a-subscription Retrieve a Subscription + * + * @param $subscriptionId string The ID of the subscription to retrieve. + * @return Subscription + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function getSubscription(string $subscriptionId): Subscription + { + $subscriptionClient = $this->getSubscriptionClient(); + + return $subscriptionClient->get($subscriptionId); + } + + /** + * Retrieve a collection of BitPay subscriptions. + * + * @see https://developer.bitpay.com/reference/retrieve-subscriptions-by-status Retrieve Subscriptions by Status + * + * @param $status string|null The status on which to filter the subscriptions. + * @return Subscription[] Filtered list of Subscription objects + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function getSubscriptions(?string $status = null): array + { + $subscriptionClient = $this->getSubscriptionClient(); + + return $subscriptionClient->getSubscriptions($status); + } + + /** + * Update a BitPay Subscription. + * + * @see https://developer.bitpay.com/reference/update-a-subscription Update a Subscription + * + * @param Subscription $subscription A Subscription object with the parameters to update defined. + * @param string $subscriptionId The ID of the Subscription to update. + * @return Subscription Updated Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function updateSubscription(Subscription $subscription, string $subscriptionId): Subscription + { + $subscriptionClient = $this->getSubscriptionClient(); + + return $subscriptionClient->update($subscription, $subscriptionId); + } + /** * Retrieve the exchange rate table maintained by BitPay. * @see https://bitpay.com/bitcoin-exchange-rates @@ -1113,6 +1184,16 @@ protected function getBillClient(): BillClient return BillClient::getInstance($this->tokenCache, $this->restCli); } + /** + * Gets subscription client + * + * @return SubscriptionClient the subscription client + */ + protected function getSubscriptionClient(): SubscriptionClient + { + return SubscriptionClient::getInstance($this->tokenCache, $this->restCli); + } + /** * Gets rate client * diff --git a/src/BitPaySDK/Client/SubscriptionClient.php b/src/BitPaySDK/Client/SubscriptionClient.php new file mode 100644 index 00000000..5588d33d --- /dev/null +++ b/src/BitPaySDK/Client/SubscriptionClient.php @@ -0,0 +1,172 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ +class SubscriptionClient +{ + private static ?self $instance = null; + private Tokens $tokenCache; + private RESTcli $restCli; + + private function __construct(Tokens $tokenCache, RESTcli $restCli) + { + $this->tokenCache = $tokenCache; + $this->restCli = $restCli; + } + + /** + * Factory method for Subscription Client. + * + * @param Tokens $tokenCache + * @param RESTcli $restCli + * @return static + */ + public static function getInstance(Tokens $tokenCache, RESTcli $restCli): self + { + if (!self::$instance) { + self::$instance = new self($tokenCache, $restCli); + } + + return self::$instance; + } + + /** + * Create a BitPay Subscription. + * + * @param Subscription $subscription A Subscription object with request parameters defined. + * @return Subscription Created Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function create(Subscription $subscription): Subscription + { + $subscription->setToken($this->tokenCache->getTokenByFacade(Facade::MERCHANT)); + + $responseJson = $this->restCli->post("subscriptions", $subscription->toArray()); + + try { + return $this->mapJsonToSubscriptionClass($responseJson); + } catch (Exception $e) { + BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); + } + } + + /** + * Retrieve a BitPay subscription by its resource ID. + * + * @param $subscriptionId string The id of the subscription to retrieve. + * @return Subscription Retrieved Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function get(string $subscriptionId): Subscription + { + $params = []; + $params["token"] = $this->tokenCache->getTokenByFacade(Facade::MERCHANT); + + $responseJson = $this->restCli->get("subscriptions/" . $subscriptionId, $params); + + try { + return $this->mapJsonToSubscriptionClass($responseJson); + } catch (Exception $e) { + BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); + } + } + + /** + * Retrieve a collection of BitPay subscriptions. + * + * @param string|null $status The status to filter the subscriptions. + * @return Subscription[] Filtered list of Subscription objects + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function getSubscriptions(?string $status = null): array + { + $params = []; + $params["token"] = $this->tokenCache->getTokenByFacade(Facade::MERCHANT); + if ($status) { + $params["status"] = $status; + } + + $responseJson = $this->restCli->get("subscriptions", $params); + + try { + $mapper = JsonMapperFactory::create(); + return $mapper->mapArray( + json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), + [], + Subscription::class + ); + } catch (Exception $e) { + BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); + } + } + + /** + * Update a BitPay Subscription. + * + * @param Subscription $subscription A Subscription object with the parameters to update defined. + * @param string $subscriptionId The ID of the Subscription to update. + * @return Subscription Updated Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function update(Subscription $subscription, string $subscriptionId): Subscription + { + $subscriptionToken = $this->get($subscription->getId())->getToken(); + $subscription->setToken($subscriptionToken); + + $responseJson = $this->restCli->update("subscriptions/" . $subscriptionId, $subscription->toArray()); + + try { + $mapper = JsonMapperFactory::create(); + + return $mapper->map( + json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), + $subscription + ); + } catch (Exception $e) { + BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); + } + } + + /** + * @param string|null $responseJson + * @return Subscription + * @throws \JsonException + * @throws \JsonMapper_Exception + */ + private function mapJsonToSubscriptionClass(?string $responseJson): Subscription + { + $mapper = JsonMapperFactory::create(); + + return $mapper->map( + json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), + new Subscription() + ); + } +} diff --git a/src/BitPaySDK/Env.php b/src/BitPaySDK/Env.php index 2c1a9e09..7e8d3d40 100644 --- a/src/BitPaySDK/Env.php +++ b/src/BitPaySDK/Env.php @@ -20,4 +20,5 @@ interface Env public const BITPAY_PLUGIN_INFO = "BitPay_PHP_Client_v9.2.0"; public const BITPAY_API_FRAME = "std"; public const BITPAY_API_FRAME_VERSION = "1.0.0"; + public const BITPAY_DATETIME_FORMAT = 'Y-m-d\TH:i:s\Z'; } diff --git a/src/BitPaySDK/Model/Subscription/BillData.php b/src/BitPaySDK/Model/Subscription/BillData.php new file mode 100644 index 00000000..afedfefa --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/BillData.php @@ -0,0 +1,483 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ +class BillData +{ + protected ?bool $emailBill = null; + protected ?array $cc = null; + protected ?string $number = null; + protected ?string $currency = null; + protected ?string $name = null; + protected ?string $address1 = null; + protected ?string $address2 = null; + protected ?string $city = null; + protected ?string $state = null; + protected ?string $zip = null; + protected ?string $country = null; + protected ?string $email = null; + protected ?string $phone = null; + protected ?string $dueDate = null; + protected ?bool $passProcessingFee = null; + protected array $items = []; + + /** + * Constructor, create a minimal request BillData object. + * + * @param string|null $number Recurring bill identifier, specified by merchant + * @param string|null $currency The three digit currency code used to compute the billData's amount. + * @param string|null $email The email address of the receiver for this billData. + * @param string|\DateTime|null $dueDate Date and time at which a bill is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ (UTC). + * @param array|null $items The list of line items to add to this billData. + */ + public function __construct( + ?string $number = null, + ?string $currency = null, + ?string $email = null, + string|\DateTime|null $dueDate = null, + ?array $items = null + ) + { + $this->number = $number; + $this->currency = $currency ?: Currency::USD; + $this->email = $email; + $this->setEmailBill(); + + if (!$dueDate || is_a($dueDate, \DateTime::class)) { + $dueDate = ($dueDate ? new \DateTime('now') : $dueDate)->format(Env::BITPAY_DATETIME_FORMAT); + } + $this->dueDate = $dueDate; + + if (!$items) { + $items = []; + } + $this->setItems($items); + } + + /** + * Gets billData emailBill + * + * If set to `true`, BitPay will automatically issue recurring bills to the `email` address provided once the status of the subscription is set to `active`. + * + * @return bool|null + */ + public function getEmailBill(): ?bool + { + return $this->emailBill; + } + + /** + * Sets billData's emailBill + * + * If set to `true`, BitPay will automatically issue recurring bills to the `email` address provided once the status of the subscription is set to `active`. + * + * @param bool|null $emailBill + * @return void + */ + public function setEmailBill(?bool $emailBill = true): void + { + $this->emailBill = $emailBill; + } + + /** + * Gets items from billData + * + * @return Item[] + */ + public function getItems(): array + { + return $this->items; + } + + /** + * Sets BillData's items + * + * @param Item[] $items List of line items + */ + public function setItems(array $items): void + { + $itemsArray = []; + + foreach ($items as $item) { + if ($item instanceof Item) { + $itemsArray[] = $item; + } else { + $itemsArray[] = Item::createFromArray((array)$item); + } + } + + $this->items = $itemsArray; + } + + /** + * Gets items as array from billData + * + * @return array|null items as array from billData + */ + public function getItemsAsArray(): ?array + { + $items = []; + + foreach ($this->items as $item) { + $items[] = $item->toArray(); + } + + return $items; + } + + /** + * Get billData data as array + * + * @return array billData data as array + */ + public function toArray(): array + { + $elements = [ + 'emailBill' => $this->emailBill, + 'cc' => $this->getCc(), + 'number' => $this->getNumber(), + 'currency' => $this->getCurrency(), + 'name' => $this->getName(), + 'address1' => $this->getAddress1(), + 'address2' => $this->getAddress2(), + 'city' => $this->getCity(), + 'state' => $this->getState(), + 'zip' => $this->getZip(), + 'country' => $this->getCountry(), + 'email' => $this->getEmail(), + 'phone' => $this->getPhone(), + 'dueDate' => $this->getDueDate(), + 'passProcessingFee' => $this->getPassProcessingFee(), + 'items' => $this->getItemsAsArray(), + ]; + + foreach ($elements as $key => $value) { + if (empty($value)) { + unset($elements[$key]); + } + } + + return $elements; + } + + /** + * Gets BillData cc + * + * Email addresses to which a copy of the billData must be sent + * + * @return array|null the cc + */ + public function getCc(): ?array + { + return $this->cc; + } + + /** + * Sets BillData's cc + * + * Email addresses to which a copy of the billData must be sent + * + * @param array $cc Email addresses to which a copy of the billData must be sent + */ + public function setCc(array $cc): void + { + $this->cc = $cc; + } + + /** + * Gets billData number + * + * BillData identifier, specified by merchant + * + * @return string|null the number + */ + public function getNumber(): ?string + { + return $this->number; + } + + /** + * Sets BillData's number + * + * BillData identifier, specified by merchant + * + * @param string $number BillData identifier, specified by merchant + */ + public function setNumber(string $number): void + { + $this->number = $number; + } + + /** + * Gets billData currency + * + * ISO 4217 3-character currency code. This is the currency associated with the price field + * + * @return string|null the billData currency + */ + public function getCurrency(): ?string + { + return $this->currency; + } + + /** + * Sets BillData's currency + * + * ISO 4217 3-character currency code. This is the currency associated with the price field + * + * @param string $currency 3-character currency code + * @throws BitPayValidationException + */ + public function setCurrency(string $currency): void + { + if (!Currency::isValid($currency)) { + BitPayExceptionProvider::throwInvalidCurrencyException($currency); + } + + $this->currency = $currency; + } + + /** + * Gets BillData recipient's name + * + * @return string|null the name + */ + public function getName(): ?string + { + return $this->name; + } + + /** + * Sets BillData recipient's name + * + * @param string $name BillData recipient's name + */ + public function setName(string $name): void + { + $this->name = $name; + } + + /** + * Gets BillData recipient's address + * + * @return string|null the address1 + */ + public function getAddress1(): ?string + { + return $this->address1; + } + + /** + * Sets BillData recipient's address + * + * @param string $address1 BillData recipient's address + */ + public function setAddress1(string $address1): void + { + $this->address1 = $address1; + } + + /** + * Gets BillData recipient's address + * + * @return string|null the address2 + */ + public function getAddress2(): ?string + { + return $this->address2; + } + + /** + * Sets BillData recipient's address + * + * @param string $address2 BillData recipient's address + */ + public function setAddress2(string $address2): void + { + $this->address2 = $address2; + } + + /** + * Gets BillData recipient's city + * + * @return string|null the city + */ + public function getCity(): ?string + { + return $this->city; + } + + /** + * Sets BillData recipient's city + * + * @param string $city BillData recipient's city + */ + public function setCity(string $city): void + { + $this->city = $city; + } + + /** + * Gets BillData recipient's state or province + * + * @return string|null the state + */ + public function getState(): ?string + { + return $this->state; + } + + /** + * Sets BillData recipient's state or province + * + * @param string $state BillData recipient's state or province + */ + public function setState(string $state): void + { + $this->state = $state; + } + + /** + * Gets BillData recipient's ZIP code + * + * @return string|null the zip + */ + public function getZip(): ?string + { + return $this->zip; + } + + /** + * Sets BillData recipient's ZIP code + * + * @param string $zip BillData recipient's ZIP code + */ + public function setZip(string $zip): void + { + $this->zip = $zip; + } + + /** + * Gets BillData recipient's country + * + * @return string|null the country + */ + public function getCountry(): ?string + { + return $this->country; + } + + /** + * Sets BillData recipient's country + * + * @param string $country BillData recipient's country + */ + public function setCountry(string $country): void + { + $this->country = $country; + } + + /** + * Gets billData email + * + * @return string|null the email + */ + public function getEmail(): ?string + { + return $this->email; + } + + /** + * Sets BillData's email + * + * @param string $email BillData's email + */ + public function setEmail(string $email): void + { + $this->email = $email; + } + + /** + * Gets BillData recipient's phone number + * + * @return string|null the phone + */ + public function getPhone(): ?string + { + return $this->phone; + } + + /** + * Sets BillData recipient's phone number + * + * @param string $phone BillData recipient's phone number + */ + public function setPhone(string $phone): void + { + $this->phone = $phone; + } + + /** + * Gets BillData due date + * + * Date and time at which a billData is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) + * + * @see Env::BITPAY_DATETIME_FORMAT + * @return string|null the number + */ + public function getDueDate(): ?string + { + return $this->dueDate; + } + + /** + * Sets BillData's due date + * + * Date and time at which a billData is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) + * + * @see Env::BITPAY_DATETIME_FORMAT + * @param string $dueDate Date and time at which a billData is due + */ + public function setDueDate(string $dueDate): void + { + $this->dueDate = $dueDate; + } + + /** + * Gets billData pass processing fee + * + * @return bool|null the pass processing fee + */ + public function getPassProcessingFee(): ?bool + { + return $this->passProcessingFee; + } + + /** + * Sets BillData's pass processing fee + * + * If set to `true`, BitPay's processing fee will be included in the amount charged on the invoice + * + * @param bool $passProcessingFee BillData's pass processing fee + */ + public function setPassProcessingFee(bool $passProcessingFee): void + { + $this->passProcessingFee = $passProcessingFee; + } +} diff --git a/src/BitPaySDK/Model/Subscription/Item.php b/src/BitPaySDK/Model/Subscription/Item.php new file mode 100644 index 00000000..3432fb4a --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/Item.php @@ -0,0 +1,153 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +namespace BitPaySDK\Model\Subscription; + +/** + * @see https://developer.bitpay.com/reference/bills REST API Bills + * + * @package BitPaySDK\Model\Subscription + * @author BitPay Integrations + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +#[\AllowDynamicProperties] +class Item +{ + protected ?string $id = null; + protected ?string $description = null; + protected ?float $price = null; + protected ?int $quantity = null; + + public function __construct() + { + } + + /** + * Gets id. + * + * @return string|null the id + */ + public function getId(): ?string + { + return $this->id; + } + + /** + * Sets id. + * + * @param string $id the id + */ + public function setId(string $id): void + { + $this->id = $id; + } + + /** + * Gets Line item description + * + * @return string|null the description + */ + public function getDescription(): ?string + { + return $this->description; + } + + /** + * Sets Line item description + * + * @param string $description the description + */ + public function setDescription(string $description): void + { + $this->description = $description; + } + + /** + * Gets Line item unit price for the corresponding currency + * + * @return float|null the price + */ + public function getPrice(): ?float + { + return $this->price; + } + + /** + * Sets Line item unit price for the corresponding currency + * + * @param float $price the price + */ + public function setPrice(float $price): void + { + $this->price = $price; + } + + /** + * Gets Line item number of units + * + * @return int|null the quantity + */ + public function getQuantity(): ?int + { + return $this->quantity; + } + + /** + * Sets Line item number of units + * + * @param int $quantity the quantity + */ + public function setQuantity(int $quantity): void + { + $this->quantity = $quantity; + } + + /** + * @param array $item List of line items + * @return Item + */ + public static function createFromArray(array $item): Item + { + $instance = new self(); + + foreach ($item as $key => $value) { + $instance->{$key} = $value; + } + + return $instance; + } + + /** + * Gets Item data as array + * + * @return array item data as array + */ + public function toArray(): array + { + $elements = [ + 'id' => $this->getId(), + 'description' => $this->getDescription(), + 'price' => $this->getPrice(), + 'quantity' => $this->getQuantity(), + ]; + + foreach ($elements as $key => $value) { + if (empty($value)) { + unset($elements[$key]); + } + } + + return $elements; + } +} diff --git a/src/BitPaySDK/Model/Subscription/Subscription.php b/src/BitPaySDK/Model/Subscription/Subscription.php new file mode 100644 index 00000000..80454ebc --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/Subscription.php @@ -0,0 +1,270 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ +class Subscription +{ + protected ?string $id = null; + protected ?string $status = null; + protected BillData $billData; + protected ?string $merchant = null; + protected ?string $schedule = null; + protected ?string $nextDelivery = null; + protected ?string $createdDate = null; + protected ?string $token = null; + + /** + * Constructor, create a minimal request Subscription object. + * + * @param BillData|null $billData Object containing the recurring billing information. + * @param string|null $schedule Schedule of recurring billing due dates + */ + public function __construct(?BillData $billData = null, ?string $schedule = SubscriptionSchedule::MONTHLY) + { + $this->billData = $billData ?: new BillData(); + $this->schedule = $schedule; + } + + /** + * Get subscription data as array + * + * @return array subscription data as array + */ + public function toArray(): array + { + $elements = [ + 'id' => $this->getId(), + 'status' => $this->getStatus(), + 'billData' => $this->getBillData()->toArray(), + 'merchant' => $this->getMerchant(), + 'schedule' => $this->getSchedule(), + 'nextDelivery' => $this->getNextDelivery(), + 'createdDate' => $this->getCreatedDate(), + 'token' => $this->getToken(), + ]; + + foreach ($elements as $key => $value) { + if (empty($value)) { + unset($elements[$key]); + } + } + + return $elements; + } + + /** + * Get Subscription id + * + * Subscription resource id + * + * @return string|null the id + */ + public function getId(): ?string + { + return $this->id; + } + + /** + * Set Subscription id + * + * Subscription resource id + * + * @param string $id Subscription resource id + */ + public function setId(string $id): void + { + $this->id = $id; + } + + /** + * Get Subscription status + * + * @return string|null the status + * @see SubscriptionStatus + * + */ + public function getStatus(): ?string + { + return $this->status; + } + + /** + * Set Subscription status + * + * @param string $status Subscription's status + * @see SubscriptionStatus + * + */ + public function setStatus(string $status): void + { + $this->status = $status; + } + + /** + * Get Subscription billData + * + * Object containing the recurring billing information + * + * @return BillData + * @see BillData + */ + public function getBillData(): BillData + { + return $this->billData; + } + + /** + * Set Subscription billData + * + * @param BillData $billData Object containing the recurring billing information. + * @return void + * @see BillData + */ + public function setBillData(BillData $billData): void + { + $this->billData = $billData; + } + + /** + * Get Subscription merchant + * + * Internal identifier for BitPay, this field can be ignored by the merchants. + * + * @return string|null the merchant + */ + public function getMerchant(): ?string + { + return $this->merchant; + } + + /** + * Set Subscription merchant + * + * Internal identifier for BitPay, this field can be ignored by the merchants. + * + * @param string $merchant Internal identifier for BitPay + */ + public function setMerchant(string $merchant): void + { + $this->merchant = $merchant; + } + + /** + * Get Subscription created date + * + * Date and time of Subscription creation, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) + * + * @return string|null the created date + * @see Env::BITPAY_DATETIME_FORMAT + */ + public function getCreatedDate(): ?string + { + return $this->createdDate; + } + + /** + * Set Subscription created date + * + * Date and time of Subscription creation, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) + * + * @param string $createdDate Subscription's created date + * @see Env::BITPAY_DATETIME_FORMAT + */ + public function setCreatedDate(string $createdDate): void + { + $this->createdDate = $createdDate; + } + + /** + * Gets token + * + * API token for subscription resource. This token is actually derived from the API token used to create the + * subscription and is tied to the specific resource id created. + * + * @return string|null the token + */ + public function getToken(): ?string + { + return $this->token; + } + + /** + * Set Subscription token + * + * API token for subscription resource. This token is actually derived from the API token used to create the + * subscription and is tied to the specific resource id created. + * + * @param string $token API token for subscription resource + */ + public function setToken(string $token): void + { + $this->token = $token; + } + + /** + * Get Subscription schedule + * + * @return string|null + * @see SubscriptionSchedule + * + */ + public function getSchedule(): ?string + { + return $this->schedule; + } + + /** + * Set Subscription schedule + * + * @param string $schedule + * @return void + * @see SubscriptionSchedule + * + */ + public function setSchedule(string $schedule): void + { + $this->schedule = $schedule; + } + + /** + * Get Subscription's next delivery date + * + * Default is current date & time, ISO-8601 format yyyy-mm-ddThh:mm:ssZ (UTC). Current or past date indicates that + * the bill can be delivered immediately. BitPay may modify the hh:mm:ss values in order to distribute deliveries + * evenly throughout the day. + * + * @return string|null Subscription's next delivery date + */ + public function getNextDelivery(): ?string + { + return $this->nextDelivery; + } + + /** + * Set Subscription's next delivery date + * + * Default is current date & time, ISO-8601 format yyyy-mm-ddThh:mm:ssZ (UTC). Current or past date indicates that + * the bill can be delivered immediately. BitPay may modify the hh:mm:ss values in order to distribute deliveries + * evenly throughout the day. + * + * @param string $nextDelivery Subscription's next delivery date + * @return void + */ + public function setNextDelivery(string $nextDelivery): void + { + $this->nextDelivery = $nextDelivery; + } +} diff --git a/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php b/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php new file mode 100644 index 00000000..e37eb516 --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php @@ -0,0 +1,44 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +namespace BitPaySDK\Model\Subscription; + +/** + * Schedule of repeat bill due dates. Can be `weekly`, `monthly`, `quarterly`, `yearly`, or a simple cron expression specifying seconds, minutes, hours, day of month, month, and day of week. BitPay maintains the difference between the due date and the delivery date in all subsequent, automatically-generated bills. + * + * +-------------- second (0 - 59) + * + * | +------------ minute (0 - 59) + * + * | | +---------- hour (0 - 23) + * + * | | | +-------- day of month (1 - 31) + * + * | | | | +------ month (1 - 12) + * + * | | | | | +---- day of week (0 - 6) (Sunday=0 or 7) + * + * | | | | | | + * + * \* * * * * Cron expression + * + * @package BitPaySDK\Model\Subscription + * @author BitPay Integrations + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @see https://developer.bitpay.com/reference/subscriptions Subscriptions + */ +interface SubscriptionSchedule +{ + public const WEEKLY = "weekly"; + public const MONTHLY = "monthly"; + public const QUARTERLY = "quarterly"; + public const YEARLY = "yearly"; +} diff --git a/src/BitPaySDK/Model/Subscription/SubscriptionStatus.php b/src/BitPaySDK/Model/Subscription/SubscriptionStatus.php new file mode 100644 index 00000000..5c08977f --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/SubscriptionStatus.php @@ -0,0 +1,28 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +namespace BitPaySDK\Model\Subscription; + +/** + * Subscription object status. Can be `draft`, `active` or `cancelled`. + * Subscriptions in `active` state will create new Bills on the `nextDelivery` date. + * + * @package BitPaySDK\Model\Subscription + * @author BitPay Integrations + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @see https://developer.bitpay.com/reference/subscriptions Subscriptions + */ +interface SubscriptionStatus +{ + public const DRAFT = "draft"; + public const ACTIVE = "active"; + public const CANCELLED = "cancelled"; +} diff --git a/test/functional/BitPaySDK/SubscriptionClientTest.php b/test/functional/BitPaySDK/SubscriptionClientTest.php new file mode 100644 index 00000000..2b2d7dba --- /dev/null +++ b/test/functional/BitPaySDK/SubscriptionClientTest.php @@ -0,0 +1,99 @@ +getSubscriptionExample(); + $subscription = $this->client->createSubscription($subscription); + + // Subscription tests + self::assertEquals(SubscriptionStatus::DRAFT, $subscription->getStatus()); + self::assertEquals(SubscriptionSchedule::MONTHLY, $subscription->getSchedule()); + + // BillData tests + self::assertEquals(3.0, $subscription->getBillData()->getItems()[0]->getPrice()); + self::assertEquals(2, $subscription->getBillData()->getItems()[0]->getQuantity()); + self::assertEquals(1, $subscription->getBillData()->getItems()[1]->getQuantity()); + self::assertEquals(7.0, $subscription->getBillData()->getItems()[1]->getPrice()); + self::assertEquals("Test Item 1", $subscription->getBillData()->getItems()[0]->getDescription()); + self::assertEquals("Test Item 2", $subscription->getBillData()->getItems()[1]->getDescription()); + self::assertEquals(Currency::USD, $subscription->getBillData()->getCurrency()); + } + + public function testGetSubscription(): void + { + $subscription = $this->getSubscriptionExample(); + $subscription = $this->client->createSubscription($subscription); + $subscription = $this->client->getSubscription($subscription->getId()); + + self::assertEquals(SubscriptionStatus::DRAFT, $subscription->getStatus()); + self::assertCount(2, $subscription->getBillData()->getItems()); + self::assertEquals(Currency::USD, $subscription->getBillData()->getCurrency()); + self::assertEquals('billData1234-ABCD', $subscription->getBillData()->getNumber()); + self::assertEquals('john.doe@example.com', $subscription->getBillData()->getEmail()); + } + + public function testGetSubscriptions(): void + { + $subscriptions = $this->client->getSubscriptions(); + + self::assertNotNull($subscriptions); + self::assertIsArray($subscriptions); + $isCount = count($subscriptions) > 0; + self::assertTrue($isCount); + } + + public function testUpdateSubscription(): void + { + $subscription = $this->getSubscriptionExample(); + $subscription = $this->client->createSubscription($subscription); + $subscription = $this->client->getSubscription($subscription->getId()); + + $bill = $subscription->getBillData(); + $bill->setEmail("jane.doe@example.com"); + $subscription->setBillData($bill); + + $subscription = $this->client->updateSubscription($subscription, $subscription->getId()); + + self::assertEquals("jane.doe@example.com", $subscription->getBillData()->getEmail()); + } + + private function getSubscriptionExample(): Subscription + { + return new Subscription($this->getBillDataExample()); + } + + private function getBillDataExample(): BillData + { + $items = []; + $item = new Item(); + $item->setPrice(3.0); + $item->setQuantity(2); + $item->setDescription("Test Item 1"); + $items[] = $item; + + $item = new Item(); + $item->setPrice(7.0); + $item->setQuantity(1); + $item->setDescription("Test Item 2"); + $items[] = $item; + + return new BillData("billData1234-ABCD", Currency::USD, "john.doe@example.com", null, $items); + } +} From 9962c88c76f6b8352c0859a183d8fab9f5faa381 Mon Sep 17 00:00:00 2001 From: "A. Stewart" Date: Sat, 8 Mar 2025 11:47:49 -0500 Subject: [PATCH 2/6] Implement Subscriptions + Created subscription related models + Integrated subscription actions into the main Client class + Added a convenience const to Env class for BitPay's datetime format + Added functional Subscription tests + Updated dependencies --- .gitignore | 5 +- composer.json | 2 +- composer.lock | 645 ++++++++---------- src/BitPaySDK/Client.php | 83 ++- src/BitPaySDK/Client/SubscriptionClient.php | 172 +++++ src/BitPaySDK/Env.php | 1 + src/BitPaySDK/Model/Subscription/BillData.php | 483 +++++++++++++ src/BitPaySDK/Model/Subscription/Item.php | 153 +++++ .../Model/Subscription/Subscription.php | 270 ++++++++ .../Subscription/SubscriptionSchedule.php | 44 ++ .../Model/Subscription/SubscriptionStatus.php | 28 + .../BitPaySDK/SubscriptionClientTest.php | 99 +++ 12 files changed, 1633 insertions(+), 352 deletions(-) create mode 100644 src/BitPaySDK/Client/SubscriptionClient.php create mode 100644 src/BitPaySDK/Model/Subscription/BillData.php create mode 100644 src/BitPaySDK/Model/Subscription/Item.php create mode 100644 src/BitPaySDK/Model/Subscription/Subscription.php create mode 100644 src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php create mode 100644 src/BitPaySDK/Model/Subscription/SubscriptionStatus.php create mode 100644 test/functional/BitPaySDK/SubscriptionClientTest.php diff --git a/.gitignore b/.gitignore index aa9bf3d2..dcdaa3a6 100644 --- a/.gitignore +++ b/.gitignore @@ -12,4 +12,7 @@ composer.phar .phpunit.result.cache test/unit/_html -PrivateKey.key \ No newline at end of file +PrivateKey.key + +# Local development +.lando.yml \ No newline at end of file diff --git a/composer.json b/composer.json index 08c4163d..f007bd8c 100644 --- a/composer.json +++ b/composer.json @@ -19,7 +19,7 @@ "guzzlehttp/guzzle": "^7.0", "symfony/yaml": "^5.0 || ^6.0 || ^7.0", "netresearch/jsonmapper": "^5.0", - "symfony/console": "^4.4 || ^5.4 || ^6.0" + "symfony/console": "^4.4 || ^5.4 || ^6.0 || ^7.0" }, "authors": [ { diff --git a/composer.lock b/composer.lock index 25325b48..8334bcd4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6c7eb342f7b7b810ebc95d10637af351", + "content-hash": "4f68715b4e44f1e44f349ed4722fa2ed", "packages": [ { "name": "bitpay/key-utils", @@ -1254,20 +1254,20 @@ }, { "name": "symfony/string", - "version": "v6.4.15", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", - "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -1277,11 +1277,12 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", - "symfony/http-client": "^5.4|^6.0|^7.0", - "symfony/intl": "^6.2|^7.0", + "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": "^5.4|^6.0|^7.0" + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -1320,7 +1321,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.15" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -1336,32 +1337,32 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:12+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.18", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5" + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5", - "reference": "bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ac238f173df0c9c1120f862d0f599e17535a87ec", + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "symfony/console": "^6.4|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -1392,7 +1393,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.18" + "source": "https://github.com/symfony/yaml/tree/v7.2.3" }, "funding": [ { @@ -1408,22 +1409,22 @@ "type": "tidelift" } ], - "time": "2025-01-07T09:44:41+00:00" + "time": "2025-01-07T12:55:42+00:00" } ], "packages-dev": [ { "name": "myclabs/deep-copy", - "version": "1.12.1", + "version": "1.13.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" + "reference": "024473a478be9df5fdaca2c793f2232fe788e414" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", - "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", + "reference": "024473a478be9df5fdaca2c793f2232fe788e414", "shasum": "" }, "require": { @@ -1462,7 +1463,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" }, "funding": [ { @@ -1470,7 +1471,7 @@ "type": "tidelift" } ], - "time": "2024-11-08T17:47:46+00:00" + "time": "2025-02-12T12:17:51+00:00" }, { "name": "nikic/php-parser", @@ -1650,35 +1651,34 @@ }, { "name": "phpunit/php-code-coverage", - "version": "10.1.16", + "version": "12.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + "reference": "79e5ef5897068689c7c325554d6df905480ce942" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/79e5ef5897068689c7c325554d6df905480ce942", + "reference": "79e5ef5897068689c7c325554d6df905480ce942", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-text-template": "^3.0.1", - "sebastian/code-unit-reverse-lookup": "^3.0.0", - "sebastian/complexity": "^3.2.0", - "sebastian/environment": "^6.1.0", - "sebastian/lines-of-code": "^2.0.2", - "sebastian/version": "^4.0.1", + "nikic/php-parser": "^5.4.0", + "php": ">=8.3", + "phpunit/php-file-iterator": "^6.0", + "phpunit/php-text-template": "^5.0", + "sebastian/complexity": "^5.0", + "sebastian/environment": "^8.0", + "sebastian/lines-of-code": "^4.0", + "sebastian/version": "^6.0", "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -1687,7 +1687,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1.x-dev" + "dev-main": "12.0.x-dev" } }, "autoload": { @@ -1716,7 +1716,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.0.4" }, "funding": [ { @@ -1724,32 +1724,32 @@ "type": "github" } ], - "time": "2024-08-22T04:31:57+00:00" + "time": "2025-02-25T13:27:48+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "4.1.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + "reference": "961bc913d42fe24a257bfff826a5068079ac7782" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/961bc913d42fe24a257bfff826a5068079ac7782", + "reference": "961bc913d42fe24a257bfff826a5068079ac7782", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1777,7 +1777,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.0" }, "funding": [ { @@ -1785,28 +1785,28 @@ "type": "github" } ], - "time": "2023-08-31T06:24:48+00:00" + "time": "2025-02-07T04:58:37+00:00" }, { "name": "phpunit/php-invoker", - "version": "4.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-pcntl": "*" @@ -1814,7 +1814,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1840,7 +1840,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/6.0.0" }, "funding": [ { @@ -1848,32 +1849,32 @@ "type": "github" } ], - "time": "2023-02-03T06:56:09+00:00" + "time": "2025-02-07T04:58:58+00:00" }, { "name": "phpunit/php-text-template", - "version": "3.0.1", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -1900,7 +1901,7 @@ "support": { "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/3.0.1" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/5.0.0" }, "funding": [ { @@ -1908,32 +1909,32 @@ "type": "github" } ], - "time": "2023-08-31T14:07:24+00:00" + "time": "2025-02-07T04:59:16+00:00" }, { "name": "phpunit/php-timer", - "version": "6.0.0", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -1959,7 +1960,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/8.0.0" }, "funding": [ { @@ -1967,20 +1969,20 @@ "type": "github" } ], - "time": "2023-02-03T06:57:52+00:00" + "time": "2025-02-07T04:59:38+00:00" }, { "name": "phpunit/phpunit", - "version": "10.5.45", + "version": "12.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" + "reference": "0f177d7316ba155d36337c3811b11993b54dae32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0f177d7316ba155d36337c3811b11993b54dae32", + "reference": "0f177d7316ba155d36337c3811b11993b54dae32", "shasum": "" }, "require": { @@ -1990,29 +1992,25 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.1", + "myclabs/deep-copy": "^1.13.0", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.16", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-invoker": "^4.0.0", - "phpunit/php-text-template": "^3.0.1", - "phpunit/php-timer": "^6.0.0", - "sebastian/cli-parser": "^2.0.1", - "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.3", - "sebastian/diff": "^5.1.1", - "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.2", - "sebastian/global-state": "^6.0.2", - "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.0", - "sebastian/type": "^4.0.0", - "sebastian/version": "^4.0.1" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" + "php": ">=8.3", + "phpunit/php-code-coverage": "^12.0.3", + "phpunit/php-file-iterator": "^6.0.0", + "phpunit/php-invoker": "^6.0.0", + "phpunit/php-text-template": "^5.0.0", + "phpunit/php-timer": "^8.0.0", + "sebastian/cli-parser": "^4.0.0", + "sebastian/comparator": "^7.0.0", + "sebastian/diff": "^7.0.0", + "sebastian/environment": "^8.0.0", + "sebastian/exporter": "^7.0.0", + "sebastian/global-state": "^8.0.0", + "sebastian/object-enumerator": "^7.0.0", + "sebastian/type": "^6.0.0", + "sebastian/version": "^6.0.0", + "staabm/side-effects-detector": "^1.0.5" }, "bin": [ "phpunit" @@ -2020,7 +2018,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.5-dev" + "dev-main": "12.0-dev" } }, "autoload": { @@ -2052,7 +2050,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.0.5" }, "funding": [ { @@ -2068,32 +2066,32 @@ "type": "tidelift" } ], - "time": "2025-02-06T16:08:12+00:00" + "time": "2025-02-25T06:13:04+00:00" }, { "name": "sebastian/cli-parser", - "version": "2.0.1", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/6d584c727d9114bcdc14c86711cd1cad51778e7c", + "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2117,118 +2115,7 @@ "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/2.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T07:12:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:43+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.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" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.0.0" }, "funding": [ { @@ -2236,36 +2123,39 @@ "type": "github" } ], - "time": "2023-02-03T06:59:15+00:00" + "time": "2025-02-07T04:53:50+00:00" }, { "name": "sebastian/comparator", - "version": "5.0.3", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" + "reference": "18eb5a4f854dbd1d6512c459b605de2edb5a0b47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/18eb5a4f854dbd1d6512c459b605de2edb5a0b47", + "reference": "18eb5a4f854dbd1d6512c459b605de2edb5a0b47", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" + "php": ">=8.3", + "sebastian/diff": "^7.0", + "sebastian/exporter": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^12.0" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2305,7 +2195,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/7.0.0" }, "funding": [ { @@ -2313,33 +2203,33 @@ "type": "github" } ], - "time": "2024-10-18T14:56:07+00:00" + "time": "2025-02-07T04:54:52+00:00" }, { "name": "sebastian/complexity", - "version": "3.2.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2363,7 +2253,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" }, "funding": [ { @@ -2371,33 +2261,33 @@ "type": "github" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2025-02-07T04:55:25+00:00" }, { "name": "sebastian/diff", - "version": "5.1.1", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2430,7 +2320,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" }, "funding": [ { @@ -2438,27 +2328,27 @@ "type": "github" } ], - "time": "2024-03-02T07:15:17+00:00" + "time": "2025-02-07T04:55:46+00:00" }, { "name": "sebastian/environment", - "version": "6.1.0", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + "reference": "8afe311eca49171bf95405cc0078be9a3821f9f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8afe311eca49171bf95405cc0078be9a3821f9f2", + "reference": "8afe311eca49171bf95405cc0078be9a3821f9f2", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-posix": "*" @@ -2466,7 +2356,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -2494,7 +2384,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/8.0.0" }, "funding": [ { @@ -2502,34 +2392,34 @@ "type": "github" } ], - "time": "2024-03-23T08:47:14+00:00" + "time": "2025-02-07T04:56:08+00:00" }, { "name": "sebastian/exporter", - "version": "5.1.2", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + "reference": "76432aafc58d50691a00d86d0632f1217a47b688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/76432aafc58d50691a00d86d0632f1217a47b688", + "reference": "76432aafc58d50691a00d86d0632f1217a47b688", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/recursion-context": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2572,7 +2462,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.0" }, "funding": [ { @@ -2580,35 +2470,35 @@ "type": "github" } ], - "time": "2024-03-02T07:17:12+00:00" + "time": "2025-02-07T04:56:42+00:00" }, { "name": "sebastian/global-state", - "version": "6.0.2", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/570a2aeb26d40f057af686d63c4e99b075fb6cbc", + "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -2634,7 +2524,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.0" }, "funding": [ { @@ -2642,33 +2532,33 @@ "type": "github" } ], - "time": "2024-03-02T07:19:19+00:00" + "time": "2025-02-07T04:56:59+00:00" }, { "name": "sebastian/lines-of-code", - "version": "2.0.2", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2692,7 +2582,7 @@ "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/2.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.0" }, "funding": [ { @@ -2700,34 +2590,34 @@ "type": "github" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2025-02-07T04:57:28+00:00" }, { "name": "sebastian/object-enumerator", - "version": "5.0.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2749,7 +2639,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" }, "funding": [ { @@ -2757,32 +2648,32 @@ "type": "github" } ], - "time": "2023-02-03T07:08:32+00:00" + "time": "2025-02-07T04:57:48+00:00" }, { "name": "sebastian/object-reflector", - "version": "3.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + "reference": "4bfa827c969c98be1e527abd576533293c634f6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2804,7 +2695,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0" }, "funding": [ { @@ -2812,32 +2704,32 @@ "type": "github" } ], - "time": "2023-02-03T07:06:18+00:00" + "time": "2025-02-07T04:58:17+00:00" }, { "name": "sebastian/recursion-context", - "version": "5.0.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + "reference": "c405ae3a63e01b32eb71577f8ec1604e39858a7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/c405ae3a63e01b32eb71577f8ec1604e39858a7c", + "reference": "c405ae3a63e01b32eb71577f8ec1604e39858a7c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -2867,7 +2759,8 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.0" }, "funding": [ { @@ -2875,32 +2768,32 @@ "type": "github" } ], - "time": "2023-02-03T07:05:40+00:00" + "time": "2025-02-07T05:00:01+00:00" }, { "name": "sebastian/type", - "version": "4.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + "reference": "533fe082889a616f330bcba6f50965135f4f2fab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/533fe082889a616f330bcba6f50965135f4f2fab", + "reference": "533fe082889a616f330bcba6f50965135f4f2fab", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2923,7 +2816,8 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/6.0.0" }, "funding": [ { @@ -2931,29 +2825,29 @@ "type": "github" } ], - "time": "2023-02-03T07:10:45+00:00" + "time": "2025-02-07T05:00:19+00:00" }, { "name": "sebastian/version", - "version": "4.0.1", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2976,7 +2870,8 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/6.0.0" }, "funding": [ { @@ -2984,7 +2879,59 @@ "type": "github" } ], - "time": "2023-02-07T11:34:05+00:00" + "time": "2025-02-07T05:00:38+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" }, { "name": "theseer/tokenizer", @@ -3039,7 +2986,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -3047,6 +2994,6 @@ "ext-json": "*", "ext-reflection": "*" }, - "platform-dev": {}, - "plugin-api-version": "2.6.0" + "platform-dev": [], + "plugin-api-version": "2.2.0" } diff --git a/src/BitPaySDK/Client.php b/src/BitPaySDK/Client.php index cb91d1e2..4fb9403e 100644 --- a/src/BitPaySDK/Client.php +++ b/src/BitPaySDK/Client.php @@ -18,6 +18,7 @@ use BitPaySDK\Client\RateClient; use BitPaySDK\Client\RefundClient; use BitPaySDK\Client\SettlementClient; +use BitPaySDK\Client\SubscriptionClient; use BitPaySDK\Client\TokenClient; use BitPaySDK\Client\WalletClient; use BitPaySDK\Exceptions\BitPayApiException; @@ -36,6 +37,7 @@ use BitPaySDK\Model\Rate\Rate; use BitPaySDK\Model\Rate\Rates; use BitPaySDK\Model\Settlement\Settlement; +use BitPaySDK\Model\Subscription\Subscription; use BitPaySDK\Model\Wallet\Wallet; use BitPaySDK\Util\RESTcli\RESTcli; use Exception; @@ -576,7 +578,7 @@ public function getBill(string $billId, string $facade = Facade::MERCHANT, bool * * @see https://developer.bitpay.com/reference/retrieve-bills-by-status Retrieve Bills by Status * - * @param string|null The status to filter the bills. + * @param $status string|null The status to filter the bills. * @return Bill[] * @throws BitPayApiException * @throws BitPayGenericException @@ -625,6 +627,75 @@ public function deliverBill(string $billId, string $billToken, bool $signRequest return $billClient->deliver($billId, $billToken, $signRequest); } + /** + * Create a BitPay Subscription. + * + * @see https://developer.bitpay.com/reference/create-a-subscription Create a Subscription + * + * @param Subscription $subscription A Subscription object with request parameters defined. + * @return Subscription Created Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function createSubscription(Subscription $subscription): Subscription + { + $subscriptionClient = $this->getSubscriptionClient(); + + return $subscriptionClient->create($subscription); + } + + /** + * Retrieve a BitPay subscription by its ID. + * + * @see https://developer.bitpay.com/reference/retrieve-a-subscription Retrieve a Subscription + * + * @param $subscriptionId string The ID of the subscription to retrieve. + * @return Subscription + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function getSubscription(string $subscriptionId): Subscription + { + $subscriptionClient = $this->getSubscriptionClient(); + + return $subscriptionClient->get($subscriptionId); + } + + /** + * Retrieve a collection of BitPay subscriptions. + * + * @see https://developer.bitpay.com/reference/retrieve-subscriptions-by-status Retrieve Subscriptions by Status + * + * @param $status string|null The status on which to filter the subscriptions. + * @return Subscription[] Filtered list of Subscription objects + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function getSubscriptions(?string $status = null): array + { + $subscriptionClient = $this->getSubscriptionClient(); + + return $subscriptionClient->getSubscriptions($status); + } + + /** + * Update a BitPay Subscription. + * + * @see https://developer.bitpay.com/reference/update-a-subscription Update a Subscription + * + * @param Subscription $subscription A Subscription object with the parameters to update defined. + * @param string $subscriptionId The ID of the Subscription to update. + * @return Subscription Updated Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function updateSubscription(Subscription $subscription, string $subscriptionId): Subscription + { + $subscriptionClient = $this->getSubscriptionClient(); + + return $subscriptionClient->update($subscription, $subscriptionId); + } + /** * Retrieve the exchange rate table maintained by BitPay. * @see https://bitpay.com/bitcoin-exchange-rates @@ -1113,6 +1184,16 @@ protected function getBillClient(): BillClient return BillClient::getInstance($this->tokenCache, $this->restCli); } + /** + * Gets subscription client + * + * @return SubscriptionClient the subscription client + */ + protected function getSubscriptionClient(): SubscriptionClient + { + return SubscriptionClient::getInstance($this->tokenCache, $this->restCli); + } + /** * Gets rate client * diff --git a/src/BitPaySDK/Client/SubscriptionClient.php b/src/BitPaySDK/Client/SubscriptionClient.php new file mode 100644 index 00000000..5588d33d --- /dev/null +++ b/src/BitPaySDK/Client/SubscriptionClient.php @@ -0,0 +1,172 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ +class SubscriptionClient +{ + private static ?self $instance = null; + private Tokens $tokenCache; + private RESTcli $restCli; + + private function __construct(Tokens $tokenCache, RESTcli $restCli) + { + $this->tokenCache = $tokenCache; + $this->restCli = $restCli; + } + + /** + * Factory method for Subscription Client. + * + * @param Tokens $tokenCache + * @param RESTcli $restCli + * @return static + */ + public static function getInstance(Tokens $tokenCache, RESTcli $restCli): self + { + if (!self::$instance) { + self::$instance = new self($tokenCache, $restCli); + } + + return self::$instance; + } + + /** + * Create a BitPay Subscription. + * + * @param Subscription $subscription A Subscription object with request parameters defined. + * @return Subscription Created Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function create(Subscription $subscription): Subscription + { + $subscription->setToken($this->tokenCache->getTokenByFacade(Facade::MERCHANT)); + + $responseJson = $this->restCli->post("subscriptions", $subscription->toArray()); + + try { + return $this->mapJsonToSubscriptionClass($responseJson); + } catch (Exception $e) { + BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); + } + } + + /** + * Retrieve a BitPay subscription by its resource ID. + * + * @param $subscriptionId string The id of the subscription to retrieve. + * @return Subscription Retrieved Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function get(string $subscriptionId): Subscription + { + $params = []; + $params["token"] = $this->tokenCache->getTokenByFacade(Facade::MERCHANT); + + $responseJson = $this->restCli->get("subscriptions/" . $subscriptionId, $params); + + try { + return $this->mapJsonToSubscriptionClass($responseJson); + } catch (Exception $e) { + BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); + } + } + + /** + * Retrieve a collection of BitPay subscriptions. + * + * @param string|null $status The status to filter the subscriptions. + * @return Subscription[] Filtered list of Subscription objects + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function getSubscriptions(?string $status = null): array + { + $params = []; + $params["token"] = $this->tokenCache->getTokenByFacade(Facade::MERCHANT); + if ($status) { + $params["status"] = $status; + } + + $responseJson = $this->restCli->get("subscriptions", $params); + + try { + $mapper = JsonMapperFactory::create(); + return $mapper->mapArray( + json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), + [], + Subscription::class + ); + } catch (Exception $e) { + BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); + } + } + + /** + * Update a BitPay Subscription. + * + * @param Subscription $subscription A Subscription object with the parameters to update defined. + * @param string $subscriptionId The ID of the Subscription to update. + * @return Subscription Updated Subscription object + * @throws BitPayApiException + * @throws BitPayGenericException + */ + public function update(Subscription $subscription, string $subscriptionId): Subscription + { + $subscriptionToken = $this->get($subscription->getId())->getToken(); + $subscription->setToken($subscriptionToken); + + $responseJson = $this->restCli->update("subscriptions/" . $subscriptionId, $subscription->toArray()); + + try { + $mapper = JsonMapperFactory::create(); + + return $mapper->map( + json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), + $subscription + ); + } catch (Exception $e) { + BitPayExceptionProvider::throwDeserializeResourceException('Subscription', $e->getMessage()); + } + } + + /** + * @param string|null $responseJson + * @return Subscription + * @throws \JsonException + * @throws \JsonMapper_Exception + */ + private function mapJsonToSubscriptionClass(?string $responseJson): Subscription + { + $mapper = JsonMapperFactory::create(); + + return $mapper->map( + json_decode($responseJson, true, 512, JSON_THROW_ON_ERROR), + new Subscription() + ); + } +} diff --git a/src/BitPaySDK/Env.php b/src/BitPaySDK/Env.php index 2c1a9e09..7e8d3d40 100644 --- a/src/BitPaySDK/Env.php +++ b/src/BitPaySDK/Env.php @@ -20,4 +20,5 @@ interface Env public const BITPAY_PLUGIN_INFO = "BitPay_PHP_Client_v9.2.0"; public const BITPAY_API_FRAME = "std"; public const BITPAY_API_FRAME_VERSION = "1.0.0"; + public const BITPAY_DATETIME_FORMAT = 'Y-m-d\TH:i:s\Z'; } diff --git a/src/BitPaySDK/Model/Subscription/BillData.php b/src/BitPaySDK/Model/Subscription/BillData.php new file mode 100644 index 00000000..afedfefa --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/BillData.php @@ -0,0 +1,483 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ +class BillData +{ + protected ?bool $emailBill = null; + protected ?array $cc = null; + protected ?string $number = null; + protected ?string $currency = null; + protected ?string $name = null; + protected ?string $address1 = null; + protected ?string $address2 = null; + protected ?string $city = null; + protected ?string $state = null; + protected ?string $zip = null; + protected ?string $country = null; + protected ?string $email = null; + protected ?string $phone = null; + protected ?string $dueDate = null; + protected ?bool $passProcessingFee = null; + protected array $items = []; + + /** + * Constructor, create a minimal request BillData object. + * + * @param string|null $number Recurring bill identifier, specified by merchant + * @param string|null $currency The three digit currency code used to compute the billData's amount. + * @param string|null $email The email address of the receiver for this billData. + * @param string|\DateTime|null $dueDate Date and time at which a bill is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ (UTC). + * @param array|null $items The list of line items to add to this billData. + */ + public function __construct( + ?string $number = null, + ?string $currency = null, + ?string $email = null, + string|\DateTime|null $dueDate = null, + ?array $items = null + ) + { + $this->number = $number; + $this->currency = $currency ?: Currency::USD; + $this->email = $email; + $this->setEmailBill(); + + if (!$dueDate || is_a($dueDate, \DateTime::class)) { + $dueDate = ($dueDate ? new \DateTime('now') : $dueDate)->format(Env::BITPAY_DATETIME_FORMAT); + } + $this->dueDate = $dueDate; + + if (!$items) { + $items = []; + } + $this->setItems($items); + } + + /** + * Gets billData emailBill + * + * If set to `true`, BitPay will automatically issue recurring bills to the `email` address provided once the status of the subscription is set to `active`. + * + * @return bool|null + */ + public function getEmailBill(): ?bool + { + return $this->emailBill; + } + + /** + * Sets billData's emailBill + * + * If set to `true`, BitPay will automatically issue recurring bills to the `email` address provided once the status of the subscription is set to `active`. + * + * @param bool|null $emailBill + * @return void + */ + public function setEmailBill(?bool $emailBill = true): void + { + $this->emailBill = $emailBill; + } + + /** + * Gets items from billData + * + * @return Item[] + */ + public function getItems(): array + { + return $this->items; + } + + /** + * Sets BillData's items + * + * @param Item[] $items List of line items + */ + public function setItems(array $items): void + { + $itemsArray = []; + + foreach ($items as $item) { + if ($item instanceof Item) { + $itemsArray[] = $item; + } else { + $itemsArray[] = Item::createFromArray((array)$item); + } + } + + $this->items = $itemsArray; + } + + /** + * Gets items as array from billData + * + * @return array|null items as array from billData + */ + public function getItemsAsArray(): ?array + { + $items = []; + + foreach ($this->items as $item) { + $items[] = $item->toArray(); + } + + return $items; + } + + /** + * Get billData data as array + * + * @return array billData data as array + */ + public function toArray(): array + { + $elements = [ + 'emailBill' => $this->emailBill, + 'cc' => $this->getCc(), + 'number' => $this->getNumber(), + 'currency' => $this->getCurrency(), + 'name' => $this->getName(), + 'address1' => $this->getAddress1(), + 'address2' => $this->getAddress2(), + 'city' => $this->getCity(), + 'state' => $this->getState(), + 'zip' => $this->getZip(), + 'country' => $this->getCountry(), + 'email' => $this->getEmail(), + 'phone' => $this->getPhone(), + 'dueDate' => $this->getDueDate(), + 'passProcessingFee' => $this->getPassProcessingFee(), + 'items' => $this->getItemsAsArray(), + ]; + + foreach ($elements as $key => $value) { + if (empty($value)) { + unset($elements[$key]); + } + } + + return $elements; + } + + /** + * Gets BillData cc + * + * Email addresses to which a copy of the billData must be sent + * + * @return array|null the cc + */ + public function getCc(): ?array + { + return $this->cc; + } + + /** + * Sets BillData's cc + * + * Email addresses to which a copy of the billData must be sent + * + * @param array $cc Email addresses to which a copy of the billData must be sent + */ + public function setCc(array $cc): void + { + $this->cc = $cc; + } + + /** + * Gets billData number + * + * BillData identifier, specified by merchant + * + * @return string|null the number + */ + public function getNumber(): ?string + { + return $this->number; + } + + /** + * Sets BillData's number + * + * BillData identifier, specified by merchant + * + * @param string $number BillData identifier, specified by merchant + */ + public function setNumber(string $number): void + { + $this->number = $number; + } + + /** + * Gets billData currency + * + * ISO 4217 3-character currency code. This is the currency associated with the price field + * + * @return string|null the billData currency + */ + public function getCurrency(): ?string + { + return $this->currency; + } + + /** + * Sets BillData's currency + * + * ISO 4217 3-character currency code. This is the currency associated with the price field + * + * @param string $currency 3-character currency code + * @throws BitPayValidationException + */ + public function setCurrency(string $currency): void + { + if (!Currency::isValid($currency)) { + BitPayExceptionProvider::throwInvalidCurrencyException($currency); + } + + $this->currency = $currency; + } + + /** + * Gets BillData recipient's name + * + * @return string|null the name + */ + public function getName(): ?string + { + return $this->name; + } + + /** + * Sets BillData recipient's name + * + * @param string $name BillData recipient's name + */ + public function setName(string $name): void + { + $this->name = $name; + } + + /** + * Gets BillData recipient's address + * + * @return string|null the address1 + */ + public function getAddress1(): ?string + { + return $this->address1; + } + + /** + * Sets BillData recipient's address + * + * @param string $address1 BillData recipient's address + */ + public function setAddress1(string $address1): void + { + $this->address1 = $address1; + } + + /** + * Gets BillData recipient's address + * + * @return string|null the address2 + */ + public function getAddress2(): ?string + { + return $this->address2; + } + + /** + * Sets BillData recipient's address + * + * @param string $address2 BillData recipient's address + */ + public function setAddress2(string $address2): void + { + $this->address2 = $address2; + } + + /** + * Gets BillData recipient's city + * + * @return string|null the city + */ + public function getCity(): ?string + { + return $this->city; + } + + /** + * Sets BillData recipient's city + * + * @param string $city BillData recipient's city + */ + public function setCity(string $city): void + { + $this->city = $city; + } + + /** + * Gets BillData recipient's state or province + * + * @return string|null the state + */ + public function getState(): ?string + { + return $this->state; + } + + /** + * Sets BillData recipient's state or province + * + * @param string $state BillData recipient's state or province + */ + public function setState(string $state): void + { + $this->state = $state; + } + + /** + * Gets BillData recipient's ZIP code + * + * @return string|null the zip + */ + public function getZip(): ?string + { + return $this->zip; + } + + /** + * Sets BillData recipient's ZIP code + * + * @param string $zip BillData recipient's ZIP code + */ + public function setZip(string $zip): void + { + $this->zip = $zip; + } + + /** + * Gets BillData recipient's country + * + * @return string|null the country + */ + public function getCountry(): ?string + { + return $this->country; + } + + /** + * Sets BillData recipient's country + * + * @param string $country BillData recipient's country + */ + public function setCountry(string $country): void + { + $this->country = $country; + } + + /** + * Gets billData email + * + * @return string|null the email + */ + public function getEmail(): ?string + { + return $this->email; + } + + /** + * Sets BillData's email + * + * @param string $email BillData's email + */ + public function setEmail(string $email): void + { + $this->email = $email; + } + + /** + * Gets BillData recipient's phone number + * + * @return string|null the phone + */ + public function getPhone(): ?string + { + return $this->phone; + } + + /** + * Sets BillData recipient's phone number + * + * @param string $phone BillData recipient's phone number + */ + public function setPhone(string $phone): void + { + $this->phone = $phone; + } + + /** + * Gets BillData due date + * + * Date and time at which a billData is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) + * + * @see Env::BITPAY_DATETIME_FORMAT + * @return string|null the number + */ + public function getDueDate(): ?string + { + return $this->dueDate; + } + + /** + * Sets BillData's due date + * + * Date and time at which a billData is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) + * + * @see Env::BITPAY_DATETIME_FORMAT + * @param string $dueDate Date and time at which a billData is due + */ + public function setDueDate(string $dueDate): void + { + $this->dueDate = $dueDate; + } + + /** + * Gets billData pass processing fee + * + * @return bool|null the pass processing fee + */ + public function getPassProcessingFee(): ?bool + { + return $this->passProcessingFee; + } + + /** + * Sets BillData's pass processing fee + * + * If set to `true`, BitPay's processing fee will be included in the amount charged on the invoice + * + * @param bool $passProcessingFee BillData's pass processing fee + */ + public function setPassProcessingFee(bool $passProcessingFee): void + { + $this->passProcessingFee = $passProcessingFee; + } +} diff --git a/src/BitPaySDK/Model/Subscription/Item.php b/src/BitPaySDK/Model/Subscription/Item.php new file mode 100644 index 00000000..3432fb4a --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/Item.php @@ -0,0 +1,153 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +namespace BitPaySDK\Model\Subscription; + +/** + * @see https://developer.bitpay.com/reference/bills REST API Bills + * + * @package BitPaySDK\Model\Subscription + * @author BitPay Integrations + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +#[\AllowDynamicProperties] +class Item +{ + protected ?string $id = null; + protected ?string $description = null; + protected ?float $price = null; + protected ?int $quantity = null; + + public function __construct() + { + } + + /** + * Gets id. + * + * @return string|null the id + */ + public function getId(): ?string + { + return $this->id; + } + + /** + * Sets id. + * + * @param string $id the id + */ + public function setId(string $id): void + { + $this->id = $id; + } + + /** + * Gets Line item description + * + * @return string|null the description + */ + public function getDescription(): ?string + { + return $this->description; + } + + /** + * Sets Line item description + * + * @param string $description the description + */ + public function setDescription(string $description): void + { + $this->description = $description; + } + + /** + * Gets Line item unit price for the corresponding currency + * + * @return float|null the price + */ + public function getPrice(): ?float + { + return $this->price; + } + + /** + * Sets Line item unit price for the corresponding currency + * + * @param float $price the price + */ + public function setPrice(float $price): void + { + $this->price = $price; + } + + /** + * Gets Line item number of units + * + * @return int|null the quantity + */ + public function getQuantity(): ?int + { + return $this->quantity; + } + + /** + * Sets Line item number of units + * + * @param int $quantity the quantity + */ + public function setQuantity(int $quantity): void + { + $this->quantity = $quantity; + } + + /** + * @param array $item List of line items + * @return Item + */ + public static function createFromArray(array $item): Item + { + $instance = new self(); + + foreach ($item as $key => $value) { + $instance->{$key} = $value; + } + + return $instance; + } + + /** + * Gets Item data as array + * + * @return array item data as array + */ + public function toArray(): array + { + $elements = [ + 'id' => $this->getId(), + 'description' => $this->getDescription(), + 'price' => $this->getPrice(), + 'quantity' => $this->getQuantity(), + ]; + + foreach ($elements as $key => $value) { + if (empty($value)) { + unset($elements[$key]); + } + } + + return $elements; + } +} diff --git a/src/BitPaySDK/Model/Subscription/Subscription.php b/src/BitPaySDK/Model/Subscription/Subscription.php new file mode 100644 index 00000000..80454ebc --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/Subscription.php @@ -0,0 +1,270 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ +class Subscription +{ + protected ?string $id = null; + protected ?string $status = null; + protected BillData $billData; + protected ?string $merchant = null; + protected ?string $schedule = null; + protected ?string $nextDelivery = null; + protected ?string $createdDate = null; + protected ?string $token = null; + + /** + * Constructor, create a minimal request Subscription object. + * + * @param BillData|null $billData Object containing the recurring billing information. + * @param string|null $schedule Schedule of recurring billing due dates + */ + public function __construct(?BillData $billData = null, ?string $schedule = SubscriptionSchedule::MONTHLY) + { + $this->billData = $billData ?: new BillData(); + $this->schedule = $schedule; + } + + /** + * Get subscription data as array + * + * @return array subscription data as array + */ + public function toArray(): array + { + $elements = [ + 'id' => $this->getId(), + 'status' => $this->getStatus(), + 'billData' => $this->getBillData()->toArray(), + 'merchant' => $this->getMerchant(), + 'schedule' => $this->getSchedule(), + 'nextDelivery' => $this->getNextDelivery(), + 'createdDate' => $this->getCreatedDate(), + 'token' => $this->getToken(), + ]; + + foreach ($elements as $key => $value) { + if (empty($value)) { + unset($elements[$key]); + } + } + + return $elements; + } + + /** + * Get Subscription id + * + * Subscription resource id + * + * @return string|null the id + */ + public function getId(): ?string + { + return $this->id; + } + + /** + * Set Subscription id + * + * Subscription resource id + * + * @param string $id Subscription resource id + */ + public function setId(string $id): void + { + $this->id = $id; + } + + /** + * Get Subscription status + * + * @return string|null the status + * @see SubscriptionStatus + * + */ + public function getStatus(): ?string + { + return $this->status; + } + + /** + * Set Subscription status + * + * @param string $status Subscription's status + * @see SubscriptionStatus + * + */ + public function setStatus(string $status): void + { + $this->status = $status; + } + + /** + * Get Subscription billData + * + * Object containing the recurring billing information + * + * @return BillData + * @see BillData + */ + public function getBillData(): BillData + { + return $this->billData; + } + + /** + * Set Subscription billData + * + * @param BillData $billData Object containing the recurring billing information. + * @return void + * @see BillData + */ + public function setBillData(BillData $billData): void + { + $this->billData = $billData; + } + + /** + * Get Subscription merchant + * + * Internal identifier for BitPay, this field can be ignored by the merchants. + * + * @return string|null the merchant + */ + public function getMerchant(): ?string + { + return $this->merchant; + } + + /** + * Set Subscription merchant + * + * Internal identifier for BitPay, this field can be ignored by the merchants. + * + * @param string $merchant Internal identifier for BitPay + */ + public function setMerchant(string $merchant): void + { + $this->merchant = $merchant; + } + + /** + * Get Subscription created date + * + * Date and time of Subscription creation, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) + * + * @return string|null the created date + * @see Env::BITPAY_DATETIME_FORMAT + */ + public function getCreatedDate(): ?string + { + return $this->createdDate; + } + + /** + * Set Subscription created date + * + * Date and time of Subscription creation, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) + * + * @param string $createdDate Subscription's created date + * @see Env::BITPAY_DATETIME_FORMAT + */ + public function setCreatedDate(string $createdDate): void + { + $this->createdDate = $createdDate; + } + + /** + * Gets token + * + * API token for subscription resource. This token is actually derived from the API token used to create the + * subscription and is tied to the specific resource id created. + * + * @return string|null the token + */ + public function getToken(): ?string + { + return $this->token; + } + + /** + * Set Subscription token + * + * API token for subscription resource. This token is actually derived from the API token used to create the + * subscription and is tied to the specific resource id created. + * + * @param string $token API token for subscription resource + */ + public function setToken(string $token): void + { + $this->token = $token; + } + + /** + * Get Subscription schedule + * + * @return string|null + * @see SubscriptionSchedule + * + */ + public function getSchedule(): ?string + { + return $this->schedule; + } + + /** + * Set Subscription schedule + * + * @param string $schedule + * @return void + * @see SubscriptionSchedule + * + */ + public function setSchedule(string $schedule): void + { + $this->schedule = $schedule; + } + + /** + * Get Subscription's next delivery date + * + * Default is current date & time, ISO-8601 format yyyy-mm-ddThh:mm:ssZ (UTC). Current or past date indicates that + * the bill can be delivered immediately. BitPay may modify the hh:mm:ss values in order to distribute deliveries + * evenly throughout the day. + * + * @return string|null Subscription's next delivery date + */ + public function getNextDelivery(): ?string + { + return $this->nextDelivery; + } + + /** + * Set Subscription's next delivery date + * + * Default is current date & time, ISO-8601 format yyyy-mm-ddThh:mm:ssZ (UTC). Current or past date indicates that + * the bill can be delivered immediately. BitPay may modify the hh:mm:ss values in order to distribute deliveries + * evenly throughout the day. + * + * @param string $nextDelivery Subscription's next delivery date + * @return void + */ + public function setNextDelivery(string $nextDelivery): void + { + $this->nextDelivery = $nextDelivery; + } +} diff --git a/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php b/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php new file mode 100644 index 00000000..e37eb516 --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php @@ -0,0 +1,44 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +namespace BitPaySDK\Model\Subscription; + +/** + * Schedule of repeat bill due dates. Can be `weekly`, `monthly`, `quarterly`, `yearly`, or a simple cron expression specifying seconds, minutes, hours, day of month, month, and day of week. BitPay maintains the difference between the due date and the delivery date in all subsequent, automatically-generated bills. + * + * +-------------- second (0 - 59) + * + * | +------------ minute (0 - 59) + * + * | | +---------- hour (0 - 23) + * + * | | | +-------- day of month (1 - 31) + * + * | | | | +------ month (1 - 12) + * + * | | | | | +---- day of week (0 - 6) (Sunday=0 or 7) + * + * | | | | | | + * + * \* * * * * Cron expression + * + * @package BitPaySDK\Model\Subscription + * @author BitPay Integrations + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @see https://developer.bitpay.com/reference/subscriptions Subscriptions + */ +interface SubscriptionSchedule +{ + public const WEEKLY = "weekly"; + public const MONTHLY = "monthly"; + public const QUARTERLY = "quarterly"; + public const YEARLY = "yearly"; +} diff --git a/src/BitPaySDK/Model/Subscription/SubscriptionStatus.php b/src/BitPaySDK/Model/Subscription/SubscriptionStatus.php new file mode 100644 index 00000000..5c08977f --- /dev/null +++ b/src/BitPaySDK/Model/Subscription/SubscriptionStatus.php @@ -0,0 +1,28 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +namespace BitPaySDK\Model\Subscription; + +/** + * Subscription object status. Can be `draft`, `active` or `cancelled`. + * Subscriptions in `active` state will create new Bills on the `nextDelivery` date. + * + * @package BitPaySDK\Model\Subscription + * @author BitPay Integrations + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @see https://developer.bitpay.com/reference/subscriptions Subscriptions + */ +interface SubscriptionStatus +{ + public const DRAFT = "draft"; + public const ACTIVE = "active"; + public const CANCELLED = "cancelled"; +} diff --git a/test/functional/BitPaySDK/SubscriptionClientTest.php b/test/functional/BitPaySDK/SubscriptionClientTest.php new file mode 100644 index 00000000..2b2d7dba --- /dev/null +++ b/test/functional/BitPaySDK/SubscriptionClientTest.php @@ -0,0 +1,99 @@ +getSubscriptionExample(); + $subscription = $this->client->createSubscription($subscription); + + // Subscription tests + self::assertEquals(SubscriptionStatus::DRAFT, $subscription->getStatus()); + self::assertEquals(SubscriptionSchedule::MONTHLY, $subscription->getSchedule()); + + // BillData tests + self::assertEquals(3.0, $subscription->getBillData()->getItems()[0]->getPrice()); + self::assertEquals(2, $subscription->getBillData()->getItems()[0]->getQuantity()); + self::assertEquals(1, $subscription->getBillData()->getItems()[1]->getQuantity()); + self::assertEquals(7.0, $subscription->getBillData()->getItems()[1]->getPrice()); + self::assertEquals("Test Item 1", $subscription->getBillData()->getItems()[0]->getDescription()); + self::assertEquals("Test Item 2", $subscription->getBillData()->getItems()[1]->getDescription()); + self::assertEquals(Currency::USD, $subscription->getBillData()->getCurrency()); + } + + public function testGetSubscription(): void + { + $subscription = $this->getSubscriptionExample(); + $subscription = $this->client->createSubscription($subscription); + $subscription = $this->client->getSubscription($subscription->getId()); + + self::assertEquals(SubscriptionStatus::DRAFT, $subscription->getStatus()); + self::assertCount(2, $subscription->getBillData()->getItems()); + self::assertEquals(Currency::USD, $subscription->getBillData()->getCurrency()); + self::assertEquals('billData1234-ABCD', $subscription->getBillData()->getNumber()); + self::assertEquals('john.doe@example.com', $subscription->getBillData()->getEmail()); + } + + public function testGetSubscriptions(): void + { + $subscriptions = $this->client->getSubscriptions(); + + self::assertNotNull($subscriptions); + self::assertIsArray($subscriptions); + $isCount = count($subscriptions) > 0; + self::assertTrue($isCount); + } + + public function testUpdateSubscription(): void + { + $subscription = $this->getSubscriptionExample(); + $subscription = $this->client->createSubscription($subscription); + $subscription = $this->client->getSubscription($subscription->getId()); + + $bill = $subscription->getBillData(); + $bill->setEmail("jane.doe@example.com"); + $subscription->setBillData($bill); + + $subscription = $this->client->updateSubscription($subscription, $subscription->getId()); + + self::assertEquals("jane.doe@example.com", $subscription->getBillData()->getEmail()); + } + + private function getSubscriptionExample(): Subscription + { + return new Subscription($this->getBillDataExample()); + } + + private function getBillDataExample(): BillData + { + $items = []; + $item = new Item(); + $item->setPrice(3.0); + $item->setQuantity(2); + $item->setDescription("Test Item 1"); + $items[] = $item; + + $item = new Item(); + $item->setPrice(7.0); + $item->setQuantity(1); + $item->setDescription("Test Item 2"); + $items[] = $item; + + return new BillData("billData1234-ABCD", Currency::USD, "john.doe@example.com", null, $items); + } +} From 24fb49caf8a4088f1ae32242b5fb439efb7e2735 Mon Sep 17 00:00:00 2001 From: "A. Stewart" Date: Mon, 10 Mar 2025 07:31:49 -0400 Subject: [PATCH 3/6] Fix PHP CodeSniffer action failure --- composer.lock | 645 +++++++++++++++++++++++++++----------------------- 1 file changed, 349 insertions(+), 296 deletions(-) diff --git a/composer.lock b/composer.lock index 8334bcd4..25325b48 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4f68715b4e44f1e44f349ed4722fa2ed", + "content-hash": "6c7eb342f7b7b810ebc95d10637af351", "packages": [ { "name": "bitpay/key-utils", @@ -1254,20 +1254,20 @@ }, { "name": "symfony/string", - "version": "v7.2.0", + "version": "v6.4.15", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "url": "https://api.github.com/repos/symfony/string/zipball/73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", + "reference": "73a5e66ea2e1677c98d4449177c5a9cf9d8b4c6f", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -1277,12 +1277,11 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "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/error-handler": "^5.4|^6.0|^7.0", + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -1321,7 +1320,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.0" + "source": "https://github.com/symfony/string/tree/v6.4.15" }, "funding": [ { @@ -1337,32 +1336,32 @@ "type": "tidelift" } ], - "time": "2024-11-13T13:31:26+00:00" + "time": "2024-11-13T13:31:12+00:00" }, { "name": "symfony/yaml", - "version": "v7.2.3", + "version": "v6.4.18", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec" + "reference": "bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/ac238f173df0c9c1120f862d0f599e17535a87ec", - "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec", + "url": "https://api.github.com/repos/symfony/yaml/zipball/bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5", + "reference": "bf598c9d9bb4a22f495a4e26e4c4fce2f8ecefc5", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/deprecation-contracts": "^2.5|^3.0", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<6.4" + "symfony/console": "<5.4" }, "require-dev": { - "symfony/console": "^6.4|^7.0" + "symfony/console": "^5.4|^6.0|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -1393,7 +1392,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.2.3" + "source": "https://github.com/symfony/yaml/tree/v6.4.18" }, "funding": [ { @@ -1409,22 +1408,22 @@ "type": "tidelift" } ], - "time": "2025-01-07T12:55:42+00:00" + "time": "2025-01-07T09:44:41+00:00" } ], "packages-dev": [ { "name": "myclabs/deep-copy", - "version": "1.13.0", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -1463,7 +1462,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -1471,7 +1470,7 @@ "type": "tidelift" } ], - "time": "2025-02-12T12:17:51+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "nikic/php-parser", @@ -1651,34 +1650,35 @@ }, { "name": "phpunit/php-code-coverage", - "version": "12.0.4", + "version": "10.1.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "79e5ef5897068689c7c325554d6df905480ce942" + "reference": "7e308268858ed6baedc8704a304727d20bc07c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/79e5ef5897068689c7c325554d6df905480ce942", - "reference": "79e5ef5897068689c7c325554d6df905480ce942", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", + "reference": "7e308268858ed6baedc8704a304727d20bc07c77", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^5.4.0", - "php": ">=8.3", - "phpunit/php-file-iterator": "^6.0", - "phpunit/php-text-template": "^5.0", - "sebastian/complexity": "^5.0", - "sebastian/environment": "^8.0", - "sebastian/lines-of-code": "^4.0", - "sebastian/version": "^6.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=8.1", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-text-template": "^3.0.1", + "sebastian/code-unit-reverse-lookup": "^3.0.0", + "sebastian/complexity": "^3.2.0", + "sebastian/environment": "^6.1.0", + "sebastian/lines-of-code": "^2.0.2", + "sebastian/version": "^4.0.1", "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.1" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -1687,7 +1687,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "12.0.x-dev" + "dev-main": "10.1.x-dev" } }, "autoload": { @@ -1716,7 +1716,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.0.4" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" }, "funding": [ { @@ -1724,32 +1724,32 @@ "type": "github" } ], - "time": "2025-02-25T13:27:48+00:00" + "time": "2024-08-22T04:31:57+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "6.0.0", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "961bc913d42fe24a257bfff826a5068079ac7782" + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/961bc913d42fe24a257bfff826a5068079ac7782", - "reference": "961bc913d42fe24a257bfff826a5068079ac7782", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", + "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1777,7 +1777,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" }, "funding": [ { @@ -1785,28 +1785,28 @@ "type": "github" } ], - "time": "2025-02-07T04:58:37+00:00" + "time": "2023-08-31T06:24:48+00:00" }, { "name": "phpunit/php-invoker", - "version": "6.0.0", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", - "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-pcntl": "*" @@ -1814,7 +1814,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -1840,8 +1840,7 @@ ], "support": { "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/6.0.0" + "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" }, "funding": [ { @@ -1849,32 +1848,32 @@ "type": "github" } ], - "time": "2025-02-07T04:58:58+00:00" + "time": "2023-02-03T06:56:09+00:00" }, { "name": "phpunit/php-text-template", - "version": "5.0.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", - "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -1901,7 +1900,7 @@ "support": { "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/5.0.0" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" }, "funding": [ { @@ -1909,32 +1908,32 @@ "type": "github" } ], - "time": "2025-02-07T04:59:16+00:00" + "time": "2023-08-31T14:07:24+00:00" }, { "name": "phpunit/php-timer", - "version": "8.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", - "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "8.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1960,8 +1959,7 @@ ], "support": { "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/8.0.0" + "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" }, "funding": [ { @@ -1969,20 +1967,20 @@ "type": "github" } ], - "time": "2025-02-07T04:59:38+00:00" + "time": "2023-02-03T06:57:52+00:00" }, { "name": "phpunit/phpunit", - "version": "12.0.5", + "version": "10.5.45", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "0f177d7316ba155d36337c3811b11993b54dae32" + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0f177d7316ba155d36337c3811b11993b54dae32", - "reference": "0f177d7316ba155d36337c3811b11993b54dae32", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", + "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", "shasum": "" }, "require": { @@ -1992,25 +1990,29 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.13.0", + "myclabs/deep-copy": "^1.12.1", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.3", - "phpunit/php-code-coverage": "^12.0.3", - "phpunit/php-file-iterator": "^6.0.0", - "phpunit/php-invoker": "^6.0.0", - "phpunit/php-text-template": "^5.0.0", - "phpunit/php-timer": "^8.0.0", - "sebastian/cli-parser": "^4.0.0", - "sebastian/comparator": "^7.0.0", - "sebastian/diff": "^7.0.0", - "sebastian/environment": "^8.0.0", - "sebastian/exporter": "^7.0.0", - "sebastian/global-state": "^8.0.0", - "sebastian/object-enumerator": "^7.0.0", - "sebastian/type": "^6.0.0", - "sebastian/version": "^6.0.0", - "staabm/side-effects-detector": "^1.0.5" + "php": ">=8.1", + "phpunit/php-code-coverage": "^10.1.16", + "phpunit/php-file-iterator": "^4.1.0", + "phpunit/php-invoker": "^4.0.0", + "phpunit/php-text-template": "^3.0.1", + "phpunit/php-timer": "^6.0.0", + "sebastian/cli-parser": "^2.0.1", + "sebastian/code-unit": "^2.0.0", + "sebastian/comparator": "^5.0.3", + "sebastian/diff": "^5.1.1", + "sebastian/environment": "^6.1.0", + "sebastian/exporter": "^5.1.2", + "sebastian/global-state": "^6.0.2", + "sebastian/object-enumerator": "^5.0.0", + "sebastian/recursion-context": "^5.0.0", + "sebastian/type": "^4.0.0", + "sebastian/version": "^4.0.1" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -2018,7 +2020,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "12.0-dev" + "dev-main": "10.5-dev" } }, "autoload": { @@ -2050,7 +2052,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/12.0.5" + "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" }, "funding": [ { @@ -2066,32 +2068,32 @@ "type": "tidelift" } ], - "time": "2025-02-25T06:13:04+00:00" + "time": "2025-02-06T16:08:12+00:00" }, { "name": "sebastian/cli-parser", - "version": "4.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c" + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/6d584c727d9114bcdc14c86711cd1cad51778e7c", - "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -2115,7 +2117,118 @@ "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/4.0.0" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:12:49+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", + "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:58:43+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "require-dev": { + "phpunit/phpunit": "^10.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" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" }, "funding": [ { @@ -2123,39 +2236,36 @@ "type": "github" } ], - "time": "2025-02-07T04:53:50+00:00" + "time": "2023-02-03T06:59:15+00:00" }, { "name": "sebastian/comparator", - "version": "7.0.0", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "18eb5a4f854dbd1d6512c459b605de2edb5a0b47" + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/18eb5a4f854dbd1d6512c459b605de2edb5a0b47", - "reference": "18eb5a4f854dbd1d6512c459b605de2edb5a0b47", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.3", - "sebastian/diff": "^7.0", - "sebastian/exporter": "^7.0" + "php": ">=8.1", + "sebastian/diff": "^5.0", + "sebastian/exporter": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^12.0" - }, - "suggest": { - "ext-bcmath": "For comparing BcMath\\Number objects" + "phpunit/phpunit": "^10.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2195,7 +2305,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" }, "funding": [ { @@ -2203,33 +2313,33 @@ "type": "github" } ], - "time": "2025-02-07T04:54:52+00:00" + "time": "2024-10-18T14:56:07+00:00" }, { "name": "sebastian/complexity", - "version": "5.0.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" + "reference": "68ff824baeae169ec9f2137158ee529584553799" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", - "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", + "reference": "68ff824baeae169ec9f2137158ee529584553799", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.3" + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "3.2-dev" } }, "autoload": { @@ -2253,7 +2363,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" }, "funding": [ { @@ -2261,33 +2371,33 @@ "type": "github" } ], - "time": "2025-02-07T04:55:25+00:00" + "time": "2023-12-21T08:37:17+00:00" }, { "name": "sebastian/diff", - "version": "7.0.0", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7ab1ea946c012266ca32390913653d844ecd085f" + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", - "reference": "7ab1ea946c012266ca32390913653d844ecd085f", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", + "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0", - "symfony/process": "^7.2" + "phpunit/phpunit": "^10.0", + "symfony/process": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -2320,7 +2430,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" }, "funding": [ { @@ -2328,27 +2438,27 @@ "type": "github" } ], - "time": "2025-02-07T04:55:46+00:00" + "time": "2024-03-02T07:15:17+00:00" }, { "name": "sebastian/environment", - "version": "8.0.0", + "version": "6.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8afe311eca49171bf95405cc0078be9a3821f9f2" + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8afe311eca49171bf95405cc0078be9a3821f9f2", - "reference": "8afe311eca49171bf95405cc0078be9a3821f9f2", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", + "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "suggest": { "ext-posix": "*" @@ -2356,7 +2466,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "8.0-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -2384,7 +2494,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/8.0.0" + "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" }, "funding": [ { @@ -2392,34 +2502,34 @@ "type": "github" } ], - "time": "2025-02-07T04:56:08+00:00" + "time": "2024-03-23T08:47:14+00:00" }, { "name": "sebastian/exporter", - "version": "7.0.0", + "version": "5.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "76432aafc58d50691a00d86d0632f1217a47b688" + "reference": "955288482d97c19a372d3f31006ab3f37da47adf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/76432aafc58d50691a00d86d0632f1217a47b688", - "reference": "76432aafc58d50691a00d86d0632f1217a47b688", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", + "reference": "955288482d97c19a372d3f31006ab3f37da47adf", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.3", - "sebastian/recursion-context": "^7.0" + "php": ">=8.1", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -2462,7 +2572,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" }, "funding": [ { @@ -2470,35 +2580,35 @@ "type": "github" } ], - "time": "2025-02-07T04:56:42+00:00" + "time": "2024-03-02T07:17:12+00:00" }, { "name": "sebastian/global-state", - "version": "8.0.0", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc" + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/570a2aeb26d40f057af686d63c4e99b075fb6cbc", - "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", "shasum": "" }, "require": { - "php": ">=8.3", - "sebastian/object-reflector": "^5.0", - "sebastian/recursion-context": "^7.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "8.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -2524,7 +2634,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.0" + "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" }, "funding": [ { @@ -2532,33 +2642,33 @@ "type": "github" } ], - "time": "2025-02-07T04:56:59+00:00" + "time": "2024-03-02T07:19:19+00:00" }, { "name": "sebastian/lines-of-code", - "version": "4.0.0", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", - "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", + "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.3" + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "2.0-dev" } }, "autoload": { @@ -2582,7 +2692,7 @@ "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/4.0.0" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" }, "funding": [ { @@ -2590,34 +2700,34 @@ "type": "github" } ], - "time": "2025-02-07T04:57:28+00:00" + "time": "2023-12-21T08:38:20+00:00" }, { "name": "sebastian/object-enumerator", - "version": "7.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", - "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", + "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", "shasum": "" }, "require": { - "php": ">=8.3", - "sebastian/object-reflector": "^5.0", - "sebastian/recursion-context": "^7.0" + "php": ">=8.1", + "sebastian/object-reflector": "^3.0", + "sebastian/recursion-context": "^5.0" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2639,8 +2749,7 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" }, "funding": [ { @@ -2648,32 +2757,32 @@ "type": "github" } ], - "time": "2025-02-07T04:57:48+00:00" + "time": "2023-02-03T07:08:32+00:00" }, { "name": "sebastian/object-reflector", - "version": "5.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "4bfa827c969c98be1e527abd576533293c634f6a" + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", - "reference": "4bfa827c969c98be1e527abd576533293c634f6a", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", + "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -2695,8 +2804,7 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "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/5.0.0" + "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" }, "funding": [ { @@ -2704,32 +2812,32 @@ "type": "github" } ], - "time": "2025-02-07T04:58:17+00:00" + "time": "2023-02-03T07:06:18+00:00" }, { "name": "sebastian/recursion-context", - "version": "7.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "c405ae3a63e01b32eb71577f8ec1604e39858a7c" + "reference": "05909fb5bc7df4c52992396d0116aed689f93712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/c405ae3a63e01b32eb71577f8ec1604e39858a7c", - "reference": "c405ae3a63e01b32eb71577f8ec1604e39858a7c", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", + "reference": "05909fb5bc7df4c52992396d0116aed689f93712", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -2759,8 +2867,7 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "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/7.0.0" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" }, "funding": [ { @@ -2768,32 +2875,32 @@ "type": "github" } ], - "time": "2025-02-07T05:00:01+00:00" + "time": "2023-02-03T07:05:40+00:00" }, { "name": "sebastian/type", - "version": "6.0.0", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "533fe082889a616f330bcba6f50965135f4f2fab" + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/533fe082889a616f330bcba6f50965135f4f2fab", - "reference": "533fe082889a616f330bcba6f50965135f4f2fab", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", + "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "require-dev": { - "phpunit/phpunit": "^12.0" + "phpunit/phpunit": "^10.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2816,8 +2923,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" }, "funding": [ { @@ -2825,29 +2931,29 @@ "type": "github" } ], - "time": "2025-02-07T05:00:19+00:00" + "time": "2023-02-03T07:10:45+00:00" }, { "name": "sebastian/version", - "version": "6.0.0", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", - "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", "shasum": "" }, "require": { - "php": ">=8.3" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2870,8 +2976,7 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" }, "funding": [ { @@ -2879,59 +2984,7 @@ "type": "github" } ], - "time": "2025-02-07T05:00:38+00:00" - }, - { - "name": "staabm/side-effects-detector", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/staabm/side-effects-detector.git", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", - "reference": "d8334211a140ce329c13726d4a715adbddd0a163", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": "^7.4 || ^8.0" - }, - "require-dev": { - "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.6", - "phpunit/phpunit": "^9.6.21", - "symfony/var-dumper": "^5.4.43", - "tomasvotruba/type-coverage": "1.0.0", - "tomasvotruba/unused-public": "1.0.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "lib/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A static analysis tool to detect side effects in PHP code", - "keywords": [ - "static analysis" - ], - "support": { - "issues": "https://github.com/staabm/side-effects-detector/issues", - "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" - }, - "funding": [ - { - "url": "https://github.com/staabm", - "type": "github" - } - ], - "time": "2024-10-20T05:08:20+00:00" + "time": "2023-02-07T11:34:05+00:00" }, { "name": "theseer/tokenizer", @@ -2986,7 +3039,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { @@ -2994,6 +3047,6 @@ "ext-json": "*", "ext-reflection": "*" }, - "platform-dev": [], - "plugin-api-version": "2.2.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } From 808e3f98aeffc812d8d4cd8a755a2d1c727ceb0a Mon Sep 17 00:00:00 2001 From: "A. Stewart" Date: Mon, 10 Mar 2025 07:40:07 -0400 Subject: [PATCH 4/6] Fix PHP CodeSniffer errors/warnings --- src/BitPaySDK/Model/Subscription/BillData.php | 24 ++++++++++--------- .../Subscription/SubscriptionSchedule.php | 4 +++- 2 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/BitPaySDK/Model/Subscription/BillData.php b/src/BitPaySDK/Model/Subscription/BillData.php index afedfefa..74611b73 100644 --- a/src/BitPaySDK/Model/Subscription/BillData.php +++ b/src/BitPaySDK/Model/Subscription/BillData.php @@ -43,17 +43,17 @@ class BillData * @param string|null $number Recurring bill identifier, specified by merchant * @param string|null $currency The three digit currency code used to compute the billData's amount. * @param string|null $email The email address of the receiver for this billData. - * @param string|\DateTime|null $dueDate Date and time at which a bill is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ (UTC). + * @param string|\DateTime|null $dueDate Date and time at which a bill is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ + * (UTC). * @param array|null $items The list of line items to add to this billData. */ public function __construct( - ?string $number = null, - ?string $currency = null, - ?string $email = null, + ?string $number = null, + ?string $currency = null, + ?string $email = null, string|\DateTime|null $dueDate = null, - ?array $items = null - ) - { + ?array $items = null + ) { $this->number = $number; $this->currency = $currency ?: Currency::USD; $this->email = $email; @@ -73,7 +73,8 @@ public function __construct( /** * Gets billData emailBill * - * If set to `true`, BitPay will automatically issue recurring bills to the `email` address provided once the status of the subscription is set to `active`. + * If set to `true`, BitPay will automatically issue recurring bills to the `email` address provided once the + * status of the subscription is set to `active`. * * @return bool|null */ @@ -85,7 +86,8 @@ public function getEmailBill(): ?bool /** * Sets billData's emailBill * - * If set to `true`, BitPay will automatically issue recurring bills to the `email` address provided once the status of the subscription is set to `active`. + * If set to `true`, BitPay will automatically issue recurring bills to the `email` address provided once the + * status of the subscription is set to `active`. * * @param bool|null $emailBill * @return void @@ -438,8 +440,8 @@ public function setPhone(string $phone): void * * Date and time at which a billData is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) * - * @see Env::BITPAY_DATETIME_FORMAT * @return string|null the number + * @see Env::BITPAY_DATETIME_FORMAT */ public function getDueDate(): ?string { @@ -451,8 +453,8 @@ public function getDueDate(): ?string * * Date and time at which a billData is due, ISO-8601 format yyyy-mm-ddThh:mm:ssZ. (UTC) * - * @see Env::BITPAY_DATETIME_FORMAT * @param string $dueDate Date and time at which a billData is due + * @see Env::BITPAY_DATETIME_FORMAT */ public function setDueDate(string $dueDate): void { diff --git a/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php b/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php index e37eb516..92c75a18 100644 --- a/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php +++ b/src/BitPaySDK/Model/Subscription/SubscriptionSchedule.php @@ -12,7 +12,9 @@ namespace BitPaySDK\Model\Subscription; /** - * Schedule of repeat bill due dates. Can be `weekly`, `monthly`, `quarterly`, `yearly`, or a simple cron expression specifying seconds, minutes, hours, day of month, month, and day of week. BitPay maintains the difference between the due date and the delivery date in all subsequent, automatically-generated bills. + * Schedule of repeat bill due dates. Can be `weekly`, `monthly`, `quarterly`, `yearly`, or a simple cron expression + * specifying seconds, minutes, hours, day of month, month, and day of week. BitPay maintains the difference between + * the due date and the delivery date in all subsequent, automatically-generated bills. * * +-------------- second (0 - 59) * From 77fa8e6fed789fcee19034d6174a088e1debc9fa Mon Sep 17 00:00:00 2001 From: "A. Stewart" Date: Mon, 10 Mar 2025 08:23:05 -0400 Subject: [PATCH 5/6] Added `SettlementStatus` convenience constants --- src/BitPaySDK/Model/Settlement/Settlement.php | 2 ++ .../Model/Settlement/SettlementStatus.php | 29 +++++++++++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/BitPaySDK/Model/Settlement/SettlementStatus.php diff --git a/src/BitPaySDK/Model/Settlement/Settlement.php b/src/BitPaySDK/Model/Settlement/Settlement.php index 43d0204b..9c95ce0d 100644 --- a/src/BitPaySDK/Model/Settlement/Settlement.php +++ b/src/BitPaySDK/Model/Settlement/Settlement.php @@ -141,6 +141,7 @@ public function setPayoutInfo(PayoutInfo $payoutInfo): void * Gets Status of the settlement. Possible statuses are "new", "processing", "rejected" and "completed". * * @return string|null + * @see SettlementStatus */ public function getStatus(): ?string { @@ -151,6 +152,7 @@ public function getStatus(): ?string * Sets Status of the settlement. Possible statuses are "new", "processing", "rejected" and "completed". * * @param string $status + * @see SettlementStatus */ public function setStatus(string $status): void { diff --git a/src/BitPaySDK/Model/Settlement/SettlementStatus.php b/src/BitPaySDK/Model/Settlement/SettlementStatus.php new file mode 100644 index 00000000..2b108fea --- /dev/null +++ b/src/BitPaySDK/Model/Settlement/SettlementStatus.php @@ -0,0 +1,29 @@ + + * @license http://www.opensource.org/licenses/mit-license.php MIT + */ + +namespace BitPaySDK\Model\Settlement; + +/** + * Status of the settlement. + * Possible statuses are "new", "processing", "rejected" and "completed". + * + * @package BitPaySDK\Model\Settlement + * @author BitPay Integrations + * @license http://www.opensource.org/licenses/mit-license.php MIT + * @see https://developer.bitpay.com/reference/settlements Settlements + */ +interface SettlementStatus +{ + public const NEW = "new"; + public const PROCESSING = "processing"; + public const REJECTED = "rejected"; + public const COMPLETED = "completed"; +} \ No newline at end of file From 399e0d4ab73aacc64fa6447941111b0c1f3b6bfa Mon Sep 17 00:00:00 2001 From: "A. Stewart" Date: Mon, 10 Mar 2025 08:27:34 -0400 Subject: [PATCH 6/6] Fix PHP CodeSniffer warnings --- src/BitPaySDK/Model/Settlement/SettlementStatus.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/BitPaySDK/Model/Settlement/SettlementStatus.php b/src/BitPaySDK/Model/Settlement/SettlementStatus.php index 2b108fea..e848653a 100644 --- a/src/BitPaySDK/Model/Settlement/SettlementStatus.php +++ b/src/BitPaySDK/Model/Settlement/SettlementStatus.php @@ -26,4 +26,4 @@ interface SettlementStatus public const PROCESSING = "processing"; public const REJECTED = "rejected"; public const COMPLETED = "completed"; -} \ No newline at end of file +}