From 5b8a43895ab9ab3b4a1ec438e1eac9f6b2487443 Mon Sep 17 00:00:00 2001 From: Rusi Papazov Date: Fri, 22 Aug 2025 11:19:59 +0300 Subject: [PATCH 1/2] php8 --- .gitignore | 5 +- .php-cs-fixer.dist.php | 12 + bin/collection | 12 +- bin/game | 8 +- bin/search | 9 +- bin/user | 19 +- composer.json | 8 +- composer.lock | 3185 +++++++++-------- .../CacheTagGeneratorInterface.php | 4 +- src/BoardGameGeekApi/Client.php | 51 +- src/BoardGameGeekApi/ClientInterface.php | 5 + .../DataTransferObject/AbstractUserItem.php | 15 +- .../DataTransferObject/Collection.php | 9 +- .../DataTransferObject/CollectionItem.php | 12 +- .../DataTransferObject/CollectionStatus.php | 46 +- .../DataTransferObject/CollectionVersion.php | 10 +- .../DataTransferObject/DataTransferObject.php | 9 +- .../DataTransferObjectInterface.php | 2 +- .../DataTransferObject/Expansion.php | 4 +- .../DataTransferObject/Game.php | 4 +- .../DataTransferObject/GameLink.php | 26 +- .../DataTransferObject/GameName.php | 15 +- .../DataTransferObject/GamePoll.php | 21 +- .../DataTransferObject/GameRank.php | 30 +- .../DataTransferObject/GameResults.php | 10 +- .../DataTransferObject/GameStatistics.php | 9 +- .../DataTransferObject/PollResult.php | 11 +- .../DataTransferObject/SearchItem.php | 22 +- .../DataTransferObject/SearchResults.php | 10 +- .../DataTransferObject/User.php | 9 +- .../DataTransferObject/UserBuddy.php | 11 +- .../DataTransferObject/UserGuild.php | 11 +- .../DataTransferObject/UserHotItem.php | 4 +- .../DataTransferObject/UserTopItem.php | 4 +- .../Exception/ExceptionInterface.php | 7 + .../Exception/InvalidArgumentException.php | 7 + .../Exception/InvalidResponseException.php | 7 + src/BoardGameGeekApi/FluentClient.php | 21 +- .../ObjectBuilder/AbstractObjectBuilder.php | 52 +- .../ObjectBuilder/CollectionBuilder.php | 67 +- .../ObjectBuilder/GameBuilder.php | 22 +- .../InvalidResponseException.php | 11 - .../ObjectBuilder/ObjectBuilder.php | 3 +- .../ObjectBuilder/ObjectBuilderInterface.php | 194 +- .../ObjectBuilder/RetryExactSearchBuilder.php | 12 +- .../ObjectBuilder/SearchResultBuilder.php | 22 +- .../ObjectBuilder/UserBuilder.php | 45 +- .../Request/CollectionRequest.php | 16 +- .../Request/RetrySearchRequest.php | 12 +- .../Request/SearchRequest.php | 6 +- src/BoardGameGeekApi/Request/UserRequest.php | 6 +- src/BoardGameGeekApi/RequestInterface.php | 94 +- src/BoardGameGeekApi/Response.php | 14 +- src/BoardGameGeekApi/ResponseInterface.php | 2 +- src/BoardGameGeekApi/UrlGenerator.php | 21 +- tests/.gitignore | 1 - tests/CacheTagGeneratorTest.php | 11 +- tests/ClientTest.php | 71 +- tests/CollectionBuilderTest.php | 84 +- tests/GameBuilderTest.php | 453 +-- tests/ObjectBuilderTest.php | 59 +- tests/RetryExactSearchBuilderTest.php | 93 +- tests/SearchResultBuilderTest.php | 29 +- tests/UrlGeneratorTest.php | 15 +- tests/UserBuilderTest.php | 35 +- tests/fixtures/game.xml | 817 +---- tests/fixtures/game_no_stats.xml | 819 +---- tests/fixtures/multi_games.xml | 1016 +----- tests/phpunit.xml | 4 +- 69 files changed, 2609 insertions(+), 5161 deletions(-) create mode 100644 src/BoardGameGeekApi/Exception/ExceptionInterface.php create mode 100644 src/BoardGameGeekApi/Exception/InvalidArgumentException.php create mode 100644 src/BoardGameGeekApi/Exception/InvalidResponseException.php delete mode 100644 src/BoardGameGeekApi/ObjectBuilder/InvalidResponseException.php delete mode 100644 tests/.gitignore diff --git a/.gitignore b/.gitignore index c0c2e81..401ea81 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,5 @@ vendor/ -.php-cs-fixer.cache \ No newline at end of file +.php-cs-fixer.cache + + tests/.phpunit.cache/ + tests/.phpunit.result.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 1930aae..bd6f59d 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -4,6 +4,7 @@ ->in(__DIR__); $config = new PhpCsFixer\Config(); + return $config->setRules([ '@PSR1' => true, '@PSR12' => true, @@ -21,5 +22,16 @@ 'call_type' => 'self', ], 'php_unit_strict' => false, // DTOs can be compared non-strictly. + 'native_function_invocation' => false, + 'trailing_comma_in_multiline' => [ + 'after_heredoc' => true, + 'elements' => [ + 'arguments', + 'array_destructuring', + 'arrays', + 'match', + 'parameters', + ], + ], ]) ->setFinder($finder); diff --git a/bin/collection b/bin/collection index 83b8cc9..ac59cf0 100755 --- a/bin/collection +++ b/bin/collection @@ -3,6 +3,8 @@ namespace TheBrokenTile\BoardGameGeekApi; use RuntimeException; +use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter; +use Symfony\Component\HttpClient\CurlHttpClient; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\CollectionBuilder; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilder; use TheBrokenTile\BoardGameGeekApi\Request\CollectionRequest; @@ -19,10 +21,10 @@ $client = new Client( new ObjectBuilder([ new CollectionBuilder(), ]), + new CurlHttpClient(), + new FilesystemTagAwareAdapter(), + new UrlGenerator(), + new CacheTagGenerator(), ); -var_dump($client->request( - (new CollectionRequest($username)) - ->filter(RequestInterface::PARAM_COLLECTION_FILTER_PREVIOUSLY_OWNED, true), - ) -); +var_dump($client->request(new CollectionRequest($username))); diff --git a/bin/game b/bin/game index 8fc2f97..e9bd3be 100755 --- a/bin/game +++ b/bin/game @@ -3,6 +3,8 @@ namespace TheBrokenTile\BoardGameGeekApi; use RuntimeException; +use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter; +use Symfony\Component\HttpClient\CurlHttpClient; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\GameBuilder; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilder; use TheBrokenTile\BoardGameGeekApi\Request\GameRequest; @@ -13,13 +15,17 @@ if (count($argv) < 2) { throw new RunTimeException('First argument is required'); } -$ids = explode(RequestInterface::PARAM_VALUE_SEPARATOR, $argv[1]); +$ids = array_map('intval', explode(RequestInterface::PARAM_VALUE_SEPARATOR, $argv[1])); $stats = (bool) ($argv[2] ?? false); $client = new Client( new ObjectBuilder([ new GameBuilder(), ]), + new CurlHttpClient(), + new FilesystemTagAwareAdapter(), + new UrlGenerator(), + new CacheTagGenerator(), ); $request = new GameRequest(...$ids); diff --git a/bin/search b/bin/search index f4eaa99..8635b1c 100755 --- a/bin/search +++ b/bin/search @@ -3,14 +3,11 @@ namespace TheBrokenTile\BoardGameGeekApi; use RuntimeException; -use Symfony\Component\Cache\Adapter\TagAwareAdapter; +use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter; use Symfony\Component\HttpClient\CurlHttpClient; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; -use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\GameBuilder; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilder; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\RetryExactSearchBuilder; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\SearchResultBuilder; -use TheBrokenTile\BoardGameGeekApi\Request\GameRequest; use TheBrokenTile\BoardGameGeekApi\Request\SearchRequest; require dirname(__DIR__).'/vendor/autoload.php'; @@ -28,6 +25,10 @@ $client = new Client( $searchResultBuilder, new RetryExactSearchBuilder($searchResultBuilder), ]), + new CurlHttpClient(), + new FilesystemTagAwareAdapter(), + new UrlGenerator(), + new CacheTagGenerator(), ); $request = new SearchRequest($query, true); diff --git a/bin/user b/bin/user index 9eb3fa9..c72c1cc 100755 --- a/bin/user +++ b/bin/user @@ -3,9 +3,8 @@ namespace TheBrokenTile\BoardGameGeekApi; use RuntimeException; -use Symfony\Component\Cache\Adapter\TagAwareAdapter; +use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter; use Symfony\Component\HttpClient\CurlHttpClient; -use Symfony\Component\Cache\Adapter\FilesystemAdapter; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilder; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\UserBuilder; use TheBrokenTile\BoardGameGeekApi\Request\UserRequest; @@ -22,15 +21,19 @@ $client = new Client( new ObjectBuilder([ new UserBuilder(), ]), + new CurlHttpClient(), + new FilesystemTagAwareAdapter(), + new UrlGenerator(), + new CacheTagGenerator(), ); var_dump( $client->request( - (new UserRequest($username)) - ->buddies() - ->guilds() - ->top() - ->hot() - ->page(1) + new UserRequest($username) + ->buddies() + ->guilds() + ->top() + ->hot() + ->page(1) ) ); diff --git a/composer.json b/composer.json index 8c2b47f..41ecc73 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ } ], "require": { - "php": ">=7.4", + "php": "^8.4", "ext-dom": "*", "symfony/cache": "^5.3", "symfony/css-selector": "^5.3", @@ -32,11 +32,9 @@ } }, "require-dev": { - "phpunit/phpunit": "^9.5", - "phpspec/prophecy-phpunit": "^2.0", - "phpstan/phpstan": "^1.2", + "phpunit/phpunit": "^12", + "phpstan/phpstan": "^2.1", "phpstan/extension-installer": "^1.1", - "jangregor/phpstan-prophecy": "^1.0", "friendsofphp/php-cs-fixer": "^3.3" }, "scripts": { diff --git a/composer.lock b/composer.lock index 44e9d3f..d9d9025 100644 --- a/composer.lock +++ b/composer.lock @@ -4,24 +4,24 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "9fe10d4ecad50cc5701507a5b75ae5f2", + "content-hash": "23aa75ffab400b6b91680f062f853584", "packages": [ { "name": "psr/cache", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "url": "https://api.github.com/repos/php-fig/cache/zipball/213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", + "reference": "213f9dbc5b9bfbc4f8db86d2838dc968752ce13b", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { @@ -41,7 +41,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for caching libraries", @@ -50,26 +50,34 @@ "psr", "psr-6" ], - "time": "2016-08-06T20:24:11+00:00" + "support": { + "source": "https://github.com/php-fig/cache/tree/2.0.0" + }, + "time": "2021-02-03T23:23:37+00:00" }, { "name": "psr/container", - "version": "1.1.1", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -94,34 +102,38 @@ "container-interop", "psr" ], - "time": "2021-03-05T17:36:06+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -141,20 +153,23 @@ "psr", "psr-3" ], - "time": "2021-05-03T11:20:27+00:00" + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" }, { "name": "symfony/cache", - "version": "v5.3.8", + "version": "v5.4.46", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "945bcebfef0aeef105de61843dd14105633ae38f" + "reference": "0fe08ee32cec2748fbfea10c52d3ee02049e0f6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/945bcebfef0aeef105de61843dd14105633ae38f", - "reference": "945bcebfef0aeef105de61843dd14105633ae38f", + "url": "https://api.github.com/repos/symfony/cache/zipball/0fe08ee32cec2748fbfea10c52d3ee02049e0f6b", + "reference": "0fe08ee32cec2748fbfea10c52d3ee02049e0f6b", "shasum": "" }, "require": { @@ -162,35 +177,35 @@ "psr/cache": "^1.0|^2.0", "psr/log": "^1.1|^2|^3", "symfony/cache-contracts": "^1.1.7|^2", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-php73": "^1.9", "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/var-exporter": "^4.4|^5.0|^6.0" }, "conflict": { - "doctrine/dbal": "<2.10", + "doctrine/dbal": "<2.13.1", "symfony/dependency-injection": "<4.4", "symfony/http-kernel": "<4.4", "symfony/var-dumper": "<4.4" }, "provide": { "psr/cache-implementation": "1.0|2.0", - "psr/simple-cache-implementation": "1.0", + "psr/simple-cache-implementation": "1.0|2.0", "symfony/cache-implementation": "1.0|2.0" }, "require-dev": { "cache/integration-tests": "dev-master", "doctrine/cache": "^1.6|^2.0", - "doctrine/dbal": "^2.10|^3.0", - "predis/predis": "^1.1", - "psr/simple-cache": "^1.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/filesystem": "^4.4|^5.0", - "symfony/http-kernel": "^4.4|^5.0", - "symfony/messenger": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" + "doctrine/dbal": "^2.13.1|^3|^4", + "predis/predis": "^1.1|^2.0", + "psr/simple-cache": "^1.0|^2.0", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/filesystem": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4|^5.0|^6.0", + "symfony/messenger": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { @@ -215,12 +230,15 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides an extended PSR-6, PSR-16 (and tags) implementation", + "description": "Provides extended PSR-6, PSR-16 (and tags) implementations", "homepage": "https://symfony.com", "keywords": [ "caching", "psr6" ], + "support": { + "source": "https://github.com/symfony/cache/tree/v5.4.46" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -235,20 +253,20 @@ "type": "tidelift" } ], - "time": "2021-09-26T18:29:18+00:00" + "time": "2024-11-04T11:43:55+00:00" }, { "name": "symfony/cache-contracts", - "version": "v2.4.0", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/symfony/cache-contracts.git", - "reference": "c0446463729b89dd4fa62e9aeecc80287323615d" + "reference": "517c3a3619dadfa6952c4651767fcadffb4df65e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/c0446463729b89dd4fa62e9aeecc80287323615d", - "reference": "c0446463729b89dd4fa62e9aeecc80287323615d", + "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/517c3a3619dadfa6952c4651767fcadffb4df65e", + "reference": "517c3a3619dadfa6952c4651767fcadffb4df65e", "shasum": "" }, "require": { @@ -260,12 +278,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "2.5-dev" } }, "autoload": { @@ -297,6 +315,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/cache-contracts/tree/v2.5.4" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -311,20 +332,20 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/css-selector", - "version": "v5.3.4", + "version": "v5.4.45", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "7fb120adc7f600a59027775b224c13a33530dd90" + "reference": "4f7f3c35fba88146b56d0025d20ace3f3901f097" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/7fb120adc7f600a59027775b224c13a33530dd90", - "reference": "7fb120adc7f600a59027775b224c13a33530dd90", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/4f7f3c35fba88146b56d0025d20ace3f3901f097", + "reference": "4f7f3c35fba88146b56d0025d20ace3f3901f097", "shasum": "" }, "require": { @@ -360,6 +381,9 @@ ], "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v5.4.45" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -374,33 +398,33 @@ "type": "tidelift" } ], - "time": "2021-07-21T12:38:00+00:00" + "time": "2024-09-25T14:11:13+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.4.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/63afe740e99a13ba87ec199bb07bbdee937a5b62", + "reference": "63afe740e99a13ba87ec199bb07bbdee937a5b62", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -424,6 +448,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.6.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -438,25 +465,25 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/dom-crawler", - "version": "v5.3.7", + "version": "v5.4.48", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "c7eef3a60ccfdd8eafe07f81652e769ac9c7146c" + "reference": "b57df76f4757a9a8dfbb57ba48d7780cc20776c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/c7eef3a60ccfdd8eafe07f81652e769ac9c7146c", - "reference": "c7eef3a60ccfdd8eafe07f81652e769ac9c7146c", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b57df76f4757a9a8dfbb57ba48d7780cc20776c6", + "reference": "b57df76f4757a9a8dfbb57ba48d7780cc20776c6", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php80": "^1.16" @@ -466,7 +493,7 @@ }, "require-dev": { "masterminds/html5": "^2.6", - "symfony/css-selector": "^4.4|^5.0" + "symfony/css-selector": "^4.4|^5.0|^6.0" }, "suggest": { "symfony/css-selector": "" @@ -496,6 +523,9 @@ ], "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/dom-crawler/tree/v5.4.48" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -510,30 +540,30 @@ "type": "tidelift" } ], - "time": "2021-08-29T19:32:13+00:00" + "time": "2024-11-13T14:36:38+00:00" }, { "name": "symfony/http-client", - "version": "v5.3.8", + "version": "v5.4.49", "source": { "type": "git", "url": "https://github.com/symfony/http-client.git", - "reference": "c6370fe2c0a445aedc08f592a6a3149da1fea4c7" + "reference": "d77d8e212cde7b5c4a64142bf431522f19487c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client/zipball/c6370fe2c0a445aedc08f592a6a3149da1fea4c7", - "reference": "c6370fe2c0a445aedc08f592a6a3149da1fea4c7", + "url": "https://api.github.com/repos/symfony/http-client/zipball/d77d8e212cde7b5c4a64142bf431522f19487c28", + "reference": "d77d8e212cde7b5c4a64142bf431522f19487c28", "shasum": "" }, "require": { "php": ">=7.2.5", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.1", - "symfony/http-client-contracts": "^2.4", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-client-contracts": "^2.5.4", "symfony/polyfill-php73": "^1.11", "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.0|^2" + "symfony/service-contracts": "^1.0|^2|^3" }, "provide": { "php-http/async-client-implementation": "*", @@ -546,14 +576,15 @@ "amphp/http-client": "^4.2.1", "amphp/http-tunnel": "^1.0", "amphp/socket": "^1.1", - "guzzlehttp/promises": "^1.4", + "guzzlehttp/promises": "^1.4|^2.0", "nyholm/psr7": "^1.0", "php-http/httplug": "^1.0|^2.0", + "php-http/message-factory": "^1.0", "psr/http-client": "^1.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/http-kernel": "^4.4.13|^5.1.5", - "symfony/process": "^4.4|^5.0", - "symfony/stopwatch": "^4.4|^5.0" + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/http-kernel": "^4.4.13|^5.1.5|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/stopwatch": "^4.4|^5.0|^6.0" }, "type": "library", "autoload": { @@ -580,6 +611,12 @@ ], "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v5.4.49" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -594,20 +631,20 @@ "type": "tidelift" } ], - "time": "2021-09-07T10:45:28+00:00" + "time": "2024-11-28T08:37:04+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v2.4.0", + "version": "v2.5.5", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4" + "reference": "48ef1d0a082885877b664332b9427662065a360c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e82f6084d7cae521a75ef2cb5c9457bbda785f4", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/48ef1d0a082885877b664332b9427662065a360c", + "reference": "48ef1d0a082885877b664332b9427662065a360c", "shasum": "" }, "require": { @@ -618,12 +655,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "2.5-dev" } }, "autoload": { @@ -655,6 +692,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.5" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -669,45 +709,45 @@ "type": "tidelift" } ], - "time": "2021-04-11T23:07:08+00:00" + "time": "2024-11-28T08:37:04+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.23.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" }, "suggest": { "ext-ctype": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -731,6 +771,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -740,50 +783,55 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.23.1", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -808,6 +856,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -817,47 +868,48 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2024-12-23T08:48:59+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.23.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -884,6 +936,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.33.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -893,47 +948,48 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.23.1", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/0cc9dd0f17f61d8131e7df6b84bd344899fe2608", + "reference": "0cc9dd0f17f61d8131e7df6b84bd344899fe2608", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -964,6 +1020,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.33.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -973,48 +1032,56 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-07-28T13:41:28+00:00" + "time": "2025-01-02T08:10:11+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.4.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f021b05a130d35510bd6b25fe9053c2a8a15d5d4", + "reference": "f021b05a130d35510bd6b25fe9053c2a8a15d5d4", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, - "suggest": { - "symfony/service-implementation": "" + "conflict": { + "ext-psr": "<1.1|>=2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1040,6 +1107,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.6.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1054,28 +1124,30 @@ "type": "tidelift" } ], - "time": "2021-04-01T10:43:52+00:00" + "time": "2025-04-25T09:37:31+00:00" }, { "name": "symfony/var-exporter", - "version": "v5.3.8", + "version": "v6.4.24", "source": { "type": "git", "url": "https://github.com/symfony/var-exporter.git", - "reference": "a7604de14bcf472fe8e33f758e9e5b7bf07d3b91" + "reference": "1e742d559fe5b19d0cdc281b1bf0b1fcc243bd35" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/a7604de14bcf472fe8e33f758e9e5b7bf07d3b91", - "reference": "a7604de14bcf472fe8e33f758e9e5b7bf07d3b91", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1e742d559fe5b19d0cdc281b1bf0b1fcc243bd35", + "reference": "1e742d559fe5b19d0cdc281b1bf0b1fcc243bd35", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3" }, "require-dev": { - "symfony/var-dumper": "^4.4.9|^5.0.9" + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -1108,8 +1180,13 @@ "export", "hydrate", "instantiate", + "lazy-loading", + "proxy", "serialize" ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v6.4.24" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1119,35 +1196,182 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-08-31T12:49:16+00:00" + "time": "2025-07-10T08:14:14+00:00" } ], "packages-dev": [ + { + "name": "clue/ndjson-react", + "version": "v1.3.0", + "source": { + "type": "git", + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" + }, + "type": "library", + "autoload": { + "psr-4": { + "Clue\\React\\NDJson\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering" + } + ], + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", + "keywords": [ + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" + ], + "support": { + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" + }, + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" + }, + { + "name": "composer/pcre", + "version": "3.3.2", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "shasum": "" + }, + "require": { + "php": "^7.4 || ^8.0" + }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, + "require-dev": { + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" + }, + "type": "library", + "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/3.3.2" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2024-11-12T16:29:46+00:00" + }, { "name": "composer/semver", - "version": "3.2.6", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "83e511e247de329283478496f7a1e114c9517506" + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", - "reference": "83e511e247de329283478496f7a1e114c9517506", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.54", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { @@ -1189,9 +1413,9 @@ "versioning" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.2.6" + "source": "https://github.com/composer/semver/tree/3.4.4" }, "funding": [ { @@ -1201,35 +1425,33 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2021-10-25T11:34:17+00:00" + "time": "2025-08-20T19:15:30+00:00" }, { "name": "composer/xdebug-handler", - "version": "2.0.2", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339" + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/84674dd3a7575ba617f5a76d7e9e29a7d3891339", - "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0", + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", "psr/log": "^1 || ^2 || ^3" }, "require-dev": { - "phpstan/phpstan": "^0.12.55", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, "type": "library", "autoload": { @@ -1253,9 +1475,9 @@ "performance" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/2.0.2" + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" }, "funding": [ { @@ -1271,39 +1493,32 @@ "type": "tidelift" } ], - "time": "2021-07-31T17:03:58+00:00" + "time": "2024-05-06T16:37:16+00:00" }, { - "name": "doctrine/annotations", - "version": "1.13.2", + "name": "evenement/evenement", + "version": "v3.0.2", "source": { "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08" + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", "shasum": "" }, "require": { - "doctrine/lexer": "1.*", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" + "php": ">=7.0" }, "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^0.12.20", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2" + "phpunit/phpunit": "^9 || ^6" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" + "Evenement\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1312,69 +1527,53 @@ ], "authors": [ { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" } ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "description": "Événement is a very simple event dispatching library for PHP", "keywords": [ - "annotations", - "docblock", - "parser" + "event-dispatcher", + "event-emitter" ], "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.2" + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" }, - "time": "2021-08-05T19:00:23+00:00" + "time": "2023-08-08T05:53:35+00:00" }, { - "name": "doctrine/instantiator", - "version": "1.4.0", + "name": "fidry/cpu-core-counter", + "version": "1.3.0", "source": { "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-deprecation-rules": "^2.0.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + "Fidry\\CpuCoreCounter\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1383,166 +1582,82 @@ ], "authors": [ { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "https://ocramius.github.io/" + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" } ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "description": "Tiny utility to get the number of CPU cores.", "keywords": [ - "constructor", - "instantiate" + "CPU", + "core" ], "support": { - "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" }, "funding": [ { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" + "url": "https://github.com/theofidry", + "type": "github" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2025-08-14T07:29:31+00:00" }, { - "name": "doctrine/lexer", - "version": "1.2.1", + "name": "friendsofphp/php-cs-fixer", + "version": "v3.86.0", "source": { "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "4a952bd19dc97879b0620f495552ef09b55f7d36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4a952bd19dc97879b0620f495552ef09b55f7d36", + "reference": "4a952bd19dc97879b0620f495552ef09b55f7d36", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpstan/phpstan": "^0.11.8", - "phpunit/phpunit": "^8.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.1" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2020-05-25T17:44:05+00:00" - }, - { - "name": "friendsofphp/php-cs-fixer", - "version": "v3.3.2", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "06bdbdfcd619183dd7a1a6948360f8af73b9ecec" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/06bdbdfcd619183dd7a1a6948360f8af73b9ecec", - "reference": "06bdbdfcd619183dd7a1a6948360f8af73b9ecec", - "shasum": "" - }, - "require": { - "composer/semver": "^3.2", - "composer/xdebug-handler": "^2.0", - "doctrine/annotations": "^1.12", + "clue/ndjson-react": "^1.3", + "composer/semver": "^3.4", + "composer/xdebug-handler": "^3.0.5", + "ext-filter": "*", + "ext-hash": "*", "ext-json": "*", "ext-tokenizer": "*", - "php": "^7.2.5 || ^8.0", - "php-cs-fixer/diff": "^2.0", - "symfony/console": "^5.1.3", - "symfony/event-dispatcher": "^5.0", - "symfony/filesystem": "^5.0", - "symfony/finder": "^5.0", - "symfony/options-resolver": "^5.0", - "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php72": "^1.23", - "symfony/polyfill-php80": "^1.23", - "symfony/polyfill-php81": "^1.23", - "symfony/process": "^5.0", - "symfony/stopwatch": "^5.0" + "fidry/cpu-core-counter": "^1.2", + "php": "^7.4 || ^8.0", + "react/child-process": "^0.6.6", + "react/event-loop": "^1.5", + "react/promise": "^3.2", + "react/socket": "^1.16", + "react/stream": "^1.4", + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0", + "symfony/console": "^5.4.47 || ^6.4.13 || ^7.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.13 || ^7.0", + "symfony/filesystem": "^5.4.45 || ^6.4.13 || ^7.0", + "symfony/finder": "^5.4.45 || ^6.4.17 || ^7.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.16 || ^7.0", + "symfony/polyfill-mbstring": "^1.32", + "symfony/polyfill-php80": "^1.32", + "symfony/polyfill-php81": "^1.32", + "symfony/process": "^5.4.47 || ^6.4.20 || ^7.2", + "symfony/stopwatch": "^5.4.45 || ^6.4.19 || ^7.0" }, "require-dev": { - "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^1.5", - "mikey179/vfsstream": "^1.6.8", - "php-coveralls/php-coveralls": "^2.4.3", + "facile-it/paraunit": "^1.3.1 || ^2.6", + "infection/infection": "^0.29.14", + "justinrainbow/json-schema": "^5.3 || ^6.4", + "keradus/cli-executor": "^2.2", + "mikey179/vfsstream": "^1.6.12", + "php-coveralls/php-coveralls": "^2.8", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.10.3", - "phpspec/prophecy-phpunit": "^1.1 || ^2.0", - "phpunit/phpunit": "^7.5.20 || ^8.5.14 || ^9.5", - "phpunitgoodpractices/polyfill": "^1.5", - "phpunitgoodpractices/traits": "^1.9.1", - "symfony/phpunit-bridge": "^5.2.4", - "symfony/yaml": "^5.0" + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", + "phpunit/phpunit": "^9.6.23 || ^10.5.47 || ^11.5.25", + "symfony/polyfill-php84": "^1.32", + "symfony/var-dumper": "^5.4.48 || ^6.4.23 || ^7.3.1", + "symfony/yaml": "^5.4.45 || ^6.4.23 || ^7.3.1" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -1555,7 +1670,10 @@ "autoload": { "psr-4": { "PhpCsFixer\\": "src/" - } + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1572,116 +1690,59 @@ } ], "description": "A tool to automatically fix PHP code style", - "support": { - "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.3.2" - }, - "funding": [ - { - "url": "https://github.com/keradus", - "type": "github" - } - ], - "time": "2021-11-15T18:06:47+00:00" - }, - { - "name": "jangregor/phpstan-prophecy", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/Jan0707/phpstan-prophecy.git", - "reference": "2bc7ca9460395690c6bf7332bdfb2f25d5cae8e0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Jan0707/phpstan-prophecy/zipball/2bc7ca9460395690c6bf7332bdfb2f25d5cae8e0", - "reference": "2bc7ca9460395690c6bf7332bdfb2f25d5cae8e0", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "phpstan/phpstan": "^1.0.0" - }, - "conflict": { - "phpspec/prophecy": "<1.7.0,>=2.0.0", - "phpunit/phpunit": "<6.0.0,>=10.0.0" - }, - "require-dev": { - "ergebnis/composer-normalize": "^2.1.1", - "ergebnis/license": "^1.0.0", - "ergebnis/php-cs-fixer-config": "~2.2.0", - "phpspec/prophecy": "^1.7.0", - "phpunit/phpunit": "^6.0.0 || ^7.0.0 || ^8.0.0 || ^9.0.0" - }, - "type": "phpstan-extension", - "extra": { - "phpstan": { - "includes": [ - "extension.neon" - ] - } - }, - "autoload": { - "psr-4": { - "JanGregor\\Prophecy\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jan Gregor Emge-Triebel", - "email": "jan@jangregor.me" - } + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" ], - "description": "Provides a phpstan/phpstan extension for phpspec/prophecy", "support": { - "issues": "https://github.com/Jan0707/phpstan-prophecy/issues", - "source": "https://github.com/Jan0707/phpstan-prophecy/tree/1.0.0" + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.86.0" }, "funding": [ { - "url": "https://github.com/localheinz", + "url": "https://github.com/keradus", "type": "github" } ], - "time": "2021-11-08T16:37:47+00:00" + "time": "2025-08-13T22:36:21+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.13.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1697,7 +1758,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" }, "funding": [ { @@ -1705,29 +1766,31 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { "name": "nikic/php-parser", - "version": "v4.13.1", + "version": "v5.6.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -1735,7 +1798,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -1759,26 +1822,27 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" }, - "time": "2021-11-03T20:52:16+00:00" + "time": "2025-08-13T20:13:15+00:00" }, { "name": "phar-io/manifest", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", @@ -1819,22 +1883,28 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-07-20T11:28:43+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "bae7c545bef187884426f042434e561ab1ddb182" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", - "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { @@ -1870,493 +1940,504 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.0" + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2021-02-23T14:00:09+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { - "name": "php-cs-fixer/diff", - "version": "v2.0.2", + "name": "phpstan/extension-installer", + "version": "1.4.3", "source": { "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3" + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/29dc0d507e838c4580d018bd8b5cb412474f7ec3", - "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/85e90b3942d06b2326fba0403ec24fe912372936", + "reference": "85e90b3942d06b2326fba0403ec24fe912372936", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0 || ^8.0" + "composer-plugin-api": "^2.0", + "php": "^7.2 || ^8.0", + "phpstan/phpstan": "^1.9.0 || ^2.0" }, "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", - "symfony/process": "^3.3" + "composer/composer": "^2.0", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12 || ^1.0" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" }, - "type": "library", "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } + "MIT" ], - "description": "sebastian/diff v3 backport support for PHP 5.6+", - "homepage": "https://github.com/PHP-CS-Fixer", + "description": "Composer plugin for automatic installation of PHPStan extensions", "keywords": [ - "diff" + "dev", + "static analysis" ], "support": { - "issues": "https://github.com/PHP-CS-Fixer/diff/issues", - "source": "https://github.com/PHP-CS-Fixer/diff/tree/v2.0.2" + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.4.3" }, - "time": "2020-10-14T08:32:19+00:00" + "time": "2024-09-04T20:21:43+00:00" }, { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", + "name": "phpstan/phpstan", + "version": "2.1.22", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + "url": "https://github.com/phpstan/phpstan.git", + "reference": "41600c8379eb5aee63e9413fe9e97273e25d57e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/41600c8379eb5aee63e9413fe9e97273e25d57e4", + "reference": "41600c8379eb5aee63e9413fe9e97273e25d57e4", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.4|^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } + "conflict": { + "phpstan/phpstan-shim": "*" }, + "bin": [ + "phpstan", + "phpstan.phar" + ], + "type": "library", "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } + "files": [ + "bootstrap.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", + "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", + "dev", "static analysis" ], "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", + "issues": "https://github.com/phpstan/phpstan/issues", + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, - "time": "2020-06-27T09:03:43+00:00" + "funding": [ + { + "url": "https://github.com/ondrejmirtes", + "type": "github" + }, + { + "url": "https://github.com/phpstan", + "type": "github" + } + ], + "time": "2025-08-04T19:17:37+00:00" }, { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "name": "phpunit/php-code-coverage", + "version": "12.3.2", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "086553c5b2e0e1e20293d782d788ab768202b621" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/086553c5b2e0e1e20293d782d788ab768202b621", + "reference": "086553c5b2e0e1e20293d782d788ab768202b621", "shasum": "" }, "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" + "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", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" + "phpunit/phpunit": "^12.1" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.x-dev" + "dev-main": "12.3.x-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + "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.3.2" }, - "time": "2021-10-19T17:43:47+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/php-code-coverage", + "type": "tidelift" + } + ], + "time": "2025-07-29T06:19:24+00:00" }, { - "name": "phpdocumentor/type-resolver", - "version": "1.5.1", + "name": "phpunit/php-file-iterator", + "version": "6.0.0", "source": { "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "961bc913d42fe24a257bfff826a5068079ac7782" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/961bc913d42fe24a257bfff826a5068079ac7782", + "reference": "961bc913d42fe24a257bfff826a5068079ac7782", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "php": ">=8.3" }, "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-1.x": "1.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + "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" }, - "time": "2021-10-02T14:08:47+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:58:37+00:00" }, { - "name": "phpspec/prophecy", - "version": "1.14.0", + "name": "phpunit/php-invoker", + "version": "6.0.0", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" + "php": ">=8.3" }, "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" + "ext-pcntl": "*", + "phpunit/phpunit": "^12.0" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" + "process" ], "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + "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" }, - "time": "2021-09-10T09:02:12+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2025-02-07T04:58:58+00:00" }, { - "name": "phpspec/prophecy-phpunit", - "version": "v2.0.1", + "name": "phpunit/php-text-template", + "version": "5.0.0", "source": { "type": "git", - "url": "https://github.com/phpspec/prophecy-phpunit.git", - "reference": "2d7a9df55f257d2cba9b1d0c0963a54960657177" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/2d7a9df55f257d2cba9b1d0c0963a54960657177", - "reference": "2d7a9df55f257d2cba9b1d0c0963a54960657177", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", "shasum": "" }, "require": { - "php": "^7.3 || ^8", - "phpspec/prophecy": "^1.3", - "phpunit/phpunit": "^9.1" + "php": ">=8.3" + }, + "require-dev": { + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { - "psr-4": { - "Prophecy\\PhpUnit\\": "src" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Christophe Coevoet", - "email": "stof@notk.org" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Integrating the Prophecy mocking library in PHPUnit test cases", - "homepage": "http://phpspec.net", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "phpunit", - "prophecy" + "template" ], "support": { - "issues": "https://github.com/phpspec/prophecy-phpunit/issues", - "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.0.1" - }, - "time": "2020-07-09T08:33:42+00:00" - }, - { - "name": "phpstan/extension-installer", - "version": "1.1.0", - "source": { - "type": "git", - "url": "https://github.com/phpstan/extension-installer.git", - "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/66c7adc9dfa38b6b5838a9fb728b68a7d8348051", - "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1 || ^2.0", - "php": "^7.1 || ^8.0", - "phpstan/phpstan": ">=0.11.6" - }, - "require-dev": { - "composer/composer": "^1.8", - "phing/phing": "^2.16.3", - "php-parallel-lint/php-parallel-lint": "^1.2.0", - "phpstan/phpstan-strict-rules": "^0.11 || ^0.12" - }, - "type": "composer-plugin", - "extra": { - "class": "PHPStan\\ExtensionInstaller\\Plugin" + "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" }, - "autoload": { - "psr-4": { - "PHPStan\\ExtensionInstaller\\": "src/" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" ], - "description": "Composer plugin for automatic installation of PHPStan extensions", - "support": { - "issues": "https://github.com/phpstan/extension-installer/issues", - "source": "https://github.com/phpstan/extension-installer/tree/1.1.0" - }, - "time": "2020-12-13T13:06:13+00:00" + "time": "2025-02-07T04:59:16+00:00" }, { - "name": "phpstan/phpstan", - "version": "1.2.0", + "name": "phpunit/php-timer", + "version": "8.0.0", "source": { "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", - "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", "shasum": "" }, "require": { - "php": "^7.1|^8.0" + "php": ">=8.3" }, - "conflict": { - "phpstan/phpstan-shim": "*" + "require-dev": { + "phpunit/phpunit": "^12.0" }, - "bin": [ - "phpstan", - "phpstan.phar" - ], "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-main": "8.0-dev" } }, "autoload": { - "files": [ - "bootstrap.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" ], - "description": "PHPStan - PHP Static Analysis Tool", "support": { - "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.2.0" + "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" }, "funding": [ { - "url": "https://github.com/ondrejmirtes", - "type": "github" - }, - { - "url": "https://github.com/phpstan", + "url": "https://github.com/sebastianbergmann", "type": "github" - }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2021-11-18T14:09:01+00:00" + "time": "2025-02-07T04:59:38+00:00" }, { - "name": "phpunit/php-code-coverage", - "version": "9.2.9", + "name": "phpunit/phpunit", + "version": "12.3.6", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b" + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "a2cab3224f687150ac2f3cc13d99b64ba1e1d088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", - "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2cab3224f687150ac2f3cc13d99b64ba1e1d088", + "reference": "a2cab3224f687150ac2f3cc13d99b64ba1e1d088", "shasum": "" }, "require": { "ext-dom": "*", + "ext-json": "*", "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.3", + "phpunit/php-code-coverage": "^12.3.2", + "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.1.3", + "sebastian/diff": "^7.0.0", + "sebastian/environment": "^8.0.3", + "sebastian/exporter": "^7.0.0", + "sebastian/global-state": "^8.0.0", + "sebastian/object-enumerator": "^7.0.0", + "sebastian/type": "^6.0.3", + "sebastian/version": "^6.0.0", + "staabm/side-effects-detector": "^1.0.5" }, + "bin": [ + "phpunit" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "12.3-dev" } }, "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], "classmap": [ "src/" ] @@ -2372,395 +2453,415 @@ "role": "lead" } ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", "keywords": [ - "coverage", + "phpunit", "testing", "xunit" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.9" + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.3.6" }, "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "time": "2021-11-19T15:21:02+00:00" + "time": "2025-08-20T14:43:23+00:00" }, { - "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "name": "psr/event-dispatcher", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=7.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" } ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "description": "Standard interfaces for event handling.", "keywords": [ - "filesystem", - "iterator" + "events", + "psr", + "psr-14" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-09-28T05:57:25+00:00" + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" }, { - "name": "phpunit/php-invoker", - "version": "3.1.1", + "name": "react/cache", + "version": "v1.2.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" }, "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcntl": "*" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "React\\Cache\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "description": "Async, Promise-based cache interface for ReactPHP", "keywords": [ - "process" + "cache", + "caching", + "promise", + "reactphp" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2022-11-30T15:59:55+00:00" }, { - "name": "phpunit/php-text-template", - "version": "2.0.4", + "name": "react/child-process", + "version": "v0.6.6", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "url": "https://github.com/reactphp/child-process.git", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", "shasum": "" }, "require": { - "php": ">=7.3" + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "React\\ChildProcess\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "Event-driven library for executing child processes with ReactPHP.", "keywords": [ - "template" + "event-driven", + "process", + "reactphp" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.6" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2025-01-01T16:37:48+00:00" }, { - "name": "phpunit/php-timer", - "version": "5.0.3", + "name": "react/dns", + "version": "v1.13.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "url": "https://github.com/reactphp/dns.git", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.7 || ^1.2.1" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "React\\Dns\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "Async DNS resolver for ReactPHP", "keywords": [ - "timer" + "async", + "dns", + "dns-resolver", + "reactphp" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.13.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2024-06-13T14:18:03+00:00" }, { - "name": "phpunit/phpunit", - "version": "9.5.10", + "name": "react/event-loop", + "version": "v1.5.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.7", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3.4", - "sebastian/version": "^3.0.2" + "php": ">=5.3.0" }, "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" }, - "bin": [ - "phpunit" - ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.5-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ], - "files": [ - "src/Framework/Assert/Functions.php" - ] + "psr-4": { + "React\\EventLoop\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", "keywords": [ - "phpunit", - "testing", - "xunit" + "asynchronous", + "event-loop" ], "support": { - "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" }, "funding": [ { - "url": "https://phpunit.de/donate.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2021-09-25T07:38:51+00:00" + "time": "2023-11-13T13:48:05+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "react/promise", + "version": "v3.3.0", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/reactphp/promise.git", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.1.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "require-dev": { + "phpstan/phpstan": "1.12.28 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" }, + "type": "library", "autoload": { + "files": [ + "src/functions_include.php" + ], "psr-4": { - "Psr\\EventDispatcher\\": "src/" + "React\\Promise\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2769,158 +2870,225 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Standard interfaces for event handling.", + "description": "A lightweight implementation of CommonJS Promises/A for PHP", "keywords": [ - "events", - "psr", - "psr-14" + "promise", + "promises" ], "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.3.0" }, - "time": "2019-01-08T18:20:26+00:00" + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2025-08-19T18:57:03+00:00" }, { - "name": "sebastian/cli-parser", - "version": "1.0.1", + "name": "react/socket", + "version": "v1.16.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "url": "https://github.com/reactphp/socket.git", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", "shasum": "" }, "require": { - "php": ">=7.3" + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.13", + "react/event-loop": "^1.2", + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4.3 || ^3.3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.11" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "React\\Socket\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", + "keywords": [ + "Connection", + "Socket", + "async", + "reactphp", + "stream" + ], "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.16.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2024-07-26T10:38:09+00:00" }, { - "name": "sebastian/code-unit", - "version": "1.0.8", + "name": "react/stream", + "version": "v1.4.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "url": "https://github.com/reactphp/stream.git", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", "shasum": "" }, "require": { - "php": ">=7.3" + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, "autoload": { - "classmap": [ - "src/" - ] + "psr-4": { + "React\\Stream\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], "authors": [ { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", + "keywords": [ + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" + ], "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.4.0" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2024-06-11T12:45:25+00:00" }, { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "name": "sebastian/cli-parser", + "version": "4.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/6d584c727d9114bcdc14c86711cd1cad51778e7c", + "reference": "6d584c727d9114bcdc14c86711cd1cad51778e7c", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -2935,14 +3103,16 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "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" }, "funding": [ { @@ -2950,34 +3120,39 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2025-02-07T04:53:50+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "7.1.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "dc904b4bb3ab070865fa4068cd84f3da8b945148" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dc904b4bb3ab070865fa4068cd84f3da8b945148", + "reference": "dc904b4bb3ab070865fa4068cd84f3da8b945148", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.3", + "sebastian/diff": "^7.0", + "sebastian/exporter": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.2" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "7.1-dev" } }, "autoload": { @@ -3016,41 +3191,54 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2025-08-20T11:27:00+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -3073,7 +3261,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" }, "funding": [ { @@ -3081,33 +3270,33 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2025-02-07T04:55:25+00:00" }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -3139,7 +3328,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" }, "funding": [ { @@ -3147,27 +3337,27 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2025-02-07T04:55:46+00:00" }, { "name": "sebastian/environment", - "version": "5.1.3", + "version": "8.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + "reference": "24a711b5c916efc6d6e62aa65aa2ec98fef77f68" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/24a711b5c916efc6d6e62aa65aa2ec98fef77f68", + "reference": "24a711b5c916efc6d6e62aa65aa2ec98fef77f68", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-posix": "*" @@ -3175,7 +3365,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -3194,7 +3384,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -3202,42 +3392,55 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/8.0.3" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/environment", + "type": "tidelift" } ], - "time": "2020-09-28T05:52:38+00:00" + "time": "2025-08-12T14:11:56+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "76432aafc58d50691a00d86d0632f1217a47b688" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/76432aafc58d50691a00d86d0632f1217a47b688", + "reference": "76432aafc58d50691a00d86d0632f1217a47b688", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.3", + "sebastian/recursion-context": "^7.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -3279,7 +3482,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.0" }, "funding": [ { @@ -3287,38 +3491,35 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2025-02-07T04:56:42+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.3", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/570a2aeb26d40f057af686d63c4e99b075fb6cbc", + "reference": "570a2aeb26d40f057af686d63c4e99b075fb6cbc", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -3337,13 +3538,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.0" }, "funding": [ { @@ -3351,33 +3553,33 @@ "type": "github" } ], - "time": "2021-06-11T13:31:12+00:00" + "time": "2025-02-07T04:56:59+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/97ffee3bcfb5805568d6af7f0f893678fc076d2f", + "reference": "97ffee3bcfb5805568d6af7f0f893678fc076d2f", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -3400,7 +3602,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.0" }, "funding": [ { @@ -3408,34 +3611,34 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2025-02-07T04:57:28+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -3457,7 +3660,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/4.0.4" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" }, "funding": [ { @@ -3465,32 +3669,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2025-02-07T04:57:48+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "4bfa827c969c98be1e527abd576533293c634f6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -3512,7 +3716,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/2.0.4" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0" }, "funding": [ { @@ -3520,32 +3725,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2025-02-07T04:58:17+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -3572,43 +3777,56 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2025-08-13T04:44:59+00:00" }, { - "name": "sebastian/resource-operations", - "version": "3.0.3", + "name": "sebastian/type", + "version": "6.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/e549163b9760b8f71f191651d22acf32d56d6d4d", + "reference": "e549163b9760b8f71f191651d22acf32d56d6d4d", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -3623,48 +3841,58 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/6.0.3" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/type", + "type": "tidelift" } ], - "abandoned": true, - "time": "2020-09-28T06:45:17+00:00" + "time": "2025-08-09T06:57:12+00:00" }, { - "name": "sebastian/type", - "version": "2.3.4", + "name": "sebastian/version", + "version": "6.0.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" + "php": ">=8.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -3683,11 +3911,12 @@ "role": "lead" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + "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" }, "funding": [ { @@ -3695,108 +3924,103 @@ "type": "github" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2025-02-07T05:00:38+00:00" }, { - "name": "sebastian/version", - "version": "3.0.2", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "php": ">=7.3" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } + "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": [ - "src/" + "lib/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "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/sebastianbergmann", + "url": "https://github.com/staabm", "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2024-10-20T05:08:20+00:00" }, { "name": "symfony/console", - "version": "v5.3.11", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3e7ab8f5905058984899b05a4648096f558bfeba" + "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3e7ab8f5905058984899b05a4648096f558bfeba", - "reference": "3e7ab8f5905058984899b05a4648096f558bfeba", + "url": "https://api.github.com/repos/symfony/console/zipball/5f360ebc65c55265a74d23d7fe27f957870158a1", + "reference": "5f360ebc65c55265a74d23d7fe27f957870158a1", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2", - "symfony/string": "^5.1" + "symfony/service-contracts": "^2.5|^3", + "symfony/string": "^7.2" }, "conflict": { - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { - "psr/log-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "psr/log": "^1|^2|^3", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -3825,12 +4049,12 @@ "homepage": "https://symfony.com", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.11" + "source": "https://github.com/symfony/console/tree/v7.3.2" }, "funding": [ { @@ -3841,53 +4065,52 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-11-21T19:41:05+00:00" + "time": "2025-07-30T17:13:41+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.3.11", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "661a7a6e085394f8513945669e31f7c1338a7e69" + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/661a7a6e085394f8513945669e31f7c1338a7e69", - "reference": "661a7a6e085394f8513945669e31f7c1338a7e69", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/497f73ac996a598c92409b44ac43b6690c4f666d", + "reference": "497f73ac996a598c92409b44ac43b6690c4f666d", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/event-dispatcher-contracts": "^2", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.2", + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<4.4" + "symfony/dependency-injection": "<6.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0" + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/error-handler": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^4.4|^5.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/service-contracts": "^2.5|^3", + "symfony/stopwatch": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -3915,7 +4138,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.11" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.3.0" }, "funding": [ { @@ -3931,37 +4154,34 @@ "type": "tidelift" } ], - "time": "2021-11-17T12:16:12+00:00" + "time": "2025-04-22T09:11:45+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.0", + "version": "v3.6.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" + "reference": "59eb412e93815df44f05f342958efa9f46b1e586" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/59eb412e93815df44f05f342958efa9f46b1e586", + "reference": "59eb412e93815df44f05f342958efa9f46b1e586", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -3994,7 +4214,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.6.0" }, "funding": [ { @@ -4010,26 +4230,29 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/filesystem", - "version": "v5.3.4", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32" + "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/343f4fe324383ca46792cae728a3b6e2f708fb32", - "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd", + "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.16" + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -4057,7 +4280,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.3.4" + "source": "https://github.com/symfony/filesystem/tree/v7.3.2" }, "funding": [ { @@ -4068,30 +4291,36 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-07-21T12:40:44+00:00" + "time": "2025-07-07T08:17:47+00:00" }, { "name": "symfony/finder", - "version": "v5.3.7", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93" + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93", + "url": "https://api.github.com/repos/symfony/finder/zipball/2a6614966ba1074fa93dae0bc804227422df4dfe", + "reference": "2a6614966ba1074fa93dae0bc804227422df4dfe", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.2" + }, + "require-dev": { + "symfony/filesystem": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -4119,7 +4348,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.3.7" + "source": "https://github.com/symfony/finder/tree/v7.3.2" }, "funding": [ { @@ -4130,32 +4359,34 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2025-07-15T13:41:35+00:00" }, { "name": "symfony/options-resolver", - "version": "v5.3.7", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "4b78e55b179003a42523a362cc0e8327f7a69b5e" + "reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4b78e55b179003a42523a362cc0e8327f7a69b5e", - "reference": "4b78e55b179003a42523a362cc0e8327f7a69b5e", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/119bcf13e67dbd188e5dbc74228b1686f66acd37", + "reference": "119bcf13e67dbd188e5dbc74228b1686f66acd37", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -4188,7 +4419,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v5.3.7" + "source": "https://github.com/symfony/options-resolver/tree/v7.3.2" }, "funding": [ { @@ -4199,50 +4430,51 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2025-07-15T11:36:08+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.23.1", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", - "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -4269,7 +4501,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" }, "funding": [ { @@ -4280,50 +4512,51 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2025-06-27T09:58:17+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.23.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -4353,7 +4586,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.33.0" }, "funding": [ { @@ -4365,79 +4598,7 @@ "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-02-19T12:13:01+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.23.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/nicolas-grekas", "type": "github" }, { @@ -4445,42 +4606,39 @@ "type": "tidelift" } ], - "time": "2021-05-27T09:17:38+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.23.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "e66119f3de95efc359483f810c4c3e6436279436" + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436", - "reference": "e66119f3de95efc359483f810c4c3e6436279436", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -4508,7 +4666,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.33.0" }, "funding": [ { @@ -4519,30 +4677,33 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-05-21T13:25:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/process", - "version": "v5.3.12", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e498803a6e95ede78e9d5646ad32a2255c033a6a" + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e498803a6e95ede78e9d5646ad32a2255c033a6a", - "reference": "e498803a6e95ede78e9d5646ad32a2255c033a6a", + "url": "https://api.github.com/repos/symfony/process/zipball/40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", + "reference": "40c295f2deb408d5e9d2d32b8ba1dd61e36f05af", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -4570,7 +4731,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.3.12" + "source": "https://github.com/symfony/process/tree/v7.3.0" }, "funding": [ { @@ -4586,25 +4747,25 @@ "type": "tidelift" } ], - "time": "2021-11-22T22:39:13+00:00" + "time": "2025-04-17T09:11:12+00:00" }, { "name": "symfony/stopwatch", - "version": "v5.3.4", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "b24c6a92c6db316fee69e38c80591e080e41536c" + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b24c6a92c6db316fee69e38c80591e080e41536c", - "reference": "b24c6a92c6db316fee69e38c80591e080e41536c", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/service-contracts": "^1.0|^2" + "php": ">=8.2", + "symfony/service-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -4632,7 +4793,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v5.3.4" + "source": "https://github.com/symfony/stopwatch/tree/v7.3.0" }, "funding": [ { @@ -4648,44 +4809,48 @@ "type": "tidelift" } ], - "time": "2021-07-10T08:58:57+00:00" + "time": "2025-02-24T10:49:57+00:00" }, { "name": "symfony/string", - "version": "v5.3.10", + "version": "v7.3.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c" + "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", - "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", + "url": "https://api.github.com/repos/symfony/string/zipball/42f505aff654e62ac7ac2ce21033818297ca89ca", + "reference": "42f505aff654e62ac7ac2ce21033818297ca89ca", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.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": "^6.4|^7.0" }, "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\String\\": "" - }, "files": [ "Resources/functions.php" ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, "exclude-from-classmap": [ "/Tests/" ] @@ -4715,7 +4880,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.10" + "source": "https://github.com/symfony/string/tree/v7.3.2" }, "funding": [ { @@ -4726,25 +4891,29 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-10-27T18:21:46+00:00" + "time": "2025-07-10T08:47:49+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -4773,7 +4942,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -4781,76 +4950,18 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.10.0", - "source": { - "type": "git", - "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<4.6.1 || 4.6.2" - }, - "require-dev": { - "phpunit/phpunit": "^8.5.13" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.10-dev" - } - }, - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "support": { - "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" - }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2024-03-03T12:36:25+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=7.4", + "php": "^8.4", "ext-dom": "*" }, - "platform-dev": [], - "plugin-api-version": "2.1.0" + "platform-dev": {}, + "plugin-api-version": "2.6.0" } diff --git a/src/BoardGameGeekApi/CacheTagGeneratorInterface.php b/src/BoardGameGeekApi/CacheTagGeneratorInterface.php index bb3e75c..afbfaba 100644 --- a/src/BoardGameGeekApi/CacheTagGeneratorInterface.php +++ b/src/BoardGameGeekApi/CacheTagGeneratorInterface.php @@ -6,8 +6,8 @@ interface CacheTagGeneratorInterface { - public const TYPE_PREFIX = 'api_type_'; - public const CACHE_TAG_PREFIX = 'the_broken_tile'; + public const string TYPE_PREFIX = 'api_type_'; + public const string CACHE_TAG_PREFIX = 'the_broken_tile'; /** @return string[] */ public function generateTags(RequestInterface $request): array; diff --git a/src/BoardGameGeekApi/Client.php b/src/BoardGameGeekApi/Client.php index ecc4fde..5f62f79 100644 --- a/src/BoardGameGeekApi/Client.php +++ b/src/BoardGameGeekApi/Client.php @@ -4,53 +4,48 @@ namespace TheBrokenTile\BoardGameGeekApi; -use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter; -use Symfony\Component\HttpClient\CurlHttpClient; +use Psr\Cache\InvalidArgumentException as CacheInvalidArgumentException; use Symfony\Contracts\Cache\ItemInterface; use Symfony\Contracts\Cache\TagAwareCacheInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use TheBrokenTile\BoardGameGeekApi\Exception\InvalidArgumentException; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilderManagerInterface; use TheBrokenTile\BoardGameGeekApi\Request\RetryRequestInterface; -final class Client implements ClientInterface +final readonly class Client implements ClientInterface { use SanitizeCacheKeyTrait; - private const METHOD = 'GET'; - - private ObjectBuilderManagerInterface $objectBuilder; - private HttpClientInterface $client; - private TagAwareCacheInterface $cache; - private UrlGeneratorInterface $urlGenerator; - private CacheTagGeneratorInterface $cacheTagGenerator; + private const string METHOD = 'GET'; public function __construct( - ObjectBuilderManagerInterface $objectBuilder, - HttpClientInterface $client = null, - TagAwareCacheInterface $cache = null, - UrlGeneratorInterface $urlGenerator = null, - CacheTagGeneratorInterface $cacheTagGenerator = null - ) { - $this->objectBuilder = $objectBuilder; - $this->client = $client ?? new CurlHttpClient(); - $this->cache = $cache ?? new FilesystemTagAwareAdapter(); - $this->urlGenerator = $urlGenerator ?? new UrlGenerator(); - $this->cacheTagGenerator = $cacheTagGenerator ?? new CacheTagGenerator(); - } + private ObjectBuilderManagerInterface $objectBuilder, + private HttpClientInterface $client, + private TagAwareCacheInterface $cache, + private UrlGeneratorInterface $urlGenerator, + private CacheTagGeneratorInterface $cacheTagGenerator, + ) {} public function request(RequestInterface $request): ResponseInterface { $url = $this->urlGenerator->generate($request); - $response = $this->cache->get($this->buildCacheKey($request), function (ItemInterface $item) use ($url, $request): string { - $item->tag($this->cacheTagGenerator->generateTags($request)); + try { + $response = $this->cache->get($this->buildCacheKey($request), function (ItemInterface $item) use ($url, $request): string { + $item->tag($this->cacheTagGenerator->generateTags($request)); - return $this->client->request(self::METHOD, $url)->getContent(); - }); - \assert(\is_string($response)); + return $this->client->request(self::METHOD, $url)->getContent(); + }); + } catch (CacheInvalidArgumentException $e) { + throw new InvalidArgumentException($e->getMessage(), $e->getCode(), $e); + } + + if (!is_string($response)) { + throw new InvalidArgumentException(); + } $thing = $this->objectBuilder->build($request, $response); - if (0 === $thing->getTotalItems() && $request instanceof RetryRequestInterface && $retryRequest = $request->getRetryRequest()) { + if (0 === $thing->totalItems && $request instanceof RetryRequestInterface && $retryRequest = $request->getRetryRequest()) { return $this->request($retryRequest); } diff --git a/src/BoardGameGeekApi/ClientInterface.php b/src/BoardGameGeekApi/ClientInterface.php index 9be4169..6f73307 100644 --- a/src/BoardGameGeekApi/ClientInterface.php +++ b/src/BoardGameGeekApi/ClientInterface.php @@ -4,7 +4,12 @@ namespace TheBrokenTile\BoardGameGeekApi; +use TheBrokenTile\BoardGameGeekApi\Exception\ExceptionInterface; + interface ClientInterface { + /** + * @throws ExceptionInterface + */ public function request(RequestInterface $request): ResponseInterface; } diff --git a/src/BoardGameGeekApi/DataTransferObject/AbstractUserItem.php b/src/BoardGameGeekApi/DataTransferObject/AbstractUserItem.php index 2352d64..b6c2341 100644 --- a/src/BoardGameGeekApi/DataTransferObject/AbstractUserItem.php +++ b/src/BoardGameGeekApi/DataTransferObject/AbstractUserItem.php @@ -4,18 +4,7 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -abstract class AbstractUserItem +abstract readonly class AbstractUserItem { - public int $id; - public int $rank; - public string $type; - public string $name; - - public function __construct(int $id, int $rank, string $name, string $type) - { - $this->id = $id; - $this->rank = $rank; - $this->name = $name; - $this->type = $type; - } + public function __construct(public int $id, public int $rank, public string $name, public string $type) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/Collection.php b/src/BoardGameGeekApi/DataTransferObject/Collection.php index 699a3f4..5656255 100644 --- a/src/BoardGameGeekApi/DataTransferObject/Collection.php +++ b/src/BoardGameGeekApi/DataTransferObject/Collection.php @@ -6,13 +6,10 @@ final class Collection implements DataTransferObjectInterface { - public int $totalItems; + public int $totalItems {get => count($this->items); } + public string $pubDate; + /** @var CollectionItem[] */ public array $items = []; - - public function getTotalItems(): int - { - return $this->totalItems; - } } diff --git a/src/BoardGameGeekApi/DataTransferObject/CollectionItem.php b/src/BoardGameGeekApi/DataTransferObject/CollectionItem.php index 1b1423d..af374eb 100644 --- a/src/BoardGameGeekApi/DataTransferObject/CollectionItem.php +++ b/src/BoardGameGeekApi/DataTransferObject/CollectionItem.php @@ -9,10 +9,6 @@ final class CollectionItem use ImageTrait; use NameTrait; - public int $objectId; - public string $objectType; - public string $subType; - public int $collId; public ?int $yearPublished = null; public CollectionStatus $status; public ?int $numberOfPlays = null; @@ -20,11 +16,5 @@ final class CollectionItem public ?CollectionVersion $version = null; public ?GameStatistics $stats = null; - public function __construct(int $objectId, string $objectType, string $subType, int $collId) - { - $this->objectId = $objectId; - $this->objectType = $objectType; - $this->subType = $subType; - $this->collId = $collId; - } + public function __construct(public int $objectId, public string $objectType, public string $subType, public int $collId) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/CollectionStatus.php b/src/BoardGameGeekApi/DataTransferObject/CollectionStatus.php index 8be8fd2..36035be 100644 --- a/src/BoardGameGeekApi/DataTransferObject/CollectionStatus.php +++ b/src/BoardGameGeekApi/DataTransferObject/CollectionStatus.php @@ -4,40 +4,18 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class CollectionStatus +final readonly class CollectionStatus { - public bool $own; - public bool $previouslyOwned; - public bool $forTrade; - public bool $want; - public bool $wantToPlay; - public bool $wantToBuy; - public bool $wishlist; - public bool $preOrdered; - public string $lastModified; - public ?int $wishlistPriority = null; - public function __construct( - bool $own, - bool $previouslyOwned, - bool $forTrade, - bool $want, - bool $wantToPlay, - bool $wantToBuy, - bool $wishlist, - bool $preOrdered, - string $lastModified, - ?int $wishlistPriority - ) { - $this->own = $own; - $this->previouslyOwned = $previouslyOwned; - $this->forTrade = $forTrade; - $this->want = $want; - $this->wantToPlay = $wantToPlay; - $this->wantToBuy = $wantToBuy; - $this->wishlist = $wishlist; - $this->preOrdered = $preOrdered; - $this->lastModified = $lastModified; - $this->wishlistPriority = $wishlistPriority; - } + public bool $own, + public bool $previouslyOwned, + public bool $forTrade, + public bool $want, + public bool $wantToPlay, + public bool $wantToBuy, + public bool $wishlist, + public bool $preOrdered, + public string $lastModified, + public ?int $wishlistPriority = null, + ) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/CollectionVersion.php b/src/BoardGameGeekApi/DataTransferObject/CollectionVersion.php index 1b512bf..8c92f66 100644 --- a/src/BoardGameGeekApi/DataTransferObject/CollectionVersion.php +++ b/src/BoardGameGeekApi/DataTransferObject/CollectionVersion.php @@ -10,10 +10,8 @@ final class CollectionVersion use LinksTrait; use NameTrait; - public const TYPE_VERSION = 'boardgameversion'; + public const string TYPE_VERSION = 'boardgameversion'; - public string $type; - public int $id; public int $yearPublished; public string $productCode; public float $width; @@ -21,9 +19,5 @@ final class CollectionVersion public float $depth; public float $weight; - public function __construct(int $id, string $type) - { - $this->id = $id; - $this->type = $type; - } + public function __construct(public int $id, public string $type) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/DataTransferObject.php b/src/BoardGameGeekApi/DataTransferObject/DataTransferObject.php index dd02de0..66fdeaf 100644 --- a/src/BoardGameGeekApi/DataTransferObject/DataTransferObject.php +++ b/src/BoardGameGeekApi/DataTransferObject/DataTransferObject.php @@ -15,19 +15,20 @@ abstract class DataTransferObject implements DataTransferObjectInterface public ?int $yearPublished; public ?int $minPlayers; public ?int $maxPlayers; + /** @var GamePoll[] */ public array $polls; + /** in minutes */ public ?int $playingTime; + /** in minutes */ public ?int $minPlayTime; + /** in minutes */ public ?int $maxPlayTime; public ?int $minAge; public ?GameStatistics $stats; - public function getTotalItems(): int - { - return 1; - } + public int $totalItems {get => 1; } } diff --git a/src/BoardGameGeekApi/DataTransferObject/DataTransferObjectInterface.php b/src/BoardGameGeekApi/DataTransferObject/DataTransferObjectInterface.php index efc932c..712d0d7 100644 --- a/src/BoardGameGeekApi/DataTransferObject/DataTransferObjectInterface.php +++ b/src/BoardGameGeekApi/DataTransferObject/DataTransferObjectInterface.php @@ -6,5 +6,5 @@ interface DataTransferObjectInterface { - public function getTotalItems(): int; + public int $totalItems { get; } } diff --git a/src/BoardGameGeekApi/DataTransferObject/Expansion.php b/src/BoardGameGeekApi/DataTransferObject/Expansion.php index f360eb1..a401d34 100644 --- a/src/BoardGameGeekApi/DataTransferObject/Expansion.php +++ b/src/BoardGameGeekApi/DataTransferObject/Expansion.php @@ -4,6 +4,4 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class Expansion extends DataTransferObject -{ -} +final class Expansion extends DataTransferObject {} diff --git a/src/BoardGameGeekApi/DataTransferObject/Game.php b/src/BoardGameGeekApi/DataTransferObject/Game.php index a5d824d..66c8cce 100644 --- a/src/BoardGameGeekApi/DataTransferObject/Game.php +++ b/src/BoardGameGeekApi/DataTransferObject/Game.php @@ -4,6 +4,4 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class Game extends DataTransferObject -{ -} +final class Game extends DataTransferObject {} diff --git a/src/BoardGameGeekApi/DataTransferObject/GameLink.php b/src/BoardGameGeekApi/DataTransferObject/GameLink.php index 7b213ff..c7148d0 100644 --- a/src/BoardGameGeekApi/DataTransferObject/GameLink.php +++ b/src/BoardGameGeekApi/DataTransferObject/GameLink.php @@ -4,24 +4,14 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class GameLink +final readonly class GameLink { - public const TYPE_VERSION = 'boardgameversion'; - public const TYPE_PUBLISHER = 'boardgamepublisher'; - public const TYPE_ARTIST = 'boardgameartist'; - public const TYPE_LANGUAGE = 'language'; - public const TYPE_CATEGORY = 'boardgamecategory'; - public const TYPE_DESIGNER = 'boardgamedesigner'; + public const string TYPE_VERSION = 'boardgameversion'; + public const string TYPE_PUBLISHER = 'boardgamepublisher'; + public const string TYPE_ARTIST = 'boardgameartist'; + public const string TYPE_LANGUAGE = 'language'; + public const string TYPE_CATEGORY = 'boardgamecategory'; + public const string TYPE_DESIGNER = 'boardgamedesigner'; - public int $id; - public string $type; - /** @var string "boardgamepublisher", "boardgamepublisher", "boardgameartist", "language", etc... */ - public string $value; - - public function __construct(int $id, string $type, string $value) - { - $this->id = $id; - $this->type = $type; - $this->value = $value; - } + public function __construct(public int $id, public string $type, public string $value) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/GameName.php b/src/BoardGameGeekApi/DataTransferObject/GameName.php index dec831c..fa33089 100644 --- a/src/BoardGameGeekApi/DataTransferObject/GameName.php +++ b/src/BoardGameGeekApi/DataTransferObject/GameName.php @@ -6,17 +6,8 @@ final class GameName { - public const TYPE_PRIMARY = 'primary'; - public const TYPE_ALTERNATE = 'alternate'; + public const string TYPE_PRIMARY = 'primary'; + public const string TYPE_ALTERNATE = 'alternate'; - public int $sortIndex; - public ?string $type = null; - public string $value; - - public function __construct(int $sortIndex, ?string $type, string $value) - { - $this->sortIndex = $sortIndex; - $this->type = $type; - $this->value = $value; - } + public function __construct(public int $sortIndex, public ?string $type, public string $value) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/GamePoll.php b/src/BoardGameGeekApi/DataTransferObject/GamePoll.php index 9a31f2b..ec07f47 100644 --- a/src/BoardGameGeekApi/DataTransferObject/GamePoll.php +++ b/src/BoardGameGeekApi/DataTransferObject/GamePoll.php @@ -4,20 +4,15 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class GamePoll +final readonly class GamePoll { - public string $name; - public string $title; - public int $totalVotes; /** - * @var PollResult[] + * @param PollResult[] $results */ - public array $results = []; - - public function __construct(string $name, string $title, int $totalVotes) - { - $this->name = $name; - $this->title = $title; - $this->totalVotes = $totalVotes; - } + public function __construct( + public string $name, + public string $title, + public int $totalVotes, + public array $results, + ) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/GameRank.php b/src/BoardGameGeekApi/DataTransferObject/GameRank.php index 7a9f239..2e60ac0 100644 --- a/src/BoardGameGeekApi/DataTransferObject/GameRank.php +++ b/src/BoardGameGeekApi/DataTransferObject/GameRank.php @@ -4,25 +4,17 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class GameRank +final readonly class GameRank { - public const TYPE_SUBTYPE = 'subtype'; - public const TYPE_FAMILY = 'family'; + public const string TYPE_SUBTYPE = 'subtype'; + public const string TYPE_FAMILY = 'family'; - public int $id; - public string $name; - public string $type; - public string $friendlyName; - public int $value; - public float $bayesAverage; - - public function __construct(int $id, string $name, string $type, string $friendlyName, int $value, float $bayesAverage) - { - $this->id = $id; - $this->name = $name; - $this->type = $type; - $this->friendlyName = $friendlyName; - $this->value = $value; - $this->bayesAverage = $bayesAverage; - } + public function __construct( + public int $id, + public string $name, + public string $type, + public string $friendlyName, + public int $value, + public float $bayesAverage, + ) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/GameResults.php b/src/BoardGameGeekApi/DataTransferObject/GameResults.php index 7eab8d3..2534b7b 100644 --- a/src/BoardGameGeekApi/DataTransferObject/GameResults.php +++ b/src/BoardGameGeekApi/DataTransferObject/GameResults.php @@ -6,12 +6,8 @@ final class GameResults implements DataTransferObjectInterface { - public int $total = 0; - /** @var DataTransferObject[] */ - public array $items = []; + public int $totalItems {get => count($this->items); } - public function getTotalItems(): int - { - return $this->total; - } + /** @param DataTransferObject[] $items */ + public function __construct(public array $items = []) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/GameStatistics.php b/src/BoardGameGeekApi/DataTransferObject/GameStatistics.php index 020edca..6fd3b9a 100644 --- a/src/BoardGameGeekApi/DataTransferObject/GameStatistics.php +++ b/src/BoardGameGeekApi/DataTransferObject/GameStatistics.php @@ -4,12 +4,7 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class GameStatistics +final readonly class GameStatistics { - public GameRatings $ratings; - - public function __construct() - { - $this->ratings = new GameRatings(); - } + public function __construct(public GameRatings $ratings) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/PollResult.php b/src/BoardGameGeekApi/DataTransferObject/PollResult.php index 7f4de5d..0858cac 100644 --- a/src/BoardGameGeekApi/DataTransferObject/PollResult.php +++ b/src/BoardGameGeekApi/DataTransferObject/PollResult.php @@ -4,14 +4,7 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class PollResult +final readonly class PollResult { - public string $value; - public int $numVotes; - - public function __construct(string $value, int $numVotes) - { - $this->value = $value; - $this->numVotes = $numVotes; - } + public function __construct(public string $value, public int $numVotes) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/SearchItem.php b/src/BoardGameGeekApi/DataTransferObject/SearchItem.php index 2976a7d..bef4c81 100644 --- a/src/BoardGameGeekApi/DataTransferObject/SearchItem.php +++ b/src/BoardGameGeekApi/DataTransferObject/SearchItem.php @@ -6,20 +6,14 @@ use TheBrokenTile\BoardGameGeekApi\RequestInterface; -final class SearchItem +final readonly class SearchItem { - public const TYPE_BOARD_GAME = RequestInterface::PARAM_BOARD_GAME; + public const string TYPE_BOARD_GAME = RequestInterface::PARAM_BOARD_GAME; - public int $id; - public string $type; - public GameName $name; - public ?int $yearPublished; - - public function __construct(int $id, string $type, GameName $name, ?int $yearPublished) - { - $this->id = $id; - $this->type = $type; - $this->name = $name; - $this->yearPublished = $yearPublished; - } + public function __construct( + public int $id, + public string $type, + public GameName $name, + public ?int $yearPublished, + ) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/SearchResults.php b/src/BoardGameGeekApi/DataTransferObject/SearchResults.php index 123d711..e43f7c3 100644 --- a/src/BoardGameGeekApi/DataTransferObject/SearchResults.php +++ b/src/BoardGameGeekApi/DataTransferObject/SearchResults.php @@ -6,12 +6,8 @@ final class SearchResults implements DataTransferObjectInterface { - public int $total; - /** @var SearchItem[] */ - public array $items = []; + public int $totalItems {get => count($this->items); } - public function getTotalItems(): int - { - return $this->total; - } + /** @param SearchItem[] $items */ + public function __construct(public array $items = []) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/User.php b/src/BoardGameGeekApi/DataTransferObject/User.php index 7815c7d..165d072 100644 --- a/src/BoardGameGeekApi/DataTransferObject/User.php +++ b/src/BoardGameGeekApi/DataTransferObject/User.php @@ -23,17 +23,18 @@ final class User implements DataTransferObjectInterface public string $steamAccount; public int $tradeRating; public int $marketRating; + /** @var UserBuddy[] */ public array $buddies = []; + /** @var UserGuild[] */ public array $guilds = []; + /** @var UserHotItem[] */ public array $hot = []; + /** @var UserTopItem[] */ public array $top = []; - public function getTotalItems(): int - { - return 1; - } + public int $totalItems {get => 1; } } diff --git a/src/BoardGameGeekApi/DataTransferObject/UserBuddy.php b/src/BoardGameGeekApi/DataTransferObject/UserBuddy.php index 0d689b2..b678609 100644 --- a/src/BoardGameGeekApi/DataTransferObject/UserBuddy.php +++ b/src/BoardGameGeekApi/DataTransferObject/UserBuddy.php @@ -4,14 +4,7 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class UserBuddy +final readonly class UserBuddy { - public int $id; - public string $name; - - public function __construct(int $id, string $name) - { - $this->id = $id; - $this->name = $name; - } + public function __construct(public int $id, public string $name) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/UserGuild.php b/src/BoardGameGeekApi/DataTransferObject/UserGuild.php index 3731849..655ac45 100644 --- a/src/BoardGameGeekApi/DataTransferObject/UserGuild.php +++ b/src/BoardGameGeekApi/DataTransferObject/UserGuild.php @@ -4,14 +4,7 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class UserGuild +final readonly class UserGuild { - public int $id; - public string $name; - - public function __construct(int $id, string $name) - { - $this->id = $id; - $this->name = $name; - } + public function __construct(public int $id, public string $name) {} } diff --git a/src/BoardGameGeekApi/DataTransferObject/UserHotItem.php b/src/BoardGameGeekApi/DataTransferObject/UserHotItem.php index b105117..aa1b2ae 100644 --- a/src/BoardGameGeekApi/DataTransferObject/UserHotItem.php +++ b/src/BoardGameGeekApi/DataTransferObject/UserHotItem.php @@ -4,6 +4,4 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class UserHotItem extends AbstractUserItem -{ -} +final readonly class UserHotItem extends AbstractUserItem {} diff --git a/src/BoardGameGeekApi/DataTransferObject/UserTopItem.php b/src/BoardGameGeekApi/DataTransferObject/UserTopItem.php index ae483aa..a76b52e 100644 --- a/src/BoardGameGeekApi/DataTransferObject/UserTopItem.php +++ b/src/BoardGameGeekApi/DataTransferObject/UserTopItem.php @@ -4,6 +4,4 @@ namespace TheBrokenTile\BoardGameGeekApi\DataTransferObject; -final class UserTopItem extends AbstractUserItem -{ -} +final readonly class UserTopItem extends AbstractUserItem {} diff --git a/src/BoardGameGeekApi/Exception/ExceptionInterface.php b/src/BoardGameGeekApi/Exception/ExceptionInterface.php new file mode 100644 index 0000000..325b31e --- /dev/null +++ b/src/BoardGameGeekApi/Exception/ExceptionInterface.php @@ -0,0 +1,7 @@ +client = $client; } + /** + * @throws ExceptionInterface + */ public function game(int $id): Game { - $game = $this->client->request(new GameRequest($id))->getData(); + $game = $this->client->request(new GameRequest($id))->data; \assert($game instanceof Game); return $game; } + /** + * @throws ExceptionInterface + */ public function search(string $query, bool $exact = false): SearchResults { - $searchResult = $this->client->request(new SearchRequest($query, $exact))->getData(); + $searchResult = $this->client->request(new SearchRequest($query, $exact))->data; \assert($searchResult instanceof SearchResults); return $searchResult; } + /** + * @throws ExceptionInterface + */ public function user(string $username): User { - $user = $this->client->request(new UserRequest($username))->getData(); + $user = $this->client->request(new UserRequest($username))->data; \assert($user instanceof User); return $user; } + /** + * @throws ExceptionInterface + */ public function collection(string $username): Collection { - $collection = $this->client->request(new CollectionRequest($username))->getData(); + $collection = $this->client->request(new CollectionRequest($username))->data; \assert($collection instanceof Collection); return $collection; diff --git a/src/BoardGameGeekApi/ObjectBuilder/AbstractObjectBuilder.php b/src/BoardGameGeekApi/ObjectBuilder/AbstractObjectBuilder.php index 8ab795e..d661240 100644 --- a/src/BoardGameGeekApi/ObjectBuilder/AbstractObjectBuilder.php +++ b/src/BoardGameGeekApi/ObjectBuilder/AbstractObjectBuilder.php @@ -4,7 +4,6 @@ namespace TheBrokenTile\BoardGameGeekApi\ObjectBuilder; -use DOMElement; use Symfony\Component\DomCrawler\Crawler; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameLink; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameName; @@ -39,7 +38,7 @@ protected function getNames(Crawler $crawler): array { $names = []; - /** @var DOMElement $name */ + /** @var \DOMElement $name */ foreach ($crawler->filter(self::NAME) as $name) { $names[] = new GameName( (int) $name->getAttribute(self::SORT_INDEX), @@ -60,21 +59,25 @@ protected function getDescription(Crawler $crawler): string protected function getPolls(Crawler $crawler): array { $polls = []; - /** @var DOMElement $pollElement */ + + /** @var \DOMElement $pollElement */ foreach ($crawler->filter(self::POLL) as $pollElement) { - $poll = new GamePoll( - $pollElement->getAttribute(self::NAME), - $pollElement->getAttribute(self::TITLE), - (int) $pollElement->getAttribute(self::TOTAL_VOTES), - ); + $results = []; $pollCrawler = new Crawler($pollElement); foreach ($pollCrawler->filter(self::RESULT) as $resultElement) { - \assert($resultElement instanceof DOMElement); - $poll->results[] = new PollResult( - $resultElement->getAttribute(self::VALUE), - (int) $resultElement->getAttribute(self::NUMBER_OF_VOTES), + assert($resultElement instanceof \DOMElement); + $results[] = new PollResult( + value: $resultElement->getAttribute(self::VALUE), + numVotes: (int) $resultElement->getAttribute(self::NUMBER_OF_VOTES), ); } + + $poll = new GamePoll( + name: $pollElement->getAttribute(self::NAME), + title: $pollElement->getAttribute(self::TITLE), + totalVotes: (int) $pollElement->getAttribute(self::TOTAL_VOTES), + results: $results, + ); $polls[] = $poll; } @@ -85,7 +88,8 @@ protected function getPolls(Crawler $crawler): array protected function getLinks(Crawler $crawler): array { $links = []; - /** @var DOMElement $linkElement */ + + /** @var \DOMElement $linkElement */ foreach ($crawler->filter(self::LINK) as $linkElement) { $links[] = new GameLink( (int) $linkElement->getAttribute(self::ID), @@ -103,19 +107,19 @@ protected function getStats(Crawler $crawler): ?GameStatistics if (0 === $statsCrawler->count()) { return null; } - $stats = new GameStatistics(); + $stats = new GameStatistics(new GameRatings()); $ratingsCrawler = $statsCrawler->filter($this->ratingsKey); - //These two should always be set. + // These two should always be set. $stats->ratings->average = (float) $ratingsCrawler->filter(self::AVERAGE)->attr(self::VALUE); $stats->ratings->bayesAverage = (float) $ratingsCrawler->filter(self::BAYESIAN_AVERAGE)->attr(self::VALUE); - //These three are set for collection and game with stats=1. + // These three are set for collection and game with stats=1. $stats->ratings->usersRated = $this->getIntAttribute($ratingsCrawler, self::USERS_RATED); $stats->ratings->stdDev = $this->getFloatAttribute($ratingsCrawler, self::STANDARD_DEVIATION); $stats->ratings->median = $this->getFloatAttribute($ratingsCrawler, self::MEDIAN); - //There rest are only set for game with stats=1. + // There rest are only set for game with stats=1. $stats->ratings->owned = $this->getIntAttribute($ratingsCrawler, self::OWNED); $stats->ratings->trading = $this->getIntAttribute($ratingsCrawler, self::TRADING); $stats->ratings->wanting = $this->getIntAttribute($ratingsCrawler, self::WANTING); @@ -155,15 +159,15 @@ private function addRanks(GameRatings $ratings, Crawler $ratingsCrawler): void return; } - /** @var DOMElement $rank */ + /** @var \DOMElement $rank */ foreach ($ranks->filter(self::RANK) as $rank) { $ratings->ranks[] = new GameRank( - (int) $rank->getAttribute(self::ID), - $rank->getAttribute(self::RANK_NAME), - $rank->getAttribute(self::RANK_TYPE), - $rank->getAttribute(self::RANK_FRIENDLY_NAME), - (int) $rank->getAttribute(self::VALUE), - (float) $rank->getAttribute(self::RANK_BAYESIAN_AVERAGE), + id: (int) $rank->getAttribute(self::ID), + name: $rank->getAttribute(self::RANK_NAME), + type: $rank->getAttribute(self::RANK_TYPE), + friendlyName: $rank->getAttribute(self::RANK_FRIENDLY_NAME), + value: (int) $rank->getAttribute(self::VALUE), + bayesAverage: (float) $rank->getAttribute(self::RANK_BAYESIAN_AVERAGE), ); } } diff --git a/src/BoardGameGeekApi/ObjectBuilder/CollectionBuilder.php b/src/BoardGameGeekApi/ObjectBuilder/CollectionBuilder.php index f4f4c92..6924749 100644 --- a/src/BoardGameGeekApi/ObjectBuilder/CollectionBuilder.php +++ b/src/BoardGameGeekApi/ObjectBuilder/CollectionBuilder.php @@ -4,7 +4,6 @@ namespace TheBrokenTile\BoardGameGeekApi\ObjectBuilder; -use DOMElement; use Symfony\Component\DomCrawler\Crawler; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\Collection; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\CollectionItem; @@ -33,10 +32,9 @@ public function build(string $response, RequestInterface $request): DataTransfer { $collection = new Collection(); $crawler = new Crawler($response); - $collection->totalItems = (int) $crawler->filter(self::ITEMS)->attr(self::TOTAL_ITEMS); $pubDate = $crawler->filter(self::ITEMS)->attr(self::PUBLISH_DATE); - \assert(\is_string($pubDate)); + assert(is_string($pubDate)); $collection->pubDate = $pubDate; $this->addItems($crawler, $collection); @@ -46,13 +44,13 @@ public function build(string $response, RequestInterface $request): DataTransfer private function addItems(Crawler $crawler, Collection $collection): void { - /** @var DOMElement $itemElement */ + /** @var \DOMElement $itemElement */ foreach ($crawler->filter(sprintf('%s > %s', self::ITEMS, self::ITEM)) as $itemElement) { $item = new CollectionItem( - (int) $itemElement->getAttribute(self::OBJECT_ID), - $itemElement->getAttribute(self::OBJECT_TYPE), - $itemElement->getAttribute(self::SUB_TYPE), - (int) $itemElement->getAttribute(self::COLLECTION_ID), + objectId: (int) $itemElement->getAttribute(self::OBJECT_ID), + objectType: $itemElement->getAttribute(self::OBJECT_TYPE), + subType: $itemElement->getAttribute(self::SUB_TYPE), + collId: (int) $itemElement->getAttribute(self::COLLECTION_ID), ); $itemCrawler = new Crawler($itemElement); @@ -80,10 +78,7 @@ private function addYearPublished(Crawler $itemCrawler, CollectionItem $item): v $item->yearPublished = (int) $yearPublishedElement->text(); } - /** - * @param CollectionItem|CollectionVersion $item - */ - private function addImage(Crawler $crawler, $item): void + private function addImage(Crawler $crawler, CollectionItem|CollectionVersion $item): void { $image = $crawler->filter(self::IMAGE); if (0 === $image->count()) { @@ -92,10 +87,7 @@ private function addImage(Crawler $crawler, $item): void $item->image = $image->text(); } - /** - * @param CollectionItem|CollectionVersion $item - */ - private function addThumbnail(Crawler $crawler, $item): void + private function addThumbnail(Crawler $crawler, CollectionItem|CollectionVersion $item): void { $thumbnail = $crawler->filter(self::THUMBNAIL); if (0 === $thumbnail->count()) { @@ -104,12 +96,9 @@ private function addThumbnail(Crawler $crawler, $item): void $item->thumbnail = $thumbnail->text(); } - /** - * @param CollectionItem|CollectionVersion $item - */ - private function addName(Crawler $crawler, $item): void + private function addName(Crawler $crawler, CollectionItem|CollectionVersion $item): void { - /** @var DOMElement $name */ + /** @var \DOMElement $name */ foreach ($crawler->children(self::NAME) as $name) { $item->names[] = new GameName( (int) $name->getAttribute(self::SORT_INDEX), @@ -124,19 +113,19 @@ private function addStatus(Crawler $itemCrawler, CollectionItem $item): void $status = $itemCrawler->filter(self::COLLECTION_STATUS); $lastModified = $status->attr(self::LAST_MODIFIED); - \assert(\is_string($lastModified)); + assert(is_string($lastModified)); $wishlistPriority = $status->attr(self::COLLECTION_WISHLIST_PRIORITY); $item->status = new CollectionStatus( - (bool) $status->attr(self::COLLECTION_OWN), - (bool) $status->attr(self::COLLECTION_PREVIOUSLY_OWN), - (bool) $status->attr(self::COLLECTION_FOR_TRADE), - (bool) $status->attr(self::COLLECTION_WANT), - (bool) $status->attr(self::COLLECTION_WANT_TO_PLAY), - (bool) $status->attr(self::COLLECTION_WANT_TO_BUY), - (bool) $status->attr(self::COLLECTION_WISHLIST), - (bool) $status->attr(self::COLLECTION_PRE_ORDERED), - $lastModified, - null === $wishlistPriority ? null : (int) $wishlistPriority, + own: (bool) $status->attr(self::COLLECTION_OWN), + previouslyOwned: (bool) $status->attr(self::COLLECTION_PREVIOUSLY_OWN), + forTrade: (bool) $status->attr(self::COLLECTION_FOR_TRADE), + want: (bool) $status->attr(self::COLLECTION_WANT), + wantToPlay: (bool) $status->attr(self::COLLECTION_WANT_TO_PLAY), + wantToBuy: (bool) $status->attr(self::COLLECTION_WANT_TO_BUY), + wishlist: (bool) $status->attr(self::COLLECTION_WISHLIST), + preOrdered: (bool) $status->attr(self::COLLECTION_PRE_ORDERED), + lastModified: $lastModified, + wishlistPriority: null === $wishlistPriority ? null : (int) $wishlistPriority, ); } @@ -166,11 +155,11 @@ private function addVersion(Crawler $itemCrawler, CollectionItem $item): void return; } - /** @var DOMElement $versionItem */ + /** @var \DOMElement $versionItem */ foreach ($version->filter(self::ITEM) as $versionItem) { $item->version = new CollectionVersion( - (int) $versionItem->getAttribute(self::ID), - $versionItem->getAttribute(self::TYPE), + id: (int) $versionItem->getAttribute(self::ID), + type: $versionItem->getAttribute(self::TYPE), ); $versionCrawler = new Crawler($versionItem); $this->addImage($versionCrawler, $item->version); @@ -182,12 +171,12 @@ private function addVersion(Crawler $itemCrawler, CollectionItem $item): void private function addLinks(Crawler $crawler, CollectionVersion $item): void { - /** @var DOMElement $link */ + /** @var \DOMElement $link */ foreach ($crawler->children(self::LINK) as $link) { $item->links[] = new GameLink( - (int) $link->getAttribute(self::ID), - $link->getAttribute(self::TYPE), - $link->getAttribute(self::VALUE), + id: (int) $link->getAttribute(self::ID), + type: $link->getAttribute(self::TYPE), + value: $link->getAttribute(self::VALUE), ); } } diff --git a/src/BoardGameGeekApi/ObjectBuilder/GameBuilder.php b/src/BoardGameGeekApi/ObjectBuilder/GameBuilder.php index e3cfdf9..14d058d 100644 --- a/src/BoardGameGeekApi/ObjectBuilder/GameBuilder.php +++ b/src/BoardGameGeekApi/ObjectBuilder/GameBuilder.php @@ -4,10 +4,7 @@ namespace TheBrokenTile\BoardGameGeekApi\ObjectBuilder; -use DOMElement; use Symfony\Component\DomCrawler\Crawler; -use TheBrokenTile\BoardGameGeekApi\DataTransferObject\DataTransferObject; -use TheBrokenTile\BoardGameGeekApi\DataTransferObject\DataTransferObjectInterface; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\Expansion; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\Game; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameResults; @@ -21,25 +18,22 @@ public function supports(RequestInterface $request): bool return $request instanceof GameRequest; } - /** - * @return GameResults - */ - public function build(string $response, RequestInterface $request): DataTransferObjectInterface + public function build(string $response, RequestInterface $request): GameResults { - $results = new GameResults(); $crawler = new Crawler($response); - /** @var DOMElement $item */ + $items = []; + + /** @var \DOMElement $item */ foreach ($crawler->filter(self::ITEM) as $item) { $itemCrawler = new Crawler($item); - $results->items[] = $this->buildItem($itemCrawler); - ++$results->total; + $items[] = $this->buildItem($itemCrawler); } - return $results; + return new GameResults($items); } - private function buildItem(Crawler $crawler): DataTransferObject + private function buildItem(Crawler $crawler): Expansion|Game { $object = $this->createObject($crawler); @@ -62,7 +56,7 @@ private function buildItem(Crawler $crawler): DataTransferObject return $object; } - private function createObject(Crawler $crawler): DataTransferObject + private function createObject(Crawler $crawler): Expansion|Game { if ('boardgame' === $crawler->attr(self::TYPE)) { return new Game(); diff --git a/src/BoardGameGeekApi/ObjectBuilder/InvalidResponseException.php b/src/BoardGameGeekApi/ObjectBuilder/InvalidResponseException.php deleted file mode 100644 index 3751e08..0000000 --- a/src/BoardGameGeekApi/ObjectBuilder/InvalidResponseException.php +++ /dev/null @@ -1,11 +0,0 @@ -searchBuilder = $searchBuilder; - } + public function __construct(private ObjectBuilderInterface $searchBuilder) {} public function supports(RequestInterface $request): bool { @@ -27,7 +22,7 @@ public function supports(RequestInterface $request): bool public function build(string $response, RequestInterface $request): DataTransferObjectInterface { $result = $this->searchBuilder->build($response, $request); - \assert($result instanceof SearchResults); + assert($result instanceof SearchResults); $result->items = array_values( array_filter( @@ -35,7 +30,6 @@ public function build(string $response, RequestInterface $request): DataTransfer static fn (SearchItem $item) => $item->name->value === $request->getParams()[RequestInterface::PARAM_QUERY], ), ); - $result->total = \count($result->items); return $result; } diff --git a/src/BoardGameGeekApi/ObjectBuilder/SearchResultBuilder.php b/src/BoardGameGeekApi/ObjectBuilder/SearchResultBuilder.php index 1918f6b..1755a6a 100644 --- a/src/BoardGameGeekApi/ObjectBuilder/SearchResultBuilder.php +++ b/src/BoardGameGeekApi/ObjectBuilder/SearchResultBuilder.php @@ -4,7 +4,6 @@ namespace TheBrokenTile\BoardGameGeekApi\ObjectBuilder; -use DOMElement; use Symfony\Component\DomCrawler\Crawler; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameName; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\SearchItem; @@ -21,36 +20,31 @@ public function supports(RequestInterface $request): bool public function build(string $response, RequestInterface $request): SearchResults { - $crawler = new Crawler($response); - $items = $crawler->filter(self::ITEMS)->eq(0); - $results = new SearchResults(); - $results->total = (int) $items->attr(self::TOTAL); - $results->items = $this->getItems($crawler); - - return $results; + return new SearchResults($this->getItems(new Crawler($response))); } /** @return SearchItem[] */ private function getItems(Crawler $crawler): array { $items = []; - /** @var DOMElement $itemElement */ + + /** @var \DOMElement $itemElement */ foreach ($crawler->filter(self::ITEM) as $itemElement) { $itemCrawler = new Crawler($itemElement); $name = $itemCrawler->filter(self::NAME)->eq(0); $yearPublished = $itemCrawler->filter(self::YEAR_PUBLISHED); $value = $name->attr(self::VALUE); - \assert(\is_string($value)); + assert(is_string($value)); $items[] = new SearchItem( - $this->getId($itemCrawler), - $itemElement->getAttribute(self::TYPE), - new GameName( + id: $this->getId($itemCrawler), + type: $itemElement->getAttribute(self::TYPE), + name: new GameName( 1, $name->attr(self::TYPE), $value, ), - $yearPublished->count() ? (int) $yearPublished->attr(self::VALUE) : null, + yearPublished: $yearPublished->count() ? (int) $yearPublished->attr(self::VALUE) : null, ); } diff --git a/src/BoardGameGeekApi/ObjectBuilder/UserBuilder.php b/src/BoardGameGeekApi/ObjectBuilder/UserBuilder.php index 3e2467f..3f66f01 100644 --- a/src/BoardGameGeekApi/ObjectBuilder/UserBuilder.php +++ b/src/BoardGameGeekApi/ObjectBuilder/UserBuilder.php @@ -4,14 +4,13 @@ namespace TheBrokenTile\BoardGameGeekApi\ObjectBuilder; -use DOMElement; use Symfony\Component\DomCrawler\Crawler; -use TheBrokenTile\BoardGameGeekApi\DataTransferObject\DataTransferObjectInterface; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\User; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\UserBuddy; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\UserGuild; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\UserHotItem; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\UserTopItem; +use TheBrokenTile\BoardGameGeekApi\Exception\InvalidResponseException; use TheBrokenTile\BoardGameGeekApi\Request\UserRequest; use TheBrokenTile\BoardGameGeekApi\RequestInterface; @@ -24,13 +23,11 @@ public function supports(RequestInterface $request): bool /** * @throws InvalidResponseException - * - * @return User */ - public function build(string $response, RequestInterface $request): DataTransferObjectInterface + public function build(string $response, RequestInterface $request): User { $user = new User(); - $crawler = (new Crawler($response))->filter(self::USER)->eq(0); + $crawler = new Crawler($response)->filter(self::USER)->eq(0); $id = $crawler->attr(self::ID); if (!is_numeric($id)) { @@ -38,7 +35,7 @@ public function build(string $response, RequestInterface $request): DataTransfer } $user->id = (int) $id; $name = $crawler->attr(self::NAME); - if (!\is_string($name)) { + if (!is_string($name)) { throw new InvalidResponseException('"name" should be a string'); } $user->name = $name; @@ -72,11 +69,12 @@ private function addBuddies(Crawler $crawler, User $user): void if (0 === $buddies->count()) { return; } - /** @var DOMElement $buddy */ + + /** @var \DOMElement $buddy */ foreach ($buddies->filter(self::USER_BUDDY) as $buddy) { $user->buddies[] = new UserBuddy( - (int) $buddy->getAttribute(self::ID), - $buddy->getAttribute(self::NAME), + id: (int) $buddy->getAttribute(self::ID), + name: $buddy->getAttribute(self::NAME), ); } } @@ -88,11 +86,11 @@ private function addGuilds(Crawler $crawler, User $user): void return; } - /** @var DOMElement $guild */ + /** @var \DOMElement $guild */ foreach ($guilds->filter(self::USER_GUILD) as $guild) { $user->guilds[] = new UserGuild( - (int) $guild->getAttribute(self::ID), - $guild->getAttribute(self::NAME), + id: (int) $guild->getAttribute(self::ID), + name: $guild->getAttribute(self::NAME), ); } } @@ -103,13 +101,14 @@ private function addTop(Crawler $crawler, User $user): void if (0 === $top->count()) { return; } - /** @var DOMElement $item */ + + /** @var \DOMElement $item */ foreach ($top->filter(self::ITEM) as $item) { $user->top[] = new UserTopItem( - (int) $item->getAttribute(self::ID), - (int) $item->getAttribute(self::RANK), - $item->getAttribute(self::NAME), - $item->getAttribute(self::VALUE), + id: (int) $item->getAttribute(self::ID), + rank: (int) $item->getAttribute(self::RANK), + name: $item->getAttribute(self::NAME), + type: $item->getAttribute(self::VALUE), ); } } @@ -121,13 +120,13 @@ private function addHot(Crawler $crawler, User $user): void return; } - /** @var DOMElement $item */ + /** @var \DOMElement $item */ foreach ($hot->filter(self::ITEM) as $item) { $user->hot[] = new UserHotItem( - (int) $item->getAttribute(self::ID), - (int) $item->getAttribute(self::RANK), - $item->getAttribute(self::NAME), - $item->getAttribute(self::VALUE), + id: (int) $item->getAttribute(self::ID), + rank: (int) $item->getAttribute(self::RANK), + name: $item->getAttribute(self::NAME), + type: $item->getAttribute(self::VALUE), ); } } diff --git a/src/BoardGameGeekApi/Request/CollectionRequest.php b/src/BoardGameGeekApi/Request/CollectionRequest.php index 1b14de0..d55e744 100644 --- a/src/BoardGameGeekApi/Request/CollectionRequest.php +++ b/src/BoardGameGeekApi/Request/CollectionRequest.php @@ -8,17 +8,14 @@ final class CollectionRequest implements RequestInterface { - private string $username; private ?string $version = null; private ?string $brief = null; private ?string $stats = null; + /** @var array */ private array $filters = []; - public function __construct(string $username) - { - $this->username = $username; - } + public function __construct(private readonly string $username) {} public function getType(): string { @@ -60,17 +57,14 @@ public function stats(): self return $this; } - /** - * @param bool|int|string $value - */ - public function filter(string $name, $value): self + public function filter(string $name, bool|int|string $value): self { - if (\is_bool($value)) { + if (is_bool($value)) { $this->filters[$name] = $value ? '1' : '0'; return $this; } - if (\is_int($value)) { + if (is_int($value)) { $this->filters[$name] = (string) $value; return $this; diff --git a/src/BoardGameGeekApi/Request/RetrySearchRequest.php b/src/BoardGameGeekApi/Request/RetrySearchRequest.php index dc4f0d5..deaa61b 100644 --- a/src/BoardGameGeekApi/Request/RetrySearchRequest.php +++ b/src/BoardGameGeekApi/Request/RetrySearchRequest.php @@ -6,18 +6,10 @@ use TheBrokenTile\BoardGameGeekApi\RequestInterface; -final class RetrySearchRequest implements RequestInterface +final readonly class RetrySearchRequest implements RequestInterface { - private RequestInterface $request; - /** @var array */ - private array $overwrites; - /** @param array $overwrites */ - public function __construct(RequestInterface $request, array $overwrites) - { - $this->request = $request; - $this->overwrites = $overwrites; - } + public function __construct(private RequestInterface $request, private array $overwrites) {} public function getType(): string { diff --git a/src/BoardGameGeekApi/Request/SearchRequest.php b/src/BoardGameGeekApi/Request/SearchRequest.php index a099e8c..0b42d8a 100644 --- a/src/BoardGameGeekApi/Request/SearchRequest.php +++ b/src/BoardGameGeekApi/Request/SearchRequest.php @@ -6,14 +6,12 @@ use TheBrokenTile\BoardGameGeekApi\RequestInterface; -final class SearchRequest implements RequestInterface, RetryRequestInterface +final readonly class SearchRequest implements RequestInterface, RetryRequestInterface { - private string $query; private ?string $exact; - public function __construct(string $query, bool $exact = null) + public function __construct(private string $query, ?bool $exact = null) { - $this->query = $query; $this->exact = null === $exact ? null : ($exact ? '1' : '0'); } diff --git a/src/BoardGameGeekApi/Request/UserRequest.php b/src/BoardGameGeekApi/Request/UserRequest.php index a630b45..4f20c17 100644 --- a/src/BoardGameGeekApi/Request/UserRequest.php +++ b/src/BoardGameGeekApi/Request/UserRequest.php @@ -8,17 +8,13 @@ final class UserRequest implements RequestInterface { - private string $username; private ?string $buddies = null; private ?string $guilds = null; private string $page = '1'; private ?string $top = null; private ?string $hot = null; - public function __construct(string $username) - { - $this->username = $username; - } + public function __construct(private readonly string $username) {} public function getType(): string { diff --git a/src/BoardGameGeekApi/RequestInterface.php b/src/BoardGameGeekApi/RequestInterface.php index a163f62..bcbb081 100644 --- a/src/BoardGameGeekApi/RequestInterface.php +++ b/src/BoardGameGeekApi/RequestInterface.php @@ -6,13 +6,14 @@ interface RequestInterface { - public const TYPE_THING = 'thing'; - public const TYPE_SEARCH = 'search'; - public const TYPE_USER = 'user'; - public const TYPE_COLLECTION = 'collection'; - public const PARAM_VALUE_SEPARATOR = ','; + public const string TYPE_THING = 'thing'; + public const string TYPE_SEARCH = 'search'; + public const string TYPE_USER = 'user'; + public const string TYPE_COLLECTION = 'collection'; + public const string PARAM_VALUE_SEPARATOR = ','; + + public const string PARAM_PAGE = 'page'; - public const PARAM_PAGE = 'page'; /** * For things (games): * Specifies the id of the thing(s) to retrieve. To request multiple things with a single query, @@ -20,86 +21,87 @@ interface RequestInterface * For collection: * Filter collection to specifically listed item(s). NNN may be a comma-delimited list of item ids. */ - public const PARAM_ID = 'id'; - public const PARAM_STATS = 'stats'; - public const PARAM_QUERY = 'query'; - public const PARAM_EXACT = 'exact'; - public const PARAM_TYPE = 'type'; - - public const PARAM_USER_NAME = 'name'; - public const PARAM_USER_BUDDIES = 'buddies'; - public const PARAM_USER_GUILDS = 'guilds'; - public const PARAM_USER_TOP = 'top'; - public const PARAM_USER_HOT = 'hot'; - - public const PARAM_BOARD_GAME = 'boardgame'; - - public const PARAM_COLLECTION_USERNAME = 'username'; - public const PARAM_COLLECTION_VERSION = 'version'; - public const PARAM_COLLECTION_BRIEF = 'brief'; - public const PARAM_COLLECTION_FILTER_OWN = 'own'; - public const PARAM_COLLECTION_FILTER_RATED = 'rated'; - public const PARAM_COLLECTION_FILTER_PLAYED = 'played'; - public const PARAM_COLLECTION_FILTER_COMMENT = 'comment'; - public const PARAM_COLLECTION_FILTER_FOR_TRADE = 'trade'; - public const PARAM_COLLECTION_FILTER_WANT = 'want'; - public const PARAM_COLLECTION_FILTER_WISHLIST = 'whishlist'; - public const PARAM_COLLECTION_FILTER_WISHLIST_PRIORITY = 'wishlistpriority'; - public const PARAM_COLLECTION_FILTER_PRE_ORDERED = 'preordered'; - public const PARAM_COLLECTION_FILTER_WANT_TO_PLAY = 'wanttoplay'; - public const PARAM_COLLECTION_FILTER_WANT_TO_BUY = 'wanttobuy'; - public const PARAM_COLLECTION_FILTER_PREVIOUSLY_OWNED = 'prevowned'; - public const PARAM_COLLECTION_FILTER_HAS_PARTS = 'hasparts'; - public const PARAM_COLLECTION_FILTER_WANTS_PARTS = 'wantsparts'; + public const string PARAM_ID = 'id'; + public const string PARAM_STATS = 'stats'; + public const string PARAM_QUERY = 'query'; + public const string PARAM_EXACT = 'exact'; + public const string PARAM_TYPE = 'type'; + + public const string PARAM_USER_NAME = 'name'; + public const string PARAM_USER_BUDDIES = 'buddies'; + public const string PARAM_USER_GUILDS = 'guilds'; + public const string PARAM_USER_TOP = 'top'; + public const string PARAM_USER_HOT = 'hot'; + + public const string PARAM_BOARD_GAME = 'boardgame'; + + public const string PARAM_COLLECTION_USERNAME = 'username'; + public const string PARAM_COLLECTION_VERSION = 'version'; + public const string PARAM_COLLECTION_BRIEF = 'brief'; + public const string PARAM_COLLECTION_FILTER_OWN = 'own'; + public const string PARAM_COLLECTION_FILTER_RATED = 'rated'; + public const string PARAM_COLLECTION_FILTER_PLAYED = 'played'; + public const string PARAM_COLLECTION_FILTER_COMMENT = 'comment'; + public const string PARAM_COLLECTION_FILTER_FOR_TRADE = 'trade'; + public const string PARAM_COLLECTION_FILTER_WANT = 'want'; + public const string PARAM_COLLECTION_FILTER_WISHLIST = 'whishlist'; + public const string PARAM_COLLECTION_FILTER_WISHLIST_PRIORITY = 'wishlistpriority'; + public const string PARAM_COLLECTION_FILTER_PRE_ORDERED = 'preordered'; + public const string PARAM_COLLECTION_FILTER_WANT_TO_PLAY = 'wanttoplay'; + public const string PARAM_COLLECTION_FILTER_WANT_TO_BUY = 'wanttobuy'; + public const string PARAM_COLLECTION_FILTER_PREVIOUSLY_OWNED = 'prevowned'; + public const string PARAM_COLLECTION_FILTER_HAS_PARTS = 'hasparts'; + public const string PARAM_COLLECTION_FILTER_WANTS_PARTS = 'wantsparts'; + /** * ?minrating=[1-10] * Filter on minimum personal rating assigned for that item in the collection. */ - public const PARAM_COLLECTION_FILTER_MIN_RATING = 'minrating'; + public const string PARAM_COLLECTION_FILTER_MIN_RATING = 'minrating'; /** * ?rating=[1-10] * Filter on maximum personal rating assigned for that item in the collection. [Note: Although you'd expect it to be maxrating, it's rating.]. */ - public const PARAM_COLLECTION_FILTER_RATING = 'rating'; + public const string PARAM_COLLECTION_FILTER_RATING = 'rating'; /** * ?minbggrating=[1-10] * Filter on minimum BGG rating for that item in the collection. Note: 0 is ignored... you can use -1 though, * for example min -1 and max 1 to get items w/no bgg rating. */ - public const PARAM_COLLECTION_FILTER_MIN_BGG_RATING = 'minbggrating'; + public const string PARAM_COLLECTION_FILTER_MIN_BGG_RATING = 'minbggrating'; /** * ?bggrating=[1-10] * Filter on maximum BGG rating for that item in the collection. [Note: Although you'd expect it to be maxbggrating, it's bggrating.]. */ - public const PARAM_COLLECTION_FILTER_BGG_RATING = 'bggrating'; + public const string PARAM_COLLECTION_FILTER_BGG_RATING = 'bggrating'; /** * ?minplays=NNN * Filter by minimum number of recorded plays. */ - public const PARAM_COLLECTION_MIN_PLAYS = 'minplays'; + public const string PARAM_COLLECTION_MIN_PLAYS = 'minplays'; /** * ?maxplays=NNN * Filter by maximum number of recorded plays. * [Note: Although the two maxima parameters above lack the max part, this one really is maxplays.]. */ - public const PARAM_COLLECTION_MAX_PLAYS = 'maxplays'; + public const string PARAM_COLLECTION_MAX_PLAYS = 'maxplays'; /** * Filter to show private collection info. Only works when viewing your own collection and you are logged in. * This will probably never be implemented here. */ - public const PARAM_COLLECTION_SHOW_PRIVATE = 'showprivate'; + public const string PARAM_COLLECTION_SHOW_PRIVATE = 'showprivate'; /** * ?collid=NNN * Restrict the collection results to the single specified collection id. Collid is returned in the results of normal queries as well. */ - public const PARAM_COLLECTION_COLLECTION_ID = 'collid'; + public const string PARAM_COLLECTION_COLLECTION_ID = 'collid'; /** * ?modifiedsince=YY-MM-DD @@ -107,7 +109,7 @@ interface RequestInterface * has changed or been added since the date specified (does not return results for deletions). * Time may be added as well: modifiedsince=YY-MM-DD%20HH:MM:SS. */ - public const PARAM_COLLECTION_MODIFIED_SINCE = 'modifiedsince'; + public const string PARAM_COLLECTION_MODIFIED_SINCE = 'modifiedsince'; public function getType(): string; diff --git a/src/BoardGameGeekApi/Response.php b/src/BoardGameGeekApi/Response.php index 07936cf..6e23774 100644 --- a/src/BoardGameGeekApi/Response.php +++ b/src/BoardGameGeekApi/Response.php @@ -6,17 +6,7 @@ use TheBrokenTile\BoardGameGeekApi\DataTransferObject\DataTransferObjectInterface; -final class Response implements ResponseInterface +final readonly class Response implements ResponseInterface { - private DataTransferObjectInterface $data; - - public function __construct(DataTransferObjectInterface $data) - { - $this->data = $data; - } - - public function getData(): DataTransferObjectInterface - { - return $this->data; - } + public function __construct(public DataTransferObjectInterface $data) {} } diff --git a/src/BoardGameGeekApi/ResponseInterface.php b/src/BoardGameGeekApi/ResponseInterface.php index 1e3bd06..7ed25ef 100644 --- a/src/BoardGameGeekApi/ResponseInterface.php +++ b/src/BoardGameGeekApi/ResponseInterface.php @@ -8,5 +8,5 @@ interface ResponseInterface { - public function getData(): DataTransferObjectInterface; + public DataTransferObjectInterface $data {get; } } diff --git a/src/BoardGameGeekApi/UrlGenerator.php b/src/BoardGameGeekApi/UrlGenerator.php index 266b19e..a9065d6 100644 --- a/src/BoardGameGeekApi/UrlGenerator.php +++ b/src/BoardGameGeekApi/UrlGenerator.php @@ -4,23 +4,15 @@ namespace TheBrokenTile\BoardGameGeekApi; -final class UrlGenerator implements UrlGeneratorInterface +final readonly class UrlGenerator implements UrlGeneratorInterface { - private const URL = 'https://api.geekdo.com/xmlapi2'; - private const DEFAULT_VALUE_FIXES = [ + private const string URL = 'https://api.geekdo.com/xmlapi2'; + private const array DEFAULT_VALUE_FIXES = [ RequestInterface::PARAM_QUERY => ['/:|!|,/', ''], ]; - private string $baseUrl; - /** @var array */ - private array $valueFixes; - /** @param array $valueFixes */ - public function __construct(string $baseUrl = self::URL, array $valueFixes = self::DEFAULT_VALUE_FIXES) - { - $this->baseUrl = $baseUrl; - $this->valueFixes = $valueFixes; - } + public function __construct(private string $baseUrl = self::URL, private array $valueFixes = self::DEFAULT_VALUE_FIXES) {} public function generate(RequestInterface $request): string { @@ -40,13 +32,10 @@ public function generate(RequestInterface $request): string private function fixValues(array $params): array { foreach ($params as $key => $value) { - \assert(\is_string($value)); if (isset($this->valueFixes[$key])) { - /** @var string $pattern */ - /** @var string $replace */ [$pattern, $replace] = $this->valueFixes[$key]; $fixed = preg_replace($pattern, $replace, $value); - \assert(\is_string($fixed)); + assert(is_string($fixed)); $params[$key] = $fixed; } } diff --git a/tests/.gitignore b/tests/.gitignore deleted file mode 100644 index 165765a..0000000 --- a/tests/.gitignore +++ /dev/null @@ -1 +0,0 @@ -.phpunit.result.cache diff --git a/tests/CacheTagGeneratorTest.php b/tests/CacheTagGeneratorTest.php index a09619f..1ec3663 100644 --- a/tests/CacheTagGeneratorTest.php +++ b/tests/CacheTagGeneratorTest.php @@ -4,6 +4,8 @@ namespace TheBrokenTile\Test\BoardGameGeekApi; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use TheBrokenTile\BoardGameGeekApi\CacheTagGenerator; use TheBrokenTile\BoardGameGeekApi\Request\CollectionRequest; @@ -14,16 +16,15 @@ use TheBrokenTile\BoardGameGeekApi\RequestInterface; /** - * @covers \TheBrokenTile\BoardGameGeekApi\CacheTagGenerator - * * @internal */ +#[CoversClass(CacheTagGenerator::class)] final class CacheTagGeneratorTest extends TestCase { /** * @param string[] $expected - * @dataProvider dataProvider */ + #[DataProvider('provideGenerateTagsCases')] public function testGenerateTags(array $expected, RequestInterface $request): void { $generator = new CacheTagGenerator(); @@ -34,7 +35,7 @@ public function testGenerateTags(array $expected, RequestInterface $request): vo /** * @return array */ - public function dataProvider(): array + public static function provideGenerateTagsCases(): iterable { $searchRequest = new SearchRequest('Aye, Dark Overlord!', true); @@ -57,7 +58,7 @@ public function dataProvider(): array ], 'user request' => [ ['the_broken_tile.api_type_user', 'the_broken_tile.name_tazzadar1337', 'the_broken_tile.buddies_1', 'the_broken_tile.page_3', 'the_broken_tile.hot_1'], - (new UserRequest('tazzadar1337'))->buddies()->hot()->page(3), + (new UserRequest('::tazzadar1337::'))->buddies()->hot()->page(3), ], ]; } diff --git a/tests/ClientTest.php b/tests/ClientTest.php index 7717035..566fe68 100644 --- a/tests/ClientTest.php +++ b/tests/ClientTest.php @@ -2,71 +2,80 @@ declare(strict_types=1); -namespace TheBrokenTile\Test\BoardGameGeekApi; +namespace TheBrokenTile\Test; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\MockObject\Exception; +use PHPUnit\Framework\MockObject\Runtime\PropertyHook; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; use Symfony\Contracts\Cache\TagAwareCacheInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; use TheBrokenTile\BoardGameGeekApi\CacheTagGeneratorInterface; use TheBrokenTile\BoardGameGeekApi\Client; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\DataTransferObjectInterface; +use TheBrokenTile\BoardGameGeekApi\Exception\ExceptionInterface; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilderManagerInterface; use TheBrokenTile\BoardGameGeekApi\RequestInterface; use TheBrokenTile\BoardGameGeekApi\UrlGeneratorInterface; /** - * @coversDefaultClass \TheBrokenTile\BoardGameGeekApi\Client - * * @internal */ +#[CoversClass(Client::class)] final class ClientTest extends TestCase { - use ProphecyTrait; - /** - * @covers ::request + * @throws Exception + * @throws ExceptionInterface */ public function testRequest(): void { - $httpClient = $this->prophesize(HttpClientInterface::class); - $cache = $this->prophesize(TagAwareCacheInterface::class); - $objectBuilder = $this->prophesize(ObjectBuilderManagerInterface::class); + $httpClient = $this->createMock(HttpClientInterface::class); + $cache = $this->createMock(TagAwareCacheInterface::class); + $objectBuilder = $this->createMock(ObjectBuilderManagerInterface::class); - $stringResponse = 'response'; + $stringResponse = '::response::'; - $cache->get(Argument::type('string'), Argument::type('callable')) + $cache->expects(self::once()) + ->method('get') + ->with(self::isString(), self::isCallable()) ->willReturn($stringResponse) ; - $request = $this->prophesize(RequestInterface::class); - $request->getType()->willReturn('type'); - $request->getParams()->willReturn([]); - $request = $request->reveal(); + $request = $this->createMock(RequestInterface::class); + $request->method('getType') + ->willReturn('::type::') + ; + $request->method('getParams') + ->willReturn([]) + ; - $thing = $this->prophesize(DataTransferObjectInterface::class); - $thing->getTotalItems()->willReturn(1); - $thing = $thing->reveal(); + $thing = $this->createMock(DataTransferObjectInterface::class); + $thing->method(PropertyHook::get('totalItems')) + ->willReturn(1) + ; - $objectBuilder->build($request, $stringResponse) - ->shouldBeCalledOnce() + $objectBuilder->expects(self::once()) + ->method('build') ->willReturn($thing) ; - $urlGenerator = $this->prophesize(UrlGeneratorInterface::class); - $urlGenerator->generate($request)->willReturn('boardgamegeek.api'); + $urlGenerator = $this->createMock(UrlGeneratorInterface::class); + $urlGenerator->method('generate') + ->with($request) + ->willReturn('::boardgamegeek.api::') + ; - $cacheTagGenerator = $this->prophesize(CacheTagGeneratorInterface::class); + $cacheTagGenerator = $this->createMock(CacheTagGeneratorInterface::class); $client = new Client( - $objectBuilder->reveal(), - $httpClient->reveal(), - $cache->reveal(), - $urlGenerator->reveal(), - $cacheTagGenerator->reveal(), + $objectBuilder, + $httpClient, + $cache, + $urlGenerator, + $cacheTagGenerator, ); - self::assertSame($thing, $client->request($request)->getData()); + self::assertSame($thing, $client->request($request)->data); } } diff --git a/tests/CollectionBuilderTest.php b/tests/CollectionBuilderTest.php index 1f2b5a9..e09767a 100644 --- a/tests/CollectionBuilderTest.php +++ b/tests/CollectionBuilderTest.php @@ -4,8 +4,10 @@ namespace TheBrokenTile\Test; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\Collection; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\CollectionItem; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\CollectionStatus; @@ -13,6 +15,7 @@ use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameLink; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameName; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameRank; +use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameRatings; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameStatistics; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\CollectionBuilder; use TheBrokenTile\BoardGameGeekApi\Request\CollectionRequest; @@ -20,32 +23,26 @@ use TheBrokenTile\BoardGameGeekApi\RequestInterface; /** - * @coversDefaultClass \TheBrokenTile\BoardGameGeekApi\ObjectBuilder\CollectionBuilder - * * @internal */ +#[CoversClass(CollectionBuilder::class)] final class CollectionBuilderTest extends TestCase { - use ProphecyTrait; - - /** - * @covers ::supports - */ public function testSupports(): void { $collectionBuilder = new CollectionBuilder(); - self::assertTrue($collectionBuilder->supports(new CollectionRequest('username'))); + self::assertTrue($collectionBuilder->supports(new CollectionRequest('::username::'))); - self::assertFalse($collectionBuilder->supports(new UserRequest('username'))); + self::assertFalse($collectionBuilder->supports(new UserRequest('::username::'))); } /** - * @covers ::build - * * @param GameName[] $itemNames - * @dataProvider buildDataProvider + * + * @throws Exception */ + #[DataProvider('provideBuildCases')] public function testBuild( int $itemIndex, string $fixture, @@ -63,20 +60,21 @@ public function testBuild( ?int $itemNumberOfPlays, ?string $itemComment, ?CollectionVersion $itemVersion, - ?GameStatistics $itemStats + ?GameStatistics $itemStats, ): void { $collectionBuilder = new CollectionBuilder(); + + /** @var string $response */ $response = file_get_contents(__DIR__.$fixture); - \assert(\is_string($response)); - $collection = $collectionBuilder->build($response, $this->prophesize(RequestInterface::class)->reveal()); + $collection = $collectionBuilder->build($response, $this->createMock(RequestInterface::class)); self::assertInstanceOf(Collection::class, $collection); self::assertSame($totalItems, $collection->totalItems); self::assertCount($totalItems, $collection->items); self::assertSame($pubDate, $collection->pubDate); - //Items + // Items $item = $collection->items[$itemIndex]; self::assertInstanceOf(CollectionItem::class, $item); self::assertSame($itemType, $item->objectType); @@ -87,7 +85,7 @@ public function testBuild( self::assertSame($itemThumbnail, $item->thumbnail); self::assertEquals($itemNames, $item->names); - //Status + // Status self::assertEquals($itemStatus, $item->status); self::assertSame($itemYearPublished, $item->yearPublished); self::assertSame($itemNumberOfPlays, $item->numberOfPlays); @@ -99,21 +97,21 @@ public function testBuild( /** * @return array */ - public function buildDataProvider(): array + public static function provideBuildCases(): iterable { $base = [ 'itemIndex' => 0, - 'fixture' => null, //placeholder - 'pubDate' => null, //placeholder + 'fixture' => null, // placeholder + 'pubDate' => null, // placeholder 'totalItems' => 480, 'itemType' => 'thing', - 'itemId' => null, //placeholder + 'itemId' => null, // placeholder 'itemSubType' => 'boardgame', - 'itemCollectionId' => null, //placeholder + 'itemCollectionId' => null, // placeholder 'itemImage' => null, 'itemThumbnail' => null, - 'itemNames' => null, //placeholder - 'itemStatus' => null, //placeholder + 'itemNames' => null, // placeholder + 'itemStatus' => null, // placeholder 'itemYearPublished' => null, 'itemNumberOfPlays' => null, 'itemComment' => null, @@ -140,7 +138,7 @@ public function buildDataProvider(): array false, false, '2018-03-02 05:30:09', - null + null, ), ]), 'collection' => array_merge($base, [ @@ -161,7 +159,7 @@ public function buildDataProvider(): array false, false, '2018-03-02 05:30:09', - null + null, ), 'itemYearPublished' => 2016, 'itemNumberOfPlays' => 1, @@ -185,12 +183,12 @@ public function buildDataProvider(): array false, false, '2018-03-02 05:30:09', - null + null, ), 'itemYearPublished' => 2016, 'itemNumberOfPlays' => 1, 'itemComment' => "Spiel'17", - 'itemStats' => $this->buildStatistics( + 'itemStats' => self::buildStatistics( 1024, 5.51024, 5.49373, @@ -216,15 +214,15 @@ public function buildDataProvider(): array false, false, '2018-03-02 05:30:09', - null + null, ), - 'itemStats' => $this->buildStatistics( + 'itemStats' => self::buildStatistics( null, 5.51024, 5.49373, null, null, - [] + [], ), ]), 'version' => array_merge($base, [ @@ -246,11 +244,11 @@ public function buildDataProvider(): array false, false, '2015-12-31 03:25:41', - null + null, ), 'itemYearPublished' => 2015, 'itemNumberOfPlays' => 0, - 'itemVersion' => $this->createVersion( + 'itemVersion' => self::createVersion( 214187, CollectionVersion::TYPE_VERSION, 'https://cf.geekdo-images.com/EjLDriIcasQlJQUHqRfOtQ__original/img/rJMMssiJCDOo_eElyDSybnrv_Zc=/0x0/filters:format(jpeg)/pic1721930.jpg', @@ -261,7 +259,7 @@ public function buildDataProvider(): array new GameLink(69356, GameLink::TYPE_ARTIST, 'Ludwin Schouten'), new GameLink(2184, GameLink::TYPE_LANGUAGE, 'English'), ], - [new GameName(1, GameName::TYPE_PRIMARY, 'English first edition')] + [new GameName(1, GameName::TYPE_PRIMARY, 'English first edition')], ), ]), ]; @@ -270,15 +268,15 @@ public function buildDataProvider(): array /** * @param GameRank[] $ranks */ - private function buildStatistics( + private static function buildStatistics( ?int $usersRated, float $average, float $bayesAverage, ?float $stdDev, ?float $median, - array $ranks + array $ranks, ): GameStatistics { - $stats = new GameStatistics(); + $stats = new GameStatistics(new GameRatings()); $stats->ratings->usersRated = $usersRated; $stats->ratings->average = $average; $stats->ratings->bayesAverage = $bayesAverage; @@ -293,8 +291,14 @@ private function buildStatistics( * @param GameLink[] $links * @param GameName[] $names */ - private function createVersion(int $id, string $type, string $image, string $thumbnail, array $links, array $names): CollectionVersion - { + private static function createVersion( + int $id, + string $type, + string $image, + string $thumbnail, + array $links, + array $names, + ): CollectionVersion { $version = new CollectionVersion($id, $type); $version->image = $image; $version->thumbnail = $thumbnail; diff --git a/tests/GameBuilderTest.php b/tests/GameBuilderTest.php index 61f7493..4212e12 100644 --- a/tests/GameBuilderTest.php +++ b/tests/GameBuilderTest.php @@ -4,252 +4,289 @@ namespace TheBrokenTile\Test; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\Game; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameLink; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameName; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GamePoll; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameRank; +use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameRatings; +use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameResults; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameStatistics; +use TheBrokenTile\BoardGameGeekApi\DataTransferObject\PollResult; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\GameBuilder; use TheBrokenTile\BoardGameGeekApi\Request\GameRequest; use TheBrokenTile\BoardGameGeekApi\Request\SearchRequest; use TheBrokenTile\BoardGameGeekApi\RequestInterface; /** - * @coversDefaultCLass \TheBrokenTile\BoardGameGeekApi\ObjectBuilder\GameBuilder - * * @internal */ +#[CoversClass(GameBuilder::class)] final class GameBuilderTest extends TestCase { - use ProphecyTrait; + private GameBuilder $builder; + + #[\Override] + protected function setUp(): void + { + parent::setUp(); + + $this->builder = new GameBuilder(); + } + + public function testSupports(): void + { + self::assertTrue($this->builder->supports(new GameRequest(1))); + self::assertFalse($this->builder->supports(new SearchRequest('::test::'))); + } /** - * @covers ::supports + * @throws Exception */ - public function testSupports(): void + public function BuildWithStats(): void { - $builder = new GameBuilder(); + /** @var string $response */ + $response = file_get_contents(__DIR__.'/fixtures/game.xml'); - self::assertTrue($builder->supports(new GameRequest(1))); - self::assertFalse($builder->supports(new SearchRequest('test'))); + $results = $this->builder->build($response, $this->createMock(RequestInterface::class)); + + self::assertEquals( + new GameResults([ + $this->mockCarcassonneGame( + stats: $this->mockStats(), + names: $this->mockCarcassoneNames(), + links: $this->mockCarcassonneLinks(), + polls: $this->mockPolls(), + )]), + $results, + ); } /** - * @covers ::build - * @dataProvider buildDataProvider + * @throws Exception */ - public function testBuild( - string $fixture, - int $expectedId, - string $expectedImage, - string $expectedThumbnail, - string $expectedDescriptionStart, - int $expectedYearPublished, - int $expectedMinPlayers, - int $expectedMaxPlayers, - int $expectedPlayingTime, - int $expectedMinPlayTime, - int $expectedMaxPlayTime, - int $expectedMinAge, - int $expectedNamesCount, - int $nameIndex, - GameName $expectedName, - int $expectedLinksCount, - int $linkIndex, - GameLink $expectedGameLink, - int $expectedPollsCount, - string $expectedPollName, - string $expectedPollTitle, - int $expectedPollVotes, - int $expectedPollResultsCount, - ?GameStatistics $expectedStats, - int $expectedTotal, - int $gameIndex - ): void { - $builder = new GameBuilder(); - $response = file_get_contents(__DIR__.$fixture); - \assert(\is_string($response)); - - $results = $builder->build($response, $this->prophesize(RequestInterface::class)->reveal()); - self::assertSame($expectedTotal, $results->total); - $game = $results->items[$gameIndex]; - \assert($game instanceof Game); - self::assertSame($expectedId, $game->id); - self::assertSame($expectedImage, $game->image); - self::assertSame($expectedThumbnail, $game->thumbnail); - self::assertStringStartsWith($expectedDescriptionStart, $game->description); - self::assertSame($expectedYearPublished, $game->yearPublished); - self::assertSame($expectedMinPlayers, $game->minPlayers); - self::assertSame($expectedMaxPlayers, $game->maxPlayers); - self::assertSame($expectedPlayingTime, $game->playingTime); - self::assertSame($expectedMinPlayTime, $game->minPlayTime); - self::assertSame($expectedMaxPlayTime, $game->maxPlayTime); - self::assertSame($expectedMinAge, $game->minAge); - - self::assertCount($expectedNamesCount, $game->names); - - $name = $game->names[$nameIndex]; - self::assertEquals($expectedName, $name); - - self::assertCount($expectedLinksCount, $game->links); - $link = $game->links[$linkIndex]; - self::assertEquals($expectedGameLink, $link); - - // @todo rework poll results, they have different structure, current implementation doesn't support both. - self::assertCount($expectedPollsCount, $game->polls); - $poll = current($game->polls); - \assert($poll instanceof GamePoll); - self::assertSame($expectedPollName, $poll->name); - self::assertSame($expectedPollTitle, $poll->title); - self::assertSame($expectedPollVotes, $poll->totalVotes); - self::assertCount($expectedPollResultsCount, $poll->results); - - self::assertEquals($expectedStats, $game->stats); + public function testBuildWithoutStats(): void + { + /** @var string $response */ + $response = file_get_contents(__DIR__.'/fixtures/game_no_stats.xml'); + + $results = $this->builder->build($response, $this->createMock(RequestInterface::class)); + + $game = $this->mockCarcassonneGame(null, $this->mockCarcassoneNames(), $this->mockCarcassonneLinks(), $this->mockPolls()); + + self::assertEquals(new GameResults([$game]), $results); } /** - * @return array + * @throws Exception */ - public function buildDataProvider(): array + public function testBuildMultiGames(): void { - $base = [ - 'fixture' => null, //placeholder - 'expectedId' => 822, - 'expectedImage' => 'https://cf.geekdo-images.com/Z3upN53-fsVPUDimN9SpOA__original/img/9LEvU4EbbBrJB36YgWQXeXQYwjo=/0x0/filters:format(jpeg)/pic2337577.jpg', - 'expectedThumbnail' => 'https://cf.geekdo-images.com/Z3upN53-fsVPUDimN9SpOA__thumb/img/_C5pWATlaq3uS8u7IlFb0WMi_ak=/fit-in/200x150/filters:strip_icc()/pic2337577.jpg', - 'expectedDescriptionStart' => 'Carcassonne is a tile-placement game in which the players draw and place a tile', - 'expectedYearPublished' => 2000, - 'expectedMinPlayers' => 2, - 'expectedMaxPlayers' => 5, - 'expectedPlayingTime' => 45, - 'expectedMinPlayTime' => 30, - 'expectedMaxPlayTime' => 45, - 'expectedMinAge' => 7, - 'expectedNamesCount' => 17, - 'nameIndex' => 0, - 'expectedName' => null, //placeholder - 'expectedLinksCount' => 243, - 'linkIndex' => 0, - 'expectedLink' => null, //placeholder - 'expectedPollsCount' => 3, - 'expectedPollName' => 'suggested_numplayers', - 'expectedPollTitle' => 'User Suggested Number of Players', - 'expectedPollVotes' => 2154, - 'expectedPollResultsCount' => 18, - 'expectedStats' => null, //placeholder - 'expectedTotal' => 1, - 'gameIndex' => 0, - ]; + /** @var string $response */ + $response = file_get_contents(__DIR__.'/fixtures/multi_games.xml'); - return [ - 'stats' => array_merge($base, [ - 'fixture' => '/fixtures/game.xml', - 'expectedStats' => $this->buildStats( - 107363, - 7.41855, - 158733, - 1696, - 577, - 7250, - 19100, - 7657, - 1.9071, - 7.30909, - 1.30574, - 0.0, - [ - new GameRank( - 1, - 'boardgame', - GameRank::TYPE_SUBTYPE, - 'Board Game Rank', - 185, - 7.30909, - ), - new GameRank( - 5499, - 'familygames', - GameRank::TYPE_FAMILY, - 'Family Game Rank', - 40, - 7.30109, - ), - ] + $results = $this->builder->build($response, $this->createMock(RequestInterface::class)); + + self::assertEquals( + new GameResults([ + $this->mockCarcassonneGame( + stats: null, + names: $this->mockCarcassoneNames(), + links: $this->mockCarcassonneLinks(), + polls: $this->mockPolls(), ), - 'nameIndex' => 1, - 'expectedName' => new GameName(1, GameName::TYPE_ALTERNATE, 'Carcassonne Jubilee Edition'), - 'expectedLink' => new GameLink(1029, GameLink::TYPE_CATEGORY, 'City Building'), - ]), - 'no stats' => array_merge($base, [ - 'fixture' => '/fixtures/game_no_stats.xml', - 'expectedName' => new GameName(1, GameName::TYPE_PRIMARY, 'Carcassonne'), - 'linkIndex' => 203, - 'expectedLink' => new GameLink(398, GameLink::TYPE_DESIGNER, 'Klaus-Jürgen Wrede'), - ]), - 'multiple_games' => array_merge($base, [ - 'fixture' => '/fixtures/multi_games.xml', - 'expectedId' => 999, - 'expectedImage' => 'https://cf.geekdo-images.com/x4ls1E4Y7KMlCnPeRTbIew__original/img/WKuYbaFCdePj84tCTdypteyBHic=/0x0/filters:format(jpeg)/pic3031803.jpg', - 'expectedThumbnail' => 'https://cf.geekdo-images.com/x4ls1E4Y7KMlCnPeRTbIew__thumb/img/QUA66MlXNclGjOLqNbfGsKlrHm8=/fit-in/200x150/filters:strip_icc()/pic3031803.jpg', - 'expectedDescriptionStart' => 'Got quick reflexes and a good memory? Test your skills in this high-energy card game of musical', - 'expectedYearPublished' => 1994, - 'expectedMinPlayers' => 3, - 'expectedMaxPlayers' => 6, - 'expectedPlayingTime' => 20, - 'expectedMinPlayTime' => 20, - 'expectedMaxPlayTime' => 20, - 'expectedMinAge' => 6, - 'expectedNamesCount' => 4, - 'expectedName' => new GameName(1, GameName::TYPE_PRIMARY, 'Panda Monium'), - 'expectedLinksCount' => 20, - 'expectedLink' => new GameLink(1032, GameLink::TYPE_CATEGORY, 'Action / Dexterity'), - 'expectedPollsCount' => 3, - 'expectedPollName' => 'suggested_numplayers', - 'expectedPollTitle' => 'User Suggested Number of Players', - 'expectedPollVotes' => 2, - 'expectedPollResultsCount' => 21, - 'expectedTotal' => 2, - 'gameIndex' => 1, + $this->mockPandaMoniumGame(), ]), + $results, + ); + } + + private function mockStats(): GameStatistics + { + $ratings = new GameRatings(); + $ratings->ranks = [ + new GameRank( + id: 1, + name: 'boardgame', + type: GameRank::TYPE_SUBTYPE, + friendlyName: 'Board Game Rank', + value: 185, + bayesAverage: 7.30909, + ), + new GameRank( + id: 5499, + name: 'familygames', + type: GameRank::TYPE_FAMILY, + friendlyName: 'Family Game Rank', + value: 40, + bayesAverage: 7.30109, + ), + ]; + $ratings->owned = 158733; + $ratings->trading = 1696; + $ratings->wanting = 577; + $ratings->wishing = 7250; + $ratings->numComments = 19100; + $ratings->numWeights = 7657; + $ratings->averageWeight = 1.9071; + $ratings->usersRated = 107363; + $ratings->average = 7.41855; + $ratings->bayesAverage = 7.30909; + $ratings->stdDev = 1.30574; + $ratings->median = 0.0; + + return new GameStatistics($ratings); + } + + /** + * @return GameName[] + */ + private function mockCarcassoneNames(): array + { + return [ + new GameName(1, GameName::TYPE_PRIMARY, 'Carcassonne'), + new GameName(1, GameName::TYPE_ALTERNATE, 'Каркасон'), + ]; + } + + /** + * @return GameLink[] + */ + private function mockCarcassonneLinks(): array + { + return [ + new GameLink(id: 1029, type: GameLink::TYPE_CATEGORY, value: 'City Building'), + new GameLink(id: 1035, type: GameLink::TYPE_CATEGORY, value: 'Medieval'), + ]; + } + + /** + * @return GamePoll[] + */ + private function mockPolls(): array + { + return [ + new GamePoll( + name: 'suggested_numplayers', + title: 'User Suggested Number of Players', + totalVotes: 2154, + results: [ + new PollResult(value: 'Best', numVotes: 6), // 1, missing prop to fill this in + new PollResult(value: 'Recommended', numVotes: 60), // 1 + new PollResult(value: 'Not Recommended', numVotes: 1294), // 1 + new PollResult(value: 'Best', numVotes: 1141), // 2 + new PollResult(value: 'Recommended', numVotes: 767), // 2 + new PollResult(value: 'Not Recommended', numVotes: 104), // 2 + ], + ), + new GamePoll( + name: 'suggested_playerage', + title: 'User Suggested Player Age', + totalVotes: 284, + results: [ + new PollResult(value: '2', numVotes: 2), + new PollResult(value: '8', numVotes: 282), + new PollResult(value: '21 and up', numVotes: 0), + ], + ), + new GamePoll( + name: 'language_dependence', + title: 'Language Dependence', + totalVotes: 462, + results: [ + new PollResult(value: 'No necessary in-game text', numVotes: 461), + new PollResult(value: 'Unplayable in another language', numVotes: 1), + ], + ), ]; } /** - * @param GameRank[] $ranks + * @param GameName[] $names + * @param GameLink[] $links + * @param GamePoll[] $polls */ - private function buildStats( - int $usersRated, - float $average, - int $owned, - int $trading, - int $wanting, - int $wishing, - int $numComments, - int $numWeights, - float $averageWeight, - float $bayesAverage, - float $stdDev, - float $median, - array $ranks - ): GameStatistics { - $stats = new GameStatistics(); - $stats->ratings->usersRated = $usersRated; - $stats->ratings->average = $average; - $stats->ratings->owned = $owned; - $stats->ratings->trading = $trading; - $stats->ratings->wanting = $wanting; - $stats->ratings->wishing = $wishing; - $stats->ratings->numComments = $numComments; - $stats->ratings->numWeights = $numWeights; - $stats->ratings->averageWeight = $averageWeight; - $stats->ratings->bayesAverage = $bayesAverage; - $stats->ratings->stdDev = $stdDev; - $stats->ratings->median = $median; - $stats->ratings->ranks = $ranks; - - return $stats; + private function mockCarcassonneGame(?GameStatistics $stats, array $names, array $links, array $polls): Game + { + $game = new Game(); + $game->image = 'https://cf.geekdo-images.com/Z3upN53-fsVPUDimN9SpOA__original/img/9LEvU4EbbBrJB36YgWQXeXQYwjo=/0x0/filters:format(jpeg)/pic2337577.jpg'; + $game->thumbnail = 'https://cf.geekdo-images.com/Z3upN53-fsVPUDimN9SpOA__thumb/img/_C5pWATlaq3uS8u7IlFb0WMi_ak=/fit-in/200x150/filters:strip_icc()/pic2337577.jpg'; + $game->id = 822; + $game->description = 'Carcassonne is a tile-placement game in which the players draw and place a tile with a piece of southern French landscape on it.'; + $game->yearPublished = 2000; + $game->minPlayers = 2; + $game->maxPlayers = 5; + $game->playingTime = 45; + $game->minPlayTime = 30; + $game->maxPlayTime = 45; + $game->minAge = 7; + + $game->stats = $stats; + $game->names = $names; + $game->links = $links; + $game->polls = $polls; + + return $game; + } + + private function mockPandaMoniumGame(): Game + { + $game = new Game(); + $game->image = 'https://cf.geekdo-images.com/x4ls1E4Y7KMlCnPeRTbIew__original/img/WKuYbaFCdePj84tCTdypteyBHic=/0x0/filters:format(jpeg)/pic3031803.jpg'; + $game->thumbnail = 'https://cf.geekdo-images.com/x4ls1E4Y7KMlCnPeRTbIew__thumb/img/QUA66MlXNclGjOLqNbfGsKlrHm8=/fit-in/200x150/filters:strip_icc()/pic3031803.jpg'; + $game->id = 999; + $game->description = 'Got quick reflexes and a good memory? Test your skills in this high-energy card game of musical mayhem.'; + $game->yearPublished = 1994; + $game->minPlayers = 3; + $game->maxPlayers = 6; + $game->playingTime = 20; + $game->minPlayTime = 20; + $game->maxPlayTime = 20; + $game->minAge = 6; + $game->stats = null; + + $game->polls = [ + new GamePoll( + name: 'suggested_numplayers', + title: 'User Suggested Number of Players', + totalVotes: 2, + results: [ + new PollResult(value: 'Recommended', numVotes: 1), // 3 + new PollResult(value: 'Best', numVotes: 1), // 6 + ], + ), + ]; + $game->links = [ + new GameLink(1032, type: GameLink::TYPE_CATEGORY, value: 'Action / Dexterity'), + new GameLink(1002, type: GameLink::TYPE_CATEGORY, value: 'Card Game'), + ]; + + $game->names = [ + new GameName( + sortIndex: 1, + type: GameName::TYPE_PRIMARY, + value: 'Panda Monium', + ), + new GameName( + sortIndex: 1, + type: GameName::TYPE_ALTERNATE, + value: 'Concerto Grosso', + ), + new GameName( + sortIndex: 1, + type: 'alternate', + value: 'Little Amadeus: Concerto Grosso', + ), + new GameName( + sortIndex: 1, + type: 'alternate', + value: '숲 속의 음악대', + ), + ]; + + return $game; } } diff --git a/tests/ObjectBuilderTest.php b/tests/ObjectBuilderTest.php index e0fa515..56b86a0 100644 --- a/tests/ObjectBuilderTest.php +++ b/tests/ObjectBuilderTest.php @@ -4,67 +4,74 @@ namespace TheBrokenTile\Test; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\DataTransferObjectInterface; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilder; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilderInterface; use TheBrokenTile\BoardGameGeekApi\RequestInterface; /** - * @coversDefaultClass \TheBrokenTile\BoardGameGeekApi\ObjectBuilder\ObjectBuilder - * * @internal */ +#[CoversClass(ObjectBuilder::class)] final class ObjectBuilderTest extends TestCase { - use ProphecyTrait; - /** - * @covers ::build + * @throws Exception */ public function testBuild(): void { - $request = $this->prophesize(RequestInterface::class)->reveal(); - $stringResponse = 'string response'; - $expectedResponse = $this->prophesize(DataTransferObjectInterface::class)->reveal(); + $request = $this->createMock(RequestInterface::class); + $stringResponse = '::string-response::'; + $expectedResponse = $this->createMock(DataTransferObjectInterface::class); - $supportedBuilder = $this->prophesize(ObjectBuilderInterface::class); + $supportedBuilder = $this->createMock(ObjectBuilderInterface::class); $supportedBuilder - ->supports($request) - ->shouldBeCalledOnce() + ->expects(self::once()) + ->method('supports') + ->with($request) ->willReturn(true) ; + $supportedBuilder - ->build($stringResponse, $request) + ->method('build') + ->with($stringResponse, $request) ->willReturn($expectedResponse) ; - $notSupportedBuilder = $this->prophesize(ObjectBuilderInterface::class); + $notSupportedBuilder = $this->createMock(ObjectBuilderInterface::class); $notSupportedBuilder - ->supports($request) - ->shouldBeCalledOnce() + ->expects(self::once()) + ->method('supports') + ->with($request) ->willReturn(false) ; + $notSupportedBuilder - ->build($stringResponse, $request) - ->shouldNotBeCalled() + ->expects(self::never()) + ->method('build') + ->with($stringResponse, $request) ; - $secondNotSupportedBuilder = $this->prophesize(ObjectBuilderInterface::class); + $secondNotSupportedBuilder = $this->createMock(ObjectBuilderInterface::class); $secondNotSupportedBuilder - ->supports($request) - ->shouldNotBeCalled() + ->expects(self::never()) + ->method('supports') + ->with($request) ; + $secondNotSupportedBuilder - ->build($stringResponse, $request) - ->shouldNotBeCalled() + ->expects(self::never()) + ->method('build') + ->with($stringResponse, $request) ; $builder = new ObjectBuilder([ - $notSupportedBuilder->reveal(), - $supportedBuilder->reveal(), - $secondNotSupportedBuilder->reveal(), + $notSupportedBuilder, + $supportedBuilder, + $secondNotSupportedBuilder, ]); $response = $builder->build($request, $stringResponse); diff --git a/tests/RetryExactSearchBuilderTest.php b/tests/RetryExactSearchBuilderTest.php index c4548e2..01b2198 100644 --- a/tests/RetryExactSearchBuilderTest.php +++ b/tests/RetryExactSearchBuilderTest.php @@ -4,9 +4,10 @@ namespace TheBrokenTile\Test; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameName; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\SearchItem; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\SearchResults; @@ -17,45 +18,43 @@ use TheBrokenTile\BoardGameGeekApi\RequestInterface; /** - * @coversDefaultClass \TheBrokenTile\BoardGameGeekApi\ObjectBuilder\RetryExactSearchBuilder - * * @internal */ +#[CoversClass(RetryExactSearchBuilder::class)] final class RetryExactSearchBuilderTest extends TestCase { - use ProphecyTrait; - - private const RESPONSE = 'response'; + private const string RESPONSE = '::response::'; /** - * @covers ::supports + * @throws Exception */ public function testSupports(): void { - $builder = new RetryExactSearchBuilder($this->prophesize(ObjectBuilderInterface::class)->reveal()); + $builder = new RetryExactSearchBuilder($this->createMock(ObjectBuilderInterface::class)); - self::assertTrue($builder->supports(new RetrySearchRequest($this->prophesize(RequestInterface::class)->reveal(), []))); + self::assertTrue($builder->supports(new RetrySearchRequest($this->createMock(RequestInterface::class), []))); self::assertFalse($builder->supports(new SearchRequest('search'))); } /** - * @covers ::build - * @dataProvider dataProvider + * @throws Exception */ + #[DataProvider('provideBuildCases')] public function testBuild(string $query, SearchResults $searchResults, SearchResults $expectedResults): void { - $searchBuilder = $this->prophesize(ObjectBuilderInterface::class); - $searchBuilder->build(self::RESPONSE, Argument::type(RequestInterface::class)) + $searchBuilder = $this->createMock(ObjectBuilderInterface::class); + $searchBuilder + ->method('build') + ->with(self::RESPONSE, self::isInstanceOf(RequestInterface::class)) ->willReturn($searchResults) ; - $searchBuilder = $searchBuilder->reveal(); - $request = $this->prophesize(RequestInterface::class); - $request->getParams()->willReturn([ - RequestInterface::PARAM_QUERY => $query, - ]); - $request = $request->reveal(); + $request = $this->createMock(RequestInterface::class); + $request + ->method('getParams') + ->willReturn([RequestInterface::PARAM_QUERY => $query]) + ; $builder = new RetryExactSearchBuilder($searchBuilder); @@ -63,42 +62,52 @@ public function testBuild(string $query, SearchResults $searchResults, SearchRes } /** - * @return array + * @return array */ - public function dataProvider(): array + public static function provideBuildCases(): iterable { - $searchItem = new SearchItem(1, SearchItem::TYPE_BOARD_GAME, new GameName(1, GameName::TYPE_PRIMARY, 'test name'), 2022); - $secondItem = new SearchItem(2, SearchItem::TYPE_BOARD_GAME, new GameName(2, GameName::TYPE_ALTERNATE, 'test'), 2022); + $searchItem = new SearchItem( + id: 1, + type: SearchItem::TYPE_BOARD_GAME, + name: new GameName( + sortIndex: 1, + type: GameName::TYPE_PRIMARY, + value: '::test-name::', + ), + yearPublished: 2022, + ); + $secondItem = new SearchItem( + id: 2, + type: SearchItem::TYPE_BOARD_GAME, + name: new GameName( + sortIndex: 2, + type: GameName::TYPE_ALTERNATE, + value: '::test::', + ), + yearPublished: 2022, + ); return [ 'first result is exact' => [ - 'query' => 'test name', - 'searchResults' => $this->buildSearchResults([ + 'query' => '::test-name::', + 'searchResults' => new SearchResults([ $searchItem, $secondItem, ]), - 'expectedResult' => $this->buildSearchResults([$searchItem]), + 'expectedResults' => new SearchResults([$searchItem]), ], 'second result is exact' => [ - 'query' => 'test name', - 'searchResults' => $this->buildSearchResults([ + 'query' => '::test-name::', + 'searchResults' => new SearchResults([ $secondItem, $searchItem, ]), - 'expectedResult' => $this->buildSearchResults([$searchItem]), + 'expectedResults' => new SearchResults([$searchItem]), ], ]; } - - /** - * @param SearchItem[] $items - */ - private function buildSearchResults(array $items): SearchResults - { - $results = new SearchResults(); - $results->items = $items; - $results->total = \count($items); - - return $results; - } } diff --git a/tests/SearchResultBuilderTest.php b/tests/SearchResultBuilderTest.php index 52f5360..ebf957d 100644 --- a/tests/SearchResultBuilderTest.php +++ b/tests/SearchResultBuilderTest.php @@ -4,8 +4,10 @@ namespace TheBrokenTile\Test; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\GameName; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\SearchItem; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\SearchResultBuilder; @@ -14,46 +16,39 @@ use TheBrokenTile\BoardGameGeekApi\RequestInterface; /** - * @coversDefaultClass \TheBrokenTile\BoardGameGeekApi\ObjectBuilder\SearchResultBuilder - * * @internal */ +#[CoversClass(SearchResultBuilder::class)] final class SearchResultBuilderTest extends TestCase { - use ProphecyTrait; - - /** - * @covers ::supports - */ public function testSupports(): void { $builder = new SearchResultBuilder(); - self::assertTrue($builder->supports(new SearchRequest('Dixit'))); + self::assertTrue($builder->supports(new SearchRequest('::Dixit::'))); self::assertFalse($builder->supports(new GameRequest(1))); } /** - * @covers ::build - * @dataProvider supportsDataProvider + * @throws Exception */ + #[DataProvider('provideBuildCases')] public function testBuild( string $fixture, int $expectedTotal, int $expectedItemId, string $expectedItemType, GameName $expectedItemName, - int $expectedItemYearPublished + int $expectedItemYearPublished, ): void { + /** @var string $response */ $response = file_get_contents(__DIR__.$fixture); - \assert(\is_string($response)); $builder = new SearchResultBuilder(); - $searchResults = $builder->build($response, $this->prophesize(RequestInterface::class)->reveal()); - self::assertSame($expectedTotal, $searchResults->total); + $searchResults = $builder->build($response, $this->createMock(RequestInterface::class)); self::assertCount($expectedTotal, $searchResults->items); + /** @var SearchItem $item */ $item = current($searchResults->items); - \assert($item instanceof SearchItem); self::assertSame($expectedItemId, $item->id); self::assertSame($expectedItemType, $item->type); self::assertEquals($expectedItemName, $item->name); @@ -63,7 +58,7 @@ public function testBuild( /** * @return array */ - public function supportsDataProvider(): array + public static function provideBuildCases(): iterable { return [ 'exact' => [ diff --git a/tests/UrlGeneratorTest.php b/tests/UrlGeneratorTest.php index cd4a0c1..1926557 100644 --- a/tests/UrlGeneratorTest.php +++ b/tests/UrlGeneratorTest.php @@ -4,6 +4,8 @@ namespace TheBrokenTile\Test; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use TheBrokenTile\BoardGameGeekApi\Request\CollectionRequest; use TheBrokenTile\BoardGameGeekApi\Request\GameRequest; @@ -13,15 +15,11 @@ use TheBrokenTile\BoardGameGeekApi\UrlGenerator; /** - * @coversDefaultClass \TheBrokenTile\BoardGameGeekApi\UrlGenerator - * * @internal */ +#[CoversClass(UrlGenerator::class)] final class UrlGeneratorTest extends TestCase { - /** - * @covers ::generate - */ public function testGenerateCustomBaseUrl(): void { $urlGenerator = new UrlGenerator('google.com'); @@ -29,10 +27,7 @@ public function testGenerateCustomBaseUrl(): void self::assertSame('google.com/thing?id=5', $urlGenerator->generate(new GameRequest(5))); } - /** - * @covers ::generate - * @dataProvider dataProvider - */ + #[DataProvider('provideGenerateCases')] public function testGenerate(string $expected, RequestInterface $request): void { $urlGenerator = new UrlGenerator(); @@ -43,7 +38,7 @@ public function testGenerate(string $expected, RequestInterface $request): void /** * @return array */ - public function dataProvider(): array + public static function provideGenerateCases(): iterable { return [ 'game' => [ diff --git a/tests/UserBuilderTest.php b/tests/UserBuilderTest.php index 022be32..557f4f3 100644 --- a/tests/UserBuilderTest.php +++ b/tests/UserBuilderTest.php @@ -2,40 +2,36 @@ declare(strict_types=1); -namespace TheBrokenTile\Test\BoardGameGeekApi\ObjectBuilder; +namespace TheBrokenTile\Test; +use PHPUnit\Framework\Attributes\CoversClass; +use PHPUnit\Framework\MockObject\Exception; use PHPUnit\Framework\TestCase; -use Prophecy\PhpUnit\ProphecyTrait; -use TheBrokenTile\BoardGameGeekApi\DataTransferObject\User; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\UserBuddy; use TheBrokenTile\BoardGameGeekApi\DataTransferObject\UserHotItem; +use TheBrokenTile\BoardGameGeekApi\Exception\InvalidResponseException; use TheBrokenTile\BoardGameGeekApi\ObjectBuilder\UserBuilder; use TheBrokenTile\BoardGameGeekApi\Request\SearchRequest; use TheBrokenTile\BoardGameGeekApi\Request\UserRequest; use TheBrokenTile\BoardGameGeekApi\RequestInterface; /** - * @coversDefaultClass \TheBrokenTile\BoardGameGeekApi\ObjectBuilder\UserBuilder - * * @internal */ +#[CoversClass(UserBuilder::class)] final class UserBuilderTest extends TestCase { - use ProphecyTrait; - - /** - * @covers ::suppports - */ public function testSupports(): void { $userBuilder = new UserBuilder(); - self::assertTrue($userBuilder->supports(new UserRequest('test'))); + self::assertTrue($userBuilder->supports(new UserRequest('::user::'))); - self::assertFalse($userBuilder->supports(new SearchRequest('test'))); + self::assertFalse($userBuilder->supports(new SearchRequest('::search::'))); } /** - * @covers ::build + * @throws InvalidResponseException + * @throws Exception */ public function testBuild(): void { @@ -43,8 +39,7 @@ public function testBuild(): void $response = file_get_contents(__DIR__.'/fixtures/user.xml'); \assert(\is_string($response)); - $user = $userBuilder->build($response, $this->prophesize(RequestInterface::class)->reveal()); - self::assertInstanceOf(User::class, $user); + $user = $userBuilder->build($response, $this->createMock(RequestInterface::class)); self::assertSame(844486, $user->id); self::assertSame('tazzadar1337', $user->name); self::assertSame('Rusi', $user->firstName); @@ -63,22 +58,22 @@ public function testBuild(): void self::assertSame(0, $user->tradeRating); self::assertSame(2, $user->marketRating); - //Buddies. + // Buddies. self::assertCount(9, $user->buddies); $buddy = current($user->buddies); - \assert($buddy instanceof UserBuddy); + self::assertInstanceOf(UserBuddy::class, $buddy); self::assertSame(1201816, $buddy->id); self::assertSame('aymaliev', $buddy->name); - //Guilds. + // Guilds. self::assertEmpty($user->guilds); - //Hot. + // Hot. self::assertCount(1, $user->hot); $hot = current($user->hot); self::assertInstanceOf(UserHotItem::class, $hot); - //Top. + // Top. self::assertEmpty($user->top); } } diff --git a/tests/fixtures/game.xml b/tests/fixtures/game.xml index edd6538..b801fc7 100644 --- a/tests/fixtures/game.xml +++ b/tests/fixtures/game.xml @@ -10,52 +10,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Carcassonne is a tile-placement game in which the players draw and place a tile with a piece of - southern French landscape on it. The tile might feature a city, a road, a cloister, grassland or some - combination thereof, and it must be placed adjacent to tiles that have already been played, in such a way - that cities are connected to cities, roads to roads, etcetera. Having placed a tile, the player can then - decide to place one of their meeples on one of the areas on it: on the city as a knight, on the road as a - robber, on a cloister as a monk, or on the grass as a farmer. When that area is complete, that meeple scores - points for its owner.&#10;&#10;During a game of Carcassonne, players are faced with decisions like: - &quot;Is it really worth putting my last meeple there?&quot; or &quot;Should I use this tile to - expand my city, or should I place it near my opponent instead, giving him a hard time to complete their - project and score points?&quot; Since players place only one tile and have the option to place one - meeple on it, turns proceed quickly even if it is a game full of options and possibilities.&#10;&#10;First - game in the Carcassonne series.&#10;&#10; - + Carcassonne is a tile-placement game in which the players draw and place a tile with a piece of southern French landscape on it. @@ -72,798 +29,30 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/tests/fixtures/game_no_stats.xml b/tests/fixtures/game_no_stats.xml index 18ee1a5..75e4291 100644 --- a/tests/fixtures/game_no_stats.xml +++ b/tests/fixtures/game_no_stats.xml @@ -9,53 +9,9 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Carcassonne is a tile-placement game in which the players draw and place a tile with a piece of - southern French landscape on it. The tile might feature a city, a road, a cloister, grassland or some - combination thereof, and it must be placed adjacent to tiles that have already been played, in such a way - that cities are connected to cities, roads to roads, etcetera. Having placed a tile, the player can then - decide to place one of their meeples on one of the areas on it: on the city as a knight, on the road as a - robber, on a cloister as a monk, or on the grass as a farmer. When that area is complete, that meeple scores - points for its owner.&#10;&#10;During a game of Carcassonne, players are faced with decisions like: - &quot;Is it really worth putting my last meeple there?&quot; or &quot;Should I use this tile to - expand my city, or should I place it near my opponent instead, giving him a hard time to complete their - project and score points?&quot; Since players place only one tile and have the option to place one - meeple on it, turns proceed quickly even if it is a game full of options and possibilities.&#10;&#10;First - game in the Carcassonne series.&#10;&#10; - + Carcassonne is a tile-placement game in which the players draw and place a tile with a piece of southern French landscape on it. @@ -72,797 +28,28 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/fixtures/multi_games.xml b/tests/fixtures/multi_games.xml index 8583d29..05afcaf 100644 --- a/tests/fixtures/multi_games.xml +++ b/tests/fixtures/multi_games.xml @@ -9,863 +9,49 @@ + + Carcassonne is a tile-placement game in which the players draw and place a tile with a piece of southern French landscape on it. + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Carcassonne is a tile-placement game in which the players draw and place a tile with a piece of - southern French landscape on it. The tile might feature a city, a road, a cloister, grassland or some - combination thereof, and it must be placed adjacent to tiles that have already been played, in such a way - that cities are connected to cities, roads to roads, etcetera. Having placed a tile, the player can then - decide to place one of their meeples on one of the areas on it: on the city as a knight, on the road as a - robber, on a cloister as a monk, or on the grass as a farmer. When that area is complete, that meeple scores - points for its owner.&#10;&#10;During a game of Carcassonne, players are faced with decisions like: - &quot;Is it really worth putting my last meeple there?&quot; or &quot;Should I use this tile to - expand my city, or should I place it near my opponent instead, giving him a hard time to complete their - project and score points?&quot; Since players place only one tile and have the option to place one - meeple on it, turns proceed quickly even if it is a game full of options and possibilities.&#10;&#10;First - game in the Carcassonne series.&#10;&#10; - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - + - + @@ -877,157 +63,29 @@ - - - - - Got quick reflexes and a good memory? Test your skills in this high-energy card game of musical - mayhem. Players must make certain gestures as certain musician cards are turned over. But make a wrong move - and you collect the whole orchestra! Whoever gets rid of their cards first is the maestro!&#10;&#10; - + Got quick reflexes and a good memory? Test your skills in this high-energy card game of musical mayhem. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/tests/phpunit.xml b/tests/phpunit.xml index aa193b3..734b33d 100644 --- a/tests/phpunit.xml +++ b/tests/phpunit.xml @@ -1,9 +1,9 @@ - + - ../tests + ../tests From 1b1efb9e524638a44f286efb9663c8ea72dcf370 Mon Sep 17 00:00:00 2001 From: Rusi Papazov Date: Fri, 26 Sep 2025 09:18:44 +0300 Subject: [PATCH 2/2] update actions/cache to v4 --- .github/workflows/phpunit.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index f983ad9..727b8c3 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -13,7 +13,7 @@ jobs: run: composer validate --strict - name: Cache Composer packages id: composer-cache - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: vendor key: ${{ runner.os }}-php-${{ hashFiles('**/composer.lock') }}