diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 97815bc..f5458eb 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -9,8 +9,8 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - php: ['8.2', '8.3', '8.4'] - dependency-version: [prefer-lowest, prefer-stable] + php: ['8.4', '8.5'] + dependency-version: [prefer-stable] name: P${{ matrix.php }} - ${{ matrix.dependency-version }} - ${{ matrix.os }} @@ -51,6 +51,9 @@ jobs: - name: Run phpstan run: composer analyze + - name: Check coding standards + run: composer coding-standards-check + - name: Start server run: (php -S localhost:8000 -t ./tests/Server &) || /bin/true diff --git a/.gitignore b/.gitignore index f794f03..7ab4d60 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /package-lock.json /package.json /node_modules +.DS_Store diff --git a/composer.json b/composer.json index b4b7486..9516f2d 100644 --- a/composer.json +++ b/composer.json @@ -10,7 +10,7 @@ } ], "require": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "php": "^8.4", "guzzlehttp/guzzle": "^7.8.0", "jakeasmith/http_build_url": "^1.0.1", "league/container": "^4.2", @@ -30,8 +30,8 @@ "ergebnis/composer-normalize": "^2.45", "ergebnis/php-cs-fixer-config": "^6.45.0", "http-interop/http-factory-guzzle": "^1.2", - "phpstan/phpstan": "^2.1", - "phpunit/phpunit": "^10.4.2", + "phpstan/phpstan": "^2.2.2", + "phpunit/phpunit": "^12.5.8", "psr/http-message": "^1.1.0", "roave/security-advisories": "dev-latest", "slim/slim": "^4.12", @@ -67,12 +67,16 @@ "composer normalize" ], "analyze": [ - "vendor/bin/phpstan" + "vendor/bin/phpstan --memory-limit=1G" ], "coding-standards": [ "mkdir -p .build/php-cs-fixer", "php-cs-fixer fix --diff --verbose" ], + "coding-standards-check": [ + "mkdir -p .build/php-cs-fixer", + "php-cs-fixer fix --diff --verbose --dry-run" + ], "test-server": [ "php -S localhost:8000 -t ./tests/Server" ], diff --git a/composer.lock b/composer.lock index 7a39670..122a13e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,29 +4,30 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "565d61d07bd97d87e3532b1ed4068a9b", + "content-hash": "b12d618984b1d9aa4d20dce8307cf528", "packages": [ { "name": "guzzlehttp/guzzle", - "version": "7.9.3", + "version": "7.12.3", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77" + "reference": "9aa17bcdd777ee31df9fc83c337ca4ca2340def3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", - "reference": "7b2f29fe81dc4da0ca0ea7d42107a0845946ea77", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/9aa17bcdd777ee31df9fc83c337ca4ca2340def3", + "reference": "9aa17bcdd777ee31df9fc83c337ca4ca2340def3", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.3", - "guzzlehttp/psr7": "^2.7.0", + "guzzlehttp/promises": "^2.5", + "guzzlehttp/psr7": "^2.12.3", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.25" }, "provide": { "psr/http-client-implementation": "1.0" @@ -35,8 +36,9 @@ "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", "guzzle/client-integration-tests": "3.0.2", + "guzzlehttp/test-server": "^0.5.1", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.39 || ^9.6.20", + "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -114,7 +116,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.9.3" + "source": "https://github.com/guzzle/guzzle/tree/7.12.3" }, "funding": [ { @@ -130,28 +132,29 @@ "type": "tidelift" } ], - "time": "2025-03-27T13:37:11+00:00" + "time": "2026-06-23T15:29:02+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.2.0", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c" + "reference": "4360e982f87f5f258bf872d094647791db2f4c8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/7c69f28996b0a6920945dd20b3857e499d9ca96c", - "reference": "7c69f28996b0a6920945dd20b3857e499d9ca96c", + "url": "https://api.github.com/repos/guzzle/promises/zipball/4360e982f87f5f258bf872d094647791db2f4c8e", + "reference": "4360e982f87f5f258bf872d094647791db2f4c8e", "shasum": "" }, "require": { - "php": "^7.2.5 || ^8.0" + "php": "^7.2.5 || ^8.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.39 || ^9.6.20" + "phpunit/phpunit": "^8.5.52 || ^9.6.34" }, "type": "library", "extra": { @@ -197,7 +200,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.2.0" + "source": "https://github.com/guzzle/promises/tree/2.5.0" }, "funding": [ { @@ -213,27 +216,29 @@ "type": "tidelift" } ], - "time": "2025-03-27T13:27:01+00:00" + "time": "2026-06-02T12:23:43+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.7.1", + "version": "2.12.3", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16" + "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/c2270caaabe631b3b44c85f99e5a04bbb8060d16", - "reference": "c2270caaabe631b3b44c85f99e5a04bbb8060d16", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/7ec62dc3f44aa218487dbed81a9bf9bc647be55d", + "reference": "7ec62dc3f44aa218487dbed81a9bf9bc647be55d", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", "psr/http-message": "^1.1 || ^2.0", - "ralouphie/getallheaders": "^3.0" + "ralouphie/getallheaders": "^3.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.25" }, "provide": { "psr/http-factory-implementation": "1.0", @@ -241,8 +246,9 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "0.9.0", - "phpunit/phpunit": "^8.5.39 || ^9.6.20" + "http-interop/http-factory-tests": "1.1.0", + "jshttp/mime-db": "1.54.0.1", + "phpunit/phpunit": "^8.5.52 || ^9.6.34" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -313,7 +319,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.7.1" + "source": "https://github.com/guzzle/psr7/tree/2.12.3" }, "funding": [ { @@ -329,7 +335,7 @@ "type": "tidelift" } ], - "time": "2025-03-27T12:30:47+00:00" + "time": "2026-06-23T15:21:08+00:00" }, { "name": "jakeasmith/http_build_url", @@ -370,16 +376,16 @@ }, { "name": "league/container", - "version": "4.2.4", + "version": "4.2.5", "source": { "type": "git", "url": "https://github.com/thephpleague/container.git", - "reference": "7ea728b013b9a156c409c6f0fc3624071b742dec" + "reference": "d3cebb0ff4685ff61c749e54b27db49319e2ec00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/container/zipball/7ea728b013b9a156c409c6f0fc3624071b742dec", - "reference": "7ea728b013b9a156c409c6f0fc3624071b742dec", + "url": "https://api.github.com/repos/thephpleague/container/zipball/d3cebb0ff4685ff61c749e54b27db49319e2ec00", + "reference": "d3cebb0ff4685ff61c749e54b27db49319e2ec00", "shasum": "" }, "require": { @@ -440,7 +446,7 @@ ], "support": { "issues": "https://github.com/thephpleague/container/issues", - "source": "https://github.com/thephpleague/container/tree/4.2.4" + "source": "https://github.com/thephpleague/container/tree/4.2.5" }, "funding": [ { @@ -448,20 +454,20 @@ "type": "github" } ], - "time": "2024-11-10T12:42:13+00:00" + "time": "2025-05-20T12:55:37+00:00" }, { "name": "masterminds/html5", - "version": "2.9.0", + "version": "2.10.1", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" + "reference": "fd5018f6815fff903946d0564977b44ce8010e29" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", - "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fd5018f6815fff903946d0564977b44ce8010e29", + "reference": "fd5018f6815fff903946d0564977b44ce8010e29", "shasum": "" }, "require": { @@ -469,7 +475,7 @@ "php": ">=5.3.0" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" + "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9 || ^10" }, "type": "library", "extra": { @@ -513,22 +519,22 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" + "source": "https://github.com/Masterminds/html5-php/tree/2.10.1" }, - "time": "2024-03-31T07:05:07+00:00" + "time": "2026-06-23T18:43:15+00:00" }, { "name": "monolog/monolog", - "version": "3.9.0", + "version": "3.10.0", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6" + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6", - "reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/b321dd6749f0bf7189444158a3ce785cc16d69b0", + "reference": "b321dd6749f0bf7189444158a3ce785cc16d69b0", "shasum": "" }, "require": { @@ -546,7 +552,7 @@ "graylog2/gelf-php": "^1.4.2 || ^2.0", "guzzlehttp/guzzle": "^7.4.5", "guzzlehttp/psr7": "^2.2", - "mongodb/mongodb": "^1.8", + "mongodb/mongodb": "^1.8 || ^2.0", "php-amqplib/php-amqplib": "~2.4 || ^3", "php-console/php-console": "^3.1.8", "phpstan/phpstan": "^2", @@ -606,7 +612,7 @@ ], "support": { "issues": "https://github.com/Seldaek/monolog/issues", - "source": "https://github.com/Seldaek/monolog/tree/3.9.0" + "source": "https://github.com/Seldaek/monolog/tree/3.10.0" }, "funding": [ { @@ -618,20 +624,20 @@ "type": "tidelift" } ], - "time": "2025-03-24T10:02:05+00:00" + "time": "2026-01-02T08:56:05+00:00" }, { "name": "nikic/php-parser", - "version": "v5.4.0", + "version": "v5.7.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494" + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", - "reference": "447a020a1f875a434d62f2a401f53b82a396e494", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", "shasum": "" }, "require": { @@ -650,7 +656,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -674,9 +680,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" }, - "time": "2024-12-30T11:07:19+00:00" + "time": "2025-12-06T11:56:16+00:00" }, { "name": "nyholm/psr7", @@ -1137,16 +1143,16 @@ }, { "name": "psy/psysh", - "version": "v0.12.8", + "version": "v0.12.23", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "85057ceedee50c49d4f6ecaff73ee96adb3b3625" + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/85057ceedee50c49d4f6ecaff73ee96adb3b3625", - "reference": "85057ceedee50c49d4f6ecaff73ee96adb3b3625", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/4dcc0f08047d52bbde475eda481146fd8e27e1a4", + "reference": "4dcc0f08047d52bbde475eda481146fd8e27e1a4", "shasum": "" }, "require": { @@ -1154,18 +1160,19 @@ "ext-tokenizer": "*", "nikic/php-parser": "^5.0 || ^4.0", "php": "^8.0 || ^7.4", - "symfony/console": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", - "symfony/var-dumper": "^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" + "symfony/console": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4", + "symfony/var-dumper": "^8.0 || ^7.0 || ^6.0 || ^5.0 || ^4.0 || ^3.4" }, "conflict": { "symfony/console": "4.4.37 || 5.3.14 || 5.3.15 || 5.4.3 || 5.4.4 || 6.0.3 || 6.0.4" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.2" + "bamarni/composer-bin-plugin": "^1.2", + "composer/class-map-generator": "^1.6" }, "suggest": { + "composer/class-map-generator": "Improved tab completion performance with better class discovery.", "ext-pcntl": "Enabling the PCNTL extension makes PsySH a lot happier :)", - "ext-pdo-sqlite": "The doc command requires SQLite to work.", "ext-posix": "If you have PCNTL, you'll want the POSIX extension as well." }, "bin": [ @@ -1196,12 +1203,11 @@ "authors": [ { "name": "Justin Hileman", - "email": "justin@justinhileman.info", - "homepage": "http://justinhileman.com" + "email": "justin@justinhileman.info" } ], "description": "An interactive shell for modern PHP.", - "homepage": "http://psysh.org", + "homepage": "https://psysh.org", "keywords": [ "REPL", "console", @@ -1210,9 +1216,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.12.8" + "source": "https://github.com/bobthecow/psysh/tree/v0.12.23" }, - "time": "2025-03-16T03:05:19+00:00" + "time": "2026-05-23T13:41:31+00:00" }, { "name": "ralouphie/getallheaders", @@ -1260,16 +1266,16 @@ }, { "name": "spatie/robots-txt", - "version": "2.3.1", + "version": "2.5.4", "source": { "type": "git", "url": "https://github.com/spatie/robots-txt.git", - "reference": "58ed7b61c2a59e72f57b46e4d025967dd5f16000" + "reference": "a8dd35d0a94e863f52509a366a634978e9c1db03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/robots-txt/zipball/58ed7b61c2a59e72f57b46e4d025967dd5f16000", - "reference": "58ed7b61c2a59e72f57b46e4d025967dd5f16000", + "url": "https://api.github.com/repos/spatie/robots-txt/zipball/a8dd35d0a94e863f52509a366a634978e9c1db03", + "reference": "a8dd35d0a94e863f52509a366a634978e9c1db03", "shasum": "" }, "require": { @@ -1304,7 +1310,7 @@ ], "support": { "issues": "https://github.com/spatie/robots-txt/issues", - "source": "https://github.com/spatie/robots-txt/tree/2.3.1" + "source": "https://github.com/spatie/robots-txt/tree/2.5.4" }, "funding": [ { @@ -1316,27 +1322,28 @@ "type": "github" } ], - "time": "2025-01-31T09:33:25+00:00" + "time": "2026-02-25T07:59:20+00:00" }, { "name": "symfony/console", - "version": "v7.2.5", + "version": "v7.4.14", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "e51498ea18570c062e7df29d05a7003585b19b88" + "reference": "92f58bc4bf97a92ed1b9f367f0cd44f20bde0e87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/e51498ea18570c062e7df29d05a7003585b19b88", - "reference": "e51498ea18570c062e7df29d05a7003585b19b88", + "url": "https://api.github.com/repos/symfony/console/zipball/92f58bc4bf97a92ed1b9f367f0cd44f20bde0e87", + "reference": "92f58bc4bf97a92ed1b9f367f0cd44f20bde0e87", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^6.4|^7.0" + "symfony/string": "^7.2|^8.0" }, "conflict": { "symfony/dependency-injection": "<6.4", @@ -1350,16 +1357,16 @@ }, "require-dev": { "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" + "symfony/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/event-dispatcher": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/lock": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0", + "symfony/var-dumper": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -1393,7 +1400,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.2.5" + "source": "https://github.com/symfony/console/tree/v7.4.14" }, "funding": [ { @@ -1404,25 +1411,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": "2025-03-12T08:11:12+00:00" + "time": "2026-06-16T11:50:14+00:00" }, { "name": "symfony/css-selector", - "version": "v7.2.0", + "version": "v7.4.9", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2" + "reference": "b75663ed96cf4756e28e3105476f220f92886cc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/601a5ce9aaad7bf10797e3663faefce9e26c24e2", - "reference": "601a5ce9aaad7bf10797e3663faefce9e26c24e2", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/b75663ed96cf4756e28e3105476f220f92886cc4", + "reference": "b75663ed96cf4756e28e3105476f220f92886cc4", "shasum": "" }, "require": { @@ -1458,7 +1469,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v7.2.0" + "source": "https://github.com/symfony/css-selector/tree/v7.4.9" }, "funding": [ { @@ -1469,25 +1480,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": "2024-09-25T14:21:43+00:00" + "time": "2026-04-18T13:18:21+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.1", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" + "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", - "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/f3202fa1b5097b0af062dc978b32ecf63404e31d", + "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d", "shasum": "" }, "require": { @@ -1500,7 +1515,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -1525,7 +1540,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.1" }, "funding": [ { @@ -1536,35 +1551,40 @@ "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": "2024-09-25T14:20:29+00:00" + "time": "2026-06-05T06:23:12+00:00" }, { "name": "symfony/dom-crawler", - "version": "v7.2.4", + "version": "v7.4.12", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "19cc7b08efe9ad1ab1b56e0948e8d02e15ed3ef7" + "reference": "b59b59122690976550fd142c23fab62c84738db6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/19cc7b08efe9ad1ab1b56e0948e8d02e15ed3ef7", - "reference": "19cc7b08efe9ad1ab1b56e0948e8d02e15ed3ef7", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/b59b59122690976550fd142c23fab62c84738db6", + "reference": "b59b59122690976550fd142c23fab62c84738db6", "shasum": "" }, "require": { "masterminds/html5": "^2.6", "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { - "symfony/css-selector": "^6.4|^7.0" + "symfony/css-selector": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -1592,7 +1612,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v7.2.4" + "source": "https://github.com/symfony/dom-crawler/tree/v7.4.12" }, "funding": [ { @@ -1603,25 +1623,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": "2025-02-17T15:53:07+00:00" + "time": "2026-05-20T07:20:23+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.2.0", + "version": "v7.4.14", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" + "reference": "51fe3d170227be8d1772214b82ae506e15ed78ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", - "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/51fe3d170227be8d1772214b82ae506e15ed78ff", + "reference": "51fe3d170227be8d1772214b82ae506e15ed78ff", "shasum": "" }, "require": { @@ -1638,13 +1662,14 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "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/config": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/error-handler": "^6.4|^7.0|^8.0", + "symfony/expression-language": "^6.4|^7.0|^8.0", + "symfony/framework-bundle": "^6.4|^7.0|^8.0", + "symfony/http-foundation": "^6.4|^7.0|^8.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^6.4|^7.0" + "symfony/stopwatch": "^6.4|^7.0|^8.0" }, "type": "library", "autoload": { @@ -1672,7 +1697,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/v7.2.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.4.14" }, "funding": [ { @@ -1683,25 +1708,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": "2024-09-25T14:21:43+00:00" + "time": "2026-06-06T11:10:32+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.1", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" + "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", - "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/c7de7a00ffb67842132da02ea92988a39ccd9f4e", + "reference": "c7de7a00ffb67842132da02ea92988a39ccd9f4e", "shasum": "" }, "require": { @@ -1715,7 +1744,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -1748,7 +1777,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.7.1" }, "funding": [ { @@ -1759,25 +1788,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": "2024-09-25T14:20:29+00:00" + "time": "2026-06-05T06:23:12+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.2.0", + "version": "v7.4.8", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" + "reference": "2888fcdc4dc2fd5f7c7397be78631e8af12e02b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", - "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/2888fcdc4dc2fd5f7c7397be78631e8af12e02b4", + "reference": "2888fcdc4dc2fd5f7c7397be78631e8af12e02b4", "shasum": "" }, "require": { @@ -1815,7 +1848,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.4.8" }, "funding": [ { @@ -1826,25 +1859,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": "2024-11-20T11:17:29+00:00" + "time": "2026-03-24T13:12:05+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.31.0", + "version": "v1.37.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", - "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", "shasum": "" }, "require": { @@ -1894,7 +1931,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" }, "funding": [ { @@ -1905,25 +1942,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": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.31.0", + "version": "v1.38.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" + "reference": "e9247d281d694a5120554d9afaf54e070e88a603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", - "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/e9247d281d694a5120554d9afaf54e070e88a603", + "reference": "e9247d281d694a5120554d9afaf54e070e88a603", "shasum": "" }, "require": { @@ -1972,7 +2013,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.38.1" }, "funding": [ { @@ -1983,25 +2024,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": "2024-09-09T11:45:10+00:00" + "time": "2026-05-26T05:58:03+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.31.0", + "version": "v1.38.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "3833d7255cc303546435cb650316bff708a1c75c" + "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", - "reference": "3833d7255cc303546435cb650316bff708a1c75c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/2d446c214bdbe5b71bde5011b060a05fece3ae6b", + "reference": "2d446c214bdbe5b71bde5011b060a05fece3ae6b", "shasum": "" }, "require": { @@ -2053,7 +2098,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.38.0" }, "funding": [ { @@ -2064,28 +2109,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": "2024-09-09T11:45:10+00:00" + "time": "2026-05-25T13:48:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.31.0", + "version": "v1.38.2", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", - "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", "shasum": "" }, "require": { + "ext-iconv": "*", "php": ">=7.2" }, "provide": { @@ -2133,7 +2183,91 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "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": "2026-05-27T06:59:30+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { @@ -2144,25 +2278,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": "2024-09-09T11:45:10+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.1", + "version": "v3.7.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" + "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", - "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0", + "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0", "shasum": "" }, "require": { @@ -2180,7 +2318,7 @@ "name": "symfony/contracts" }, "branch-alias": { - "dev-main": "3.5-dev" + "dev-main": "3.7-dev" } }, "autoload": { @@ -2216,7 +2354,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.1" }, "funding": [ { @@ -2227,44 +2365,47 @@ "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": "2024-09-25T14:20:29+00:00" + "time": "2026-06-16T09:55:08+00:00" }, { "name": "symfony/string", - "version": "v7.2.0", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" + "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", - "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", + "url": "https://api.github.com/repos/symfony/string/zipball/afd5944f4005862d961efb85c8bbd5c523c4e3c9", + "reference": "afd5944f4005862d961efb85c8bbd5c523c4e3c9", "shasum": "" }, "require": { - "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" + "php": ">=8.4.1", + "symfony/polyfill-ctype": "^1.8", + "symfony/polyfill-intl-grapheme": "^1.33", + "symfony/polyfill-intl-normalizer": "^1.0", + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/emoji": "^7.1", - "symfony/error-handler": "^6.4|^7.0", - "symfony/http-client": "^6.4|^7.0", - "symfony/intl": "^6.4|^7.0", + "symfony/emoji": "^7.4|^8.0", + "symfony/http-client": "^7.4|^8.0", + "symfony/intl": "^7.4|^8.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.4|^7.0" + "symfony/var-exporter": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -2303,7 +2444,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.2.0" + "source": "https://github.com/symfony/string/tree/v8.1.0" }, "funding": [ { @@ -2314,40 +2455,44 @@ "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": "2024-11-13T13:31:26+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.2.3", + "version": "v8.1.1", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "82b478c69745d8878eb60f9a049a4d584996f73a" + "reference": "40096a2515a979f3125c5c928603995b8664c62a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/82b478c69745d8878eb60f9a049a4d584996f73a", - "reference": "82b478c69745d8878eb60f9a049a4d584996f73a", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/40096a2515a979f3125c5c928603995b8664c62a", + "reference": "40096a2515a979f3125c5c928603995b8664c62a", "shasum": "" }, "require": { - "php": ">=8.2", - "symfony/polyfill-mbstring": "~1.0" + "php": ">=8.4.1", + "symfony/polyfill-mbstring": "^1.0" }, "conflict": { - "symfony/console": "<6.4" + "symfony/console": "<7.4", + "symfony/error-handler": "<7.4" }, "require-dev": { - "ext-iconv": "*", - "symfony/console": "^6.4|^7.0", - "symfony/http-kernel": "^6.4|^7.0", - "symfony/process": "^6.4|^7.0", - "symfony/uid": "^6.4|^7.0", + "symfony/console": "^7.4|^8.0", + "symfony/http-kernel": "^7.4|^8.0", + "symfony/process": "^7.4|^8.0", + "symfony/uid": "^7.4|^8.0", "twig/twig": "^3.12" }, "bin": [ @@ -2386,7 +2531,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.2.3" + "source": "https://github.com/symfony/var-dumper/tree/v8.1.1" }, "funding": [ { @@ -2397,12 +2542,16 @@ "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": "2025-01-17T11:39:41+00:00" + "time": "2026-06-09T10:54:51+00:00" } ], "packages-dev": [ @@ -2472,28 +2621,29 @@ }, { "name": "composer/pcre", - "version": "3.3.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" + "reference": "d5a341b3fb61f3001970940afb1d332968a183ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", - "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "url": "https://api.github.com/repos/composer/pcre/zipball/d5a341b3fb61f3001970940afb1d332968a183ed", + "reference": "d5a341b3fb61f3001970940afb1d332968a183ed", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, "conflict": { - "phpstan/phpstan": "<1.11.10" + "phpstan/phpstan": "<2.2.2" }, "require-dev": { - "phpstan/phpstan": "^1.12 || ^2", - "phpstan/phpstan-strict-rules": "^1 || ^2", - "phpunit/phpunit": "^8 || ^9" + "phpstan/phpstan": "^2", + "phpstan/phpstan-deprecation-rules": "^2", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "^9" }, "type": "library", "extra": { @@ -2531,7 +2681,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.3.2" + "source": "https://github.com/composer/pcre/tree/3.4.0" }, "funding": [ { @@ -2541,26 +2691,22 @@ { "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" + "time": "2026-06-07T11:47:49+00:00" }, { "name": "composer/semver", - "version": "3.4.3", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", - "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", "shasum": "" }, "require": { @@ -2612,7 +2758,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.3" + "source": "https://github.com/composer/semver/tree/3.4.4" }, "funding": [ { @@ -2622,13 +2768,9 @@ { "url": "https://github.com/composer", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" } ], - "time": "2024-09-19T14:15:21+00:00" + "time": "2025-08-20T19:15:30+00:00" }, { "name": "composer/xdebug-handler", @@ -2696,51 +2838,121 @@ ], "time": "2024-05-06T16:37:16+00:00" }, + { + "name": "ergebnis/agent-detector", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/ergebnis/agent-detector.git", + "reference": "e211f17928c8b95a51e06040792d57f5462fb271" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ergebnis/agent-detector/zipball/e211f17928c8b95a51e06040792d57f5462fb271", + "reference": "e211f17928c8b95a51e06040792d57f5462fb271", + "shasum": "" + }, + "require": { + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0" + }, + "require-dev": { + "ergebnis/composer-normalize": "^2.51.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.60.2", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.24.0", + "ergebnis/rector-rules": "^1.18.1", + "fakerphp/faker": "^1.24.1", + "infection/infection": "^0.26.6", + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^2.1.54", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.10", + "phpunit/phpunit": "^9.6.34", + "rector/rector": "^2.4.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.2-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, + "autoload": { + "psr-4": { + "Ergebnis\\AgentDetector\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Andreas Möller", + "email": "am@localheinz.com", + "homepage": "https://localheinz.com" + } + ], + "description": "Provides a detector for detecting the presence of an agent.", + "homepage": "https://github.com/ergebnis/agent-detector", + "support": { + "issues": "https://github.com/ergebnis/agent-detector/issues", + "security": "https://github.com/ergebnis/agent-detector/blob/main/.github/SECURITY.md", + "source": "https://github.com/ergebnis/agent-detector" + }, + "time": "2026-05-07T08:19:07+00:00" + }, { "name": "ergebnis/composer-normalize", - "version": "2.45.0", + "version": "2.52.0", "source": { "type": "git", "url": "https://github.com/ergebnis/composer-normalize.git", - "reference": "bb82b484bed2556da6311b9eff779fa7e73ce937" + "reference": "988f83f5e51a42cdd2337e5fcd935432f8dfa33c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/bb82b484bed2556da6311b9eff779fa7e73ce937", - "reference": "bb82b484bed2556da6311b9eff779fa7e73ce937", + "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/988f83f5e51a42cdd2337e5fcd935432f8dfa33c", + "reference": "988f83f5e51a42cdd2337e5fcd935432f8dfa33c", "shasum": "" }, "require": { "composer-plugin-api": "^2.0.0", "ergebnis/json": "^1.4.0", - "ergebnis/json-normalizer": "^4.8.0", + "ergebnis/json-normalizer": "^4.9.0", "ergebnis/json-printer": "^3.7.0", "ext-json": "*", "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", - "localheinz/diff": "^1.2.0", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "localheinz/diff": "^1.3.0", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "composer/composer": "^2.8.3", - "ergebnis/license": "^2.6.0", - "ergebnis/php-cs-fixer-config": "^6.39.0", - "ergebnis/phpunit-slow-test-detector": "^2.17.0", + "composer/composer": "^2.9.8", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.62.1", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.24.0", + "ergebnis/rector-rules": "^1.18.1", "fakerphp/faker": "^1.24.1", - "infection/infection": "~0.26.6", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.12", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.1", - "phpstan/phpstan-strict-rules": "^1.6.1", - "phpunit/phpunit": "^9.6.20", - "rector/rector": "^1.2.10", + "phpstan/phpstan": "^2.1.54", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.11", + "phpunit/phpunit": "^9.6.33", + "rector/rector": "^2.4.3", "symfony/filesystem": "^5.4.41" }, "type": "composer-plugin", "extra": { "class": "Ergebnis\\Composer\\Normalize\\NormalizePlugin", "branch-alias": { - "dev-main": "2.44-dev" + "dev-main": "2.52-dev" }, "plugin-optional": true, "composer-normalize": { @@ -2777,43 +2989,48 @@ "security": "https://github.com/ergebnis/composer-normalize/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/composer-normalize" }, - "time": "2024-12-04T18:36:37+00:00" + "time": "2026-05-15T15:39:24+00:00" }, { "name": "ergebnis/json", - "version": "1.4.0", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json.git", - "reference": "7656ac2aa6c2ca4408f96f599e9a17a22c464f69" + "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json/zipball/7656ac2aa6c2ca4408f96f599e9a17a22c464f69", - "reference": "7656ac2aa6c2ca4408f96f599e9a17a22c464f69", + "url": "https://api.github.com/repos/ergebnis/json/zipball/7b56d2b5d9e897e75b43e2e753075a0904c921b1", + "reference": "7b56d2b5d9e897e75b43e2e753075a0904c921b1", "shasum": "" }, "require": { "ext-json": "*", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { + "ergebnis/composer-normalize": "^2.44.0", "ergebnis/data-provider": "^3.3.0", "ergebnis/license": "^2.5.0", "ergebnis/php-cs-fixer-config": "^6.37.0", + "ergebnis/phpstan-rules": "^2.11.0", "ergebnis/phpunit-slow-test-detector": "^2.16.1", "fakerphp/faker": "^1.24.0", "infection/infection": "~0.26.6", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.10", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.0", - "phpstan/phpstan-strict-rules": "^1.6.1", - "phpunit/phpunit": "^9.6.18", - "rector/rector": "^1.2.10" + "phpstan/phpstan": "^2.1.22", + "phpstan/phpstan-deprecation-rules": "^2.0.3", + "phpstan/phpstan-phpunit": "^2.0.7", + "phpstan/phpstan-strict-rules": "^2.0.6", + "phpunit/phpunit": "^9.6.24", + "rector/rector": "^2.1.4" }, "type": "library", "extra": { + "branch-alias": { + "dev-main": "1.7-dev" + }, "composer-normalize": { "indent-size": 2, "indent-style": "space" @@ -2845,20 +3062,20 @@ "security": "https://github.com/ergebnis/json/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json" }, - "time": "2024-11-17T11:51:22+00:00" + "time": "2025-09-06T09:08:45+00:00" }, { "name": "ergebnis/json-normalizer", - "version": "4.8.0", + "version": "4.10.1", "source": { "type": "git", "url": "https://github.com/ergebnis/json-normalizer.git", - "reference": "e3a477b62808f377f4fc69a50f9eb66ec102747b" + "reference": "77961faf2c651c3f05977b53c6c68e8434febf62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-normalizer/zipball/e3a477b62808f377f4fc69a50f9eb66ec102747b", - "reference": "e3a477b62808f377f4fc69a50f9eb66ec102747b", + "url": "https://api.github.com/repos/ergebnis/json-normalizer/zipball/77961faf2c651c3f05977b53c6c68e8434febf62", + "reference": "77961faf2c651c3f05977b53c6c68e8434febf62", "shasum": "" }, "require": { @@ -2868,7 +3085,7 @@ "ergebnis/json-schema-validator": "^4.2.0", "ext-json": "*", "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { "composer/semver": "^3.4.3", @@ -2893,7 +3110,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.8-dev" + "dev-main": "4.11-dev" }, "composer-normalize": { "indent-size": 2, @@ -2927,45 +3144,47 @@ "security": "https://github.com/ergebnis/json-normalizer/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-normalizer" }, - "time": "2024-12-04T16:48:55+00:00" + "time": "2025-09-06T09:18:13+00:00" }, { "name": "ergebnis/json-pointer", - "version": "3.6.0", + "version": "3.8.0", "source": { "type": "git", "url": "https://github.com/ergebnis/json-pointer.git", - "reference": "4fc85d8edb74466d282119d8d9541ec7cffc0798" + "reference": "b58c3c468a7ff109fdf9a255f17de29ecbe5276c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-pointer/zipball/4fc85d8edb74466d282119d8d9541ec7cffc0798", - "reference": "4fc85d8edb74466d282119d8d9541ec7cffc0798", + "url": "https://api.github.com/repos/ergebnis/json-pointer/zipball/b58c3c468a7ff109fdf9a255f17de29ecbe5276c", + "reference": "b58c3c468a7ff109fdf9a255f17de29ecbe5276c", "shasum": "" }, "require": { - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.43.0", - "ergebnis/data-provider": "^3.2.0", - "ergebnis/license": "^2.4.0", - "ergebnis/php-cs-fixer-config": "^6.32.0", - "ergebnis/phpunit-slow-test-detector": "^2.15.0", - "fakerphp/faker": "^1.23.1", + "ergebnis/composer-normalize": "^2.50.0", + "ergebnis/data-provider": "^3.6.0", + "ergebnis/license": "^2.7.0", + "ergebnis/php-cs-fixer-config": "^6.60.2", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.24.0", + "ergebnis/rector-rules": "^1.16.0", + "fakerphp/faker": "^1.24.1", "infection/infection": "~0.26.6", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^1.12.10", - "phpstan/phpstan-deprecation-rules": "^1.2.1", - "phpstan/phpstan-phpunit": "^1.4.0", - "phpstan/phpstan-strict-rules": "^1.6.1", - "phpunit/phpunit": "^9.6.19", - "rector/rector": "^1.2.10" + "phpstan/phpstan": "^2.1.46", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.10", + "phpunit/phpunit": "^9.6.34", + "rector/rector": "^2.4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.6-dev" + "dev-main": "3.8-dev" }, "composer-normalize": { "indent-size": 2, @@ -3000,28 +3219,29 @@ "security": "https://github.com/ergebnis/json-pointer/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-pointer" }, - "time": "2024-11-17T12:37:06+00:00" + "time": "2026-04-07T14:52:13+00:00" }, { "name": "ergebnis/json-printer", - "version": "3.7.0", + "version": "3.8.1", "source": { "type": "git", "url": "https://github.com/ergebnis/json-printer.git", - "reference": "ced41fce7854152f0e8f38793c2ffe59513cdd82" + "reference": "211d73fc7ec6daf98568ee6ed6e6d133dee8503e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-printer/zipball/ced41fce7854152f0e8f38793c2ffe59513cdd82", - "reference": "ced41fce7854152f0e8f38793c2ffe59513cdd82", + "url": "https://api.github.com/repos/ergebnis/json-printer/zipball/211d73fc7ec6daf98568ee6ed6e6d133dee8503e", + "reference": "211d73fc7ec6daf98568ee6ed6e6d133dee8503e", "shasum": "" }, "require": { "ext-json": "*", "ext-mbstring": "*", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { + "ergebnis/composer-normalize": "^2.44.0", "ergebnis/data-provider": "^3.3.0", "ergebnis/license": "^2.5.0", "ergebnis/php-cs-fixer-config": "^6.37.0", @@ -3037,6 +3257,15 @@ "rector/rector": "^1.2.10" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.9-dev" + }, + "composer-normalize": { + "indent-size": 2, + "indent-style": "space" + } + }, "autoload": { "psr-4": { "Ergebnis\\Json\\Printer\\": "src/" @@ -3065,20 +3294,20 @@ "security": "https://github.com/ergebnis/json-printer/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-printer" }, - "time": "2024-11-17T11:20:51+00:00" + "time": "2025-09-06T09:59:26+00:00" }, { "name": "ergebnis/json-schema-validator", - "version": "4.4.0", + "version": "4.5.1", "source": { "type": "git", "url": "https://github.com/ergebnis/json-schema-validator.git", - "reference": "85f90c81f718aebba1d738800af83eeb447dc7ec" + "reference": "b739527a480a9e3651360ad351ea77e7e9019df2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/json-schema-validator/zipball/85f90c81f718aebba1d738800af83eeb447dc7ec", - "reference": "85f90c81f718aebba1d738800af83eeb447dc7ec", + "url": "https://api.github.com/repos/ergebnis/json-schema-validator/zipball/b739527a480a9e3651360ad351ea77e7e9019df2", + "reference": "b739527a480a9e3651360ad351ea77e7e9019df2", "shasum": "" }, "require": { @@ -3086,7 +3315,7 @@ "ergebnis/json-pointer": "^3.4.0", "ext-json": "*", "justinrainbow/json-schema": "^5.2.12 || ^6.0.0", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { "ergebnis/composer-normalize": "^2.44.0", @@ -3107,7 +3336,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.4-dev" + "dev-main": "4.6-dev" }, "composer-normalize": { "indent-size": 2, @@ -3142,44 +3371,44 @@ "security": "https://github.com/ergebnis/json-schema-validator/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/json-schema-validator" }, - "time": "2024-11-18T06:32:28+00:00" + "time": "2025-09-06T11:37:35+00:00" }, { "name": "ergebnis/php-cs-fixer-config", - "version": "6.45.0", + "version": "6.62.2", "source": { "type": "git", "url": "https://github.com/ergebnis/php-cs-fixer-config.git", - "reference": "8f0ef2548422a0fd5a0fa80d02b5075192532a86" + "reference": "dc36d086819708e62190745418aca12a487ca81a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/php-cs-fixer-config/zipball/8f0ef2548422a0fd5a0fa80d02b5075192532a86", - "reference": "8f0ef2548422a0fd5a0fa80d02b5075192532a86", + "url": "https://api.github.com/repos/ergebnis/php-cs-fixer-config/zipball/dc36d086819708e62190745418aca12a487ca81a", + "reference": "dc36d086819708e62190745418aca12a487ca81a", "shasum": "" }, "require": { - "erickskrauch/php-cs-fixer-custom-fixers": "~1.3.0", + "erickskrauch/php-cs-fixer-custom-fixers": "~1.3.1", "ext-filter": "*", - "friendsofphp/php-cs-fixer": "~3.71.0", - "kubawerlos/php-cs-fixer-custom-fixers": "~3.23.0", - "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "friendsofphp/php-cs-fixer": "~3.95.5", + "kubawerlos/php-cs-fixer-custom-fixers": "~3.37.2", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.45.0", - "ergebnis/data-provider": "^3.4.0", - "ergebnis/license": "^2.6.0", - "ergebnis/phpstan-rules": "^2.8.0", - "ergebnis/phpunit-slow-test-detector": "^2.19.0", - "ergebnis/rector-rules": "^1.3.0", + "ergebnis/composer-normalize": "^2.52.0", + "ergebnis/data-provider": "^3.6.0", + "ergebnis/license": "^2.7.0", + "ergebnis/phpstan-rules": "^2.13.1", + "ergebnis/phpunit-slow-test-detector": "^2.24.0", + "ergebnis/rector-rules": "^1.18.1", "fakerphp/faker": "^1.24.1", "phpstan/extension-installer": "^1.4.3", - "phpstan/phpstan": "^2.1.7", - "phpstan/phpstan-deprecation-rules": "^2.0.1", - "phpstan/phpstan-phpunit": "^2.0.4", - "phpstan/phpstan-strict-rules": "^2.0.3", - "phpunit/phpunit": "^9.6.22", - "rector/rector": "^2.0.10", + "phpstan/phpstan": "^2.2.2", + "phpstan/phpstan-deprecation-rules": "^2.0.4", + "phpstan/phpstan-phpunit": "^2.0.16", + "phpstan/phpstan-strict-rules": "^2.0.11", + "phpunit/phpunit": "^9.6.33", + "rector/rector": "^2.4.5", "symfony/filesystem": "^5.0.0 || ^6.0.0", "symfony/process": "^5.0.0 || ^6.0.0" }, @@ -3213,20 +3442,20 @@ "security": "https://github.com/ergebnis/php-cs-fixer-config/blob/main/.github/SECURITY.md", "source": "https://github.com/ergebnis/php-cs-fixer-config" }, - "time": "2025-03-08T08:34:05+00:00" + "time": "2026-06-18T08:22:00+00:00" }, { "name": "erickskrauch/php-cs-fixer-custom-fixers", - "version": "1.3.0", + "version": "1.3.1", "source": { "type": "git", "url": "https://github.com/erickskrauch/php-cs-fixer-custom-fixers.git", - "reference": "36fb7f8204c1e17d9b8a24910e2147d0a3973b9c" + "reference": "8c54170266d7a98610f43f8223b3ac653043821a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/erickskrauch/php-cs-fixer-custom-fixers/zipball/36fb7f8204c1e17d9b8a24910e2147d0a3973b9c", - "reference": "36fb7f8204c1e17d9b8a24910e2147d0a3973b9c", + "url": "https://api.github.com/repos/erickskrauch/php-cs-fixer-custom-fixers/zipball/8c54170266d7a98610f43f8223b3ac653043821a", + "reference": "8c54170266d7a98610f43f8223b3ac653043821a", "shasum": "" }, "require": { @@ -3278,9 +3507,9 @@ ], "support": { "issues": "https://github.com/erickskrauch/php-cs-fixer-custom-fixers/issues", - "source": "https://github.com/erickskrauch/php-cs-fixer-custom-fixers/tree/1.3.0" + "source": "https://github.com/erickskrauch/php-cs-fixer-custom-fixers/tree/1.3.1" }, - "time": "2024-06-21T20:19:52+00:00" + "time": "2025-11-24T16:54:01+00:00" }, { "name": "evenement/evenement", @@ -3331,16 +3560,16 @@ }, { "name": "fidry/cpu-core-counter", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "8520451a140d3f46ac33042715115e290cf5785f" + "reference": "db9508f7b1474469d9d3c53b86f817e344732678" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", - "reference": "8520451a140d3f46ac33042715115e290cf5785f", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/db9508f7b1474469d9d3c53b86f817e344732678", + "reference": "db9508f7b1474469d9d3c53b86f817e344732678", "shasum": "" }, "require": { @@ -3350,10 +3579,10 @@ "fidry/makefile": "^0.2.0", "fidry/php-cs-fixer-config": "^1.1.2", "phpstan/extension-installer": "^1.2.0", - "phpstan/phpstan": "^1.9.2", - "phpstan/phpstan-deprecation-rules": "^1.0.0", - "phpstan/phpstan-phpunit": "^1.2.2", - "phpstan/phpstan-strict-rules": "^1.4.4", + "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" }, @@ -3380,7 +3609,7 @@ ], "support": { "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.3.0" }, "funding": [ { @@ -3388,61 +3617,63 @@ "type": "github" } ], - "time": "2024-08-06T10:04:20+00:00" + "time": "2025-08-14T07:29:31+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.71.0", + "version": "v3.95.11", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "3825ffdc69501e1c9230291b79f036a0c0d8749d" + "reference": "35f98e1293283397824d7f349ce5afb8747c3cd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/3825ffdc69501e1c9230291b79f036a0c0d8749d", - "reference": "3825ffdc69501e1c9230291b79f036a0c0d8749d", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/35f98e1293283397824d7f349ce5afb8747c3cd5", + "reference": "35f98e1293283397824d7f349ce5afb8747c3cd5", "shasum": "" }, "require": { - "clue/ndjson-react": "^1.0", + "clue/ndjson-react": "^1.3", "composer/semver": "^3.4", - "composer/xdebug-handler": "^3.0.3", + "composer/xdebug-handler": "^3.0.5", + "ergebnis/agent-detector": "^1.2", "ext-filter": "*", + "ext-hash": "*", "ext-json": "*", "ext-tokenizer": "*", - "fidry/cpu-core-counter": "^1.2", + "fidry/cpu-core-counter": "^1.3", "php": "^7.4 || ^8.0", - "react/child-process": "^0.6.5", - "react/event-loop": "^1.0", - "react/promise": "^2.0 || ^3.0", - "react/socket": "^1.0", - "react/stream": "^1.0", - "sebastian/diff": "^4.0 || ^5.1 || ^6.0 || ^7.0", - "symfony/console": "^5.4 || ^6.4 || ^7.0", - "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", - "symfony/finder": "^5.4 || ^6.4 || ^7.0", - "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", - "symfony/polyfill-mbstring": "^1.31", - "symfony/polyfill-php80": "^1.31", - "symfony/polyfill-php81": "^1.31", - "symfony/process": "^5.4 || ^6.4 || ^7.2", - "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" + "react/child-process": "^0.6.6", + "react/event-loop": "^1.5", + "react/socket": "^1.16", + "react/stream": "^1.4", + "sebastian/diff": "^4.0.6 || ^5.1.1 || ^6.0.2 || ^7.0 || ^8.0 || ^9.0", + "symfony/console": "^5.4.47 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/event-dispatcher": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/filesystem": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/finder": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/options-resolver": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0", + "symfony/polyfill-mbstring": "^1.37", + "symfony/polyfill-php80": "^1.37", + "symfony/polyfill-php81": "^1.37", + "symfony/polyfill-php84": "^1.37", + "symfony/process": "^5.4.47 || ^6.4.24 || ^7.2 || ^8.0", + "symfony/stopwatch": "^5.4.45 || ^6.4.24 || ^7.0 || ^8.0" }, "require-dev": { - "facile-it/paraunit": "^1.3.1 || ^2.5", - "infection/infection": "^0.29.10", - "justinrainbow/json-schema": "^5.3 || ^6.0", - "keradus/cli-executor": "^2.1", + "facile-it/paraunit": "^1.3.1 || ^2.11.0", + "infection/infection": "^0.32.7", + "justinrainbow/json-schema": "^6.10.0", + "keradus/cli-executor": "^2.3", "mikey179/vfsstream": "^1.6.12", - "php-coveralls/php-coveralls": "^2.7", - "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.6", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.6", - "phpunit/phpunit": "^9.6.22 || ^10.5.45 || ^11.5.7", - "symfony/var-dumper": "^5.4.48 || ^6.4.18 || ^7.2.0", - "symfony/yaml": "^5.4.45 || ^6.4.18 || ^7.2.0" + "php-coveralls/php-coveralls": "^2.9.1", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.8", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.8", + "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.55", + "symfony/polyfill-php85": "^1.38", + "symfony/var-dumper": "^5.4.48 || ^6.4.36 || ^7.4.8 || ^8.1.0", + "symfony/yaml": "^5.4.53 || ^6.4.41 || ^7.4.13 || ^8.1.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -3457,7 +3688,7 @@ "PhpCsFixer\\": "src/" }, "exclude-from-classmap": [ - "src/Fixer/Internal/*" + "src/**/Internal/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -3483,7 +3714,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.71.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.95.11" }, "funding": [ { @@ -3491,20 +3722,20 @@ "type": "github" } ], - "time": "2025-03-07T23:06:56+00:00" + "time": "2026-06-25T14:17:04+00:00" }, { "name": "http-interop/http-factory-guzzle", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/http-interop/http-factory-guzzle.git", - "reference": "8f06e92b95405216b237521cc64c804dd44c4a81" + "reference": "c2c859ceb05c3f42e710b60555f4c35b6a4a3995" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/8f06e92b95405216b237521cc64c804dd44c4a81", - "reference": "8f06e92b95405216b237521cc64c804dd44c4a81", + "url": "https://api.github.com/repos/http-interop/http-factory-guzzle/zipball/c2c859ceb05c3f42e710b60555f4c35b6a4a3995", + "reference": "c2c859ceb05c3f42e710b60555f4c35b6a4a3995", "shasum": "" }, "require": { @@ -3547,32 +3778,32 @@ ], "support": { "issues": "https://github.com/http-interop/http-factory-guzzle/issues", - "source": "https://github.com/http-interop/http-factory-guzzle/tree/1.2.0" + "source": "https://github.com/http-interop/http-factory-guzzle/tree/1.2.1" }, - "time": "2021-07-21T13:50:14+00:00" + "time": "2025-12-15T11:28:16+00:00" }, { "name": "justinrainbow/json-schema", - "version": "6.4.1", + "version": "6.10.0", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "35d262c94959571e8736db1e5c9bc36ab94ae900" + "reference": "8b1308a9d7bdbdb20ce87ef920f82b4564bb2d33" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/35d262c94959571e8736db1e5c9bc36ab94ae900", - "reference": "35d262c94959571e8736db1e5c9bc36ab94ae900", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/8b1308a9d7bdbdb20ce87ef920f82b4564bb2d33", + "reference": "8b1308a9d7bdbdb20ce87ef920f82b4564bb2d33", "shasum": "" }, "require": { "ext-json": "*", - "marc-mabe/php-enum": "^4.0", + "marc-mabe/php-enum": "^4.4", "php": "^7.2 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "3.3.0", - "json-schema/json-schema-test-suite": "1.2.0", + "json-schema/json-schema-test-suite": "dev-main", "marc-mabe/php-enum-phpstan": "^2.0", "phpspec/prophecy": "^1.19", "phpstan/phpstan": "^1.12", @@ -3622,32 +3853,32 @@ ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/6.4.1" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.10.0" }, - "time": "2025-04-04T13:08:07+00:00" + "time": "2026-06-16T20:50:26+00:00" }, { "name": "kubawerlos/php-cs-fixer-custom-fixers", - "version": "v3.23.0", + "version": "v3.37.2", "source": { "type": "git", "url": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers.git", - "reference": "b3210c6e546bdfc95664297a8971ae3b6b1f4a5a" + "reference": "678df979ce743466b42ddb6eea46b3f4c9a7bade" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/kubawerlos/php-cs-fixer-custom-fixers/zipball/b3210c6e546bdfc95664297a8971ae3b6b1f4a5a", - "reference": "b3210c6e546bdfc95664297a8971ae3b6b1f4a5a", + "url": "https://api.github.com/repos/kubawerlos/php-cs-fixer-custom-fixers/zipball/678df979ce743466b42ddb6eea46b3f4c9a7bade", + "reference": "678df979ce743466b42ddb6eea46b3f4c9a7bade", "shasum": "" }, "require": { "ext-filter": "*", "ext-tokenizer": "*", - "friendsofphp/php-cs-fixer": "^3.61.1", + "friendsofphp/php-cs-fixer": "^3.87", "php": "^7.4 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^9.6.4 || ^10.5.29" + "phpunit/phpunit": "^9.6.34 || ^10.5.63 || ^11.5.55" }, "type": "library", "autoload": { @@ -3668,26 +3899,32 @@ "description": "A set of custom fixers for PHP CS Fixer", "support": { "issues": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/issues", - "source": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/tree/v3.23.0" + "source": "https://github.com/kubawerlos/php-cs-fixer-custom-fixers/tree/v3.37.2" }, - "time": "2025-02-15T09:15:56+00:00" + "funding": [ + { + "url": "https://github.com/kubawerlos", + "type": "github" + } + ], + "time": "2026-05-12T16:22:19+00:00" }, { "name": "localheinz/diff", - "version": "1.2.0", + "version": "1.3.0", "source": { "type": "git", "url": "https://github.com/localheinz/diff.git", - "reference": "ec413943c2b518464865673fd5b38f7df867a010" + "reference": "33bd840935970cda6691c23fc7d94ae764c0734c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/localheinz/diff/zipball/ec413943c2b518464865673fd5b38f7df867a010", - "reference": "ec413943c2b518464865673fd5b38f7df867a010", + "url": "https://api.github.com/repos/localheinz/diff/zipball/33bd840935970cda6691c23fc7d94ae764c0734c", + "reference": "33bd840935970cda6691c23fc7d94ae764c0734c", "shasum": "" }, "require": { - "php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0" }, "require-dev": { "phpunit/phpunit": "^7.5.0 || ^8.5.23", @@ -3723,22 +3960,22 @@ ], "support": { "issues": "https://github.com/localheinz/diff/issues", - "source": "https://github.com/localheinz/diff/tree/1.2.0" + "source": "https://github.com/localheinz/diff/tree/1.3.0" }, - "time": "2024-12-04T14:16:01+00:00" + "time": "2025-08-30T09:44:18+00:00" }, { "name": "marc-mabe/php-enum", - "version": "v4.7.1", + "version": "v4.7.2", "source": { "type": "git", "url": "https://github.com/marc-mabe/php-enum.git", - "reference": "7159809e5cfa041dca28e61f7f7ae58063aae8ed" + "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/7159809e5cfa041dca28e61f7f7ae58063aae8ed", - "reference": "7159809e5cfa041dca28e61f7f7ae58063aae8ed", + "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/bb426fcdd65c60fb3638ef741e8782508fda7eef", + "reference": "bb426fcdd65c60fb3638ef741e8782508fda7eef", "shasum": "" }, "require": { @@ -3796,22 +4033,22 @@ ], "support": { "issues": "https://github.com/marc-mabe/php-enum/issues", - "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.1" + "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.2" }, - "time": "2024-11-28T04:54:44+00:00" + "time": "2025-09-14T11:18:39+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.13.0", + "version": "1.13.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414" + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/024473a478be9df5fdaca2c793f2232fe788e414", - "reference": "024473a478be9df5fdaca2c793f2232fe788e414", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { @@ -3850,7 +4087,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.13.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" }, "funding": [ { @@ -3858,7 +4095,7 @@ "type": "tidelift" } ], - "time": "2025-02-12T12:17:51+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { "name": "nikic/fast-route", @@ -4030,16 +4267,11 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.11", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan.git", - "reference": "8ca5f79a8f63c49b2359065832a654e1ec70ac30" - }, + "version": "2.2.2", "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8ca5f79a8f63c49b2359065832a654e1ec70ac30", - "reference": "8ca5f79a8f63c49b2359065832a654e1ec70ac30", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/e5cc34d491a90e79c216d824f60fe21fd4d93bd6", + "reference": "e5cc34d491a90e79c216d824f60fe21fd4d93bd6", "shasum": "" }, "require": { @@ -4062,6 +4294,17 @@ "license": [ "MIT" ], + "authors": [ + { + "name": "Ondřej Mirtes" + }, + { + "name": "Markus Staab" + }, + { + "name": "Vincent Langlet" + } + ], "description": "PHPStan - PHP Static Analysis Tool", "keywords": [ "dev", @@ -4084,39 +4327,37 @@ "type": "github" } ], - "time": "2025-03-24T13:45:00+00:00" + "time": "2026-06-05T09:00:01+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "10.1.16", + "version": "12.5.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77" + "reference": "186dab580576598076de6818596d12b61801880e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e308268858ed6baedc8704a304727d20bc07c77", - "reference": "7e308268858ed6baedc8704a304727d20bc07c77", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/186dab580576598076de6818596d12b61801880e", + "reference": "186dab580576598076de6818596d12b61801880e", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.19.1 || ^5.1.0", - "php": ">=8.1", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-text-template": "^3.0.1", - "sebastian/code-unit-reverse-lookup": "^3.0.0", - "sebastian/complexity": "^3.2.0", - "sebastian/environment": "^6.1.0", - "sebastian/lines-of-code": "^2.0.2", - "sebastian/version": "^4.0.1", - "theseer/tokenizer": "^1.2.3" + "nikic/php-parser": "^5.7.0", + "php": ">=8.3", + "phpunit/php-text-template": "^5.0", + "sebastian/complexity": "^5.0", + "sebastian/environment": "^8.1.2", + "sebastian/lines-of-code": "^4.0.1", + "sebastian/version": "^6.0", + "theseer/tokenizer": "^2.0.1" }, "require-dev": { - "phpunit/phpunit": "^10.1" + "phpunit/phpunit": "^12.5.28" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -4125,7 +4366,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.1.x-dev" + "dev-main": "12.5.x-dev" } }, "autoload": { @@ -4154,40 +4395,52 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/10.1.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/12.5.7" }, "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": "2024-08-22T04:31:57+00:00" + "time": "2026-06-01T13:24:19+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "4.1.0", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c" + "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/a95037b6d9e608ba092da1b23931e537cadc3c3c", - "reference": "a95037b6d9e608ba092da1b23931e537cadc3c3c", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5", + "reference": "3d1cd096ef6bea4bf2762ba586e35dbd317cbfd5", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -4215,36 +4468,48 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/4.1.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/6.0.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/phpunit/php-file-iterator", + "type": "tidelift" } ], - "time": "2023-08-31T06:24:48+00:00" + "time": "2026-02-02T14:04:18+00:00" }, { "name": "phpunit/php-invoker", - "version": "4.0.0", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7" + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", - "reference": "f5e568ba02fa5ba0ddd0f618391d5a9ea50b06d7", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/12b54e689b07a25a9b41e57736dfab6ec9ae5406", + "reference": "12b54e689b07a25a9b41e57736dfab6ec9ae5406", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "suggest": { "ext-pcntl": "*" @@ -4252,7 +4517,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -4278,7 +4543,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/6.0.0" }, "funding": [ { @@ -4286,32 +4552,32 @@ "type": "github" } ], - "time": "2023-02-03T06:56:09+00:00" + "time": "2025-02-07T04:58:58+00:00" }, { "name": "phpunit/php-text-template", - "version": "3.0.1", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748" + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/0c7b06ff49e3d5072f057eb1fa59258bf287a748", - "reference": "0c7b06ff49e3d5072f057eb1fa59258bf287a748", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/e1367a453f0eda562eedb4f659e13aa900d66c53", + "reference": "e1367a453f0eda562eedb4f659e13aa900d66c53", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -4338,7 +4604,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/3.0.1" + "source": "https://github.com/sebastianbergmann/php-text-template/tree/5.0.0" }, "funding": [ { @@ -4346,32 +4612,32 @@ "type": "github" } ], - "time": "2023-08-31T14:07:24+00:00" + "time": "2025-02-07T04:59:16+00:00" }, { "name": "phpunit/php-timer", - "version": "6.0.0", + "version": "8.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d" + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/e2a2d67966e740530f4a3343fe2e030ffdc1161d", - "reference": "e2a2d67966e740530f4a3343fe2e030ffdc1161d", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", + "reference": "f258ce36aa457f3aa3339f9ed4c81fc66dc8c2cc", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -4397,7 +4663,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/6.0.0" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/8.0.0" }, "funding": [ { @@ -4405,20 +4672,20 @@ "type": "github" } ], - "time": "2023-02-03T06:57:52+00:00" + "time": "2025-02-07T04:59:38+00:00" }, { "name": "phpunit/phpunit", - "version": "10.5.45", + "version": "12.5.30", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8" + "reference": "900400a5b616d6fb306f9549f6da33ba615d3fbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/bd68a781d8e30348bc297449f5234b3458267ae8", - "reference": "bd68a781d8e30348bc297449f5234b3458267ae8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/900400a5b616d6fb306f9549f6da33ba615d3fbb", + "reference": "900400a5b616d6fb306f9549f6da33ba615d3fbb", "shasum": "" }, "require": { @@ -4428,29 +4695,26 @@ "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.12.1", + "myclabs/deep-copy": "^1.13.4", "phar-io/manifest": "^2.0.4", "phar-io/version": "^3.2.1", - "php": ">=8.1", - "phpunit/php-code-coverage": "^10.1.16", - "phpunit/php-file-iterator": "^4.1.0", - "phpunit/php-invoker": "^4.0.0", - "phpunit/php-text-template": "^3.0.1", - "phpunit/php-timer": "^6.0.0", - "sebastian/cli-parser": "^2.0.1", - "sebastian/code-unit": "^2.0.0", - "sebastian/comparator": "^5.0.3", - "sebastian/diff": "^5.1.1", - "sebastian/environment": "^6.1.0", - "sebastian/exporter": "^5.1.2", - "sebastian/global-state": "^6.0.2", - "sebastian/object-enumerator": "^5.0.0", - "sebastian/recursion-context": "^5.0.0", - "sebastian/type": "^4.0.0", - "sebastian/version": "^4.0.1" - }, - "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" + "php": ">=8.3", + "phpunit/php-code-coverage": "^12.5.7", + "phpunit/php-file-iterator": "^6.0.1", + "phpunit/php-invoker": "^6.0.0", + "phpunit/php-text-template": "^5.0.0", + "phpunit/php-timer": "^8.0.0", + "sebastian/cli-parser": "^4.2.1", + "sebastian/comparator": "^7.1.8", + "sebastian/diff": "^7.0.0", + "sebastian/environment": "^8.1.2", + "sebastian/exporter": "^7.0.3", + "sebastian/global-state": "^8.0.3", + "sebastian/object-enumerator": "^7.0.0", + "sebastian/recursion-context": "^7.0.1", + "sebastian/type": "^6.0.4", + "sebastian/version": "^6.0.0", + "staabm/side-effects-detector": "^1.0.5" }, "bin": [ "phpunit" @@ -4458,7 +4722,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "10.5-dev" + "dev-main": "12.5-dev" } }, "autoload": { @@ -4490,23 +4754,15 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/10.5.45" + "source": "https://github.com/sebastianbergmann/phpunit/tree/12.5.30" }, "funding": [ { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" + "url": "https://phpunit.de/sponsoring.html", + "type": "other" } ], - "time": "2025-02-06T16:08:12+00:00" + "time": "2026-06-15T13:12:30+00:00" }, { "name": "psr/http-server-handler", @@ -4695,16 +4951,16 @@ }, { "name": "react/child-process", - "version": "v0.6.6", + "version": "v0.6.7", "source": { "type": "git", "url": "https://github.com/reactphp/child-process.git", - "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", - "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/970f0e71945556422ee4570ccbabaedc3cf04ad3", + "reference": "970f0e71945556422ee4570ccbabaedc3cf04ad3", "shasum": "" }, "require": { @@ -4758,7 +5014,7 @@ ], "support": { "issues": "https://github.com/reactphp/child-process/issues", - "source": "https://github.com/reactphp/child-process/tree/v0.6.6" + "source": "https://github.com/reactphp/child-process/tree/v0.6.7" }, "funding": [ { @@ -4766,20 +5022,20 @@ "type": "open_collective" } ], - "time": "2025-01-01T16:37:48+00:00" + "time": "2025-12-23T15:25:20+00:00" }, { "name": "react/dns", - "version": "v1.13.0", + "version": "v1.14.0", "source": { "type": "git", "url": "https://github.com/reactphp/dns.git", - "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", - "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "url": "https://api.github.com/repos/reactphp/dns/zipball/7562c05391f42701c1fccf189c8225fece1cd7c3", + "reference": "7562c05391f42701c1fccf189c8225fece1cd7c3", "shasum": "" }, "require": { @@ -4834,7 +5090,7 @@ ], "support": { "issues": "https://github.com/reactphp/dns/issues", - "source": "https://github.com/reactphp/dns/tree/v1.13.0" + "source": "https://github.com/reactphp/dns/tree/v1.14.0" }, "funding": [ { @@ -4842,20 +5098,20 @@ "type": "open_collective" } ], - "time": "2024-06-13T14:18:03+00:00" + "time": "2025-11-18T19:34:28+00:00" }, { "name": "react/event-loop", - "version": "v1.5.0", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/reactphp/event-loop.git", - "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", - "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/ba276bda6083df7e0050fd9b33f66ad7a4ac747a", + "reference": "ba276bda6083df7e0050fd9b33f66ad7a4ac747a", "shasum": "" }, "require": { @@ -4906,7 +5162,7 @@ ], "support": { "issues": "https://github.com/reactphp/event-loop/issues", - "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + "source": "https://github.com/reactphp/event-loop/tree/v1.6.0" }, "funding": [ { @@ -4914,27 +5170,27 @@ "type": "open_collective" } ], - "time": "2023-11-13T13:48:05+00:00" + "time": "2025-11-17T20:46:25+00:00" }, { "name": "react/promise", - "version": "v3.2.0", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/reactphp/promise.git", - "reference": "8a164643313c71354582dc850b42b33fa12a4b63" + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", - "reference": "8a164643313c71354582dc850b42b33fa12a4b63", + "url": "https://api.github.com/repos/reactphp/promise/zipball/23444f53a813a3296c1368bb104793ce8d88f04a", + "reference": "23444f53a813a3296c1368bb104793ce8d88f04a", "shasum": "" }, "require": { "php": ">=7.1.0" }, "require-dev": { - "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpstan/phpstan": "1.12.28 || 1.4.10", "phpunit/phpunit": "^9.6 || ^7.5" }, "type": "library", @@ -4979,7 +5235,7 @@ ], "support": { "issues": "https://github.com/reactphp/promise/issues", - "source": "https://github.com/reactphp/promise/tree/v3.2.0" + "source": "https://github.com/reactphp/promise/tree/v3.3.0" }, "funding": [ { @@ -4987,20 +5243,20 @@ "type": "open_collective" } ], - "time": "2024-05-24T10:39:05+00:00" + "time": "2025-08-19T18:57:03+00:00" }, { "name": "react/socket", - "version": "v1.16.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/reactphp/socket.git", - "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", - "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "url": "https://api.github.com/repos/reactphp/socket/zipball/ef5b17b81f6f60504c539313f94f2d826c5faa08", + "reference": "ef5b17b81f6f60504c539313f94f2d826c5faa08", "shasum": "" }, "require": { @@ -5059,7 +5315,7 @@ ], "support": { "issues": "https://github.com/reactphp/socket/issues", - "source": "https://github.com/reactphp/socket/tree/v1.16.0" + "source": "https://github.com/reactphp/socket/tree/v1.17.0" }, "funding": [ { @@ -5067,7 +5323,7 @@ "type": "open_collective" } ], - "time": "2024-07-26T10:38:09+00:00" + "time": "2025-11-19T20:47:34+00:00" }, { "name": "react/stream", @@ -5153,42 +5409,53 @@ "source": { "type": "git", "url": "https://github.com/Roave/SecurityAdvisories.git", - "reference": "3a9fedb6eaaa962e76b776b9de7c5fc7f1c432df" + "reference": "36ba91e82e1b493faef2c13277d6bd2669ea9f31" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/3a9fedb6eaaa962e76b776b9de7c5fc7f1c432df", - "reference": "3a9fedb6eaaa962e76b776b9de7c5fc7f1c432df", + "url": "https://api.github.com/repos/Roave/SecurityAdvisories/zipball/36ba91e82e1b493faef2c13277d6bd2669ea9f31", + "reference": "36ba91e82e1b493faef2c13277d6bd2669ea9f31", "shasum": "" }, "conflict": { "3f/pygmentize": "<1.2", - "admidio/admidio": "<4.3.12", - "adodb/adodb-php": "<=5.20.20|>=5.21,<=5.21.3", + "adaptcms/adaptcms": "<=1.3", + "admidio/admidio": "<=5.0.9", + "adodb/adodb-php": "<=5.22.9", "aheinze/cockpit": "<2.2", "aimeos/ai-admin-graphql": ">=2022.04.1,<2022.10.10|>=2023.04.1,<2023.10.6|>=2024.04.1,<2024.07.2", "aimeos/ai-admin-jsonadm": "<2020.10.13|>=2021.04.1,<2021.10.6|>=2022.04.1,<2022.10.3|>=2023.04.1,<2023.10.4|==2024.04.1", "aimeos/ai-client-html": ">=2020.04.1,<2020.10.27|>=2021.04.1,<2021.10.22|>=2022.04.1,<2022.10.13|>=2023.04.1,<2023.10.15|>=2024.04.1,<2024.04.7", + "aimeos/ai-cms-grapesjs": ">=2021.04.1,<2021.10.8|>=2022.04.1,<2022.10.9|>=2023.04.1,<2023.10.15|>=2024.04.1,<2024.10.8|>=2025.04.1,<2025.10.2", "aimeos/ai-controller-frontend": "<2020.10.15|>=2021.04.1,<2021.10.8|>=2022.04.1,<2022.10.8|>=2023.04.1,<2023.10.9|==2024.04.1", "aimeos/aimeos-core": ">=2022.04.1,<2022.10.17|>=2023.04.1,<2023.10.17|>=2024.04.1,<2024.04.7", + "aimeos/aimeos-laravel": "==2021.10", "aimeos/aimeos-typo3": "<19.10.12|>=20,<20.10.5", + "aimeos/pagible": "<0.10.4", "airesvsg/acf-to-rest-api": "<=3.1", "akaunting/akaunting": "<2.1.13", "akeneo/pim-community-dev": "<5.0.119|>=6,<6.0.53", - "alextselegidis/easyappointments": "<=1.5", + "alextselegidis/easyappointments": "<=1.5.2", + "alexusmai/laravel-file-manager": "<=3.3.1", + "algolia/algoliasearch-magento-2": "<=3.16.1|>=3.17.0.0-beta1,<=3.17.1", + "almirhodzic/nova-toggle-5": "<1.3", + "alt-design/alt-redirect": "<1.6.4", + "altcha-org/altcha": "<1.3.1", "alterphp/easyadmin-extension-bundle": ">=1.2,<1.2.11|>=1.3,<1.3.1", "amazing/media2click": ">=1,<1.3.3", "ameos/ameos_tarteaucitron": "<1.2.23", "amphp/artax": "<1.0.6|>=2,<2.0.6", "amphp/http": "<=1.7.2|>=2,<=2.1", "amphp/http-client": ">=4,<4.4", + "amphp/http-server": ">=2.0.0.0-RC1-dev,<2.1.10|>=3.0.0.0-beta1,<3.4.4", "anchorcms/anchor-cms": "<=0.12.7", "andreapollastri/cipi": "<=3.1.15", "andrewhaine/silverstripe-form-capture": ">=0.2,<=0.2.3|>=1,<1.0.2|>=2,<2.2.5", + "aoe/restler": "<1.7.1", "apache-solr-for-typo3/solr": "<2.8.3", "apereo/phpcas": "<1.6", - "api-platform/core": "<3.4.17|>=4.0.0.0-alpha1,<4.0.22", - "api-platform/graphql": "<3.4.17|>=4.0.0.0-alpha1,<4.0.22", + "api-platform/core": "<3.4.17|>=4,<4.0.22|>=4.1,<4.1.5", + "api-platform/graphql": "<3.4.17|>=4,<4.0.22|>=4.1,<4.1.5", "appwrite/server-ce": "<=1.2.1", "arc/web": "<3", "area17/twill": "<1.2.5|>=2,<2.5.3", @@ -5197,30 +5464,40 @@ "athlon1600/php-proxy": "<=5.1", "athlon1600/php-proxy-app": "<=3", "athlon1600/youtube-downloader": "<=4", + "aureuserp/aureuserp": "<1.3.0.0-beta1", "austintoddj/canvas": "<=3.4.2", - "auth0/wordpress": "<=4.6", - "automad/automad": "<2.0.0.0-alpha5", + "auth0/auth0-php": ">=3.3,<=8.18", + "auth0/login": "<=7.20", + "auth0/symfony": "<=5.7", + "auth0/wordpress": "<=5.5", + "automad/automad": "<=2.0.0.0-beta27", "automattic/jetpack": "<9.8", "awesome-support/awesome-support": "<=6.0.7", - "aws/aws-sdk-php": "<3.288.1", - "azuracast/azuracast": "<0.18.3", - "backdrop/backdrop": "<1.27.3|>=1.28,<1.28.2", - "backpack/crud": "<3.4.9", + "aws/aws-sdk-php": "<=3.371.3", + "ayacoo/redirect-tab": "<2.1.2|>=3,<3.1.7|>=4,<4.0.5", + "azuracast/azuracast": "<=0.23.5", + "b13/seo_basics": "<0.8.2", + "backdrop/backdrop": "<=1.32", + "backpack/crud": "<4.0.63|>=4.1,<4.1.69|>=5,<5.0.13", "backpack/filemanager": "<2.0.2|>=3,<3.0.9", - "bacula-web/bacula-web": "<8.0.0.0-RC2-dev", - "badaso/core": "<2.7", - "bagisto/bagisto": "<2.1", + "bacula-web/bacula-web": "<9.7.1", + "badaso/core": "<=2.9.11", + "bagisto/bagisto": "<=2.3.15", "barrelstrength/sprout-base-email": "<1.2.7", "barrelstrength/sprout-forms": "<3.9", - "barryvdh/laravel-translation-manager": "<0.6.2", + "barryvdh/laravel-translation-manager": "<0.6.8", "barzahlen/barzahlen-php": "<2.0.1", - "baserproject/basercms": "<=5.1.1", + "baserproject/basercms": "<=5.2.2", "bassjobsen/bootstrap-3-typeahead": ">4.0.2", "bbpress/bbpress": "<2.6.5", + "bcit-ci/codeigniter": "<3.1.3", "bcosca/fatfree": "<3.7.2", "bedita/bedita": "<4", + "bednee/cooluri": "<1.0.30", "bigfork/silverstripe-form-capture": ">=3,<3.1.1", - "billz/raspap-webgui": "<=3.1.4", + "billabear/billabear": "<=2025.01.03", + "billz/raspap-webgui": "<3.3.6", + "binarytorch/larecipe": "<2.8.1", "bk2k/bootstrap-package": ">=7.1,<7.1.2|>=8,<8.0.8|>=9,<9.0.4|>=9.1,<9.1.3|>=10,<10.0.10|>=11,<11.0.3", "blueimp/jquery-file-upload": "==6.4.4", "bmarshall511/wordpress_zero_spam": "<5.2.13", @@ -5235,46 +5512,67 @@ "brotkrueml/typo3-matomo-integration": "<1.3.2", "buddypress/buddypress": "<7.2.1", "bugsnag/bugsnag-laravel": ">=2,<2.0.2", + "bvbmedia/multishop": "<2.0.39", "bytefury/crater": "<6.0.2", "cachethq/cachet": "<2.5.1", - "cakephp/cakephp": "<3.10.3|>=4,<4.0.10|>=4.1,<4.1.4|>=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", + "cadmium-org/cadmium-cms": "<=0.4.9", + "cakephp/authentication": "<3.3.6|>=4,<4.1.1", + "cakephp/cakephp": "<4.5.11|>=4.6,<4.6.4|>=5,<5.1.7|>=5.2,<5.2.13|>=5.3,<5.3.6", "cakephp/database": ">=4.2,<4.2.12|>=4.3,<4.3.11|>=4.4,<4.4.10", "cardgate/magento2": "<2.0.33", "cardgate/woocommerce": "<=3.1.15", - "cart2quote/module-quotation": ">=4.1.6,<=4.4.5|>=5,<5.4.4", + "cart2quote/module-quotation": ">=4.1.6,<4.4.6|>=5,<5.4.4", "cart2quote/module-quotation-encoded": ">=4.1.6,<=4.4.5|>=5,<5.4.4", - "cartalyst/sentry": "<=2.1.6", + "cartalyst/sentry": "<2.1.7", "catfan/medoo": "<1.7.5", "causal/oidc": "<4", "cecil/cecil": "<7.47.1", "centreon/centreon": "<22.10.15", + "cesargb/laravel-magiclink": ">=2,<2.25.1", "cesnet/simplesamlphp-module-proxystatistics": "<3.1", "chriskacerguis/codeigniter-restserver": "<=2.7.1", + "chrome-php/chrome": "<1.14", + "ci4-cms-erp/ci4ms": "<=0.31.8", "civicrm/civicrm-core": ">=4.2,<4.2.9|>=4.3,<4.3.3", "ckeditor/ckeditor": "<4.25", - "clickstorm/cs-seo": ">=6,<6.7|>=7,<7.4|>=8,<8.3|>=9,<9.2", - "cockpit-hq/cockpit": "<2.7|==2.7", + "clickstorm/cs-seo": ">=6,<6.8|>=7,<7.5|>=8,<8.4|>=9,<9.3", + "co-stack/fal_sftp": "<0.2.6", + "cockpit-hq/cockpit": "<=2.14", + "code16/sharp": "<9.22", "codeception/codeception": "<3.1.3|>=4,<4.1.22", - "codeigniter/framework": "<3.1.9", - "codeigniter4/framework": "<4.5.8", + "codeigniter/framework": "<3.1.10", + "codeigniter4/framework": "<4.7.2", "codeigniter4/shield": "<1.0.0.0-beta8", "codiad/codiad": "<=2.8.4", "codingms/additional-tca": ">=1.7,<1.15.17|>=1.16,<1.16.9", + "codingms/modules": "<4.3.11|>=5,<5.7.4|>=6,<6.4.2|>=7,<7.5.5", + "commerceteam/commerce": ">=0.9.6,<0.9.9", "components/jquery": ">=1.0.3,<3.5", - "composer/composer": "<1.10.27|>=2,<2.2.24|>=2.3,<2.7.7", - "concrete5/concrete5": "<9.4.0.0-RC2-dev", + "composer/composer": "<2.2.28|>=2.3,<2.9.8", + "concrete5/concrete5": "<9.5.1", "concrete5/core": "<8.5.8|>=9,<9.1", "contao-components/mediaelement": ">=2.14.2,<2.21.1", "contao/comments-bundle": ">=2,<4.13.40|>=5.0.0.0-RC1-dev,<5.3.4", - "contao/contao": "<=5.4.1", + "contao/contao": ">=3,<3.5.37|>=4,<4.4.56|>=4.5,<4.13.56|>=5,<5.3.38|>=5.4.0.0-RC1-dev,<5.6.1", "contao/core": "<3.5.39", - "contao/core-bundle": "<4.13.54|>=5,<5.3.30|>=5.4,<5.5.6", + "contao/core-bundle": "<4.13.57|>=5,<5.3.42|>=5.4,<5.6.5", "contao/listing-bundle": ">=3,<=3.5.30|>=4,<4.4.8", "contao/managed-edition": "<=1.5", + "coreshop/core-shop": "<4.1.9|==5", "corveda/phpsandbox": "<1.3.5", "cosenary/instagram": "<=2.3", - "craftcms/cms": "<4.13.8|>=5,<5.5.5", - "croogo/croogo": "<4", + "cotonti/cotonti": "<=1", + "couleurcitron/tarteaucitron-wp": "<0.3", + "cpsit/typo3-mailqueue": "<0.4.5|>=0.5,<0.5.2", + "craftcms/aws-s3": ">=2.0.2,<=2.2.4", + "craftcms/azure-blob": ">=2.0.0.0-beta1,<=2.1", + "craftcms/cms": "<4.18|>=5,<5.10", + "craftcms/commerce": ">=4,<=4.11.1|>=5,<=5.6.4", + "craftcms/composer": ">=4.0.0.0-RC1-dev,<=4.10|>=5.0.0.0-RC1-dev,<=5.5.1", + "craftcms/craft": ">=3.5,<=4.16.17|>=5.0.0.0-RC1-dev,<=5.8.21", + "craftcms/google-cloud": ">=2.0.0.0-beta1,<=2.2", + "craftcms/webhooks": ">=3,<3.2", + "croogo/croogo": "<=4.0.7", "cuyz/valinor": "<0.12", "czim/file-handling": "<1.5|>=2,<2.3", "czproject/git-php": "<4.0.3", @@ -5282,17 +5580,24 @@ "dapphp/securimage": "<3.6.6", "darylldoyle/safe-svg": "<1.9.10", "datadog/dd-trace": ">=0.30,<0.30.2", + "datahihi1/tiny-env": "<1.0.3|>=1.0.9,<1.0.11", "datatables/datatables": "<1.10.10", "david-garcia/phpwhois": "<=4.3.1", "dbrisinajumi/d2files": "<1", "dcat/laravel-admin": "<=2.1.3|==2.2.0.0-beta|==2.2.2.0-beta", + "dedoc/scramble": ">=0.13.2,<0.13.22", "derhansen/fe_change_pwd": "<2.0.5|>=3,<3.0.3", "derhansen/sf_event_mgt": "<4.3.1|>=5,<5.1.1|>=7,<7.4", "desperado/xml-bundle": "<=0.1.7", "dev-lancer/minecraft-motd-parser": "<=1.0.5", + "devcode-it/openstamanager": "<=2.10.1", "devgroup/dotplant": "<2020.09.14-dev", "digimix/wp-svg-upload": "<=1", "directmailteam/direct-mail": "<6.0.3|>=7,<7.0.3|>=8,<9.5.2", + "directorytree/imapengine": "<1.22.3", + "dl/yag": "<3.0.1", + "dmk/webkitpdf": "<1.1.4", + "dnadesign/silverstripe-elemental": "<5.3.12", "doctrine/annotations": "<1.2.7", "doctrine/cache": ">=1,<1.3.2|>=1.4,<1.4.2", "doctrine/common": "<2.4.3|>=2.5,<2.5.1", @@ -5302,44 +5607,65 @@ "doctrine/mongodb-odm": "<1.0.2", "doctrine/mongodb-odm-bundle": "<3.0.1", "doctrine/orm": ">=1,<1.2.4|>=2,<2.4.8|>=2.5,<2.5.1|>=2.8.3,<2.8.4", - "dolibarr/dolibarr": "<19.0.2|==21.0.0.0-beta", + "dolibarr/dolibarr": "<=23.0.2", "dompdf/dompdf": "<2.0.4", "doublethreedigital/guest-entries": "<3.1.2", + "dreamfactory/df-core": "<1.0.4", + "drupal-pattern-lab/unified-twig-extensions": "<=0.1", + "drupal/access_code": "<2.0.5", + "drupal/acquia_dam": "<1.1.5", + "drupal/admin_audit_trail": "<1.0.5", "drupal/ai": "<1.0.5", "drupal/alogin": "<2.0.6", "drupal/cache_utility": "<1.2.1", + "drupal/civictheme": "<1.12", + "drupal/commerce_alphabank_redirect": "<1.0.3", + "drupal/commerce_eurobank_redirect": "<2.1.1", "drupal/config_split": "<1.10|>=2,<2.0.2", - "drupal/core": ">=6,<6.38|>=7,<7.102|>=8,<10.3.14|>=10.4,<10.4.5|>=11,<11.0.13|>=11.1,<11.1.5", + "drupal/core": ">=6,<6.38|>=7,<7.103|>=8,<10.5.10|>=10.6,<10.6.9|>=11,<11.2.12|>=11.3,<11.3.10", "drupal/core-recommended": ">=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", + "drupal/currency": "<3.5", "drupal/drupal": ">=5,<5.11|>=6,<6.38|>=7,<7.102|>=8,<10.2.11|>=10.3,<10.3.9|>=11,<11.0.8", + "drupal/email_tfa": "<2.0.6", "drupal/formatter_suite": "<2.1", "drupal/gdpr": "<3.0.1|>=3.1,<3.1.2", "drupal/google_tag": "<1.8|>=2,<2.0.8", "drupal/ignition": "<1.0.4", + "drupal/json_field": "<1.5", + "drupal/lightgallery": "<1.6", "drupal/link_field_display_mode_formatter": "<1.6", "drupal/matomo": "<1.24", "drupal/oauth2_client": "<4.1.3", "drupal/oauth2_server": "<2.1", "drupal/obfuscate": "<2.0.1", + "drupal/plausible_tracking": "<1.0.2", + "drupal/quick_node_block": "<2", "drupal/rapidoc_elements_field_formatter": "<1.0.1", + "drupal/reverse_proxy_header": "<1.1.2", + "drupal/simple_multistep": "<2", + "drupal/simple_oauth": ">=6,<6.0.7", "drupal/spamspan": "<3.2.1", "drupal/tfa": "<1.10", + "drupal/umami_analytics": "<1.0.1", "duncanmcclean/guest-entries": "<3.1.2", "dweeves/magmi": "<=0.7.24", - "ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.1.2", + "easycorp/easyadmin-bundle": ">=4,<4.29.10|>=5,<5.0.13", + "ec-cube/ec-cube": "<2.4.4|>=2.11,<=2.17.1|>=3,<=3.0.18.0-patch4|>=4,<=4.3.1", "ecodev/newsletter": "<=4", "ectouch/ectouch": "<=2.7.2", - "egroupware/egroupware": "<23.1.20240624", + "egroupware/egroupware": "<23.1.20260113|>=26.0.20251208,<26.0.20260113", "elefant/cms": "<2.0.7", "elgg/elgg": "<3.3.24|>=4,<4.0.5", "elijaa/phpmemcacheadmin": "<=1.3", + "elmsln/haxcms": "<11.0.14", "encore/laravel-admin": "<=1.8.19", "endroid/qr-code-bundle": "<3.4.2", "enhavo/enhavo-app": "<=0.13.1", - "enshrined/svg-sanitize": "<0.15", + "enshrined/svg-sanitize": "<0.22", "erusev/parsedown": "<1.7.2", "ether/logs": "<3.0.4", "evolutioncms/evolution": "<=3.2.3", + "evoweb/sf-register": "<13.2.4|>=14,<14.0.2", "exceedone/exment": "<4.4.3|>=5,<5.0.3", "exceedone/laravel-admin": "<2.2.3|==3", "ezsystems/demobundle": ">=5.4,<5.4.6.1-dev", @@ -5347,45 +5673,50 @@ "ezsystems/ezdemo-ls-extension": ">=5.4,<5.4.2.1-dev", "ezsystems/ezfind-ls": ">=5.3,<5.3.6.1-dev|>=5.4,<5.4.11.1-dev|>=2017.12,<2017.12.0.1-dev", "ezsystems/ezplatform": "<=1.13.6|>=2,<=2.5.24", - "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.26|>=3.3,<3.3.39", - "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1", + "ezsystems/ezplatform-admin-ui": ">=1.3,<1.3.5|>=1.4,<1.4.6|>=1.5,<1.5.29|>=2.3,<2.3.39|>=3.3,<3.3.39", + "ezsystems/ezplatform-admin-ui-assets": ">=4,<4.2.1|>=5,<5.0.1|>=5.1,<5.1.1|>=5.3.0.0-beta1,<5.3.5", "ezsystems/ezplatform-graphql": ">=1.0.0.0-RC1-dev,<1.0.13|>=2.0.0.0-beta1,<2.3.12", "ezsystems/ezplatform-http-cache": "<2.3.16", - "ezsystems/ezplatform-kernel": "<1.2.5.1-dev|>=1.3,<1.3.35", + "ezsystems/ezplatform-kernel": "<=1.2.5|>=1.3,<1.3.35", "ezsystems/ezplatform-rest": ">=1.2,<=1.2.2|>=1.3,<1.3.8", - "ezsystems/ezplatform-richtext": ">=2.3,<2.3.7.1-dev|>=3.3,<3.3.40", + "ezsystems/ezplatform-richtext": ">=2.3,<2.3.26|>=3.3,<3.3.40", "ezsystems/ezplatform-solr-search-engine": ">=1.7,<1.7.12|>=2,<2.0.2|>=3.3,<3.3.15", "ezsystems/ezplatform-user": ">=1,<1.0.1", - "ezsystems/ezpublish-kernel": "<6.13.8.2-dev|>=7,<7.5.31", + "ezsystems/ezpublish-kernel": "<=6.13.8.1|>=7,<7.5.31", "ezsystems/ezpublish-legacy": "<=2017.12.7.3|>=2018.6,<=2019.03.5.1", "ezsystems/platform-ui-assets-bundle": ">=4.2,<4.2.3", "ezsystems/repository-forms": ">=2.3,<2.3.2.1-dev|>=2.5,<2.5.15", "ezyang/htmlpurifier": "<=4.2", "facade/ignition": "<1.16.15|>=2,<2.4.2|>=2.5,<2.5.2", - "facturascripts/facturascripts": "<=2022.08", + "facturascripts/facturascripts": "<=2025.92|>=2026,<=2026.1", "fastly/magento2": "<1.2.26", "feehi/cms": "<=2.1.1", "feehi/feehicms": "<=2.1.1", "fenom/fenom": "<=2.12.1", - "filament/actions": ">=3.2,<3.2.123", - "filament/infolists": ">=3,<3.2.115", - "filament/tables": ">=3,<3.2.115", + "filament/actions": ">=3.2,<3.2.123|>=4,<=4.11.3|>=5,<=5.6.3", + "filament/filament": ">=3,<=3.3.51|>=4,<4.11.5|>=5,<5.6.5", + "filament/forms": ">=3,<=3.3.52", + "filament/infolists": ">=3,<3.2.115|>=4,<=4.11.4|>=5,<=5.6.4", + "filament/tables": ">=3,<=3.3.50|>=4,<=4.11.4|>=5,<=5.6.4", "filegator/filegator": "<7.8", "filp/whoops": "<2.1.13", "fineuploader/php-traditional-server": "<=1.2.2", - "firebase/php-jwt": "<6", + "firebase/php-jwt": "<7", "fisharebest/webtrees": "<=2.1.18", "fixpunkt/fp-masterquiz": "<2.2.1|>=3,<3.5.2", - "fixpunkt/fp-newsletter": "<1.1.1|>=2,<2.1.2|>=2.2,<3.2.6", - "flarum/core": "<1.8.10", + "fixpunkt/fp-newsletter": "<1.1.1|>=1.2,<2.1.2|>=2.2,<3.2.6", + "flarum/core": "<=1.8.15|>=2.0.0.0-beta1,<=2.0.0.0-beta8", "flarum/flarum": "<0.1.0.0-beta8", "flarum/framework": "<1.8.10", "flarum/mentions": "<1.6.3", + "flarum/nicknames": "<1.8.3", "flarum/sticky": ">=0.1.0.0-beta14,<=0.1.0.0-beta15", "flarum/tags": "<=0.1.0.0-beta13", + "flightphp/core": "<3.18.1", "floriangaerber/magnesium": "<0.3.1", "fluidtypo3/vhs": "<5.1.1", "fof/byobu": ">=0.3.0.0-beta2,<1.1.7", + "fof/pretty-mail": "<=1.1.2", "fof/upload": "<1.2.3", "foodcoopshop/foodcoopshop": ">=3.2,<3.6.1", "fooman/tcpdf": "<6.2.22", @@ -5400,17 +5731,23 @@ "friendsofsymfony1/symfony1": ">=1.1,<1.5.19", "friendsoftypo3/mediace": ">=7.6.2,<7.6.5", "friendsoftypo3/openid": ">=4.5,<4.5.31|>=4.7,<4.7.16|>=6,<6.0.11|>=6.1,<6.1.6", + "friendsoftypo3/tt-address": "<8.1.2|>=9,<9.1.1|>=10,<10.0.1", "froala/wysiwyg-editor": "<=4.3", - "froxlor/froxlor": "<=2.2.5", + "frosh/adminer-platform": "<2.2.1", + "froxlor/froxlor": "<2.3.7", "frozennode/administrator": "<=5.0.12", "fuel/core": "<1.8.1", - "funadmin/funadmin": "<=5.0.2", + "funadmin/funadmin": "<=7.1.0.0-RC6", "gaoming13/wechat-php-sdk": "<=1.10.2", "genix/cms": "<=1.1.11", - "getformwork/formwork": "<1.13.1|>=2.0.0.0-beta1,<2.0.0.0-beta4", - "getgrav/grav": "<1.7.46", - "getkirby/cms": "<=3.6.6.5|>=3.7,<=3.7.5.4|>=3.8,<=3.8.4.3|>=3.9,<=3.9.8.1|>=3.10,<=3.10.1|>=4,<=4.3", - "getkirby/kirby": "<=2.5.12", + "georgringer/news": "<10.0.4|>=11,<11.4.4|>=12,<12.3.2|>=13,<13.0.2|>=14,<14.0.3", + "geshi/geshi": "<=1.0.9.1", + "getformwork/formwork": "<=2.3.3", + "getgrav/grav": "<=2.0.0.0-RC8", + "getgrav/grav-plugin-api": "<1.0.0.0-beta15", + "getgrav/grav-plugin-form": "<9.1", + "getkirby/cms": "<=4.9.3|>=5,<=5.4.3", + "getkirby/kirby": "<3.9.8.3-dev|>=3.10,<3.10.1.2-dev|>=4,<4.7.1", "getkirby/panel": "<2.5.14", "getkirby/starterkit": "<=3.7.0.2", "gilacms/gila": "<=1.15.4", @@ -5418,16 +5755,20 @@ "globalpayments/php-sdk": "<2", "goalgorilla/open_social": "<12.3.11|>=12.4,<12.4.10|>=13.0.0.0-alpha1,<13.0.0.0-alpha11", "gogentooss/samlbase": "<1.2.7", - "google/protobuf": "<3.15", + "goodoneuz/pay-uz": "<=2.2.24", + "google/protobuf": "<4.33.6", "gos/web-socket-bundle": "<1.10.4|>=2,<2.6.1|>=3,<3.3", + "gp247/core": "<1.1.24", "gree/jose": "<2.2.1", "gregwar/rst": "<1.0.3", - "grumpydictator/firefly-iii": "<6.1.17", + "grumpydictator/firefly-iii": "<=6.6.2", "gugoan/economizzer": "<=0.9.0.0-beta1", - "guzzlehttp/guzzle": "<6.5.8|>=7,<7.4.5", + "guzzlehttp/guzzle": "<7.12.1", + "guzzlehttp/guzzle-services": "<1.5.4", "guzzlehttp/oauth-subscriber": "<0.8.1", - "guzzlehttp/psr7": "<1.9.1|>=2,<2.4.5", + "guzzlehttp/psr7": "<2.12.1", "haffner/jh_captcha": "<=2.1.3|>=3,<=3.0.2", + "handcraftedinthealps/goodby-csv": "<1.4.3", "harvesthq/chosen": "<1.8.7", "helloxz/imgurl": "<=2.31", "hhxsv5/laravel-s": "<3.7.36", @@ -5436,155 +5777,196 @@ "hjue/justwriting": "<=1", "hov/jobfair": "<1.0.13|>=2,<2.0.2", "httpsoft/http-message": "<1.0.12", + "hybridauth/hybridauth": "<=3.12.2", "hyn/multi-tenant": ">=5.6,<5.7.2", - "ibexa/admin-ui": ">=4.2,<4.2.3|>=4.6,<4.6.14", + "ibexa/admin-ui": ">=4.2,<4.2.3|>=4.6,<4.6.25|>=5,<5.0.3", + "ibexa/admin-ui-assets": ">=4.6.0.0-alpha1,<4.6.21", "ibexa/core": ">=4,<4.0.7|>=4.1,<4.1.4|>=4.2,<4.2.3|>=4.5,<4.5.6|>=4.6,<4.6.2", - "ibexa/fieldtype-richtext": ">=4.6,<4.6.10", + "ibexa/fieldtype-richtext": ">=4.6,<4.6.25|>=5,<5.0.3", "ibexa/graphql": ">=2.5,<2.5.31|>=3.3,<3.3.28|>=4.2,<4.2.3", "ibexa/http-cache": ">=4.6,<4.6.14", "ibexa/post-install": "<1.0.16|>=4.6,<4.6.14", "ibexa/solr": ">=4.5,<4.5.4", - "ibexa/user": ">=4,<4.4.3", + "ibexa/user": ">=4,<4.4.3|>=5,<5.0.4", "icecoder/icecoder": "<=8.1", - "idno/known": "<=1.3.1", + "idno/known": "<1.6.4", "ilicmiljan/secure-props": ">=1.2,<1.2.2", "illuminate/auth": "<5.5.10", "illuminate/cookie": ">=4,<=4.0.11|>=4.1,<6.18.31|>=7,<7.22.4", "illuminate/database": "<6.20.26|>=7,<7.30.5|>=8,<8.40", "illuminate/encryption": ">=4,<=4.0.11|>=4.1,<=4.1.31|>=4.2,<=4.2.22|>=5,<=5.0.35|>=5.1,<=5.1.46|>=5.2,<=5.2.45|>=5.3,<=5.3.31|>=5.4,<=5.4.36|>=5.5,<5.5.40|>=5.6,<5.6.15", + "illuminate/mail": ">=9,<12.60|>=13,<13.10", "illuminate/view": "<6.20.42|>=7,<7.30.6|>=8,<8.75", "imdbphp/imdbphp": "<=5.1.1", "impresscms/impresscms": "<=1.4.5", - "impresspages/impresspages": "<=1.0.12", - "in2code/femanager": "<5.5.3|>=6,<6.3.4|>=7,<7.2.3", + "impresspages/impresspages": "<1.0.13", + "in2code/femanager": "<6.4.2|>=7,<7.5.3|>=8,<8.3.1", "in2code/ipandlanguageredirect": "<5.1.2", "in2code/lux": "<17.6.1|>=18,<24.0.2", - "in2code/powermail": "<7.5.1|>=8,<8.5.1|>=9,<10.9.1|>=11,<12.4.1", + "in2code/powermail": "<7.5.1|>=8,<8.5.1|>=9,<10.9.1|>=11,<12.5.3|==13", "innologi/typo3-appointments": "<2.0.6", "intelliants/subrion": "<4.2.2", "inter-mediator/inter-mediator": "==5.5", - "ipl/web": "<0.10.1", + "intercom/intercom-php": "==5.0.2", + "invoiceninja/invoiceninja": "<5.13.4", + "ipl/web": "<=0.10.2|>=0.11,<=0.13", "islandora/crayfish": "<4.1", "islandora/islandora": ">=2,<2.4.1", "ivankristianto/phpwhois": "<=4.3", + "j0k3r/graby": "<=2.5", "jackalope/jackalope-doctrine-dbal": "<1.7.4", + "jambagecom/div2007": "<0.10.2", "james-heinrich/getid3": "<1.9.21", - "james-heinrich/phpthumb": "<1.7.12", + "james-heinrich/phpthumb": "<=1.7.23", "jasig/phpcas": "<1.3.3", + "jbartels/wec-map": "<3.0.3", "jcbrand/converse.js": "<3.3.3", + "jleehr/canto-saas-api": "<=2", + "joedolson/my-calendar": "<3.7.7", "joelbutcher/socialstream": "<5.6|>=6,<6.2", - "johnbillion/wp-crontrol": "<1.16.2", + "johnbillion/query-monitor": "<3.20.4", + "johnbillion/wp-crontrol": "<1.16.2|>=1.17,<1.19.2", "joomla/application": "<1.0.13", "joomla/archive": "<1.1.12|>=2,<2.0.1", + "joomla/database": ">=1,<2.2|>=3,<3.4", "joomla/filesystem": "<1.6.2|>=2,<2.0.1", - "joomla/filter": "<1.4.4|>=2,<2.0.1", + "joomla/filter": "<2.0.6|>=3,<3.0.5|==4", "joomla/framework": "<1.5.7|>=2.5.4,<=3.8.12", "joomla/input": ">=2,<2.0.2", - "joomla/joomla-cms": ">=2.5,<3.9.12", + "joomla/joomla-cms": "<3.9.12|>=4,<4.4.13|>=5,<5.2.6", + "joomla/joomla-platform": "<1.5.4", "joomla/session": "<1.3.1", "joyqi/hyper-down": "<=2.4.27", "jsdecena/laracom": "<2.0.9", "jsmitty12/phpwhois": "<5.1", - "juzaweb/cms": "<=3.4", + "juzaweb/cms": "<=3.4.2", "jweiland/events2": "<8.3.8|>=9,<9.0.6", + "jweiland/kk-downloader": "<1.2.2", + "kantorge/yaffa": "<=2", "kazist/phpwhois": "<=4.2.6", + "kelvinmo/simplejwt": "<=1.1", "kelvinmo/simplexrd": "<3.1.1", "kevinpapst/kimai2": "<1.16.7", - "khodakhah/nodcms": "<=3", - "kimai/kimai": "<=2.20.1", + "khodakhah/nodcms": "<=3.4.1", + "kimai/kimai": "<=2.55", "kitodo/presentation": "<3.2.3|>=3.3,<3.3.4", "klaviyo/magento2-extension": ">=1,<3", - "knplabs/knp-snappy": "<=1.4.2", + "knplabs/knp-snappy": "<=1.7", "kohana/core": "<3.3.3", - "krayin/laravel-crm": "<=1.3", + "koillection/koillection": "<1.6.12", + "krayin/laravel-crm": "<=2.2", "kreait/firebase-php": ">=3.2,<3.8.1", "kumbiaphp/kumbiapp": "<=1.1.1", "la-haute-societe/tcpdf": "<6.2.22", + "laktak/hjson": "<2.3", "laminas/laminas-diactoros": "<2.18.1|==2.19|==2.20|==2.21|==2.22|==2.23|>=2.24,<2.24.2|>=2.25,<2.25.2", "laminas/laminas-form": "<2.17.1|>=3,<3.0.2|>=3.1,<3.1.1", "laminas/laminas-http": "<2.14.2", "lara-zeus/artemis": ">=1,<=1.0.6", "lara-zeus/dynamic-dashboard": ">=3,<=3.0.1", "laravel/fortify": "<1.11.1", - "laravel/framework": "<10.48.29|>=11,<11.44.1|>=12,<12.1.1", + "laravel/framework": "<12.61.1|>=13,<13.12", "laravel/laravel": ">=5.4,<5.4.22", + "laravel/passport": ">=13,<13.7.1", "laravel/pulse": "<1.3.1", - "laravel/reverb": "<1.4", + "laravel/reverb": "<1.7", "laravel/socialite": ">=1,<2.0.10", "latte/latte": "<2.10.8", - "lavalite/cms": "<=9|==10.1", + "lavalite/cms": "<=10.1", + "lavitto/typo3-form-to-database": "<2.2.5|>=3,<3.2.2|>=4,<4.2.3|>=5,<5.0.2", "lcobucci/jwt": ">=3.4,<3.4.6|>=4,<4.0.4|>=4.1,<4.1.5", - "league/commonmark": "<2.6", + "league/commonmark": "<=2.8.1", "league/flysystem": "<1.1.4|>=2,<2.1.1", "league/oauth2-server": ">=8.3.2,<8.4.2|>=8.5,<8.5.3", "leantime/leantime": "<3.3", "lexik/jwt-authentication-bundle": "<2.10.7|>=2.11,<2.11.3", "libreform/libreform": ">=2,<=2.0.8", - "librenms/librenms": "<2017.08.18", + "librenms/librenms": "<26.3", "liftkit/database": "<2.13.2", "lightsaml/lightsaml": "<1.3.5", - "limesurvey/limesurvey": "<6.5.12", + "limesurvey/limesurvey": "<6.15.4", "livehelperchat/livehelperchat": "<=3.91", - "livewire/livewire": "<2.12.7|>=3.0.0.0-beta1,<3.5.2", + "livewire-filemanager/filemanager": "<=1.0.4", + "livewire/livewire": "<2.12.7|>=3.0.0.0-beta1,<3.6.4", "livewire/volt": "<1.7", "lms/routes": "<2.1.1", "localizationteam/l10nmgr": "<7.4|>=8,<8.7|>=9,<9.2", + "lomkit/laravel-rest-api": "<2.13", + "luracast/restler": "<3.1", "luyadev/yii-helpers": "<1.2.1", "macropay-solutions/laravel-crud-wizard-free": "<3.4.17", "maestroerror/php-heic-to-jpg": "<1.0.5", - "magento/community-edition": "<2.4.5|==2.4.5|>=2.4.5.0-patch1,<2.4.5.0-patch11|==2.4.6|>=2.4.6.0-patch1,<2.4.6.0-patch9|>=2.4.7.0-beta1,<2.4.7.0-patch4|>=2.4.8.0-beta1,<2.4.8.0-beta2", + "magento/community-edition": "<2.4.6.0-patch13|>=2.4.7.0-beta1,<2.4.7.0-patch8|>=2.4.8.0-beta1,<2.4.8.0-patch3|>=2.4.9.0-alpha1,<2.4.9.0-alpha3|==2.4.9", "magento/core": "<=1.9.4.5", "magento/magento1ce": "<1.9.4.3-dev", "magento/magento1ee": ">=1,<1.14.4.3-dev", "magento/product-community-edition": "<2.4.4.0-patch9|>=2.4.5,<2.4.5.0-patch8|>=2.4.6,<2.4.6.0-patch6|>=2.4.7,<2.4.7.0-patch1", "magento/project-community-edition": "<=2.0.2", "magneto/core": "<1.9.4.4-dev", + "mahocommerce/maho": "<25.9", "maikuolan/phpmussel": ">=1,<1.6", "mainwp/mainwp": "<=4.4.3.3", - "mantisbt/mantisbt": "<=2.26.3", + "manogi/nova-tiptap": "<=3.2.6", + "mantisbt/mantisbt": "<2.28.2", "marcwillmann/turn": "<0.3.3", + "markhuot/craftql": "<=1.3.7", + "marshmallow/nova-tiptap": "<5.7", + "matomo/matomo": "<1.11", "matyhtf/framework": "<3.0.6", - "mautic/core": "<5.2.3", + "mautic/core": "<5.2.10|>=6,<6.0.8|>=7.0.0.0-alpha,<7.0.1", "mautic/core-lib": ">=1.0.0.0-beta,<4.4.13|>=5.0.0.0-alpha,<5.1.1", + "mautic/grapes-js-builder-bundle": ">=4,<4.4.18|>=5,<5.2.9|>=6,<6.0.7", "maximebf/debugbar": "<1.19", + "mckenziearts/livewire-markdown-editor": "<1.3", "mdanter/ecc": "<2", "mediawiki/abuse-filter": "<1.39.9|>=1.40,<1.41.3|>=1.42,<1.42.2", - "mediawiki/cargo": "<3.6.1", + "mediawiki/cargo": "<3.8.3", "mediawiki/core": "<1.39.5|==1.40", "mediawiki/data-transfer": ">=1.39,<1.39.11|>=1.41,<1.41.3|>=1.42,<1.42.2", "mediawiki/matomo": "<2.4.3", "mediawiki/semantic-media-wiki": "<4.0.2", + "mehrwert/phpmyadmin": "<3.2", "melisplatform/melis-asset-manager": "<5.0.1", - "melisplatform/melis-cms": "<5.0.1", + "melisplatform/melis-cms": "<5.3.4", + "melisplatform/melis-cms-slider": "<5.3.1", + "melisplatform/melis-core": "<5.3.11", "melisplatform/melis-front": "<5.0.1", "mezzio/mezzio-swoole": "<3.7|>=4,<4.3", "mgallegos/laravel-jqgrid": "<=1.3", "microsoft/microsoft-graph": ">=1.16,<1.109.1|>=2,<2.0.1", "microsoft/microsoft-graph-beta": "<2.0.1", "microsoft/microsoft-graph-core": "<2.0.2", - "microweber/microweber": "<=2.0.16", + "microweber/microweber": "<2.0.20", "mikehaertl/php-shellcommand": "<1.6.1", + "mineadmin/mineadmin": "<=3.0.9", "miniorange/miniorange-saml": "<1.4.3", + "miraheze/ts-portal": "<=33", "mittwald/typo3_forum": "<1.2.1", + "mix/mix": ">=2,<=2.2.17", + "mmc/ceselector": "<3.0.3|>=4,<4.0.2|>=5,<5.0.1|>=6,<6.0.1", "mobiledetect/mobiledetectlib": "<2.8.32", "modx/revolution": "<=3.1", "mojo42/jirafeau": "<4.4", "mongodb/mongodb": ">=1,<1.9.2", + "mongodb/mongodb-extension": "<1.21.2", "monolog/monolog": ">=1.8,<1.12", - "moodle/moodle": "<4.3.10|>=4.4,<4.4.6|>=4.5.0.0-beta,<4.5.2", + "moodle/moodle": "<4.5.9|>=5.0.0.0-beta,<5.0.5|>=5.1.0.0-beta,<5.1.2", + "moonshine/moonshine": "<=3.12.5", "mos/cimage": "<0.7.19", "movim/moxl": ">=0.8,<=0.10", "movingbytes/social-network": "<=1.2.1", "mpdf/mpdf": "<=7.1.7", - "munkireport/comment": "<4.1", + "mtdowling/jmespath.php": "<2.9.1", + "munkireport/comment": "<4", "munkireport/managedinstalls": "<2.6", "munkireport/munki_facts": "<1.5", - "munkireport/munkireport": ">=2.5.3,<5.6.3", "munkireport/reportdata": "<3.5", "munkireport/softwareupdate": "<1.6", "mustache/mustache": ">=2,<2.14.1", "mwdelaney/wp-enable-svg": "<=0.2", + "nabeel/phpvms": "<7.0.6", "namshi/jose": "<2.2", + "nasirkhan/laravel-starter": "<11.11", "nategood/httpful": "<1", "neoan3-apps/template": "<1.1.1", "neorazorx/facturascripts": "<2022.04", @@ -5598,11 +5980,14 @@ "netgen/tagsbundle": ">=3.4,<3.4.11|>=4,<4.0.15", "nette/application": ">=2,<2.0.19|>=2.1,<2.1.13|>=2.2,<2.2.10|>=2.3,<2.3.14|>=2.4,<2.4.16|>=3,<3.0.6", "nette/nette": ">=2,<2.0.19|>=2.1,<2.1.13", + "neuron-core/neuron-ai": "<=2.8.11", "nilsteampassnet/teampass": "<3.1.3.1-dev", + "nitsan/ns-backup": "<13.0.1", "nonfiction/nterchange": "<4.1.1", "notrinos/notrinos-erp": "<=0.7", "noumo/easyii": "<=0.9", "novaksolutions/infusionsoft-php-sdk": "<1", + "novosga/novosga": "<=2.2.12", "nukeviet/nukeviet": "<4.5.02", "nyholm/psr7": "<1.6.1", "nystudio107/craft-seomatic": "<3.4.12", @@ -5610,18 +5995,19 @@ "nzo/url-encryptor-bundle": ">=4,<4.3.2|>=5,<5.0.1", "october/backend": "<1.1.2", "october/cms": "<1.0.469|==1.0.469|==1.0.471|==1.1.1", - "october/october": "<=3.6.4", - "october/rain": "<1.0.472|>=1.1,<1.1.2", - "october/system": "<1.0.476|>=1.1,<1.1.12|>=2,<2.2.34|>=3,<3.5.15", + "october/october": "<3.7.14|>=4,<4.1.10", + "october/rain": "<=3.7.13|>=4,<=4.1.9", + "october/system": "<3.7.16|>=4,<4.1.16", + "oliverklee/phpunit": "<3.5.15", "omeka/omeka-s": "<4.0.3", - "onelogin/php-saml": "<2.10.4", + "onelogin/php-saml": "<2.21.1|>=3,<3.8.1|>=4,<4.3.1", "oneup/uploader-bundle": ">=1,<1.9.3|>=2,<2.1.5", - "open-web-analytics/open-web-analytics": "<1.7.4", + "open-web-analytics/open-web-analytics": "<1.8.1", "opencart/opencart": ">=0", "openid/php-openid": "<2.3", - "openmage/magento-lts": "<20.12.3", + "openmage/magento-lts": "<=20.17", "opensolutions/vimbadmin": "<=3.0.15", - "opensource-workshop/connect-cms": "<1.8.7|>=2,<2.4.7", + "opensource-workshop/connect-cms": "<1.41.1|>=2,<2.41.1", "orchid/platform": ">=8,<14.43", "oro/calendar-bundle": ">=4.2,<=4.2.6|>=5,<=5.0.6|>=5.1,<5.1.1", "oro/commerce": ">=4.1,<5.0.11|>=5.1,<5.1.1", @@ -5630,7 +6016,7 @@ "oro/customer-portal": ">=4.1,<=4.1.13|>=4.2,<=4.2.10|>=5,<=5.0.11|>=5.1,<=5.1.3", "oro/platform": ">=1.7,<1.7.4|>=3.1,<3.1.29|>=4.1,<4.1.17|>=4.2,<=4.2.10|>=5,<=5.0.12|>=5.1,<=5.1.3", "oveleon/contao-cookiebar": "<1.16.3|>=2,<2.1.3", - "oxid-esales/oxideshop-ce": "<4.5", + "oxid-esales/oxideshop-ce": "<=7.0.5", "oxid-esales/paymorrow-module": ">=1,<1.0.2|>=2,<2.0.1", "packbackbooks/lti-1-3-php-library": "<5", "padraic/humbug_get_contents": "<1.1.2", @@ -5638,7 +6024,9 @@ "pagekit/pagekit": "<=1.0.18", "paragonie/ecc": "<2.0.1", "paragonie/random_compat": "<2", + "paragonie/sodium_compat": "<1.24|>=2,<2.5", "passbolt/passbolt_api": "<4.6.2", + "paymenter/paymenter": "<1.5", "paypal/adaptivepayments-sdk-php": "<=3.9.2", "paypal/invoice-sdk-php": "<=3.9", "paypal/merchant-sdk-php": "<3.12", @@ -5646,65 +6034,81 @@ "pear/archive_tar": "<1.4.14", "pear/auth": "<1.2.4", "pear/crypt_gpg": "<1.6.7", + "pear/http_request2": "<2.7", "pear/pear": "<=1.10.1", "pegasus/google-for-jobs": "<1.5.1|>=2,<2.1.1", "personnummer/personnummer": "<3.0.2", - "phanan/koel": "<5.1.4", + "ph7software/ph7builder": "<=17.9.1", + "phanan/koel": "<=9.3.4", + "pheditor/pheditor": ">=2.0.1,<=2.0.3", "phenx/php-svg-lib": "<0.5.2", "php-censor/php-censor": "<2.0.13|>=2.1,<2.1.5", "php-mod/curl": "<2.3.2", - "phpbb/phpbb": "<3.3.11", + "php-standard-library/h2": ">=6.1,<6.1.2|>=6.2,<6.2.1", + "php-standard-library/php-standard-library": ">=6.1,<6.1.2|>=6.2,<6.2.1", + "phpbb/phpbb": "<3.3.16|==4.0.0.0-alpha1", "phpems/phpems": ">=6,<=6.1.3", "phpfastcache/phpfastcache": "<6.1.5|>=7,<7.1.2|>=8,<8.0.7", "phpmailer/phpmailer": "<6.5", "phpmussel/phpmussel": ">=1,<1.6", "phpmyadmin/phpmyadmin": "<5.2.2", - "phpmyfaq/phpmyfaq": "<3.2.5|==3.2.5|>=3.2.10,<=4.0.1", + "phpmyfaq/phpmyfaq": "<4.1.4", "phpoffice/common": "<0.2.9", + "phpoffice/math": "<=0.2", "phpoffice/phpexcel": "<=1.8.2", - "phpoffice/phpspreadsheet": "<1.29.9|>=2,<2.1.8|>=2.2,<2.3.7|>=3,<3.9", - "phpseclib/phpseclib": "<2.0.47|>=3,<3.0.36", + "phpoffice/phpspreadsheet": "<=1.30.4|>=2,<=2.1.15|>=2.2,<=2.4.4|>=3,<=3.10.4|>=4,<=5.6", + "phppgadmin/phppgadmin": "<=7.13", + "phpseclib/phpseclib": "<=2.0.54|>=3,<=3.0.53", "phpservermon/phpservermon": "<3.6", "phpsysinfo/phpsysinfo": "<3.4.3", - "phpunit/phpunit": ">=4.8.19,<4.8.28|>=5.0.10,<5.6.3", + "phpunit/phpunit": "<8.5.52|>=9,<9.6.33|>=10,<10.5.62|>=11,<11.5.50|>=12,<12.5.8|>=12.5.21,<12.5.22|>=13.1.5,<13.1.6", "phpwhois/phpwhois": "<=4.2.5", "phpxmlrpc/extras": "<0.6.1", "phpxmlrpc/phpxmlrpc": "<4.9.2", + "phraseanet/phraseanet": "==4.0.3", "pi/pi": "<=2.5", - "pimcore/admin-ui-classic-bundle": "<1.7.6", + "pimcore/admin-ui-classic-bundle": "<=2.3.5", "pimcore/customer-management-framework-bundle": "<4.2.1", "pimcore/data-hub": "<1.2.4", "pimcore/data-importer": "<1.8.9|>=1.9,<1.9.3", "pimcore/demo": "<10.3", "pimcore/ecommerce-framework-bundle": "<1.0.10", "pimcore/perspective-editor": "<1.5.1", - "pimcore/pimcore": "<11.5.4", + "pimcore/pimcore": "<=12.3.8", + "pimcore/web2print-tools-bundle": "<=5.2.1|>=6.0.0.0-RC1-dev,<=6.1", + "piwik/piwik": "<1.11", "pixelfed/pixelfed": "<0.12.5", "plotly/plotly.js": "<2.25.2", "pocketmine/bedrock-protocol": "<8.0.2", - "pocketmine/pocketmine-mp": "<5.25.2", + "pocketmine/pocketmine-mp": "<5.42.1", "pocketmine/raklib": ">=0.14,<0.14.6|>=0.15,<0.15.1", + "pontedilana/php-weasyprint": "<=2.5.1", + "poweradmin/poweradmin": "<4.2.4|>=4.3,<4.3.3", "pressbooks/pressbooks": "<5.18", "prestashop/autoupgrade": ">=4,<4.10.1", "prestashop/blockreassurance": "<=5.1.3", "prestashop/blockwishlist": ">=2,<2.1.1", "prestashop/contactform": ">=1.0.1,<4.3", "prestashop/gamification": "<2.3.2", - "prestashop/prestashop": "<8.1.6", + "prestashop/prestashop": "<8.2.6|>=9,<9.1.1", "prestashop/productcomments": "<5.0.2", + "prestashop/ps_checkout": "<5.3", "prestashop/ps_contactinfo": "<=3.3.2", "prestashop/ps_emailsubscription": "<2.6.1", "prestashop/ps_facetedsearch": "<3.4.1", "prestashop/ps_linklist": "<3.1", - "privatebin/privatebin": "<1.4|>=1.5,<1.7.4", - "processwire/processwire": "<=3.0.229", - "propel/propel": ">=2.0.0.0-alpha1,<=2.0.0.0-alpha7", - "propel/propel1": ">=1,<=1.7.1", - "pterodactyl/panel": "<1.11.8", + "privatebin/privatebin": "<1.4|>=1.5,<1.7.4|>=1.7.7,<2.0.3", + "processwire/processwire": "<=3.0.255", + "propel/propel": ">=2.0.0.0-alpha1,<2.0.0.0-alpha8", + "propel/propel1": ">=1,<1.7.2", + "psy/psysh": "<=0.11.22|>=0.12,<=0.12.18", + "pterodactyl/panel": "<1.12.3", "ptheofan/yii2-statemachine": ">=2.0.0.0-RC1-dev,<=2", "ptrofimov/beanstalk_console": "<1.7.14", "pubnub/pubnub": "<6.1", + "punktde/pt_extbase": "<1.5.1", "pusher/pusher-php-server": "<2.2.1", + "putyourlightson/craft-sprig": ">=2,<2.15.2|>=3,<3.7.2", "pwweb/laravel-core": "<=0.3.6.0-beta", "pxlrbt/filament-excel": "<1.1.14|>=2.0.0.0-alpha,<2.3.3", "pyrocms/pyrocms": "<=3.9.1", @@ -5713,44 +6117,54 @@ "rainlab/blog-plugin": "<1.4.1", "rainlab/debugbar-plugin": "<3.1", "rainlab/user-plugin": "<=1.4.5", + "ralffreit/mfa-email": "<1.0.7|==2", "rankmath/seo-by-rank-math": "<=1.0.95", "rap2hpoutre/laravel-log-viewer": "<0.13", "react/http": ">=0.7,<1.9", "really-simple-plugins/complianz-gdpr": "<6.4.2", - "redaxo/source": "<5.18.3", + "redaxo/source": "<5.21", "remdex/livehelperchat": "<4.29", + "renolit/reint-downloadmanager": "<4.0.2|>=5,<5.0.1", "reportico-web/reportico": "<=8.1", - "rhukster/dom-sanitizer": "<1.0.7", + "rhukster/dom-sanitizer": "<1.0.10", "rmccue/requests": ">=1.6,<1.8", - "robrichards/xmlseclibs": ">=1,<3.0.4", + "roadiz/documents": "<2.3.42|>=2.4,<2.5.44|>=2.6,<2.6.28|>=2.7,<2.7.9", + "roadiz/openid": "<2.3.43|>=2.5,<2.5.45|>=2.6,<2.6.31|>=2.7,<2.7.18", + "robrichards/xmlseclibs": "<3.1.5", "roots/soil": "<4.1", + "roundcube/roundcubemail": "<1.5.10|>=1.6,<1.6.11|>=1.7.0.0-beta,<1.7.0.0-RC5-dev", "rudloff/alltube": "<3.0.3", "rudloff/rtmpdump-bin": "<=2.3.1", - "s-cart/core": "<6.9", + "s-cart/core": "<=9.0.5", "s-cart/s-cart": "<6.9", + "s9y/serendipity": "<2.6", "sabberworm/php-css-parser": ">=1,<1.0.1|>=2,<2.0.1|>=3,<3.0.1|>=4,<4.0.1|>=5,<5.0.9|>=5.1,<5.1.3|>=5.2,<5.2.1|>=6,<6.0.2|>=7,<7.0.4|>=8,<8.0.1|>=8.1,<8.1.1|>=8.2,<8.2.1|>=8.3,<8.3.1", "sabre/dav": ">=1.6,<1.7.11|>=1.8,<1.8.9", + "saloonphp/saloon": "<4", "samwilson/unlinked-wikibase": "<1.42", "scheb/two-factor-bundle": "<3.26|>=4,<4.11", "sensiolabs/connect": "<4.2.3", "serluck/phpwhois": "<=4.2.6", + "setasign/fpdi": "<2.6.7", "sfroemken/url_redirect": "<=1.2.1", "sheng/yiicms": "<1.2.1", - "shopware/core": "<6.5.8.17-dev|>=6.6,<6.6.10.3-dev|>=6.7.0.0-RC1-dev,<6.7.0.0-RC2-dev", - "shopware/platform": "<6.5.8.17-dev|>=6.6,<6.6.10.3-dev|>=6.7.0.0-RC1-dev,<6.7.0.0-RC2-dev", + "shopper/cart": "<2.8", + "shopper/framework": "<2.8", + "shopware/core": "<6.6.10.18-dev|>=6.7,<6.7.10.1-dev", + "shopware/platform": "<6.6.10.18-dev|>=6.7,<6.7.10.1-dev", "shopware/production": "<=6.3.5.2", - "shopware/shopware": "<=5.7.17", - "shopware/storefront": "<=6.4.8.1|>=6.5.8,<6.5.8.7-dev", + "shopware/shopware": "<=6.3.5.2|>=6.4.6,<6.6.10.10-dev|>=6.7,<6.7.6.1-dev", + "shopware/storefront": "<6.6.10.10-dev|>=6.7,<6.7.5.1-dev", "shopxo/shopxo": "<=6.4", - "showdoc/showdoc": "<2.10.4", + "showdoc/showdoc": "<3.8.1", "shuchkin/simplexlsx": ">=1.0.12,<1.1.13", "silverstripe-australia/advancedreports": ">=1,<=2", "silverstripe/admin": "<1.13.19|>=2,<2.1.8", - "silverstripe/assets": ">=1,<1.11.1", - "silverstripe/cms": "<4.11.3", + "silverstripe/assets": "<2.4.5|>=3,<3.1.3", + "silverstripe/cms": "<6.2.1", "silverstripe/comments": ">=1.3,<3.1.1", - "silverstripe/forum": "<=0.6.1|>=0.7,<=0.7.3", - "silverstripe/framework": "<5.3.8", + "silverstripe/forum": "<0.6.2|>=0.7,<0.7.4", + "silverstripe/framework": "<6.2.2", "silverstripe/graphql": ">=2,<2.0.5|>=3,<3.8.2|>=4,<4.3.7|>=5,<5.1.3", "silverstripe/hybridsessions": ">=1,<2.4.1|>=2.5,<2.5.1", "silverstripe/recipe-cms": ">=4.5,<4.5.3", @@ -5760,47 +6174,61 @@ "silverstripe/silverstripe-omnipay": "<2.5.2|>=3,<3.0.2|>=3.1,<3.1.4|>=3.2,<3.2.1", "silverstripe/subsites": ">=2,<2.6.1", "silverstripe/taxonomy": ">=1.3,<1.3.1|>=2,<2.0.1", - "silverstripe/userforms": "<3|>=5,<5.4.2", + "silverstripe/userforms": "<6.4.9|>=7,<7.0.7|>=7.1,<7.1.1", + "silverstripe/versioned": "<3.2.1", "silverstripe/versioned-admin": ">=1,<1.11.1", + "simogeo/filemanager": "<=2.5", "simple-updates/phpwhois": "<=1", "simplesamlphp/saml2": "<=4.16.15|>=5.0.0.0-alpha1,<=5.0.0.0-alpha19", "simplesamlphp/saml2-legacy": "<=4.16.15", "simplesamlphp/simplesamlphp": "<1.18.6", + "simplesamlphp/simplesamlphp-module-casserver": "<=7.0.2", "simplesamlphp/simplesamlphp-module-infocard": "<1.0.1", "simplesamlphp/simplesamlphp-module-openid": "<1", "simplesamlphp/simplesamlphp-module-openidprovider": "<0.9", "simplesamlphp/xml-common": "<1.20", - "simplesamlphp/xml-security": "==1.6.11", + "simplesamlphp/xml-security": "<1.13.9|>=2,<2.3.1", "simplito/elliptic-php": "<1.0.6", "sitegeist/fluid-components": "<3.5", + "sjbr/sr-feuser-register": "<2.6.2|>=5.1,<12.5", "sjbr/sr-freecap": "<2.4.6|>=2.5,<2.5.3", + "sjbr/static-info-tables": "<2.3.1", "slim/psr7": "<1.4.1|>=1.5,<1.5.1|>=1.6,<1.6.1", - "slim/slim": "<2.6", + "slim/slim": "<2.6|>=4.4,<=4.15.1", "slub/slub-events": "<3.0.3", "smarty/smarty": "<4.5.3|>=5,<5.1.1", - "snipe/snipe-it": "<=7.0.13", + "snipe/snipe-it": "<=8.6.1", "socalnick/scn-social-auth": "<1.15.2", "socialiteproviders/steam": "<1.1", + "solidinvoice/solidinvoice": "<=2.3.15", + "solspace/craft-freeform": "<4.1.29|>=5,<=5.14.6", + "soosyze/soosyze": "<=2", "spatie/browsershot": "<5.0.5", "spatie/image-optimizer": "<1.7.3", + "spatie/schema-org": ">=3.23.1,<3.23.2|>=4,<4.0.2", "spencer14420/sp-php-email-handler": "<1", "spipu/html2pdf": "<5.2.8", + "spiral/roadrunner": "<2025.1", + "spomky-labs/otphp": "<11.4.3", "spoon/library": "<1.4.1", "spoonity/tcpdf": "<6.2.22", "squizlabs/php_codesniffer": ">=1,<2.8.1|>=3,<3.0.1", "ssddanbrown/bookstack": "<24.05.1", - "starcitizentools/citizen-skin": ">=2.6.3,<2.31", - "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2", - "statamic/cms": "<=5.16", + "starcitizentools/citizen-skin": ">=1.9.4,<3.9", + "starcitizentools/short-description": ">=4,<4.0.1", + "starcitizentools/tabber-neue": ">=1.9.1,<2.7.2|>=3,<3.1.1", + "starcitizenwiki/embedvideo": "<=4", + "statamic/cms": "<5.74|>=6,<6.20.3", "stormpath/sdk": "<9.9.99", - "studio-42/elfinder": "<=2.1.64", + "studio-42/elfinder": "<=2.1.67", "studiomitte/friendlycaptcha": "<0.1.4", "subhh/libconnect": "<7.0.8|>=8,<8.1", "sukohi/surpass": "<1", "sulu/form-bundle": ">=2,<2.5.3", - "sulu/sulu": "<1.6.44|>=2,<2.5.21|>=2.6,<2.6.5", + "sulu/sulu": "<=2.6.22|>=3,<=3.0.5", "sumocoders/framework-user-bundle": "<1.4", "superbig/craft-audit": "<3.0.2", + "svewap/a21glossary": "<=0.4.10", "swag/paypal": "<5.4.4", "swiftmailer/swiftmailer": "<6.2.5", "swiftyedit/swiftyedit": "<1.2", @@ -5809,46 +6237,62 @@ "sylius/grid-bundle": "<1.10.1", "sylius/paypal-plugin": "<1.6.2|>=1.7,<1.7.2|>=2,<2.0.2", "sylius/resource-bundle": ">=1,<1.3.14|>=1.4,<1.4.7|>=1.5,<1.5.2|>=1.6,<1.6.4", - "sylius/sylius": "<1.12.19|>=1.13.0.0-alpha1,<1.13.4", + "sylius/sylius": "<1.9.12|>=1.10,<1.10.16|>=1.11,<1.11.17|>=1.12,<=1.12.22|>=1.13,<=1.13.14|>=1.14,<=1.14.17|>=2,<=2.0.15|>=2.1,<=2.1.11|>=2.2,<=2.2.2", + "symbiote/silverstripe-advancedworkflow": "<6.4.5|>=7,<7.1.3|>=7.2,<7.2.1", "symbiote/silverstripe-multivaluefield": ">=3,<3.1", "symbiote/silverstripe-queuedjobs": ">=3,<3.0.2|>=3.1,<3.1.4|>=4,<4.0.7|>=4.1,<4.1.2|>=4.2,<4.2.4|>=4.3,<4.3.3|>=4.4,<4.4.3|>=4.5,<4.5.1|>=4.6,<4.6.4", "symbiote/silverstripe-seed": "<6.0.3", "symbiote/silverstripe-versionedfiles": "<=2.0.3", "symfont/process": ">=0", - "symfony/cache": ">=3.1,<3.4.35|>=4,<4.2.12|>=4.3,<4.3.8", + "symfony/cache": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/dependency-injection": ">=2,<2.0.17|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", + "symfony/dom-crawler": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/error-handler": ">=4.4,<4.4.4|>=5,<5.0.4", "symfony/form": ">=2.3,<2.3.35|>=2.4,<2.6.12|>=2.7,<2.7.50|>=2.8,<2.8.49|>=3,<3.4.20|>=4,<4.0.15|>=4.1,<4.1.9|>=4.2,<4.2.1", "symfony/framework-bundle": ">=2,<2.3.18|>=2.4,<2.4.8|>=2.5,<2.5.2|>=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7|>=5.3.14,<5.3.15|>=5.4.3,<5.4.4|>=6.0.3,<6.0.4", - "symfony/http-client": ">=4.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", - "symfony/http-foundation": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", - "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6", + "symfony/html-sanitizer": ">=6.1,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", + "symfony/http-client": ">=4.3,<5.4.53|>=6,<6.4.15|>=7,<7.1.8", + "symfony/http-foundation": "<5.4.50|>=6,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", + "symfony/http-kernel": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.2.6|>=7.4,<7.4.12|>=8,<8.0.12", "symfony/intl": ">=2.7,<2.7.38|>=2.8,<2.8.31|>=3,<3.2.14|>=3.3,<3.3.13", + "symfony/json-path": ">=7.3,<7.4.12|>=8,<8.0.12", + "symfony/lox24-notifier": ">=7.1,<7.4.12|>=8,<8.0.12", + "symfony/mailer": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", + "symfony/mailjet-mailer": ">=6.4,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", + "symfony/mailomat-mailer": ">=7.2,<7.4.13|>=8,<8.0.13", + "symfony/mailtrap-mailer": ">=7.2,<7.4.12|>=8,<8.0.12", "symfony/maker-bundle": ">=1.27,<1.29.2|>=1.30,<1.31.1", - "symfony/mime": ">=4.3,<4.3.8", + "symfony/mime": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", + "symfony/monolog-bridge": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/phpunit-bridge": ">=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", - "symfony/polyfill": ">=1,<1.10", + "symfony/polyfill": ">=1,<1.10|>=1.17.1,<1.38.1", + "symfony/polyfill-intl-idn": ">=1.17.1,<1.38.1", "symfony/polyfill-php55": ">=1,<1.10", - "symfony/process": "<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/process": "<5.4.51|>=6,<6.4.33|>=7,<7.1.7|>=7.3,<7.3.11|>=7.4,<7.4.5|>=8,<8.0.5", "symfony/proxy-manager-bridge": ">=2.7,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.1.12|>=4.2,<4.2.7", - "symfony/routing": ">=2,<2.0.19", - "symfony/runtime": ">=5.3,<5.4.46|>=6,<6.4.14|>=7,<7.1.7", + "symfony/routing": "<5.4.53|>=6,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", + "symfony/runtime": ">=5.3,<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symfony/security": ">=2,<2.7.51|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.8", "symfony/security-bundle": ">=2,<4.4.50|>=5,<5.4.20|>=6,<6.0.20|>=6.1,<6.1.12|>=6.2,<6.4.10|>=7,<7.0.10|>=7.1,<7.1.3", "symfony/security-core": ">=2.4,<2.6.13|>=2.7,<2.7.9|>=2.7.30,<2.7.32|>=2.8,<3.4.49|>=4,<4.4.24|>=5,<5.2.9", "symfony/security-csrf": ">=2.4,<2.7.48|>=2.8,<2.8.41|>=3,<3.3.17|>=3.4,<3.4.11|>=4,<4.0.11", "symfony/security-guard": ">=2.8,<3.4.48|>=4,<4.4.23|>=5,<5.2.8", - "symfony/security-http": ">=2.3,<2.3.41|>=2.4,<2.7.51|>=2.8,<2.8.50|>=3,<3.4.26|>=4,<4.2.12|>=4.3,<4.3.8|>=4.4,<4.4.7|>=5,<5.0.7|>=5.1,<5.2.8|>=5.3,<5.4.47|>=6,<6.4.15|>=7,<7.1.8", + "symfony/security-http": "<5.4.53|>=6,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", "symfony/serializer": ">=2,<2.0.11|>=4.1,<4.4.35|>=5,<5.3.12", - "symfony/symfony": "<5.4.47|>=6,<6.4.15|>=7,<7.1.8", + "symfony/symfony": "<5.4.53|>=6,<6.4.41|>=7,<7.4.13|>=8,<8.0.13", "symfony/translation": ">=2,<2.0.17", - "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8", - "symfony/ux-autocomplete": "<2.11.2", + "symfony/twig-bridge": ">=2,<4.4.51|>=5,<5.4.31|>=6,<6.3.8|>=6.4.24,<6.4.40", + "symfony/twilio-notifier": ">=6.4,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", + "symfony/ux-autocomplete": "<2.36|>=3,<3.1", + "symfony/ux-icons": ">=2.17,<2.36.1|>=3,<3.2", + "symfony/ux-live-component": "<2.36|>=3,<3.1", + "symfony/ux-toolkit": ">=2.32,<2.36.1|>=3,<3.2", + "symfony/ux-twig-component": "<2.25.1", "symfony/validator": "<5.4.43|>=6,<6.4.11|>=7,<7.1.4", "symfony/var-exporter": ">=4.2,<4.2.12|>=4.3,<4.3.8", - "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4", + "symfony/web-profiler-bundle": ">=2,<2.3.19|>=2.4,<2.4.9|>=2.5,<2.5.4|>=7.2.9,<7.4.12|>=8,<8.0.12", "symfony/webhook": ">=6.3,<6.3.8", - "symfony/yaml": ">=2,<2.0.22|>=2.1,<2.1.7|>=2.2.0.0-beta1,<2.2.0.0-beta2", + "symfony/yaml": "<5.4.52|>=6,<6.4.40|>=7,<7.4.12|>=8,<8.0.12", "symphonycms/symphony-2": "<2.6.4", "t3/dce": "<0.11.5|>=2.2,<2.6.2", "t3g/svg-sanitizer": "<1.0.3", @@ -5862,42 +6306,55 @@ "thelia/thelia": ">=2.1,<2.1.3", "theonedemon/phpwhois": "<=4.2.5", "thinkcmf/thinkcmf": "<6.0.8", - "thorsten/phpmyfaq": "<=4.0.1", + "thorsten/phpmyfaq": "<4.1.4", "tikiwiki/tiki-manager": "<=17.1", "timber/timber": ">=0.16.6,<1.23.1|>=1.24,<1.24.1|>=2,<2.1", - "tinymce/tinymce": "<7.2", + "tinymce/tinymce": "<7.9.3|>=8,<8.5.1", "tinymighty/wiki-seo": "<1.2.2", "titon/framework": "<9.9.99", "tltneon/lgsl": "<7", "tobiasbg/tablepress": "<=2.0.0.0-RC1", + "tomasnorre/crawler": "<11.0.13|>=12,<12.0.11", "topthink/framework": "<6.0.17|>=6.1,<=8.0.4", "topthink/think": "<=6.1.1", "topthink/thinkphp": "<=3.2.3|>=6.1.3,<=8.0.4", - "torrentpier/torrentpier": "<=2.4.3", - "tpwd/ke_search": "<4.0.3|>=4.1,<4.6.6|>=5,<5.0.2", + "torrentpier/torrentpier": "<=2.8.8", + "tpwd/ke_search": "<5.6.2|>=6,<6.6.1|>=7,<7.0.1", "tribalsystems/zenario": "<=9.7.61188", "truckersmp/phpwhois": "<=4.3.1", "ttskch/pagination-service-provider": "<1", - "twbs/bootstrap": "<=3.4.1|>=4,<=4.6.2", - "twig/twig": "<3.11.2|>=3.12,<3.14.1|>=3.16,<3.19", + "twbs/bootstrap": "<3.4.1|>=4,<4.3.1", + "twig/cssinliner-extra": "<3.26", + "twig/intl-extra": "<3.26", + "twig/markdown-extra": "<3.26", + "twig/twig": "<3.27", + "typicms/core": "<16.1.7", "typo3/cms": "<9.5.29|>=10,<10.4.35|>=11,<11.5.23|>=12,<12.2", - "typo3/cms-backend": "<4.1.14|>=4.2,<4.2.15|>=4.3,<4.3.7|>=4.4,<4.4.4|>=7,<=7.6.50|>=8,<=8.7.39|>=9,<=9.5.24|>=10,<10.4.46|>=11,<11.5.40|>=12,<12.4.21|>=13,<13.3.1", + "typo3/cms-backend": "<10.4.57|>=11,<11.5.51|>=12,<12.4.46|>=13,<13.4.31|>=14,<14.3.3", "typo3/cms-belog": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", - "typo3/cms-beuser": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", - "typo3/cms-core": "<=8.7.56|>=9,<=9.5.48|>=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", - "typo3/cms-dashboard": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", + "typo3/cms-beuser": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", + "typo3/cms-core": "<10.4.57|>=11,<11.5.51|>=12,<12.4.46|>=13,<13.4.31|>=14,<14.3.3", + "typo3/cms-dashboard": ">=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", "typo3/cms-extbase": "<6.2.24|>=7,<7.6.8|==8.1.1", "typo3/cms-extensionmanager": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", + "typo3/cms-felogin": ">=4.2,<4.2.3", + "typo3/cms-filelist": ">=11,<11.5.51|>=12,<12.4.46|>=13,<13.4.31|>=14,<14.3.3", "typo3/cms-fluid": "<4.3.4|>=4.4,<4.4.1", - "typo3/cms-form": ">=8,<=8.7.39|>=9,<=9.5.24|>=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", + "typo3/cms-form": "<10.4.57|>=11,<11.5.51|>=12,<12.4.46|>=13,<13.4.31|>=14,<14.3.3", "typo3/cms-frontend": "<4.3.9|>=4.4,<4.4.5", - "typo3/cms-indexed-search": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<=13.4.2", + "typo3/cms-indexed-search": ">=10,<=10.4.47|>=11,<=11.5.41|>=12,<=12.4.24|>=13,<13.4.31|>=14,<14.3.3", "typo3/cms-install": "<4.1.14|>=4.2,<4.2.16|>=4.3,<4.3.9|>=4.4,<4.4.5|>=12.2,<12.4.8|==13.4.2", "typo3/cms-lowlevel": ">=11,<=11.5.41", + "typo3/cms-recordlist": ">=11,<11.5.48", + "typo3/cms-recycler": "<10.4.57|>=11,<11.5.51|>=12,<12.4.46|>=13,<13.4.31|>=14,<14.3.3", + "typo3/cms-redirects": ">=10,<=10.4.54|>=11,<=11.5.48|>=12,<=12.4.40|>=13,<=13.4.22|>=14,<=14.0.1", "typo3/cms-rte-ckeditor": ">=9.5,<9.5.42|>=10,<10.4.39|>=11,<11.5.30", "typo3/cms-scheduler": ">=11,<=11.5.41", + "typo3/cms-setup": ">=9,<=9.5.50|>=10,<=10.4.49|>=11,<=11.5.43|>=12,<=12.4.30|>=13,<=13.4.11", + "typo3/cms-webhooks": ">=12,<=12.4.30|>=13,<=13.4.11", + "typo3/cms-workspaces": ">=9,<9.5.55|>=10,<10.4.54|>=11,<11.5.48|>=12,<12.4.37|>=13,<13.4.18", "typo3/flow": ">=1,<1.0.4|>=1.1,<1.1.1|>=2,<2.0.1|>=2.3,<2.3.16|>=3,<3.0.12|>=3.1,<3.1.10|>=3.2,<3.2.13|>=3.3,<3.3.13|>=4,<4.0.6", - "typo3/html-sanitizer": ">=1,<=1.5.2|>=2,<=2.1.3", + "typo3/html-sanitizer": "<2.3.2", "typo3/neos": ">=1.1,<1.1.3|>=1.2,<1.2.13|>=2,<2.0.4|>=2.3,<2.3.99|>=3,<3.0.20|>=3.1,<3.1.18|>=3.2,<3.2.14|>=3.3,<3.3.23|>=4,<4.0.17|>=4.1,<4.1.16|>=4.2,<4.2.12|>=4.3,<4.3.3", "typo3/phar-stream-wrapper": ">=1,<2.1.1|>=3,<3.1.1", "typo3/swiftmailer": ">=4.1,<4.1.99|>=5.4,<5.4.5", @@ -5905,38 +6362,48 @@ "ua-parser/uap-php": "<3.8", "uasoft-indonesia/badaso": "<=2.9.7", "unisharp/laravel-filemanager": "<2.9.1", - "unopim/unopim": "<0.1.5", + "universal-omega/dynamic-page-list3": "<3.6.4", + "unopim/unopim": "<=0.3", "userfrosting/userfrosting": ">=0.3.1,<4.6.3", "usmanhalalit/pixie": "<1.0.3|>=2,<2.0.2", "uvdesk/community-skeleton": "<=1.1.1", "uvdesk/core-framework": "<=1.1.1", "vanilla/safecurl": "<0.9.2", "verbb/comments": "<1.5.5", - "verbb/formie": "<2.1.6", + "verbb/formie": "<2.2.21|>=3,<3.1.26", "verbb/image-resizer": "<2.0.9", "verbb/knock-knock": "<1.2.8", "verot/class.upload.php": "<=2.1.6", + "vertexvaar/falsftp": "<0.2.6", "villagedefrance/opencart-overclocked": "<=1.11.1", "vova07/yii2-fileapi-widget": "<0.1.9", - "vrana/adminer": "<4.8.1", + "vrana/adminer": "<5.4.2", "vufind/vufind": ">=2,<9.1.1", "waldhacker/hcaptcha": "<2.1.2", "wallabag/tcpdf": "<6.2.22", - "wallabag/wallabag": "<2.6.7", + "wallabag/wallabag": "<2.6.11", "wanglelecc/laracms": "<=1.0.3", - "web-auth/webauthn-framework": ">=3.3,<3.3.4|>=4.5,<4.9", - "web-auth/webauthn-lib": ">=4.5,<4.9", + "wapplersystems/a21glossary": "<=0.4.10", + "web-auth/webauthn-framework": ">=3.3,<3.3.4|>=4.5,<4.9|>=5.2,<5.2.4|>=5.3,<5.3.1", + "web-auth/webauthn-lib": ">=4.5,<4.9|>=5.2,<5.2.4", + "web-auth/webauthn-symfony-bundle": "<5.3.4", "web-feet/coastercms": "==5.5", + "web-token/jwt-experimental": "<=4.1.6", + "web-token/jwt-framework": "<=4.2.99", + "web-token/jwt-library": "<3.4.10|>=4,<4.0.7|>=4.1,<4.1.7", + "web-tp3/wec_map": "<3.0.3", "webbuilders-group/silverstripe-kapost-bridge": "<0.4", "webcoast/deferred-image-processing": "<1.0.2", "webklex/laravel-imap": "<5.3", "webklex/php-imap": "<5.3", + "webonyx/graphql-php": "<=15.32.2", "webpa/webpa": "<3.1.2", + "webreinvent/vaahcms": "<=2.3.1", "wikibase/wikibase": "<=1.39.3", "wikimedia/parsoid": "<0.12.2", "willdurand/js-translation-bundle": "<2.1.1", - "winter/wn-backend-module": "<1.2.4", - "winter/wn-cms-module": "<1.0.476|>=1.1,<1.1.11|>=1.2,<1.2.7", + "winter/wn-backend-module": "<1.2.12", + "winter/wn-cms-module": "<=1.2.9", "winter/wn-dusk-plugin": "<2.1", "winter/wn-system-module": "<1.2.4", "wintercms/winter": "<=1.2.3", @@ -5948,27 +6415,32 @@ "wpanel/wpanel4-cms": "<=4.3.1", "wpcloud/wp-stateless": "<3.2", "wpglobus/wpglobus": "<=1.9.6", - "wwbn/avideo": "<14.3", + "wpmetabox/meta-box": "<5.11.2", + "wwbn/avideo": "<=29", "xataface/xataface": "<3", "xpressengine/xpressengine": "<3.0.15", "yab/quarx": "<2.4.5", - "yeswiki/yeswiki": "<4.5.2", + "yansongda/pay": "<=3.7.19", + "yeswiki/yeswiki": "<4.6.4", "yetiforce/yetiforce-crm": "<6.5", "yidashi/yii2cmf": "<=2", "yii2mod/yii2-cms": "<1.9.2", - "yiisoft/yii": "<1.1.29", - "yiisoft/yii2": "<2.0.49.4-dev", + "yiisoft/yii": "<1.1.31", + "yiisoft/yii2": "<2.0.55", "yiisoft/yii2-authclient": "<2.2.15", "yiisoft/yii2-bootstrap": "<2.0.4", "yiisoft/yii2-dev": "<=2.0.45", "yiisoft/yii2-elasticsearch": "<2.0.5", "yiisoft/yii2-gii": "<=2.2.4", "yiisoft/yii2-jui": "<2.0.4", - "yiisoft/yii2-redis": "<2.0.8", + "yiisoft/yii2-redis": "<2.0.20", "yikesinc/yikes-inc-easy-mailchimp-extender": "<6.8.6", "yoast-seo-for-typo3/yoast_seo": "<7.2.3", - "yourls/yourls": "<=1.8.2", + "yoast/duplicate-post": "<=4.5", + "yourls/yourls": "<=1.10.2", "yuan1994/tpadmin": "<=1.3.12", + "yungifez/skuul": "<=2.6.5", + "z-push/z-push-dev": "<2.7.6", "zencart/zencart": "<=1.5.7.0-beta", "zendesk/zendesk_api_client_php": "<2.2.11", "zendframework/zend-cache": ">=2.4,<2.4.8|>=2.5,<2.5.3", @@ -6005,7 +6477,8 @@ "zf-commons/zfc-user": "<1.2.2", "zfcampus/zf-apigility-doctrine": ">=1,<1.0.3", "zfr/zfr-oauth2-server-module": "<0.1.2", - "zoujingli/thinkadmin": "<=6.1.53" + "zoujingli/thinkadmin": "<=6.1.53", + "zumba/json-serializer": "<3.2.3" }, "default-branch": true, "type": "metapackage", @@ -6043,32 +6516,32 @@ "type": "tidelift" } ], - "time": "2025-04-08T15:06:02+00:00" + "time": "2026-06-26T23:29:05+00:00" }, { "name": "sebastian/cli-parser", - "version": "2.0.1", + "version": "4.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084" + "reference": "7d05781b13f7dec9043a629a21d086ed74582a15" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/c34583b87e7b7a8055bf6c450c2c77ce32a24084", - "reference": "c34583b87e7b7a8055bf6c450c2c77ce32a24084", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/7d05781b13f7dec9043a629a21d086ed74582a15", + "reference": "7d05781b13f7dec9043a629a21d086ed74582a15", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "4.2-dev" } }, "autoload": { @@ -6092,155 +6565,59 @@ "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/2.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/4.2.1" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" - } - ], - "time": "2024-03-02T07:12:49+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/a81fee9eef0b7a76af11d121767abc44c104e503", - "reference": "a81fee9eef0b7a76af11d121767abc44c104e503", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/2.0.0" - }, - "funding": [ + }, { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2023-02-03T06:58:43+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "reference": "5e3a687f7d8ae33fb362c5c0743794bbb2420a1d", - "shasum": "" - }, - "require": { - "php": ">=8.1" - }, - "require-dev": { - "phpunit/phpunit": "^10.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/3.0.0" - }, - "funding": [ + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, { - "url": "https://github.com/sebastianbergmann", - "type": "github" + "url": "https://tidelift.com/funding/github/packagist/sebastian/cli-parser", + "type": "tidelift" } ], - "time": "2023-02-03T06:59:15+00:00" + "time": "2026-05-17T05:29:34+00:00" }, { "name": "sebastian/comparator", - "version": "5.0.3", + "version": "7.1.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e" + "reference": "7c65c1e79836812819705b473a90c12399542485" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", - "reference": "a18251eb0b7a2dcd2f7aa3d6078b18545ef0558e", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/7c65c1e79836812819705b473a90c12399542485", + "reference": "7c65c1e79836812819705b473a90c12399542485", "shasum": "" }, "require": { "ext-dom": "*", "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/diff": "^5.0", - "sebastian/exporter": "^5.0" + "php": ">=8.3", + "sebastian/diff": "^7.0", + "sebastian/exporter": "^7.0.3" }, "require-dev": { - "phpunit/phpunit": "^10.5" + "phpunit/phpunit": "^12.5.25" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.1-dev" } }, "autoload": { @@ -6280,41 +6657,53 @@ "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/comparator/tree/7.1.8" }, "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": "2024-10-18T14:56:07+00:00" + "time": "2026-05-21T04:45:25+00:00" }, { "name": "sebastian/complexity", - "version": "3.2.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "68ff824baeae169ec9f2137158ee529584553799" + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/68ff824baeae169ec9f2137158ee529584553799", - "reference": "68ff824baeae169ec9f2137158ee529584553799", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/bad4316aba5303d0221f43f8cee37eb58d384bbb", + "reference": "bad4316aba5303d0221f43f8cee37eb58d384bbb", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -6338,7 +6727,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/complexity/tree/5.0.0" }, "funding": [ { @@ -6346,33 +6735,33 @@ "type": "github" } ], - "time": "2023-12-21T08:37:17+00:00" + "time": "2025-02-07T04:55:25+00:00" }, { "name": "sebastian/diff", - "version": "5.1.1", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e" + "reference": "7ab1ea946c012266ca32390913653d844ecd085f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/c41e007b4b62af48218231d6c2275e4c9b975b2e", - "reference": "c41e007b4b62af48218231d6c2275e4c9b975b2e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7ab1ea946c012266ca32390913653d844ecd085f", + "reference": "7ab1ea946c012266ca32390913653d844ecd085f", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0", - "symfony/process": "^6.4" + "phpunit/phpunit": "^12.0", + "symfony/process": "^7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -6405,7 +6794,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/5.1.1" + "source": "https://github.com/sebastianbergmann/diff/tree/7.0.0" }, "funding": [ { @@ -6413,27 +6802,27 @@ "type": "github" } ], - "time": "2024-03-02T07:15:17+00:00" + "time": "2025-02-07T04:55:46+00:00" }, { "name": "sebastian/environment", - "version": "6.1.0", + "version": "8.1.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984" + "reference": "9d32c685773823b1983e256ae4ecd48a10d6e439" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/8074dbcd93529b357029f5cc5058fd3e43666984", - "reference": "8074dbcd93529b357029f5cc5058fd3e43666984", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/9d32c685773823b1983e256ae4ecd48a10d6e439", + "reference": "9d32c685773823b1983e256ae4ecd48a10d6e439", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.5.26" }, "suggest": { "ext-posix": "*" @@ -6441,7 +6830,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "6.1-dev" + "dev-main": "8.1-dev" } }, "autoload": { @@ -6469,42 +6858,54 @@ "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/6.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/8.1.2" }, "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/environment", + "type": "tidelift" } ], - "time": "2024-03-23T08:47:14+00:00" + "time": "2026-05-25T13:40:20+00:00" }, { "name": "sebastian/exporter", - "version": "5.1.2", + "version": "7.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf" + "reference": "c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/955288482d97c19a372d3f31006ab3f37da47adf", - "reference": "955288482d97c19a372d3f31006ab3f37da47adf", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23", + "reference": "c5e21b5de653ce0a769fb36f5cdfcb5e7a32cf23", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=8.1", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/recursion-context": "^7.0.1" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.1-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -6547,43 +6948,55 @@ "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/5.1.2" + "source": "https://github.com/sebastianbergmann/exporter/tree/7.0.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/exporter", + "type": "tidelift" } ], - "time": "2024-03-02T07:17:12+00:00" + "time": "2026-05-20T04:37:17+00:00" }, { "name": "sebastian/global-state", - "version": "6.0.2", + "version": "8.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9" + "reference": "b164d3274d6537ab462591c5755f76a8f5b1aae9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", - "reference": "987bafff24ecc4c9ac418cab1145b96dd6e9cbd9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b164d3274d6537ab462591c5755f76a8f5b1aae9", + "reference": "b164d3274d6537ab462591c5755f76a8f5b1aae9", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0.1" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.5.28" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-main": "8.0-dev" } }, "autoload": { @@ -6609,41 +7022,53 @@ "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/6.0.2" + "source": "https://github.com/sebastianbergmann/global-state/tree/8.0.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/global-state", + "type": "tidelift" } ], - "time": "2024-03-02T07:19:19+00:00" + "time": "2026-06-01T15:10:33+00:00" }, { "name": "sebastian/lines-of-code", - "version": "2.0.2", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0" + "reference": "d543b8ef219dcd8da262cbb958639a96bedba10e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/856e7f6a75a84e339195d48c556f23be2ebf75d0", - "reference": "856e7f6a75a84e339195d48c556f23be2ebf75d0", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d543b8ef219dcd8da262cbb958639a96bedba10e", + "reference": "d543b8ef219dcd8da262cbb958639a96bedba10e", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=8.1" + "nikic/php-parser": "^5.7.0", + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -6667,42 +7092,54 @@ "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/4.0.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/lines-of-code", + "type": "tidelift" } ], - "time": "2023-12-21T08:38:20+00:00" + "time": "2026-05-19T16:22:07+00:00" }, { "name": "sebastian/object-enumerator", - "version": "5.0.0", + "version": "7.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906" + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/202d0e344a580d7f7d04b3fafce6933e59dae906", - "reference": "202d0e344a580d7f7d04b3fafce6933e59dae906", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1effe8e9b8e068e9ae228e542d5d11b5d16db894", + "reference": "1effe8e9b8e068e9ae228e542d5d11b5d16db894", "shasum": "" }, "require": { - "php": ">=8.1", - "sebastian/object-reflector": "^3.0", - "sebastian/recursion-context": "^5.0" + "php": ">=8.3", + "sebastian/object-reflector": "^5.0", + "sebastian/recursion-context": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -6724,7 +7161,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/7.0.0" }, "funding": [ { @@ -6732,32 +7170,32 @@ "type": "github" } ], - "time": "2023-02-03T07:08:32+00:00" + "time": "2025-02-07T04:57:48+00:00" }, { "name": "sebastian/object-reflector", - "version": "3.0.0", + "version": "5.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957" + "reference": "4bfa827c969c98be1e527abd576533293c634f6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/24ed13d98130f0e7122df55d06c5c4942a577957", - "reference": "24ed13d98130f0e7122df55d06c5c4942a577957", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/4bfa827c969c98be1e527abd576533293c634f6a", + "reference": "4bfa827c969c98be1e527abd576533293c634f6a", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -6779,7 +7217,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/3.0.0" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/5.0.0" }, "funding": [ { @@ -6787,32 +7226,32 @@ "type": "github" } ], - "time": "2023-02-03T07:06:18+00:00" + "time": "2025-02-07T04:58:17+00:00" }, { "name": "sebastian/recursion-context", - "version": "5.0.0", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712" + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/05909fb5bc7df4c52992396d0116aed689f93712", - "reference": "05909fb5bc7df4c52992396d0116aed689f93712", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", + "reference": "0b01998a7d5b1f122911a66bebcb8d46f0c82d8c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -6842,40 +7281,53 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/5.0.0" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/7.0.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": "2023-02-03T07:05:40+00:00" + "time": "2025-08-13T04:44:59+00:00" }, { "name": "sebastian/type", - "version": "4.0.0", + "version": "6.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf" + "reference": "82ff822c2edc46724be9f7411d3163021f602773" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/462699a16464c3944eefc02ebdd77882bd3925bf", - "reference": "462699a16464c3944eefc02ebdd77882bd3925bf", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/82ff822c2edc46724be9f7411d3163021f602773", + "reference": "82ff822c2edc46724be9f7411d3163021f602773", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "require-dev": { - "phpunit/phpunit": "^10.0" + "phpunit/phpunit": "^12.5.25" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -6898,37 +7350,50 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/4.0.0" + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/6.0.4" }, "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" } ], - "time": "2023-02-03T07:10:45+00:00" + "time": "2026-05-20T06:45:45+00:00" }, { "name": "sebastian/version", - "version": "4.0.1", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17" + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c51fa83a5d8f43f1402e3f32a005e6262244ef17", - "reference": "c51fa83a5d8f43f1402e3f32a005e6262244ef17", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/3e6ccf7657d4f0a59200564b08cead899313b53c", + "reference": "3e6ccf7657d4f0a59200564b08cead899313b53c", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -6951,7 +7416,8 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/4.0.1" + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/6.0.0" }, "funding": [ { @@ -6959,26 +7425,26 @@ "type": "github" } ], - "time": "2023-02-07T11:34:05+00:00" + "time": "2025-02-07T05:00:38+00:00" }, { "name": "slim/slim", - "version": "4.14.0", + "version": "4.15.2", "source": { "type": "git", "url": "https://github.com/slimphp/Slim.git", - "reference": "5943393b88716eb9e82c4161caa956af63423913" + "reference": "e12cb05ca2a14e8f459d019e87a31dc915b80470" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/slimphp/Slim/zipball/5943393b88716eb9e82c4161caa956af63423913", - "reference": "5943393b88716eb9e82c4161caa956af63423913", + "url": "https://api.github.com/repos/slimphp/Slim/zipball/e12cb05ca2a14e8f459d019e87a31dc915b80470", + "reference": "e12cb05ca2a14e8f459d019e87a31dc915b80470", "shasum": "" }, "require": { "ext-json": "*", "nikic/fast-route": "^1.3", - "php": "^7.4 || ^8.0", + "php": "~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0", "psr/container": "^1.0 || ^2.0", "psr/http-factory": "^1.1", "psr/http-message": "^1.1 || ^2.0", @@ -6987,7 +7453,7 @@ "psr/log": "^1.1 || ^2.0 || ^3.0" }, "require-dev": { - "adriansuter/php-autoload-override": "^1.4", + "adriansuter/php-autoload-override": "^1.4 || ^2", "ext-simplexml": "*", "guzzlehttp/psr7": "^2.6", "httpsoft/http-message": "^1.1", @@ -6997,12 +7463,12 @@ "nyholm/psr7-server": "^1.1", "phpspec/prophecy": "^1.19", "phpspec/prophecy-phpunit": "^2.1", - "phpstan/phpstan": "^1.11", - "phpunit/phpunit": "^9.6", + "phpstan/phpstan": "^1 || ^2", + "phpunit/phpunit": "^9.6 || ^10 || ^11 || ^12", "slim/http": "^1.3", "slim/psr7": "^1.6", "squizlabs/php_codesniffer": "^3.10", - "vimeo/psalm": "^5.24" + "vimeo/psalm": "^5 || ^6" }, "suggest": { "ext-simplexml": "Needed to support XML format in BodyParsingMiddleware", @@ -7029,17 +7495,17 @@ { "name": "Andrew Smith", "email": "a.smith@silentworks.co.uk", - "homepage": "http://silentworks.co.uk" + "homepage": "https://silentworks.co.uk" }, { "name": "Rob Allen", "email": "rob@akrabat.com", - "homepage": "http://akrabat.com" + "homepage": "https://akrabat.com" }, { "name": "Pierre Berube", "email": "pierre@lgse.com", - "homepage": "http://www.lgse.com" + "homepage": "https://www.lgse.com" }, { "name": "Gabriel Manricks", @@ -7075,20 +7541,20 @@ "type": "tidelift" } ], - "time": "2024-06-13T08:54:48+00:00" + "time": "2026-05-22T08:00:12+00:00" }, { "name": "spatie/browsershot", - "version": "5.0.8", + "version": "5.4.0", "source": { "type": "git", "url": "https://github.com/spatie/browsershot.git", - "reference": "0102971ae974022ec4a7a149e8924ea355b52cc3" + "reference": "dcf7a65fd1d0fc8fd113739b84982377728d0b2f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/browsershot/zipball/0102971ae974022ec4a7a149e8924ea355b52cc3", - "reference": "0102971ae974022ec4a7a149e8924ea355b52cc3", + "url": "https://api.github.com/repos/spatie/browsershot/zipball/dcf7a65fd1d0fc8fd113739b84982377728d0b2f", + "reference": "dcf7a65fd1d0fc8fd113739b84982377728d0b2f", "shasum": "" }, "require": { @@ -7096,13 +7562,13 @@ "ext-json": "*", "php": "^8.2", "spatie/temporary-directory": "^2.0", - "symfony/process": "^6.0|^7.0" + "symfony/process": "^6.0|^7.0|^8.0" }, "require-dev": { - "pestphp/pest": "^3.0", + "pestphp/pest": "^3.0|^4.0", "spatie/image": "^3.6", "spatie/pdf-to-text": "^1.52", - "spatie/phpunit-snapshot-assertions": "^4.2.3|^5.0" + "spatie/phpunit-snapshot-assertions": "^5.0" }, "type": "library", "autoload": { @@ -7135,7 +7601,7 @@ "webpage" ], "support": { - "source": "https://github.com/spatie/browsershot/tree/5.0.8" + "source": "https://github.com/spatie/browsershot/tree/5.4.0" }, "funding": [ { @@ -7143,20 +7609,20 @@ "type": "github" } ], - "time": "2025-02-17T09:56:12+00:00" + "time": "2026-05-26T13:13:33+00:00" }, { "name": "spatie/temporary-directory", - "version": "2.3.0", + "version": "2.4.0", "source": { "type": "git", "url": "https://github.com/spatie/temporary-directory.git", - "reference": "580eddfe9a0a41a902cac6eeb8f066b42e65a32b" + "reference": "32cbb9645b28839cf4f476708e99a2c70e6802c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/580eddfe9a0a41a902cac6eeb8f066b42e65a32b", - "reference": "580eddfe9a0a41a902cac6eeb8f066b42e65a32b", + "url": "https://api.github.com/repos/spatie/temporary-directory/zipball/32cbb9645b28839cf4f476708e99a2c70e6802c9", + "reference": "32cbb9645b28839cf4f476708e99a2c70e6802c9", "shasum": "" }, "require": { @@ -7192,7 +7658,7 @@ ], "support": { "issues": "https://github.com/spatie/temporary-directory/issues", - "source": "https://github.com/spatie/temporary-directory/tree/2.3.0" + "source": "https://github.com/spatie/temporary-directory/tree/2.4.0" }, "funding": [ { @@ -7204,29 +7670,82 @@ "type": "github" } ], - "time": "2025-01-13T13:04:43+00:00" + "time": "2026-06-22T07:55:44+00:00" + }, + { + "name": "staabm/side-effects-detector", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" + }, + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "lib/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" + ], + "support": { + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" + }, + "funding": [ + { + "url": "https://github.com/staabm", + "type": "github" + } + ], + "time": "2024-10-20T05:08:20+00:00" }, { "name": "symfony/filesystem", - "version": "v7.2.0", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" + "reference": "99aec13b82b4967ec5088222c4a3ecca955949c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", - "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/99aec13b82b4967ec5088222c4a3ecca955949c2", + "reference": "99aec13b82b4967ec5088222c4a3ecca955949c2", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^6.4|^7.0" + "symfony/process": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7254,7 +7773,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.2.0" + "source": "https://github.com/symfony/filesystem/tree/v8.1.0" }, "funding": [ { @@ -7265,32 +7784,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": "2024-10-25T15:15:23+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/finder", - "version": "v7.2.2", + "version": "v8.1.1", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb" + "reference": "e2989e762c70f9490fa3a00a0ac0fae5aa97a531" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", - "reference": "87a71856f2f56e4100373e92529eed3171695cfb", + "url": "https://api.github.com/repos/symfony/finder/zipball/e2989e762c70f9490fa3a00a0ac0fae5aa97a531", + "reference": "e2989e762c70f9490fa3a00a0ac0fae5aa97a531", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.4.1" }, "require-dev": { - "symfony/filesystem": "^6.4|^7.0" + "symfony/filesystem": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -7318,7 +7841,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v7.2.2" + "source": "https://github.com/symfony/finder/tree/v8.1.1" }, "funding": [ { @@ -7329,25 +7852,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": "2024-12-30T19:00:17+00:00" + "time": "2026-06-27T09:05:56+00:00" }, { - "name": "symfony/polyfill-php80", - "version": "v1.31.0", + "name": "symfony/polyfill-php81", + "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", - "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/6bfb9c766cacffbc8e118cb87217d08ed84e5cd7", + "reference": "6bfb9c766cacffbc8e118cb87217d08ed84e5cd7", "shasum": "" }, "require": { @@ -7365,7 +7892,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" + "Symfony\\Polyfill\\Php81\\": "" }, "classmap": [ "Resources/stubs" @@ -7376,10 +7903,6 @@ "MIT" ], "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -7389,7 +7912,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -7398,7 +7921,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.38.1" }, "funding": [ { @@ -7409,25 +7932,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": "2024-09-09T11:45:10+00:00" + "time": "2026-05-26T12:45:58+00:00" }, { - "name": "symfony/polyfill-php81", - "version": "v1.31.0", + "name": "symfony/polyfill-php84", + "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" + "url": "https://github.com/symfony/polyfill-php84.git", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", - "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "url": "https://api.github.com/repos/symfony/polyfill-php84/zipball/f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", + "reference": "f4e1dfaee5b74aba5964fe1fd4dfc7ba5e3085fa", "shasum": "" }, "require": { @@ -7445,7 +7972,7 @@ "bootstrap.php" ], "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" + "Symfony\\Polyfill\\Php84\\": "" }, "classmap": [ "Resources/stubs" @@ -7465,7 +7992,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "description": "Symfony polyfill backporting some PHP 8.4+ features to lower PHP versions", "homepage": "https://symfony.com", "keywords": [ "compatibility", @@ -7474,7 +8001,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" + "source": "https://github.com/symfony/polyfill-php84/tree/v1.38.1" }, "funding": [ { @@ -7485,29 +8012,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": "2024-09-09T11:45:10+00:00" + "time": "2026-05-26T12:51:13+00:00" }, { "name": "symfony/process", - "version": "v7.2.5", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "87b7c93e57df9d8e39a093d32587702380ff045d" + "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/87b7c93e57df9d8e39a093d32587702380ff045d", - "reference": "87b7c93e57df9d8e39a093d32587702380ff045d", + "url": "https://api.github.com/repos/symfony/process/zipball/c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", + "reference": "c4a9e58f235a6bf7f97ffbfedae2687353ac79e5", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=8.4.1" }, "type": "library", "autoload": { @@ -7535,7 +8066,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v7.2.5" + "source": "https://github.com/symfony/process/tree/v8.1.0" }, "funding": [ { @@ -7546,29 +8077,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": "2025-03-13T12:21:46+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.2.4", + "version": "v8.1.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd" + "reference": "21c07b026905d596e8379caeb115d87aa479499d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", - "reference": "5a49289e2b308214c8b9c2fda4ea454d8b8ad7cd", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/21c07b026905d596e8379caeb115d87aa479499d", + "reference": "21c07b026905d596e8379caeb115d87aa479499d", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4.1", "symfony/service-contracts": "^2.5|^3" }, "type": "library", @@ -7597,7 +8132,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.2.4" + "source": "https://github.com/symfony/stopwatch/tree/v8.1.0" }, "funding": [ { @@ -7608,32 +8143,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": "2025-02-24T10:49:57+00:00" + "time": "2026-05-29T05:06:50+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.3", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", - "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/7989e43bf381af0eac72e4f0ca5bcbfa81658be4", + "reference": "7989e43bf381af0eac72e4f0ca5bcbfa81658be4", "shasum": "" }, "require": { "ext-dom": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" + "php": "^8.1" }, "type": "library", "autoload": { @@ -7655,7 +8194,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.3" + "source": "https://github.com/theseer/tokenizer/tree/2.0.1" }, "funding": [ { @@ -7663,7 +8202,7 @@ "type": "github" } ], - "time": "2024-03-03T12:36:25+00:00" + "time": "2025-12-08T11:19:18+00:00" } ], "aliases": [], @@ -7674,8 +8213,8 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": "~8.2.0 || ~8.3.0 || ~8.4.0" + "php": "^8.4" }, "platform-dev": {}, - "plugin-api-version": "2.6.0" + "plugin-api-version": "2.9.0" } diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 3b81616..aab4991 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,13 +1,2 @@ parameters: - ignoreErrors: - - - message: '#^Parameter \#1 \$item of method RoachPHP\\Spider\\Middleware\\ItemMiddlewareInterface\:\:handleItem\(\) expects RoachPHP\\ItemPipeline\\ItemInterface, RoachPHP\\Http\\Request\|RoachPHP\\ItemPipeline\\ItemInterface given\.$#' - identifier: argument.type - count: 1 - path: src/Spider/Processor.php - - - - message: '#^Parameter \#1 \$request of method RoachPHP\\Spider\\Middleware\\RequestMiddlewareInterface\:\:handleRequest\(\) expects RoachPHP\\Http\\Request, RoachPHP\\Http\\Request\|RoachPHP\\ItemPipeline\\ItemInterface given\.$#' - identifier: argument.type - count: 1 - path: src/Spider/Processor.php + ignoreErrors: [] diff --git a/phpstan.neon b/phpstan.neon index 52af279..39a891b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,6 +1,3 @@ -includes: - - phpstan-baseline.neon - parameters: paths: - src diff --git a/src/Core/DefaultContainer.php b/src/Core/DefaultContainer.php index ef4bb7a..00e88a2 100644 --- a/src/Core/DefaultContainer.php +++ b/src/Core/DefaultContainer.php @@ -72,7 +72,7 @@ private function registerDefaultBindings(): void EventDispatcher::class, ); $this->container->add(ClockInterface::class, SystemClock::class); - $this->container->add( + $this->container->addShared( RequestSchedulerInterface::class, /** @phpstan-ignore return.type */ fn (): RequestSchedulerInterface => $this->container->get(ArrayRequestScheduler::class), diff --git a/src/Core/Engine.php b/src/Core/Engine.php index 5650ba0..93e692f 100644 --- a/src/Core/Engine.php +++ b/src/Core/Engine.php @@ -47,27 +47,35 @@ public function collect(Run $run): array $extension = new ScrapedItemCollectorExtension(); $this->eventDispatcher->addSubscriber($extension); - $this->start($run); + try { + $this->start($run); - return $extension->getScrapedItems(); + return $extension->getScrapedItems(); + } finally { + $this->eventDispatcher->removeSubscriber($extension); + } } public function start(Run $run): void { - $this->configure($run); + try { + $this->configure($run); - $this->eventDispatcher->dispatch( - new RunStarting($run), - RunStarting::NAME, - ); + $this->eventDispatcher->dispatch( + new RunStarting($run), + RunStarting::NAME, + ); - if ($this->scheduler->empty()) { - foreach ($run->startRequests as $request) { - $this->scheduleRequest($request); + if ($this->scheduler->empty()) { + foreach ($run->startRequests as $request) { + $this->scheduleRequest($request); + } } - } - $this->work($run); + $this->work($run); + } finally { + $this->cleanup($run); + } } private function work(Run $run): void @@ -100,9 +108,7 @@ private function work(Run $run): void $scheduledRequests = $this->downloader->scheduledRequests(); } - $this->downloader->flush( - fn (Response $response) => $this->onFulfilled($response), - ); + $this->downloader->flush(fn (Response $response) => $this->onFulfilled($response)); } $this->eventDispatcher->dispatch( @@ -156,4 +162,11 @@ private function configure(Run $run): void $this->eventDispatcher->addSubscriber($extension); } } + + private function cleanup(Run $run): void + { + foreach ($run->extensions as $extension) { + $this->eventDispatcher->removeSubscriber($extension); + } + } } diff --git a/src/Downloader/Middleware/DownloaderMiddlewareAdapter.php b/src/Downloader/Middleware/DownloaderMiddlewareAdapter.php index cb7219a..cef8a93 100644 --- a/src/Downloader/Middleware/DownloaderMiddlewareAdapter.php +++ b/src/Downloader/Middleware/DownloaderMiddlewareAdapter.php @@ -22,14 +22,12 @@ */ final class DownloaderMiddlewareAdapter implements DownloaderMiddlewareInterface { - private function __construct( - private RequestMiddlewareInterface|ResponseMiddlewareInterface $middleware, - ) { + private function __construct(private RequestMiddlewareInterface|ResponseMiddlewareInterface $middleware) + { } - public static function fromMiddleware( - RequestMiddlewareInterface|ResponseMiddlewareInterface $middleware, - ): DownloaderMiddlewareInterface { + public static function fromMiddleware(RequestMiddlewareInterface|ResponseMiddlewareInterface $middleware): DownloaderMiddlewareInterface + { if ($middleware instanceof DownloaderMiddlewareInterface) { return $middleware; } diff --git a/src/Downloader/Middleware/ExecuteJavascriptMiddleware.php b/src/Downloader/Middleware/ExecuteJavascriptMiddleware.php index 6e1495a..5b1be8a 100644 --- a/src/Downloader/Middleware/ExecuteJavascriptMiddleware.php +++ b/src/Downloader/Middleware/ExecuteJavascriptMiddleware.php @@ -13,12 +13,14 @@ namespace RoachPHP\Downloader\Middleware; +use GuzzleHttp\Psr7\Response as Psr7Response; use Psr\Log\LoggerInterface; +use RoachPHP\Http\Request; use RoachPHP\Http\Response; use RoachPHP\Support\Configurable; use Spatie\Browsershot\Browsershot; -final class ExecuteJavascriptMiddleware implements ResponseMiddlewareInterface +final class ExecuteJavascriptMiddleware implements RequestMiddlewareInterface { use Configurable; @@ -34,14 +36,12 @@ public function __construct( private LoggerInterface $logger, ?callable $getBrowsershot = null, ) { - $this->getBrowsershot = $getBrowsershot ?? static fn (string $uri): Browsershot => Browsershot::url($uri)->waitUntilNetworkIdle(); + $this->getBrowsershot = $getBrowsershot ?? static fn (string $uri): Browsershot => Browsershot::url($uri); } - public function handleResponse(Response $response): Response + public function handleRequest(Request $request): Request { - $browsershot = $this->configureBrowsershot( - $response->getRequest()->getUri(), - ); + $browsershot = $this->configureBrowsershot($request->getUri()); try { $body = $browsershot->bodyHtml(); @@ -51,10 +51,13 @@ public function handleResponse(Response $response): Response 'trace' => $e->getTraceAsString(), ]); - return $response->drop('Error while executing javascript'); + return $request->drop('Error while executing javascript'); } - return $response->withBody($body); + return $request->withResponse(new Response( + new Psr7Response(200, [], $body), + $request, + ), ); } /** @@ -64,6 +67,13 @@ private function configureBrowsershot(string $uri): Browsershot { $browsershot = ($this->getBrowsershot)($uri); + /** @var null|bool $waitUntilNetworkIdle */ + $waitUntilNetworkIdle = $this->option('waitUntilNetworkIdle'); + + if (null !== $waitUntilNetworkIdle) { + $browsershot->waitUntilNetworkIdle($waitUntilNetworkIdle); + } + if (!empty($this->option('chromiumArguments'))) { /** @phpstan-ignore argument.type */ $browsershot->addChromiumArguments($this->option('chromiumArguments')); @@ -112,9 +122,10 @@ private function configureBrowsershot(string $uri): Browsershot return $browsershot; } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ + 'waitUntilNetworkIdle' => true, 'chromiumArguments' => [], 'chromePath' => null, 'binPath' => null, diff --git a/src/Downloader/Middleware/HttpErrorMiddleware.php b/src/Downloader/Middleware/HttpErrorMiddleware.php index e218a92..57fb226 100644 --- a/src/Downloader/Middleware/HttpErrorMiddleware.php +++ b/src/Downloader/Middleware/HttpErrorMiddleware.php @@ -51,7 +51,7 @@ public function handleResponse(Response $response): Response return $response->drop('Unallowed HTTP status: ' . $status); } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ 'handleStatus' => [], diff --git a/src/Downloader/Middleware/ProxyMiddleware.php b/src/Downloader/Middleware/ProxyMiddleware.php index d3e5e0d..d39b4a4 100644 --- a/src/Downloader/Middleware/ProxyMiddleware.php +++ b/src/Downloader/Middleware/ProxyMiddleware.php @@ -36,9 +36,7 @@ public function __construct( public function handleRequest(Request $request): Request { if (null === $this->proxy) { - $this->logger->warning( - '[ProxyMiddleware] No proxy configured for middleware', - ); + $this->logger->warning('[ProxyMiddleware] No proxy configured for middleware'); return $request; } @@ -57,7 +55,7 @@ public function handleRequest(Request $request): Request return $request->addOption('proxy', $options->toArray()); } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ 'proxy' => [], diff --git a/src/Downloader/Middleware/RequestDeduplicationMiddleware.php b/src/Downloader/Middleware/RequestDeduplicationMiddleware.php index 2d0dbaf..9e598cd 100644 --- a/src/Downloader/Middleware/RequestDeduplicationMiddleware.php +++ b/src/Downloader/Middleware/RequestDeduplicationMiddleware.php @@ -48,8 +48,7 @@ public function handleRequest(Request $request): Request $replaceFlags |= \HTTP_URL_STRIP_QUERY; } - /** @phpstan-ignore argument.type */ - $uri = http_build_url($uri, $parts, $replaceFlags); + $uri = http_build_url($uri, false === $parts ? [] : $parts, $replaceFlags); if (\in_array($uri, $this->seenUris, true)) { $this->logger->info( @@ -65,7 +64,7 @@ public function handleRequest(Request $request): Request return $request; } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ 'ignore_url_fragments' => false, diff --git a/src/Downloader/Middleware/RetryMiddleware.php b/src/Downloader/Middleware/RetryMiddleware.php new file mode 100644 index 0000000..3f2eb69 --- /dev/null +++ b/src/Downloader/Middleware/RetryMiddleware.php @@ -0,0 +1,113 @@ +getRequest(); + + /** @var int $retryCount */ + $retryCount = $request->getMeta('roach_retry_count', 0); + + /** @var list $retryOnStatus */ + $retryOnStatus = $this->option('retryOnStatus'); + + /** @var int $maxRetries */ + $maxRetries = $this->option('maxRetries'); + + if (!\in_array($response->getStatus(), $retryOnStatus, true) || $retryCount >= $maxRetries) { + return $response; + } + + $nextRetryCount = $retryCount + 1; + $delay = $this->delayForAttempt($retryCount); + $retryRequest = $request + ->withMeta('roach_retry_count', $nextRetryCount) + ->addOption('delay', $delay); + + $this->scheduler->schedule($retryRequest); + + $this->logger->info('[RetryMiddleware] Retrying request', [ + 'uri' => $request->getUri(), + 'status' => $response->getStatus(), + 'retry_count' => $nextRetryCount, + 'delay_ms' => $delay, + ]); + + return $response->drop('Request scheduled for retry'); + } + + private function delayForAttempt(int $retryCount): int + { + /** @var int $initialDelay */ + $initialDelay = $this->option('initialDelay'); + + /** @var float $multiplier */ + $multiplier = $this->option('multiplier'); + + return (int) \round($initialDelay * ($multiplier ** $retryCount)); + } + + /** + * @return array + */ + private static function defaultOptions(): array + { + return [ + 'retryOnStatus' => [500, 502, 503, 504], + 'maxRetries' => 3, + 'initialDelay' => 1000, + 'multiplier' => 2.0, + ]; + } + + private function onAfterConfigured(): void + { + $resolver = new OptionsResolver(); + $resolver->setRequired(['retryOnStatus', 'maxRetries', 'initialDelay', 'multiplier']); + $resolver->setAllowedTypes('retryOnStatus', 'int[]'); + $resolver->setAllowedTypes('maxRetries', 'int'); + $resolver->setAllowedTypes('initialDelay', 'int'); + $resolver->setAllowedTypes('multiplier', ['float', 'int']); + $resolver->setAllowedValues('maxRetries', static fn (int $value): bool => 0 <= $value); + $resolver->setAllowedValues('initialDelay', static fn (int $value): bool => 0 <= $value); + $resolver->setAllowedValues('multiplier', static fn (float|int $value): bool => 1 <= $value); + + /** @var array $options */ + $options = [ + 'retryOnStatus' => $this->option('retryOnStatus'), + 'maxRetries' => $this->option('maxRetries'), + 'initialDelay' => $this->option('initialDelay'), + 'multiplier' => $this->option('multiplier'), + ]; + + $resolver->resolve($options); + } +} diff --git a/src/Downloader/Middleware/RobotsTxtMiddleware.php b/src/Downloader/Middleware/RobotsTxtMiddleware.php index 5cf279b..48c14ee 100644 --- a/src/Downloader/Middleware/RobotsTxtMiddleware.php +++ b/src/Downloader/Middleware/RobotsTxtMiddleware.php @@ -62,7 +62,7 @@ private function createRobotsUrl(string $url): string return "{$robotsUrl}/{$fileName}"; } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ 'fileName' => 'robots.txt', diff --git a/src/Downloader/Middleware/UserAgentMiddleware.php b/src/Downloader/Middleware/UserAgentMiddleware.php index 4849fa0..5f4daae 100644 --- a/src/Downloader/Middleware/UserAgentMiddleware.php +++ b/src/Downloader/Middleware/UserAgentMiddleware.php @@ -26,7 +26,7 @@ public function handleRequest(Request $request): Request return $request->addHeader('User-Agent', $this->option('userAgent')); } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ 'userAgent' => 'roach-php', diff --git a/src/Extensions/MaxRequestExtension.php b/src/Extensions/MaxRequestExtension.php index 41a849a..116197a 100644 --- a/src/Extensions/MaxRequestExtension.php +++ b/src/Extensions/MaxRequestExtension.php @@ -55,7 +55,7 @@ private function dropRequestIfLimitReached(RequestScheduling|RequestSending $eve } } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ 'limit' => 10, diff --git a/src/Http/URL.php b/src/Http/URL.php index bf146e2..1b05fec 100644 --- a/src/Http/URL.php +++ b/src/Http/URL.php @@ -33,7 +33,7 @@ public function __construct( public static function parse(string $url): self { /** - * @var false|array{ + * @var array{ * host?: string, * user?: string, * pass?: string, @@ -42,7 +42,7 @@ public static function parse(string $url): self * path?: string, * query?: string, * fragment?: string, - * } $parts + * }|false $parts */ $parts = \parse_url($url); diff --git a/src/Http/UnknownQueryParameterException.php b/src/Http/UnknownQueryParameterException.php index d8c98e3..88748b0 100644 --- a/src/Http/UnknownQueryParameterException.php +++ b/src/Http/UnknownQueryParameterException.php @@ -17,8 +17,6 @@ final class UnknownQueryParameterException extends \Exception { public static function forParameter(string $parameter): self { - return new self( - "Trying to retrieve unknown parameter [{$parameter}] from query string", - ); + return new self("Trying to retrieve unknown parameter [{$parameter}] from query string"); } } diff --git a/src/ItemPipeline/AbstractItem.php b/src/ItemPipeline/AbstractItem.php index f236ca2..9414ac6 100644 --- a/src/ItemPipeline/AbstractItem.php +++ b/src/ItemPipeline/AbstractItem.php @@ -60,15 +60,11 @@ final public function set(string $key, mixed $value): ItemInterface try { $property = $reflectionClass->getProperty($key); } catch (\ReflectionException) { - throw new \InvalidArgumentException( - \sprintf('No public property %s exists on class %s', $key, static::class), - ); + throw new \InvalidArgumentException(\sprintf('No public property %s exists on class %s', $key, static::class)); } if (!$property->isPublic()) { - throw new \InvalidArgumentException( - \sprintf('No public property %s exists on class %s', $key, static::class), - ); + throw new \InvalidArgumentException(\sprintf('No public property %s exists on class %s', $key, static::class)); } $property->setValue($this, $value); diff --git a/src/ItemPipeline/Item.php b/src/ItemPipeline/Item.php index d5ec2e6..968526e 100644 --- a/src/ItemPipeline/Item.php +++ b/src/ItemPipeline/Item.php @@ -58,7 +58,12 @@ public function offsetGet(mixed $offset): mixed public function offsetSet(mixed $offset, mixed $value): void { - /** @psalm-suppress PossiblyNullArrayOffset */ + if (null === $offset) { + $this->data[] = $value; + + return; + } + $this->data[$offset] = $value; } diff --git a/src/Scheduling/Timing/FakeClock.php b/src/Scheduling/Timing/FakeClock.php index 2cbd33a..24a2fc1 100644 --- a/src/Scheduling/Timing/FakeClock.php +++ b/src/Scheduling/Timing/FakeClock.php @@ -31,9 +31,7 @@ public function now(): \DateTimeImmutable public function sleep(int $seconds): void { - $this->sleepUntil( - $this->now->add(new \DateInterval("PT{$seconds}S")), - ); + $this->sleepUntil($this->now->add(new \DateInterval("PT{$seconds}S"))); } public function sleepUntil(\DateTimeImmutable $date): void diff --git a/src/Shell/Commands/FetchCommand.php b/src/Shell/Commands/FetchCommand.php index ca2abcc..9a4949a 100644 --- a/src/Shell/Commands/FetchCommand.php +++ b/src/Shell/Commands/FetchCommand.php @@ -49,8 +49,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $request, ); - $output->writeln( - <<writeln(<< Available variables: \$response: <{$response->getStatus()} '{$url}'> @@ -58,8 +57,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int Commands: fetch Fetch URL and update the \$response and \$html objects -TEXT - ); +TEXT); /** @var Shell $app */ $app = $this->getApplication(); diff --git a/src/Shell/Resolver/StaticNamespaceResolver.php b/src/Shell/Resolver/StaticNamespaceResolver.php index ecb6a2b..09f8634 100644 --- a/src/Shell/Resolver/StaticNamespaceResolver.php +++ b/src/Shell/Resolver/StaticNamespaceResolver.php @@ -32,7 +32,7 @@ public function resolveSpiderNamespace(string $spiderClass): string throw new InvalidSpiderException("The spider class {$spiderClass} does not exist"); } - if (!$this->isSpider($spiderClass)) { + if (!self::isSpider($spiderClass)) { throw new InvalidSpiderException("The class {$spiderClass} is not a spider"); } @@ -44,7 +44,7 @@ public function resolveSpiderNamespace(string $spiderClass): string * * @throws \ReflectionException */ - private function isSpider(string $spiderClass): bool + private static function isSpider(string $spiderClass): bool { return (new \ReflectionClass($spiderClass))->implementsInterface(SpiderInterface::class); } diff --git a/src/Spider/Configuration/ArrayLoader.php b/src/Spider/Configuration/ArrayLoader.php index c4afd7c..7dc9a46 100644 --- a/src/Spider/Configuration/ArrayLoader.php +++ b/src/Spider/Configuration/ArrayLoader.php @@ -24,11 +24,11 @@ final class ArrayLoader implements ConfigurationLoaderStrategy { /** * @var array{ - * startUrls: string[], - * downloaderMiddleware: class-string[], - * spiderMiddleware: class-string[], - * itemProcessors: class-string[], - * extensions: class-string[], + * startUrls: list, + * downloaderMiddleware: list>, + * spiderMiddleware: list>, + * itemProcessors: list>, + * extensions: list>, * concurrency: int, * requestDelay: int * } diff --git a/src/Spider/Configuration/Overrides.php b/src/Spider/Configuration/Overrides.php index ce27966..6e93052 100644 --- a/src/Spider/Configuration/Overrides.php +++ b/src/Spider/Configuration/Overrides.php @@ -45,11 +45,11 @@ public function __construct( * @psalm-suppress MoreSpecificReturnType, LessSpecificReturnStatement * * @return array{ - * startUrls?: string[], - * downloaderMiddleware?: class-string[], - * spiderMiddleware?: class-string[], - * itemProcessors?: class-string[], - * extensions?: class-string[], + * startUrls?: list, + * downloaderMiddleware?: list>, + * spiderMiddleware?: list>, + * itemProcessors?: list>, + * extensions?: list>, * concurrency?: int, * requestDelay?: int, * } diff --git a/src/Spider/Middleware/MaximumCrawlDepthMiddleware.php b/src/Spider/Middleware/MaximumCrawlDepthMiddleware.php index b0b2bff..a0a4b79 100644 --- a/src/Spider/Middleware/MaximumCrawlDepthMiddleware.php +++ b/src/Spider/Middleware/MaximumCrawlDepthMiddleware.php @@ -34,7 +34,7 @@ public function handleRequest(Request $request, Response $response): Request return $request->withMeta('depth', $currentDepth + 1); } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ 'maxCrawlDepth' => 10, diff --git a/src/Spider/Middleware/SpiderMiddlewareAdapter.php b/src/Spider/Middleware/SpiderMiddlewareAdapter.php index 4251f07..319f23e 100644 --- a/src/Spider/Middleware/SpiderMiddlewareAdapter.php +++ b/src/Spider/Middleware/SpiderMiddlewareAdapter.php @@ -23,14 +23,12 @@ */ final class SpiderMiddlewareAdapter implements SpiderMiddlewareInterface { - private function __construct( - private ItemMiddlewareInterface|RequestMiddlewareInterface|ResponseMiddlewareInterface $middleware, - ) { + private function __construct(private ItemMiddlewareInterface|RequestMiddlewareInterface|ResponseMiddlewareInterface $middleware) + { } - public static function fromMiddleware( - ItemMiddlewareInterface|RequestMiddlewareInterface|ResponseMiddlewareInterface $middleware, - ): SpiderMiddlewareInterface { + public static function fromMiddleware(ItemMiddlewareInterface|RequestMiddlewareInterface|ResponseMiddlewareInterface $middleware): SpiderMiddlewareInterface + { if ($middleware instanceof SpiderMiddlewareInterface) { return $middleware; } diff --git a/src/Spider/Processor.php b/src/Spider/Processor.php index 8bf12ef..c49fbb8 100644 --- a/src/Spider/Processor.php +++ b/src/Spider/Processor.php @@ -59,13 +59,14 @@ public function handle(Response $response): \Generator foreach ($results as $result) { $value = $result->value(); - $handleMethod = $value instanceof Request - ? 'handleRequest' - : 'handleItem'; foreach ($this->middleware as $handler) { - /** @var ItemInterface|Request $value */ - $value = $handler->{$handleMethod}($value, $response); + if ($value instanceof Request) { + $value = $handler->handleRequest($value, $response); + } else { + /** @var ItemInterface $value */ + $value = $handler->handleItem($value, $response); + } if ($value->wasDropped()) { if ($value instanceof Request) { diff --git a/src/Testing/FakeLogger.php b/src/Testing/FakeLogger.php index b7ab67f..88dd476 100644 --- a/src/Testing/FakeLogger.php +++ b/src/Testing/FakeLogger.php @@ -132,4 +132,19 @@ public function messageWasLogged(string $level, string $message, ?array $context && (null === $context || $log['context'] === $context); })); } + + /** + * @param array $context + */ + public function countMessages(string $level, string $message, ?array $context = null): int + { + if (empty($this->logs[$level])) { + return 0; + } + + return \count(\array_filter($this->logs[$level], static function (array $log) use ($message, $context) { + return $log['message'] === $message + && (null === $context || $log['context'] === $context); + })); + } } diff --git a/tests/BrandingTest.php b/tests/BrandingTest.php new file mode 100644 index 0000000..3a923ee --- /dev/null +++ b/tests/BrandingTest.php @@ -0,0 +1,56 @@ +makeRequest($url)], + '::namespace::', + extensions: [new LoggerExtension($loggerA)], + ); + $runB = new Run( + [$this->makeRequest($url)], + '::namespace::', + extensions: [new LoggerExtension($loggerB)], + ); + + $this->engine->start($runA); + $this->engine->start($runB); + + self::assertSame(1, $loggerA->countMessages('info', 'Dispatching request', ['uri' => $url])); + self::assertSame(1, $loggerB->countMessages('info', 'Dispatching request', ['uri' => $url])); + } + + public function testRemovesRunExtensionsAfterRunFails(): void + { + $url = 'http://localhost:8000/test1'; + $loggerA = new FakeLogger(); + $loggerB = new FakeLogger(); + $failingRun = new Run( + [$this->makeRequest($url, static function (): \Generator { + throw new \RuntimeException('::failure::'); + + yield from []; + })], + '::namespace::', + extensions: [new LoggerExtension($loggerA)], + ); + $successfulRun = new Run( + [$this->makeRequest($url)], + '::namespace::', + extensions: [new LoggerExtension($loggerB)], + ); + + try { + $this->engine->start($failingRun); + } catch (\RuntimeException) { + } + + $this->engine->start($successfulRun); + + self::assertSame(1, $loggerA->countMessages('info', 'Dispatching request', ['uri' => $url])); + self::assertSame(1, $loggerB->countMessages('info', 'Dispatching request', ['uri' => $url])); + } + public function testCollectAndReturnScrapedItems(): void { $parseCallback = static function () { diff --git a/tests/Core/RunFactoryTest.php b/tests/Core/RunFactoryTest.php index 026e956..7ef9a52 100644 --- a/tests/Core/RunFactoryTest.php +++ b/tests/Core/RunFactoryTest.php @@ -15,6 +15,7 @@ use League\Container\Container; use League\Container\ReflectionContainer; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Core\Run; use RoachPHP\Core\RunFactory; @@ -48,7 +49,7 @@ protected function setUp(): void public function testGetInitialRequestsFromSpider(): void { - $spider = $this->createSpider(startUrls: ['::url-1::', '::url-2::']); + $spider = self::createSpider(startUrls: ['::url-1::', '::url-2::']); $run = $this->factory->fromSpider($spider); @@ -59,7 +60,7 @@ public function testGetInitialRequestsFromSpider(): void public function testWrapDownloaderMiddlewareInAdapater(): void { - $spider = $this->createSpider(downloaderMiddleware: [ + $spider = self::createSpider(downloaderMiddleware: [ RequestDownloaderMiddleware::class, ResponseDownloaderMiddleware::class, ]); @@ -73,7 +74,7 @@ public function testWrapDownloaderMiddlewareInAdapater(): void public function testConfigureDownloaderMiddlewareWithDefaults(): void { - $spider = $this->createSpider(downloaderMiddleware: [ + $spider = self::createSpider(downloaderMiddleware: [ RequestDownloaderMiddleware::class, ]); @@ -87,7 +88,7 @@ public function testConfigureDownloaderMiddlewareWithDefaults(): void public function testConfigureDownloaderMiddlewareWithOverrides(): void { - $spider = $this->createSpider(downloaderMiddleware: [ + $spider = self::createSpider(downloaderMiddleware: [ [RequestDownloaderMiddleware::class, ['::option-key::' => '::override-value::']], ]); @@ -101,7 +102,7 @@ public function testConfigureDownloaderMiddlewareWithOverrides(): void public function testWrapSpiderMiddlewareInAdapter(): void { - $spider = $this->createSpider(spiderMiddleware: [ + $spider = self::createSpider(spiderMiddleware: [ RequestSpiderMiddleware::class, ResponseSpiderMiddleware::class, ItemSpiderMiddleware::class, @@ -117,7 +118,7 @@ public function testWrapSpiderMiddlewareInAdapter(): void public function testConfigureSpiderMiddlewareWithDefaults(): void { - $spider = $this->createSpider(spiderMiddleware: [ + $spider = self::createSpider(spiderMiddleware: [ RequestSpiderMiddleware::class, ]); @@ -131,7 +132,7 @@ public function testConfigureSpiderMiddlewareWithDefaults(): void public function testConfigureSpiderMiddlewareWithOverrides(): void { - $spider = $this->createSpider(spiderMiddleware: [ + $spider = self::createSpider(spiderMiddleware: [ [RequestSpiderMiddleware::class, ['::option-key::' => '::override-value::']], ]); @@ -145,7 +146,7 @@ public function testConfigureSpiderMiddlewareWithOverrides(): void public function testConfigureItemProcessorsWithDefaults(): void { - $spider = $this->createSpider(itemProcessors: [ + $spider = self::createSpider(itemProcessors: [ ItemProcessor::class, ]); @@ -159,7 +160,7 @@ public function testConfigureItemProcessorsWithDefaults(): void public function testConfigureItemProcessorsWithOverrides(): void { - $spider = $this->createSpider(itemProcessors: [ + $spider = self::createSpider(itemProcessors: [ [ItemProcessor::class, ['::option-key::' => '::override-value::']], ]); @@ -173,7 +174,7 @@ public function testConfigureItemProcessorsWithOverrides(): void public function testConfigureExtensionsWithDefaults(): void { - $spider = $this->createSpider(extensions: [ + $spider = self::createSpider(extensions: [ Extension::class, ]); @@ -187,7 +188,7 @@ public function testConfigureExtensionsWithDefaults(): void public function testConfigureExtensionsWithOverrides(): void { - $spider = $this->createSpider(extensions: [ + $spider = self::createSpider(extensions: [ [Extension::class, ['::option-key::' => '::override-value::']], ]); @@ -199,24 +200,20 @@ public function testConfigureExtensionsWithOverrides(): void ); } - /** - * @dataProvider numberProvider - */ + #[DataProvider('numberProvider')] public function testConfigureConcurrencyWithDefault(int $concurrency): void { - $spider = $this->createSpider(concurrency: $concurrency); + $spider = self::createSpider(concurrency: $concurrency); $run = $this->factory->fromSpider($spider); self::assertSame($concurrency, $run->concurrency); } - /** - * @dataProvider numberProvider - */ + #[DataProvider('numberProvider')] public function testConfigureRequestDelay(int $requestDelay): void { - $spider = $this->createSpider(requestDelay: $requestDelay); + $spider = self::createSpider(requestDelay: $requestDelay); $run = $this->factory->fromSpider($spider); @@ -236,16 +233,14 @@ public static function numberProvider(): iterable public function testConfigureRunNamespace(): void { - $spider = $this->createSpider(); + $spider = self::createSpider(); $run = $this->factory->fromSpider($spider); self::assertSame($spider::class, $run->namespace); } - /** - * @dataProvider configurationOverrideProvider - */ + #[DataProvider('configurationOverrideProvider')] public function testMergeSpiderConfigurationWithRunOverrides(array $overrides, callable $verifyRun): void { $defaults = [ @@ -270,7 +265,7 @@ public function testMergeSpiderConfigurationWithRunOverrides(array $overrides, c 'requestDelay' => 5, 'concurrency' => 2, ]; - $spider = $this->createSpider(...$defaults); + $spider = self::createSpider(...$defaults); $run = $this->factory->fromSpider($spider, new Overrides(...$overrides)); @@ -288,14 +283,12 @@ static function (Run $run): void { self::assertSame('::override-url-2::', $run->startRequests[1]->getUri()); }, ], - 'override itemProcessors' => [ ['itemProcessors' => []], static function (Run $run): void { self::assertEmpty($run->itemProcessors); }, ], - 'override spiderMiddleware' => [ ['spiderMiddleware' => [ItemSpiderMiddleware::class]], static function (Run $run): void { @@ -306,7 +299,6 @@ static function (Run $run): void { ); }, ], - 'override downloaderMiddleware' => [ ['downloaderMiddleware' => [ResponseDownloaderMiddleware::class]], static function (Run $run): void { @@ -317,21 +309,18 @@ static function (Run $run): void { ); }, ], - 'override extensions' => [ ['extensions' => []], static function (Run $run): void { self::assertEmpty($run->extensions); }, ], - 'override concurrency' => [ ['concurrency' => 25], static function (Run $run): void { self::assertSame(25, $run->concurrency); }, ], - 'override requestDelay' => [ ['requestDelay' => 150], static function (Run $run): void { @@ -341,7 +330,7 @@ static function (Run $run): void { ]; } - private function createSpider( + private static function createSpider( array $startUrls = [], array $downloaderMiddleware = [], array $spiderMiddleware = [], diff --git a/tests/Downloader/DownloaderMiddlewareAdapterTest.php b/tests/Downloader/DownloaderMiddlewareAdapterTest.php index a2886e5..b4c8379 100644 --- a/tests/Downloader/DownloaderMiddlewareAdapterTest.php +++ b/tests/Downloader/DownloaderMiddlewareAdapterTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Downloader; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Downloader\DownloaderMiddlewareInterface; use RoachPHP\Downloader\Middleware\DownloaderMiddlewareAdapter; @@ -52,9 +53,7 @@ public function handleResponse(Response $response): Response self::assertSame($middleware, $class); } - /** - * @dataProvider requestMiddlewareProvider - */ + #[DataProvider('requestMiddlewareProvider')] public function testRequestMiddlewareImplementation(callable $testCase): void { $middleware = new class() implements RequestMiddlewareInterface { @@ -89,9 +88,7 @@ public static function requestMiddlewareProvider(): iterable }]; } - /** - * @dataProvider responseMiddlewareProvider - */ + #[DataProvider('responseMiddlewareProvider')] public function testResponseMiddlewareImplementation(callable $testCase): void { $middleware = new class() implements ResponseMiddlewareInterface { diff --git a/tests/Downloader/DownloaderTest.php b/tests/Downloader/DownloaderTest.php index f36dfa0..8ef5228 100644 --- a/tests/Downloader/DownloaderTest.php +++ b/tests/Downloader/DownloaderTest.php @@ -307,13 +307,11 @@ public function testDontCallParseCallbackIfRequestWasDroppedByExtension(): void public function testDispatchEventWhenResponseWasProcessedByMiddleware(): void { $request = $this->makeRequest(); - $middleware = new FakeMiddleware( - responseHandler: function (Response $response) { - $this->dispatcher->assertNotDispatched(ResponseReceived::NAME); + $middleware = new FakeMiddleware(responseHandler: function (Response $response) { + $this->dispatcher->assertNotDispatched(ResponseReceived::NAME); - return $response; - }, - ); + return $response; + }, ); $this->downloader->withMiddleware($middleware); $this->downloader->prepare($request); diff --git a/tests/Downloader/Middleware/ExecuteJavascriptMiddlewareTest.php b/tests/Downloader/Middleware/ExecuteJavascriptMiddlewareTest.php index c935d09..81a34ef 100644 --- a/tests/Downloader/Middleware/ExecuteJavascriptMiddlewareTest.php +++ b/tests/Downloader/Middleware/ExecuteJavascriptMiddlewareTest.php @@ -28,13 +28,22 @@ final class ExecuteJavascriptMiddlewareTest extends IntegrationTestCase public function testUpdateResponseBodyWithHtmlAfterExecutingJavascript(): void { - $response = $this->makeResponse( - $this->makeRequest('http://localhost:8000/javascript'), + $browsershot = new class() extends Browsershot { + public function bodyHtml(): string + { + return '

Headline

I was loaded via Javascript!

'; + } + }; + $request = $this->makeRequest('http://localhost:8000/javascript'); + $middleware = new ExecuteJavascriptMiddleware( + new FakeLogger(), + static fn (string $uri): Browsershot => $browsershot->setUrl($uri), ); - $middleware = new ExecuteJavascriptMiddleware(new FakeLogger()); - $processedResponse = $middleware->handleResponse($response); + $processedRequest = $middleware->handleRequest($request); + $processedResponse = $processedRequest->getResponse(); + self::assertNotNull($processedResponse); self::assertSame('Headline', $processedResponse->filter('#content h1')->text('')); self::assertSame('I was loaded via Javascript!', $processedResponse->filter('#content p')->text('')); } @@ -52,9 +61,9 @@ public function bodyHtml(): string static fn (string $uri): Browsershot => $throwingBrowsershot->setUrl($uri), ); - $processedResponse = $middleware->handleResponse($this->makeResponse()); + $processedRequest = $middleware->handleRequest($this->makeRequest('http://fake-url.com')); - self::assertTrue($processedResponse->wasDropped()); + self::assertTrue($processedRequest->wasDropped()); } public function testLogErrors(): void @@ -71,32 +80,49 @@ public function bodyHtml(): string static fn (string $uri): Browsershot => $throwingBrowsershot->setUrl($uri), ); - $middleware->handleResponse($this->makeResponse()); + $middleware->handleRequest($this->makeRequest('http://fake-url.com')); - self::assertTrue( - $logger->messageWasLogged( - 'info', - '[ExecuteJavascriptMiddleware] Error while executing javascript', - ), - ); + self::assertTrue($logger->messageWasLogged( + 'info', + '[ExecuteJavascriptMiddleware] Error while executing javascript', + ), ); } public function testUsesTheProvidedUserAgentOption(): void { $mockBrowserShot = $this->createMock(Browsershot::class); - $response = $this->makeResponse( - $this->makeRequest('http://localhost:8000/javascript'), - ); + $request = $this->makeRequest('http://localhost:8000/javascript'); $middleware = new ExecuteJavascriptMiddleware( new FakeLogger(), static fn (string $uri): Browsershot => $mockBrowserShot, ); $middleware->configure(['userAgent' => 'custom']); - $mockBrowserShot->expects(self::once()) + $mockBrowserShot->expects($this->once()) ->method('userAgent') ->with(self::equalTo('custom')); + $mockBrowserShot->method('bodyHtml') + ->willReturn(''); + + $middleware->handleRequest($request); + } + + public function testConfiguresNetworkIdleWaiting(): void + { + $mockBrowserShot = $this->createMock(Browsershot::class); + $request = $this->makeRequest('http://localhost:8000/javascript'); + $middleware = new ExecuteJavascriptMiddleware( + new FakeLogger(), + static fn (string $uri): Browsershot => $mockBrowserShot, + ); + $middleware->configure(['waitUntilNetworkIdle' => false]); + + $mockBrowserShot->expects($this->once()) + ->method('waitUntilNetworkIdle') + ->with(self::equalTo(false)); + $mockBrowserShot->method('bodyHtml') + ->willReturn(''); - $middleware->handleResponse($response); + $middleware->handleRequest($request); } } diff --git a/tests/Downloader/Middleware/HttpErrorMiddlewareTest.php b/tests/Downloader/Middleware/HttpErrorMiddlewareTest.php index 8cdabe5..5a2d97d 100644 --- a/tests/Downloader/Middleware/HttpErrorMiddlewareTest.php +++ b/tests/Downloader/Middleware/HttpErrorMiddlewareTest.php @@ -36,7 +36,19 @@ protected function setUp(): void $this->middleware = new HttpErrorMiddleware($this->logger); } - public static function successfulHTTPStatus(): \Generator + #[DataProvider('successfulHTTPStatus')] + public function testAllowResponseWithSuccessfulHTTPStatus(int $status): void + { + $response = $this->makeResponse(status: $status); + $this->middleware->configure([]); + + $result = $this->middleware->handleResponse($response); + + self::assertSame($result, $response); + self::assertFalse($result->wasDropped()); + } + + public static function successfulHTTPStatus(): iterable { yield from [ [200], @@ -51,7 +63,19 @@ public static function successfulHTTPStatus(): \Generator ]; } - public static function unsuccessfulHTTPStatus(): \Generator + #[DataProvider('unsuccessfulHTTPStatus')] + public function testDropResponseWithNonSuccessfulHTTPStatus(int $status): void + { + $response = $this->makeResponse(status: $status); + $this->middleware->configure([]); + + $result = $this->middleware->handleResponse($response); + + self::assertNotSame($result, $response); + self::assertTrue($result->wasDropped()); + } + + public static function unsuccessfulHTTPStatus(): iterable { yield from [ [100], @@ -110,30 +134,6 @@ public static function unsuccessfulHTTPStatus(): \Generator ]; } - #[DataProvider('successfulHTTPStatus')] - public function testAllowResponseWithSuccessfulHTTPStatus(int $status): void - { - $response = $this->makeResponse(status: $status); - $this->middleware->configure([]); - - $result = $this->middleware->handleResponse($response); - - self::assertSame($result, $response); - self::assertFalse($result->wasDropped()); - } - - #[DataProvider('unsuccessfulHTTPStatus')] - public function testDropResponseWithNonSuccessfulHTTPStatus(int $status): void - { - $response = $this->makeResponse(status: $status); - $this->middleware->configure([]); - - $result = $this->middleware->handleResponse($response); - - self::assertNotSame($result, $response); - self::assertTrue($result->wasDropped()); - } - public function testLogDroppedResponses(): void { $request = $this->makeRequest('https://example.com'); @@ -142,13 +142,11 @@ public function testLogDroppedResponses(): void $this->middleware->handleResponse($response); - self::assertTrue( - $this->logger->messageWasLogged( - 'info', - '[HttpErrorMiddleware] Dropping unsuccessful response', - ['uri' => 'https://example.com', 'status' => 400], - ), - ); + self::assertTrue($this->logger->messageWasLogged( + 'info', + '[HttpErrorMiddleware] Dropping unsuccessful response', + ['uri' => 'https://example.com', 'status' => 400], + ), ); } public function testDontLogAllowedResponses(): void @@ -158,12 +156,10 @@ public function testDontLogAllowedResponses(): void $this->middleware->handleResponse($response); - self::assertFalse( - $this->logger->messageWasLogged( - 'info', - '[AllowedHttpStatusMiddleware] Dropping response with unallowed HTTP status', - ), - ); + self::assertFalse($this->logger->messageWasLogged( + 'info', + '[AllowedHttpStatusMiddleware] Dropping response with unallowed HTTP status', + ), ); } public function testAllowResponsesWithCustomAllowedStatuses(): void diff --git a/tests/Downloader/Middleware/ProxyMiddlewareTest.php b/tests/Downloader/Middleware/ProxyMiddlewareTest.php index 04991c6..3b3bfee 100644 --- a/tests/Downloader/Middleware/ProxyMiddlewareTest.php +++ b/tests/Downloader/Middleware/ProxyMiddlewareTest.php @@ -114,9 +114,9 @@ public function testAddWildCardProxyToAllRequests(string $url): void ); } - public static function requestURLProvider(): array + public static function requestURLProvider(): iterable { - return [ + yield from [ ['https://example.com'], ['https://lorem-ipsum.com'], ['https://google.com'], @@ -168,17 +168,15 @@ public function testLogProxyOptionsForRequest(): void $this->middleware->handleRequest($request); - self::assertTrue( - $this->logger->messageWasLogged( - 'info', - '[ProxyMiddleware] Using proxy for request', - [ - 'http' => '::http-proxy::', - 'https' => '::https-proxy::', - 'no' => ['::no::'], - ], - ), - ); + self::assertTrue($this->logger->messageWasLogged( + 'info', + '[ProxyMiddleware] Using proxy for request', + [ + 'http' => '::http-proxy::', + 'https' => '::https-proxy::', + 'no' => ['::no::'], + ], + ), ); } public function testUseCustomConfigurationLoaderClassIfProvided(): void @@ -207,12 +205,10 @@ public function testLogWarningIfNoProxyWasConfiguredForMiddleware(): void $this->middleware->handleRequest($request); self::assertArrayNotHasKey('proxy', $request->getOptions()); - self::assertTrue( - $this->logger->messageWasLogged( - 'warning', - '[ProxyMiddleware] No proxy configured for middleware', - ), - ); + self::assertTrue($this->logger->messageWasLogged( + 'warning', + '[ProxyMiddleware] No proxy configured for middleware', + ), ); } } diff --git a/tests/Downloader/Middleware/RequestDeduplicationMiddlewareTest.php b/tests/Downloader/Middleware/RequestDeduplicationMiddlewareTest.php index ac9db09..535a45e 100644 --- a/tests/Downloader/Middleware/RequestDeduplicationMiddlewareTest.php +++ b/tests/Downloader/Middleware/RequestDeduplicationMiddlewareTest.php @@ -71,13 +71,11 @@ public function testLogDroppedRequestsIfLoggerWasProvided(): void $this->middleware->handleRequest($request); $this->middleware->handleRequest($request); - self::assertTrue( - $this->logger->messageWasLogged( - 'info', - '[RequestDeduplicationMiddleware] Dropping duplicate request', - ['uri' => 'https://example.com'], - ), - ); + self::assertTrue($this->logger->messageWasLogged( + 'info', + '[RequestDeduplicationMiddleware] Dropping duplicate request', + ['uri' => 'https://example.com'], + ), ); } public function testIgnoresTrailingSlashesByDefaultWhenComparingUrls(): void diff --git a/tests/Downloader/Middleware/RetryMiddlewareTest.php b/tests/Downloader/Middleware/RetryMiddlewareTest.php new file mode 100644 index 0000000..2752922 --- /dev/null +++ b/tests/Downloader/Middleware/RetryMiddlewareTest.php @@ -0,0 +1,113 @@ +scheduler = new ArrayRequestScheduler(new FakeClock()); + $this->logger = new FakeLogger(); + $this->middleware = new RetryMiddleware($this->scheduler, $this->logger); + } + + public function testDoesNotRetrySuccessfulResponse(): void + { + $response = $this->makeResponse(status: 200); + + $result = $this->middleware->handleResponse($response); + + self::assertSame($response, $result); + self::assertFalse($result->wasDropped()); + self::assertSame([], $this->scheduler->forceNextRequests(10)); + } + + public function testDoesNotRetryUnconfiguredStatus(): void + { + $response = $this->makeResponse(status: 404); + + $result = $this->middleware->handleResponse($response); + + self::assertSame($response, $result); + self::assertFalse($result->wasDropped()); + self::assertSame([], $this->scheduler->forceNextRequests(10)); + } + + public function testRetriesConfiguredStatus(): void + { + $request = $this->makeRequest('https://example.com'); + $response = $this->makeResponse(request: $request, status: 503); + $this->middleware->configure([ + 'retryOnStatus' => [503], + 'maxRetries' => 2, + 'initialDelay' => 500, + 'multiplier' => 2.0, + ]); + + $result = $this->middleware->handleResponse($response); + + self::assertTrue($result->wasDropped()); + + $retriedRequests = $this->scheduler->forceNextRequests(10); + self::assertCount(1, $retriedRequests); + self::assertSame('https://example.com', $retriedRequests[0]->getUri()); + self::assertSame(1, $retriedRequests[0]->getMeta('roach_retry_count')); + self::assertSame(500, $retriedRequests[0]->getOptions()['delay']); + self::assertTrue($this->logger->messageWasLogged('info', '[RetryMiddleware] Retrying request')); + } + + public function testStopsRetryingAtMaxRetries(): void + { + $request = $this->makeRequest('https://example.com')->withMeta('roach_retry_count', 3); + $response = $this->makeResponse(request: $request, status: 500); + $this->middleware->configure(['maxRetries' => 3]); + + $result = $this->middleware->handleResponse($response); + + self::assertSame($response, $result); + self::assertFalse($result->wasDropped()); + self::assertSame([], $this->scheduler->forceNextRequests(10)); + } + + public function testUsesExponentialBackoff(): void + { + $request = $this->makeRequest('https://example.com')->withMeta('roach_retry_count', 2); + $response = $this->makeResponse(request: $request, status: 500); + $this->middleware->configure([ + 'initialDelay' => 1000, + 'multiplier' => 2.0, + ]); + + $this->middleware->handleResponse($response); + + $retriedRequests = $this->scheduler->forceNextRequests(10); + + self::assertSame(4000, $retriedRequests[0]->getOptions()['delay']); + } +} diff --git a/tests/Downloader/Proxy/ProxyOptionsTest.php b/tests/Downloader/Proxy/ProxyOptionsTest.php index 31492cb..9f0b56a 100644 --- a/tests/Downloader/Proxy/ProxyOptionsTest.php +++ b/tests/Downloader/Proxy/ProxyOptionsTest.php @@ -171,9 +171,9 @@ public function testEmpty(ProxyOptions $options, bool $expected): void self::assertEquals($expected, $options->isEmpty()); } - public static function emptyProxyProvider(): array + public static function emptyProxyProvider(): iterable { - return [ + yield from [ 'only http' => [ new ProxyOptions('::http-proxy-url::'), false, diff --git a/tests/Downloader/Proxy/ProxyTest.php b/tests/Downloader/Proxy/ProxyTest.php index e6c945e..0e4ced6 100644 --- a/tests/Downloader/Proxy/ProxyTest.php +++ b/tests/Downloader/Proxy/ProxyTest.php @@ -43,23 +43,11 @@ public function testReturnMatchingProxyOptionsForRequestIfConfigured(): void ->allProtocols('::proxy-url-2::'), ]); - $options = $proxy->optionsFor( - $this->makeRequest('https://domain-1.com'), - ); - self::assertTrue( - $options->equals( - ProxyOptions::make()->allProtocols('::proxy-url-1::'), - ), - ); + $options = $proxy->optionsFor($this->makeRequest('https://domain-1.com')); + self::assertTrue($options->equals(ProxyOptions::make()->allProtocols('::proxy-url-1::'))); - $options = $proxy->optionsFor( - $this->makeRequest('https://domain-2.com'), - ); - self::assertTrue( - $options->equals( - ProxyOptions::make()->allProtocols('::proxy-url-2::'), - ), - ); + $options = $proxy->optionsFor($this->makeRequest('https://domain-2.com')); + self::assertTrue($options->equals(ProxyOptions::make()->allProtocols('::proxy-url-2::'))); } public function testReturnsWildcardOptionsIfConfiguredAndDomainDoesntMatch(): void @@ -71,14 +59,8 @@ public function testReturnsWildcardOptionsIfConfiguredAndDomainDoesntMatch(): vo ->allProtocols('::proxy-url-2::'), ]); - $options = $proxy->optionsFor( - $this->makeRequest('https://domain-2.com'), - ); - self::assertTrue( - $options->equals( - ProxyOptions::make()->allProtocols('::proxy-url-2::'), - ), - ); + $options = $proxy->optionsFor($this->makeRequest('https://domain-2.com')); + self::assertTrue($options->equals(ProxyOptions::make()->allProtocols('::proxy-url-2::'))); } public function testPreferDomainConfigurationOverWildcard(): void @@ -90,13 +72,7 @@ public function testPreferDomainConfigurationOverWildcard(): void ->allProtocols('::proxy-url-2::'), ]); - $options = $proxy->optionsFor( - $this->makeRequest('https://domain-1.com'), - ); - self::assertTrue( - $options->equals( - ProxyOptions::make()->allProtocols('::proxy-url-1::'), - ), - ); + $options = $proxy->optionsFor($this->makeRequest('https://domain-1.com')); + self::assertTrue($options->equals(ProxyOptions::make()->allProtocols('::proxy-url-1::'))); } } diff --git a/tests/Extensions/LoggerExtensionTest.php b/tests/Extensions/LoggerExtensionTest.php index 99de5a9..ecb3f41 100644 --- a/tests/Extensions/LoggerExtensionTest.php +++ b/tests/Extensions/LoggerExtensionTest.php @@ -40,92 +40,68 @@ final class LoggerExtensionTest extends ExtensionTestCase public function testLogWhenRunStarts(): void { - self::assertFalse( - $this->logger->messageWasLogged('info', 'Run starting'), - ); + self::assertFalse($this->logger->messageWasLogged('info', 'Run starting')); $this->dispatch(new RunStarting(new Run([], '::namespace::')), RunStarting::NAME); - self::assertTrue( - $this->logger->messageWasLogged('info', 'Run starting'), - ); + self::assertTrue($this->logger->messageWasLogged('info', 'Run starting')); } public function testLogWhenRunFinished(): void { - self::assertFalse( - $this->logger->messageWasLogged('info', 'Run finished'), - ); + self::assertFalse($this->logger->messageWasLogged('info', 'Run finished')); $this->dispatch(new RunFinished(new Run([], '::namespace::')), RunFinished::NAME); - self::assertTrue( - $this->logger->messageWasLogged('info', 'Run finished'), - ); + self::assertTrue($this->logger->messageWasLogged('info', 'Run finished')); } public function testLogWhenItemGotDropped(): void { - self::assertFalse( - $this->logger->messageWasLogged('info', 'Item dropped'), - ); + self::assertFalse($this->logger->messageWasLogged('info', 'Item dropped')); $item = (new Item(['foo' => 'bar']))->drop('::reason::'); $this->dispatch(new ItemDropped($item), ItemDropped::NAME); - self::assertTrue( - $this->logger->messageWasLogged('info', 'Item dropped', [ - 'item' => $item->all(), - 'reason' => '::reason::', - ]), - ); + self::assertTrue($this->logger->messageWasLogged('info', 'Item dropped', [ + 'item' => $item->all(), + 'reason' => '::reason::', + ]), ); } public function testLogWhenRequestWasDropped(): void { - self::assertFalse( - $this->logger->messageWasLogged('info', 'Request dropped'), - ); + self::assertFalse($this->logger->messageWasLogged('info', 'Request dropped')); $request = $this->makeRequest('::request-url::')->drop('::reason::'); $this->dispatch(new RequestDropped($request), RequestDropped::NAME); - self::assertTrue( - $this->logger->messageWasLogged('info', 'Request dropped', [ - 'uri' => '::request-url::', - 'reason' => '::reason::', - ]), - ); + self::assertTrue($this->logger->messageWasLogged('info', 'Request dropped', [ + 'uri' => '::request-url::', + 'reason' => '::reason::', + ]), ); } public function testLogWhenRequestWasSent(): void { - self::assertFalse( - $this->logger->messageWasLogged('info', 'Dispatching request'), - ); + self::assertFalse($this->logger->messageWasLogged('info', 'Dispatching request')); $request = $this->makeRequest('::request-url::'); $this->dispatch(new RequestSending($request), RequestSending::NAME); - self::assertTrue( - $this->logger->messageWasLogged('info', 'Dispatching request', [ - 'uri' => '::request-url::', - ]), - ); + self::assertTrue($this->logger->messageWasLogged('info', 'Dispatching request', [ + 'uri' => '::request-url::', + ]), ); } public function testLogWhenItemWasScraped(): void { - self::assertFalse( - $this->logger->messageWasLogged('info', 'Item scraped'), - ); + self::assertFalse($this->logger->messageWasLogged('info', 'Item scraped')); $item = new Item(['foo' => 'bar']); $this->dispatch(new ItemScraped($item), ItemScraped::NAME); - self::assertTrue( - $this->logger->messageWasLogged('info', 'Item scraped', ['foo' => 'bar']), - ); + self::assertTrue($this->logger->messageWasLogged('info', 'Item scraped', ['foo' => 'bar'])); } protected function createExtension(): ExtensionInterface diff --git a/tests/Extensions/MaxRequestExtensionTest.php b/tests/Extensions/MaxRequestExtensionTest.php index a7fa4c0..3e051cc 100644 --- a/tests/Extensions/MaxRequestExtensionTest.php +++ b/tests/Extensions/MaxRequestExtensionTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Extensions; +use PHPUnit\Framework\Attributes\DataProvider; use RoachPHP\Events\RequestScheduling; use RoachPHP\Events\RequestSending; use RoachPHP\Extensions\ExtensionInterface; @@ -26,9 +27,7 @@ final class MaxRequestExtensionTest extends ExtensionTestCase { use InteractsWithRequestsAndResponses; - /** - * @dataProvider thresholdProvider - */ + #[DataProvider('thresholdProvider')] public function testDontDropRequestIfThresholdNotReachedYet(int $threshold): void { $this->extension->configure(['limit' => $threshold]); @@ -46,9 +45,7 @@ public function testDontDropRequestIfThresholdNotReachedYet(int $threshold): voi self::assertFalse($event->request->wasDropped()); } - /** - * @dataProvider thresholdProvider - */ + #[DataProvider('thresholdProvider')] public function testDropRequestAfterThresholdWasReached(int $threshold): void { $this->extension->configure(['limit' => $threshold]); diff --git a/tests/Extensions/StatsCollectorExtensionTest.php b/tests/Extensions/StatsCollectorExtensionTest.php index 8527707..15006f1 100644 --- a/tests/Extensions/StatsCollectorExtensionTest.php +++ b/tests/Extensions/StatsCollectorExtensionTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Extensions; +use PHPUnit\Framework\Attributes\DataProvider; use RoachPHP\Core\Run; use RoachPHP\Events\ItemDropped; use RoachPHP\Events\ItemScraped; @@ -40,10 +41,9 @@ final class StatsCollectorExtensionTest extends ExtensionTestCase private FakeClock $clock; /** - * @dataProvider statsScenarioProvider - * * @param array{event: Event, eventName: string, stat: string} $scenario */ + #[DataProvider('statsScenarioProvider')] public function testCountNumberOfEventOccurrence(array $scenario, int $eventCount): void { $this->extension->configure([]); @@ -65,19 +65,16 @@ public static function statsScenarioProvider(): iterable 'eventName' => ItemScraped::NAME, 'stat' => 'items.scraped', ], - 'items.dropped' => [ 'event' => new ItemDropped(new Item([])), 'eventName' => ItemDropped::NAME, 'stat' => 'items.dropped', ], - 'requests.sent' => [ 'event' => new RequestSending(self::makeRequest()), 'eventName' => RequestSending::NAME, 'stat' => 'requests.sent', ], - 'requests.dropped' => [ 'event' => new RequestDropped(self::makeRequest()), 'eventName' => RequestDropped::NAME, @@ -92,9 +89,7 @@ public static function statsScenarioProvider(): iterable } } - /** - * @dataProvider runtimeProvider - */ + #[DataProvider('runtimeProvider')] public function testLogRuntime(int $seconds, string $expected): void { $this->extension->configure([]); @@ -148,12 +143,10 @@ private function assertStatWasLogged(string $stat, int|string $expectedValue): v 'items.dropped' => 0, ]; - self::assertTrue( - $this->logger->messageWasLogged( - 'info', - 'Run statistics', - \array_merge($defaults, [$stat => $expectedValue]), - ), - ); + self::assertTrue($this->logger->messageWasLogged( + 'info', + 'Run statistics', + \array_merge($defaults, [$stat => $expectedValue]), + ), ); } } diff --git a/tests/Fixtures/Extension.php b/tests/Fixtures/Extension.php index 503f73e..4835b38 100644 --- a/tests/Fixtures/Extension.php +++ b/tests/Fixtures/Extension.php @@ -25,7 +25,7 @@ public static function getSubscribedEvents(): array return []; } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ '::option-key::' => '::default-option-value::', diff --git a/tests/Fixtures/ItemProcessor.php b/tests/Fixtures/ItemProcessor.php index 63e910d..08ec2f9 100644 --- a/tests/Fixtures/ItemProcessor.php +++ b/tests/Fixtures/ItemProcessor.php @@ -26,7 +26,7 @@ public function processItem(ItemInterface $item): ItemInterface return $item; } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ '::option-key::' => '::default-option-value::', diff --git a/tests/Fixtures/RequestDownloaderMiddleware.php b/tests/Fixtures/RequestDownloaderMiddleware.php index 3e4801d..918b9a5 100644 --- a/tests/Fixtures/RequestDownloaderMiddleware.php +++ b/tests/Fixtures/RequestDownloaderMiddleware.php @@ -26,7 +26,7 @@ public function handleRequest(Request $request): Request return $request; } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ '::option-key::' => '::default-option-value::', diff --git a/tests/Fixtures/RequestSpiderMiddleware.php b/tests/Fixtures/RequestSpiderMiddleware.php index 3b9cee1..413800f 100644 --- a/tests/Fixtures/RequestSpiderMiddleware.php +++ b/tests/Fixtures/RequestSpiderMiddleware.php @@ -27,7 +27,7 @@ public function handleRequest(Request $request, Response $response): Request return $request; } - private function defaultOptions(): array + private static function defaultOptions(): array { return [ '::option-key::' => '::default-option-value::', diff --git a/tests/Http/ClientTest.php b/tests/Http/ClientTest.php index 83e4fa6..ce62de5 100644 --- a/tests/Http/ClientTest.php +++ b/tests/Http/ClientTest.php @@ -15,6 +15,7 @@ use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Psr\Http\Message\RequestInterface; use RoachPHP\Http\Client; @@ -31,7 +32,7 @@ final class ClientTest extends TestCase public function testCallFulfilledCallbackForAllSuccessfulResponses(): void { - $client = new Client($this->withMockClient([ + $client = new Client(self::withMockClient([ $response1 = new \GuzzleHttp\Psr7\Response(200), $response2 = new \GuzzleHttp\Psr7\Response(202), $response3 = new \GuzzleHttp\Psr7\Response(204), @@ -58,7 +59,7 @@ public function testCallFulfilledCallbackForAllSuccessfulResponses(): void public function testPassBadResponseExceptionsToFulfilledHandler(): void { - $client = new Client($this->withMockClient([ + $client = new Client(self::withMockClient([ $response = new \GuzzleHttp\Psr7\Response(400), ])); @@ -76,12 +77,10 @@ static function (Response $response) use (&$responses): void { self::assertSame($response, $responses[0]->getResponse()); } - /** - * @dataProvider exceptionProvider - */ + #[DataProvider('exceptionProvider')] public function testCallRejectCallbackOnRequestException(string $exceptionClass, callable $makeException): void { - $client = new Client($this->withMockClient([ + $client = new Client(self::withMockClient([ static fn (RequestInterface $request) => throw $makeException($request), ])); @@ -119,12 +118,10 @@ public static function exceptionProvider(): iterable ]; } - private function withMockClient(array $handlers): \GuzzleHttp\Client + private static function withMockClient(array $handlers): \GuzzleHttp\Client { return new \GuzzleHttp\Client([ - 'handler' => HandlerStack::create( - new MockHandler($handlers), - ), + 'handler' => HandlerStack::create(new MockHandler($handlers)), ]); } } diff --git a/tests/Http/QueryTest.php b/tests/Http/QueryTest.php index 742d4f0..3fe090d 100644 --- a/tests/Http/QueryTest.php +++ b/tests/Http/QueryTest.php @@ -197,15 +197,9 @@ public function testCompareEqualityWithString(): void 'baz' => ['qux', 'bla'], ]); - self::assertTrue( - $query1->equals('foo=bar&baz%5B0%5D=qux&baz%5B1%5D=bla'), - ); - self::assertFalse( - $query1->equals('foo=bar&baz%5B0%5D=qux&baz%5B1%5D=derp'), - ); - self::assertFalse( - $query1->equals('foo=bar'), - ); + self::assertTrue($query1->equals('foo=bar&baz%5B0%5D=qux&baz%5B1%5D=bla')); + self::assertFalse($query1->equals('foo=bar&baz%5B0%5D=qux&baz%5B1%5D=derp')); + self::assertFalse($query1->equals('foo=bar')); } public function testComparingForEqualityIgnoresOrderOfParameters(): void diff --git a/tests/Http/RequestTest.php b/tests/Http/RequestTest.php index 7057801..14b54e8 100644 --- a/tests/Http/RequestTest.php +++ b/tests/Http/RequestTest.php @@ -41,7 +41,7 @@ public function testCanAccessTheRequestUri(): void public function testCanAccessTheRequestUriPath(): void { - $request = $this->makeRequest('https://::request-uri::/::path::'); + $request = $this->makeRequest('https://example.com/::path::'); self::assertSame('/::path::', $request->getPath()); } @@ -82,9 +82,7 @@ public function testCanCallParseCallback(): void yield ParseResult::item(['::item::']); }); - $request->callback( - new Response(new GuzzleResponse(), $request), - )->next(); + $request->callback(new Response(new GuzzleResponse(), $request))->next(); self::assertTrue($called); } @@ -123,9 +121,7 @@ public function testReturnParsedURL(): void { $request = $this->makeRequest('https://example.com/path#anchor'); - self::assertTrue( - $request->url->equals('https://example.com/path#anchor'), - ); + self::assertTrue($request->url->equals('https://example.com/path#anchor')); } protected function createDroppable(): DroppableInterface diff --git a/tests/Http/ResponseTest.php b/tests/Http/ResponseTest.php index 14e3503..f593321 100644 --- a/tests/Http/ResponseTest.php +++ b/tests/Http/ResponseTest.php @@ -14,6 +14,7 @@ namespace RoachPHP\Tests\Http; use GuzzleHttp\Psr7\Stream; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Http\Response; use RoachPHP\Support\DroppableInterface; @@ -37,9 +38,7 @@ public function testCanAccessDomCrawlerDirectlyFromResponse(): void self::assertCount(1, $links); } - /** - * @dataProvider responseCodeProvider - */ + #[DataProvider('responseCodeProvider')] public function testCanRetrieveStatusCodeOfOriginalResponse(int $statusCode): void { $response = new Response(new \GuzzleHttp\Psr7\Response($statusCode), $this->makeRequest()); @@ -60,9 +59,7 @@ public static function responseCodeProvider(): iterable ]; } - /** - * @dataProvider responseBodyProvider - */ + #[DataProvider('responseBodyProvider')] public function testCanRetrieveHtmlBodyOfOriginalResponse(callable $getBody): void { $body = '

Hello, world!

'; @@ -86,7 +83,6 @@ public static function responseBodyProvider(): iterable return $stream; }], - 'StreamInterface' => [static function (string $body) { $stream = \fopen('php://memory', 'r+b'); \fwrite($stream, $body); @@ -127,8 +123,6 @@ public function testUpdatingResponseBodyUpdatesCrawler(): void protected function createDroppable(): DroppableInterface { - return $this->makeResponse( - $this->makeRequest(), - ); + return $this->makeResponse($this->makeRequest()); } } diff --git a/tests/Http/URLTest.php b/tests/Http/URLTest.php index 14d7e41..acc8a4e 100644 --- a/tests/Http/URLTest.php +++ b/tests/Http/URLTest.php @@ -25,9 +25,7 @@ final class URLTest extends TestCase { public function testParseAURLFromAString(): void { - $url = URL::parse( - 'https://username:password@sub.example.com:9000/foo/bar#anchor', - ); + $url = URL::parse('https://username:password@sub.example.com:9000/foo/bar#anchor'); self::assertSame('https', $url->scheme); self::assertSame('username', $url->username); @@ -72,12 +70,8 @@ public function testThrowExceptionForMalformedURL(): void public function testIsEqualIfURLsAreIdentical(): void { - $url1 = URL::parse( - 'https://username:password@sub.example.com:9000/foo/bar#anchor', - ); - $url2 = URL::parse( - 'https://username:password@sub.example.com:9000/foo/bar#anchor', - ); + $url1 = URL::parse('https://username:password@sub.example.com:9000/foo/bar#anchor'); + $url2 = URL::parse('https://username:password@sub.example.com:9000/foo/bar#anchor'); self::assertTrue($url1->equals($url2)); } @@ -91,9 +85,9 @@ public function testIsNotEqualIfURLsAreDifferent(string $url1, string $url2): vo self::assertFalse($url1->equals($url2)); } - public static function differentUrlsProvider(): array + public static function differentUrlsProvider(): iterable { - return [ + yield from [ 'scheme' => [ 'https://username:password@sub.example.com:9000/foo/bar#anchor', 'http://username:password@sub.example.com:9000/foo/bar#anchor', @@ -131,16 +125,10 @@ public static function differentUrlsProvider(): array public function testCompareEqualityWithStrings(): void { - $url = URL::parse( - 'https://username:password@sub.example.com:9000/foo/bar#anchor', - ); - - self::assertTrue( - $url->equals('https://username:password@sub.example.com:9000/foo/bar#anchor'), - ); - self::assertFalse( - $url->equals('https://username:password@example.com:9000/foo/bar#anchor'), - ); + $url = URL::parse('https://username:password@sub.example.com:9000/foo/bar#anchor'); + + self::assertTrue($url->equals('https://username:password@sub.example.com:9000/foo/bar#anchor')); + self::assertFalse($url->equals('https://username:password@example.com:9000/foo/bar#anchor')); } public function testEqualityCheckIgnoresOrderOfQueryParameters(): void @@ -158,9 +146,9 @@ public function testCanBeTurnedIntoAString(string $urlString): void self::assertSame($urlString, $url->toString()); } - public static function urlProvider(): array + public static function urlProvider(): iterable { - return [ + yield from [ ['https://username:password@sub.example.com:9000/foo/bar?foo=bar#anchor'], ['https://sub.example.com:9000/foo/bar?foo=bar#anchor'], ['https://example.com:9000/foo/bar'], diff --git a/tests/ItemPipeline/AbstractItemTest.php b/tests/ItemPipeline/AbstractItemTest.php index e60c5c4..5bf01bf 100644 --- a/tests/ItemPipeline/AbstractItemTest.php +++ b/tests/ItemPipeline/AbstractItemTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\ItemPipeline; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Tests\Fixtures\TestItem; @@ -66,9 +67,7 @@ public function testCanSetPublicProperty(): void self::assertSame('::new-value-2::', $item->bar); } - /** - * @dataProvider inaccessiblePropertiesProvider - */ + #[DataProvider('inaccessiblePropertiesProvider')] public function testThrowsExceptionWhenTryingToSetNonPublicOrNonExistentProperty(string $property): void { $item = new TestItem(foo: '::old-value-1::', bar: '::old-value-2::'); @@ -78,9 +77,7 @@ public function testThrowsExceptionWhenTryingToSetNonPublicOrNonExistentProperty $item->set($property, '::new-value::'); } - /** - * @dataProvider hasPropertyProvider - */ + #[DataProvider('hasPropertyProvider')] public function testHasProperty(string $property, bool $expected): void { $item = new TestItem(foo: '::value-1::', bar: '::value-2::'); @@ -88,9 +85,7 @@ public function testHasProperty(string $property, bool $expected): void self::assertSame($expected, $item->has($property)); } - /** - * @dataProvider hasPropertyProvider - */ + #[DataProvider('hasPropertyProvider')] public function testOffsetExists(string $property, bool $expected): void { $item = new TestItem(foo: '::value-1::', bar: '::value-2::'); @@ -153,9 +148,7 @@ public function testOffsetSetCanSetPublicProperties(): void self::assertSame('::new-value-2::', $item->bar); } - /** - * @dataProvider inaccessiblePropertiesProvider - */ + #[DataProvider('inaccessiblePropertiesProvider')] public function testOffsetSetThrowsExceptionWhenSettingInaccessibleOrNonExistentProperty(string $property): void { $item = new TestItem(foo: '::value-1::', bar: '::value-2::'); diff --git a/tests/ItemPipeline/CustomItemProcessorTest.php b/tests/ItemPipeline/CustomItemProcessorTest.php index 958d4a3..fadc7e0 100644 --- a/tests/ItemPipeline/CustomItemProcessorTest.php +++ b/tests/ItemPipeline/CustomItemProcessorTest.php @@ -26,26 +26,18 @@ final class CustomItemProcessorTest extends TestCase public function testHandlesItemsDefinedByTheChildClass(): void { $processor = new TestCustomItemProcessor([TestItem::class]); - self::assertTrue( - $processor->shouldHandle(new TestItem('::foo::', '::bar::')), - ); + self::assertTrue($processor->shouldHandle(new TestItem('::foo::', '::bar::'))); $processor = new TestCustomItemProcessor([TestItem2::class]); - self::assertTrue( - $processor->shouldHandle(new TestItem2()), - ); + self::assertTrue($processor->shouldHandle(new TestItem2())); } public function testDoesNotHandleItemsNotDefinedInTheChildClass(): void { $processor = new TestCustomItemProcessor([TestItem::class]); - self::assertFalse( - $processor->shouldHandle(new TestItem2()), - ); + self::assertFalse($processor->shouldHandle(new TestItem2())); $processor = new TestCustomItemProcessor([TestItem2::class]); - self::assertFalse( - $processor->shouldHandle(new TestItem('::foo::', '::bar::')), - ); + self::assertFalse($processor->shouldHandle(new TestItem('::foo::', '::bar::'))); } } diff --git a/tests/ItemPipeline/ItemPipelineTest.php b/tests/ItemPipeline/ItemPipelineTest.php index 3db0284..b72602f 100644 --- a/tests/ItemPipeline/ItemPipelineTest.php +++ b/tests/ItemPipeline/ItemPipelineTest.php @@ -43,12 +43,8 @@ protected function setUp(): void public function testCallsProcessorsInOrder(): void { - $processorA = $this->makeProcessor( - static fn ($item) => $item->set('value', $item->get('value') . 'A'), - ); - $processorB = $this->makeProcessor( - static fn ($item) => $item->set('value', $item->get('value') . 'B'), - ); + $processorA = self::makeProcessor(static fn ($item) => $item->set('value', $item->get('value') . 'A')); + $processorB = self::makeProcessor(static fn ($item) => $item->set('value', $item->get('value') . 'B')); $result = $this->pipeline ->setProcessors($processorA, $processorB) @@ -59,13 +55,9 @@ public function testCallsProcessorsInOrder(): void public function testDontCallNextProcessorsIfItemWasDropped(): void { - $processorA = $this->makeProcessor( - static fn ($item) => $item->set('value', $item->get('value') . 'A'), - ); - $processorB = $this->makeProcessor(static fn ($item) => $item->drop('::reason::')); - $processorC = $this->makeProcessor( - static fn ($item) => $item->set('value', $item->get('value') . 'C'), - ); + $processorA = self::makeProcessor(static fn ($item) => $item->set('value', $item->get('value') . 'A')); + $processorB = self::makeProcessor(static fn ($item) => $item->drop('::reason::')); + $processorC = self::makeProcessor(static fn ($item) => $item->set('value', $item->get('value') . 'C')); $result = $this->pipeline ->setProcessors($processorA, $processorB, $processorC) @@ -76,7 +68,7 @@ public function testDontCallNextProcessorsIfItemWasDropped(): void public function testDispatchesEventIfItemWasDropped(): void { - $processor = $this->makeProcessor(static fn ($item) => $item->drop('::reason::')); + $processor = self::makeProcessor(static fn ($item) => $item->drop('::reason::')); $item = new Item(['foo' => 'bar']); $this->pipeline @@ -108,7 +100,7 @@ public function testDispatchesEventIfItemWasScraped(): void public function testDoesNotDispatchEventIfItemWasNotScraped(): void { - $processor = $this->makeProcessor(static fn ($item) => $item->drop('::reason::')); + $processor = self::makeProcessor(static fn ($item) => $item->drop('::reason::')); $this->pipeline ->setProcessors($processor) ->sendItem(new Item([])); @@ -118,7 +110,7 @@ public function testDoesNotDispatchEventIfItemWasNotScraped(): void public function testRunsConditionalItemProcessorIfItHandlesItem(): void { - $processor = $this->makeConditionalProcessor(true, static fn (ItemInterface $item) => $item->drop('::reason::')); + $processor = self::makeConditionalProcessor(true, static fn (ItemInterface $item) => $item->drop('::reason::')); $result = $this->pipeline ->setProcessors($processor) @@ -129,7 +121,7 @@ public function testRunsConditionalItemProcessorIfItHandlesItem(): void public function testDoesNotRunConditionalItemProcessorIfItDoesNotHandleItem(): void { - $processor = $this->makeConditionalProcessor(false, static fn (ItemInterface $item) => $item->drop('::reason::')); + $processor = self::makeConditionalProcessor(false, static fn (ItemInterface $item) => $item->drop('::reason::')); $result = $this->pipeline ->setProcessors($processor) @@ -138,7 +130,7 @@ public function testDoesNotRunConditionalItemProcessorIfItDoesNotHandleItem(): v self::assertFalse($result->wasDropped()); } - private function makeProcessor(\Closure $processItem): ItemProcessorInterface + private static function makeProcessor(\Closure $processItem): ItemProcessorInterface { return new class($processItem) implements ItemProcessorInterface { use Configurable; @@ -154,7 +146,7 @@ public function processItem(ItemInterface $item): ItemInterface }; } - private function makeConditionalProcessor( + private static function makeConditionalProcessor( bool $handlesItem, \Closure $processItem, ): ConditionalItemProcessor { diff --git a/tests/Scheduling/ArrayRequestSchedulerTest.php b/tests/Scheduling/ArrayRequestSchedulerTest.php index a5c1ea3..eb3b5ff 100644 --- a/tests/Scheduling/ArrayRequestSchedulerTest.php +++ b/tests/Scheduling/ArrayRequestSchedulerTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Scheduling; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Scheduling\ArrayRequestScheduler; use RoachPHP\Scheduling\Timing\FakeClock; @@ -46,9 +47,7 @@ public function testEmpty(): void self::assertFalse($this->scheduler->empty()); } - /** - * @dataProvider batchSizeProvider - */ + #[DataProvider('batchSizeProvider')] public function testGroupScheduledRequestAccordingToBatchSize(int $batchSize, array $expectedBatchSizes): void { for ($i = 0; 10 > $i; ++$i) { @@ -64,27 +63,27 @@ public static function batchSizeProvider(): iterable { yield 'batch size 1' => [ 'batchSize' => 1, - 'expectedRequestCounts' => [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], + 'expectedBatchSizes' => [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0], ]; yield 'batch size 2' => [ 'batchSize' => 2, - 'expectedRequestCounts' => [2, 2, 2, 2, 2, 0], + 'expectedBatchSizes' => [2, 2, 2, 2, 2, 0], ]; yield 'batch size 3' => [ 'batchSize' => 3, - 'expectedRequestCounts' => [3, 3, 3, 1, 0], + 'expectedBatchSizes' => [3, 3, 3, 1, 0], ]; yield 'batch size 4' => [ 'batchSize' => 4, - 'expectedRequestCounts' => [4, 4, 2, 0], + 'expectedBatchSizes' => [4, 4, 2, 0], ]; yield 'batch size 5' => [ 'batchSize' => 5, - 'expectedRequestCounts' => [5, 5, 0], + 'expectedBatchSizes' => [5, 5, 0], ]; } diff --git a/tests/Shell/Resolver/DefaultNamespaceResolverDecoratorTest.php b/tests/Shell/Resolver/DefaultNamespaceResolverDecoratorTest.php index fea0863..bbc0169 100644 --- a/tests/Shell/Resolver/DefaultNamespaceResolverDecoratorTest.php +++ b/tests/Shell/Resolver/DefaultNamespaceResolverDecoratorTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Shell\Resolver; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Shell\Resolver\DefaultNamespaceResolverDecorator; use RoachPHP\Shell\Resolver\FakeNamespaceResolver; @@ -25,17 +26,15 @@ final class DefaultNamespaceResolverDecoratorTest extends TestCase { public function testPassInputThroughUnchangedIfItAlreadyPointsToExistingClass(): void { - $result = $this->getResolver('::different-default-namespace::')->resolveSpiderNamespace(TestSpider::class); + $result = self::getResolver('::different-default-namespace::')->resolveSpiderNamespace(TestSpider::class); self::assertSame(TestSpider::class, $result); } - /** - * @dataProvider prependNamespaceProvider - */ + #[DataProvider('prependNamespaceProvider')] public function testPrependsDefaultNamespaceIfPassedClassDoesNotExist(string $spiderName): void { - $result = $this->getResolver()->resolveSpiderNamespace($spiderName); + $result = self::getResolver()->resolveSpiderNamespace($spiderName); self::assertSame('RoachPHP\Tests\Fixtures\\' . $spiderName, $result); } @@ -49,19 +48,16 @@ public static function prependNamespaceProvider(): iterable 'only class name' => [ 'TestSpider', ], - 'relative namespace' => [ 'Derp\TestSpider', ], ]; } - /** - * @dataProvider defaultNamespaceProvider - */ + #[DataProvider('defaultNamespaceProvider')] public function testNormalizesDefaultNamespace(string $nonNormalizedNamespace): void { - $result = $this->getResolver($nonNormalizedNamespace)->resolveSpiderNamespace('TestSpider'); + $result = self::getResolver($nonNormalizedNamespace)->resolveSpiderNamespace('TestSpider'); self::assertSame('RoachPHP\Tests\Fixtures\TestSpider', $result); } @@ -75,27 +71,22 @@ public static function defaultNamespaceProvider(): iterable 'leading backslashes' => [ '\RoachPHP\Tests\Fixtures', ], - 'trailing backslashes' => [ 'RoachPHP\Tests\Fixtures\\', ], - 'trailing spaces' => [ 'RoachPHP\Tests\Fixtures ', ], - 'leading spaces' => [ ' RoachPHP\Tests\Fixtures', ], ]; } - /** - * @dataProvider spiderNameProvider - */ + #[DataProvider('spiderNameProvider')] public function testNormalizesProvidedSpiderName(string $nonNormalizedSpiderName): void { - $result = $this->getResolver()->resolveSpiderNamespace($nonNormalizedSpiderName); + $result = self::getResolver()->resolveSpiderNamespace($nonNormalizedSpiderName); self::assertSame('RoachPHP\Tests\Fixtures\TestSpider', $result); } @@ -109,7 +100,6 @@ public static function spiderNameProvider(): iterable 'leading spaces' => [ ' TestSpider', ], - 'trailing spaces' => [ 'TestSpider ', ], @@ -118,19 +108,19 @@ public static function spiderNameProvider(): iterable public function testTreatsLeadingBackslashesAsAbsolutePathAndReturnsItAsIs(): void { - $result = $this->getResolver()->resolveSpiderNamespace('\Test\Spider'); + $result = self::getResolver()->resolveSpiderNamespace('\Test\Spider'); self::assertSame('\Test\Spider', $result); } public function testDoesNotPrependDefaultNamespaceIfInputAlreadyStartsWithIt(): void { - $result = $this->getResolver('::default-namespace::')->resolveSpiderNamespace('::default-namespace::\Spider'); + $result = self::getResolver('::default-namespace::')->resolveSpiderNamespace('::default-namespace::\Spider'); self::assertSame('::default-namespace::\Spider', $result); } - private function getResolver(string $defaultNamespace = 'RoachPHP\Tests\Fixtures'): DefaultNamespaceResolverDecorator + private static function getResolver(string $defaultNamespace = 'RoachPHP\Tests\Fixtures'): DefaultNamespaceResolverDecorator { return new DefaultNamespaceResolverDecorator( new FakeNamespaceResolver(), diff --git a/tests/Shell/Resolver/FakeNamespaceResolverTest.php b/tests/Shell/Resolver/FakeNamespaceResolverTest.php index a5d1efd..c0ad04f 100644 --- a/tests/Shell/Resolver/FakeNamespaceResolverTest.php +++ b/tests/Shell/Resolver/FakeNamespaceResolverTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Shell\Resolver; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Shell\Resolver\FakeNamespaceResolver; use RoachPHP\Tests\Fixtures\RequestSpiderMiddleware; @@ -23,9 +24,7 @@ */ final class FakeNamespaceResolverTest extends TestCase { - /** - * @dataProvider inputStringProvider - */ + #[DataProvider('inputStringProvider')] public function testAlwaysReturnsTheOriginalString(string $input): void { $result = (new FakeNamespaceResolver())->resolveSpiderNamespace($input); diff --git a/tests/Spider/Configuration/ConfigurationTest.php b/tests/Spider/Configuration/ConfigurationTest.php index 095c3bd..48c6d35 100644 --- a/tests/Spider/Configuration/ConfigurationTest.php +++ b/tests/Spider/Configuration/ConfigurationTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Spider\Configuration; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Spider\Configuration\Configuration; use RoachPHP\Spider\Configuration\Overrides; @@ -29,13 +30,12 @@ final class ConfigurationTest extends TestCase { /** - * @dataProvider overridesProvider - * * @param array $overrides */ + #[DataProvider('overridesProvider')] public function testMergeWithOverrides(array $overrides, callable $verifyConfig): void { - $originalConfig = $this->makeConfiguration([ + $originalConfig = self::makeConfiguration([ 'startUrls' => ['::original-url::'], 'spiderMiddleware' => [ RequestSpiderMiddleware::class, @@ -70,42 +70,36 @@ static function (Configuration $config): void { self::assertEquals(['::override-url::'], $config->startUrls); }, ], - 'override spiderMiddleware' => [ ['spiderMiddleware' => [ResponseSpiderMiddleware::class]], static function (Configuration $config): void { self::assertEquals([ResponseSpiderMiddleware::class], $config->spiderMiddleware); }, ], - 'override downloaderMiddleware' => [ ['downloaderMiddleware' => [ResponseDownloaderMiddleware::class]], static function (Configuration $config): void { self::assertEquals([ResponseDownloaderMiddleware::class], $config->downloaderMiddleware); }, ], - 'override itemProcessors' => [ ['itemProcessors' => []], static function (Configuration $config): void { self::assertEmpty($config->itemProcessors); }, ], - 'override extensions' => [ ['extensions' => []], static function (Configuration $config): void { self::assertEmpty($config->extensions); }, ], - 'override concurrency' => [ ['concurrency' => 10], static function (Configuration $config): void { self::assertSame(10, $config->concurrency); }, ], - 'override requestDelay' => [ ['requestDelay' => 11], static function (Configuration $config): void { @@ -118,7 +112,7 @@ static function (Configuration $config): void { /** * @param array $values */ - private function makeConfiguration(array $values): Configuration + private static function makeConfiguration(array $values): Configuration { $defaults = [ 'startUrls' => [], diff --git a/tests/Spider/Middleware/FakeHandlerTest.php b/tests/Spider/Middleware/FakeHandlerTest.php index 510e32e..0a4d926 100644 --- a/tests/Spider/Middleware/FakeHandlerTest.php +++ b/tests/Spider/Middleware/FakeHandlerTest.php @@ -90,9 +90,7 @@ static function (ItemInterface $item, Response $response) { public function testCallsConfiguredRequestCallbackIfProvided(): void { - $handler = new FakeHandler( - handleRequestCallback: static fn ($request) => $request->withMeta('::key::', '::value::'), - ); + $handler = new FakeHandler(handleRequestCallback: static fn ($request) => $request->withMeta('::key::', '::value::')); $request = $this->makeRequest(); $response = $this->makeResponse($this->makeRequest()); diff --git a/tests/Spider/Middleware/MaximumCrawlDepthMiddlewareTest.php b/tests/Spider/Middleware/MaximumCrawlDepthMiddlewareTest.php index 8f21124..dbf82a0 100644 --- a/tests/Spider/Middleware/MaximumCrawlDepthMiddlewareTest.php +++ b/tests/Spider/Middleware/MaximumCrawlDepthMiddlewareTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Spider\Middleware; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Spider\Middleware\MaximumCrawlDepthMiddleware; use RoachPHP\Testing\Concerns\InteractsWithRequestsAndResponses; @@ -24,16 +25,13 @@ final class MaximumCrawlDepthMiddlewareTest extends TestCase { use InteractsWithRequestsAndResponses; - /** - * @dataProvider initialDepthProvider - */ + #[DataProvider('initialDepthProvider')] public function testIncrementsCrawlDepthForOutgoingRequestsBasedOnResponseCrawlDepth(int $initialDepth): void { $previousRequest = $this->makeRequest()->withMeta('depth', $initialDepth); $response = $this->makeResponse($previousRequest); - $processedRequest = $this - ->createMiddleware() + $processedRequest = self::createMiddleware() ->handleRequest($this->makeRequest(), $response); self::assertSame($initialDepth + 1, $processedRequest->getMeta('depth')); @@ -56,16 +54,13 @@ public static function initialDepthProvider(): iterable public function testHandleMissingDepthOnResponse(): void { - $processedRequest = $this - ->createMiddleware() + $processedRequest = self::createMiddleware() ->handleRequest($this->makeRequest(), $this->makeResponse()); self::assertSame(2, $processedRequest->getMeta('depth')); } - /** - * @dataProvider maxCrawlDepthProvider - */ + #[DataProvider('maxCrawlDepthProvider')] public function testDropRequestsAboveTheMaximumCrawlDepth(int $maxCrawlDepth): void { $previousRequest = $this @@ -74,16 +69,13 @@ public function testDropRequestsAboveTheMaximumCrawlDepth(int $maxCrawlDepth): v ->withMeta('depth', $maxCrawlDepth); $response = $this->makeResponse($previousRequest); - $processedRequest = $this - ->createMiddleware($maxCrawlDepth) + $processedRequest = self::createMiddleware($maxCrawlDepth) ->handleRequest($this->makeRequest(), $response); self::assertTrue($processedRequest->wasDropped()); } - /** - * @dataProvider maxCrawlDepthProvider - */ + #[DataProvider('maxCrawlDepthProvider')] public function testAllowRequestsBelowTheMaximumCrawlDepth(int $maxCrawlDepth): void { $previousRequest = $this @@ -93,8 +85,7 @@ public function testAllowRequestsBelowTheMaximumCrawlDepth(int $maxCrawlDepth): $response = $this->makeResponse($previousRequest); - $processedRequest = $this - ->createMiddleware($maxCrawlDepth) + $processedRequest = self::createMiddleware($maxCrawlDepth) ->handleRequest($this->makeRequest(), $response); self::assertFalse($processedRequest->wasDropped()); @@ -113,7 +104,7 @@ public static function maxCrawlDepthProvider(): iterable ]; } - private function createMiddleware(?int $maxCrawlDepth = null): MaximumCrawlDepthMiddleware + private static function createMiddleware(?int $maxCrawlDepth = null): MaximumCrawlDepthMiddleware { $middleware = new MaximumCrawlDepthMiddleware(); diff --git a/tests/Spider/Middleware/SpiderMiddlewareAdapterTest.php b/tests/Spider/Middleware/SpiderMiddlewareAdapterTest.php index b15ad4f..4527003 100644 --- a/tests/Spider/Middleware/SpiderMiddlewareAdapterTest.php +++ b/tests/Spider/Middleware/SpiderMiddlewareAdapterTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Spider\Middleware; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Http\Request; use RoachPHP\Http\Response; @@ -60,9 +61,7 @@ public function handleResponse(Response $response): Response self::assertSame($middleware, $class); } - /** - * @dataProvider itemMiddlewareProvider - */ + #[DataProvider('itemMiddlewareProvider')] public function testItemMiddlewareImplementation(callable $testCase): void { $middleware = new class() implements ItemMiddlewareInterface { @@ -110,9 +109,7 @@ public static function itemMiddlewareProvider(): iterable }]; } - /** - * @dataProvider requestMiddlewareProvider - */ + #[DataProvider('requestMiddlewareProvider')] public function testRequestMiddlewareImplementation(callable $testCase): void { $middleware = new class() implements RequestMiddlewareInterface { @@ -160,9 +157,7 @@ public static function requestMiddlewareProvider(): iterable }]; } - /** - * @dataProvider responseMiddlewareProvider - */ + #[DataProvider('responseMiddlewareProvider')] public function testResponseMiddlewareImplementation(callable $testCase): void { $middleware = new class() implements ResponseMiddlewareInterface { diff --git a/tests/Spider/ProcessorTest.php b/tests/Spider/ProcessorTest.php index 84156e9..a31cc55 100644 --- a/tests/Spider/ProcessorTest.php +++ b/tests/Spider/ProcessorTest.php @@ -56,7 +56,7 @@ public function testCallsCallbackOnRequest(): void public function testCallsHandlersForIncomingResponses(): void { - $handler = $this->makeHandler(); + $handler = self::makeHandler(); $request = $this->makeRequest(callback: static fn () => yield ParseResult::item([])); $response = $this->makeResponse($request); @@ -70,8 +70,8 @@ public function testCallsHandlersForIncomingResponses(): void public function testDoesNotPassOnResponseIfDroppedByHandler(): void { - $dropHandler = $this->makeHandler(handleResponse: static fn ($response) => $response->drop('::reason::')); - $otherHandler = $this->makeHandler(); + $dropHandler = self::makeHandler(handleResponse: static fn ($response) => $response->drop('::reason::')); + $otherHandler = self::makeHandler(); $response = $this->makeResponse($this->makeRequest()); $stack = $this->processor->withMiddleware($dropHandler, $otherHandler); @@ -83,10 +83,10 @@ public function testDoesNotPassOnResponseIfDroppedByHandler(): void public function testCallResponseHandlersInOrder(): void { - $handlerA = $this->makeHandler(static function (Response $response) { + $handlerA = self::makeHandler(static function (Response $response) { return $response->withMeta('foo', $response->getMeta('foo') . 'A'); }); - $handlerB = $this->makeHandler(static function (Response $response) { + $handlerB = self::makeHandler(static function (Response $response) { return $response->withMeta('foo', $response->getMeta('foo') . 'B'); }); $request = $this->makeRequest(callback: static function (Response $response) { @@ -103,12 +103,8 @@ public function testCallResponseHandlersInOrder(): void public function testPassesEachNewRequestToHandlersInOrder(): void { - $handlerA = $this->makeHandler( - handleRequestCallback: static fn ($r) => $r->withMeta('::key::', $r->getMeta('::key::', '') . 'A'), - ); - $handlerB = $this->makeHandler( - handleRequestCallback: static fn ($r) => $r->withMeta('::key::', $r->getMeta('::key::', '') . 'B'), - ); + $handlerA = self::makeHandler(handleRequestCallback: static fn ($r) => $r->withMeta('::key::', $r->getMeta('::key::', '') . 'A')); + $handlerB = self::makeHandler(handleRequestCallback: static fn ($r) => $r->withMeta('::key::', $r->getMeta('::key::', '') . 'B')); $results = [ ParseResult::request('GET', '::url::', static fn (Response $response) => yield from []), ParseResult::request('GET', '::url::', static fn (Response $response) => yield from []), @@ -124,13 +120,11 @@ public function testPassesEachNewRequestToHandlersInOrder(): void public function testDoesNotPassOnRequestIfDroppedByHandler(): void { - $dropHandler = $this->makeHandler(handleRequestCallback: static function ($request, $response) { + $dropHandler = self::makeHandler(handleRequestCallback: static function ($request, $response) { return $request->drop('::reason::'); }); - $handlerB = $this->makeHandler(); - $request = $this->makeRequest( - callback: fn () => yield ParseResult::fromValue($this->makeRequest()), - ); + $handlerB = self::makeHandler(); + $request = $this->makeRequest(callback: fn () => yield ParseResult::fromValue($this->makeRequest())); $stack = $this->processor->withMiddleware($dropHandler, $handlerB); $result = \iterator_to_array($stack->handle($this->makeResponse($request))); @@ -141,12 +135,8 @@ public function testDoesNotPassOnRequestIfDroppedByHandler(): void public function testCallsItemHandlersInOrderForOutgoingItems(): void { - $handlerA = $this->makeHandler( - handleItemCallback: static fn ($item) => $item->set('::key::', $item->get('::key::', '') . 'A'), - ); - $handlerB = $this->makeHandler( - handleItemCallback: static fn ($item) => $item->set('::key::', $item->get('::key::', '') . 'B'), - ); + $handlerA = self::makeHandler(handleItemCallback: static fn ($item) => $item->set('::key::', $item->get('::key::', '') . 'A')); + $handlerB = self::makeHandler(handleItemCallback: static fn ($item) => $item->set('::key::', $item->get('::key::', '') . 'B')); $request = $this->makeRequest(callback: static function (Response $response) { yield ParseResult::item([]); }); @@ -161,10 +151,10 @@ public function testCallsItemHandlersInOrderForOutgoingItems(): void public function testDoesNotPassOnItemIfDroppedByHandler(): void { - $dropHandler = $this->makeHandler(handleItemCallback: static function ($item, $response) { + $dropHandler = self::makeHandler(handleItemCallback: static function ($item, $response) { return $item->drop('::reason::'); }); - $handlerB = $this->makeHandler(); + $handlerB = self::makeHandler(); $item = new Item([]); $request = $this->makeRequest(callback: static fn () => yield ParseResult::fromValue($item)); $stack = $this->processor->withMiddleware($dropHandler, $handlerB); @@ -177,8 +167,8 @@ public function testDoesNotPassOnItemIfDroppedByHandler(): void public function testDispatchesEventIfResponseWasDropped(): void { - $dropHandler = $this->makeHandler(handleResponse: static fn ($response) => $response->drop('::reason::')); - $otherHandler = $this->makeHandler(); + $dropHandler = self::makeHandler(handleResponse: static fn ($response) => $response->drop('::reason::')); + $otherHandler = self::makeHandler(); $response = $this->makeResponse($this->makeRequest()); $stack = $this->processor->withMiddleware($dropHandler, $otherHandler); @@ -196,12 +186,10 @@ public function testDoesNotDispatchEventIfResponseWasNotDropped(): void public function testDispatchEventIfRequestWasDropped(): void { - $dropHandler = $this->makeHandler(handleRequestCallback: static function ($request, $response) { + $dropHandler = self::makeHandler(handleRequestCallback: static function ($request, $response) { return $request->drop('::reason::'); }); - $request = $this->makeRequest( - callback: fn () => yield ParseResult::fromValue($this->makeRequest()), - ); + $request = $this->makeRequest(callback: fn () => yield ParseResult::fromValue($this->makeRequest())); $this->processor ->withMiddleware($dropHandler) @@ -216,9 +204,7 @@ public function testDispatchEventIfRequestWasDropped(): void public function testDontDispatchEventIfRequestWasNotDropped(): void { - $request = $this->makeRequest( - callback: fn () => yield ParseResult::fromValue($this->makeRequest()), - ); + $request = $this->makeRequest(callback: fn () => yield ParseResult::fromValue($this->makeRequest())); $this->processor ->handle($this->makeResponse($request)) @@ -229,7 +215,7 @@ public function testDontDispatchEventIfRequestWasNotDropped(): void public function testDispatchEventIfItemWasDropped(): void { - $dropHandler = $this->makeHandler(handleItemCallback: static function ($item) { + $dropHandler = self::makeHandler(handleItemCallback: static function ($item) { return $item->drop('::reason::'); }); $request = $this->makeRequest(callback: static fn () => yield ParseResult::item(['foo' => 'bar'])); @@ -256,7 +242,7 @@ public function testDontDispatchEventIfItemWasNotDropped(): void $this->dispatcher->assertNotDispatched(ItemDropped::NAME); } - private function makeHandler( + private static function makeHandler( ?\Closure $handleResponse = null, ?\Closure $handleItemCallback = null, ?\Closure $handleRequestCallback = null, diff --git a/tests/Testing/FakeLoggerTest.php b/tests/Testing/FakeLoggerTest.php index 8a71c83..59b7739 100644 --- a/tests/Testing/FakeLoggerTest.php +++ b/tests/Testing/FakeLoggerTest.php @@ -13,6 +13,7 @@ namespace RoachPHP\Tests\Testing; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Testing\FakeLogger; @@ -24,10 +25,9 @@ final class FakeLoggerTest extends TestCase { /** - * @dataProvider logMessageProvider - * * @param array $context */ + #[DataProvider('logMessageProvider')] public function testCheckIfSpecificMessageWasLoggedAtLevel(string $level, string $message, array $context): void { $logger = new FakeLogger(); @@ -40,10 +40,9 @@ public function testCheckIfSpecificMessageWasLoggedAtLevel(string $level, string } /** - * @dataProvider logMessageProvider - * * @param array $context */ + #[DataProvider('logMessageProvider')] public function testCheckIfMessageWasLoggedWithContext(string $level, string $message, array $context): void { $logger = new FakeLogger(); @@ -87,4 +86,17 @@ public static function logMessageProvider(): iterable ], ]; } + + public function testCountMessages(): void + { + $logger = new FakeLogger(); + + $logger->info('::message::', ['uri' => '::a::']); + $logger->info('::message::', ['uri' => '::a::']); + $logger->info('::message::', ['uri' => '::b::']); + + self::assertSame(3, $logger->countMessages('info', '::message::')); + self::assertSame(2, $logger->countMessages('info', '::message::', ['uri' => '::a::'])); + self::assertSame(0, $logger->countMessages('error', '::message::')); + } } diff --git a/tests/Testing/FakeRunnerTest.php b/tests/Testing/FakeRunnerTest.php index 4be4ebe..bd8f8c1 100644 --- a/tests/Testing/FakeRunnerTest.php +++ b/tests/Testing/FakeRunnerTest.php @@ -14,6 +14,7 @@ namespace RoachPHP\Tests\Testing; use PHPUnit\Framework\AssertionFailedError; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use RoachPHP\Core\FakeRunner; use RoachPHP\Spider\Configuration\Overrides; @@ -32,9 +33,7 @@ protected function setUp(): void $this->runner = new FakeRunner(); } - /** - * @dataProvider runnerMethodProvider - */ + #[DataProvider('runnerMethodProvider')] public function testAssertRunWasStartedPassesIfAnyRunForTheGivenSpiderClassWasStarted(string $method): void { $this->runner->{$method}(TestSpider::class); @@ -49,9 +48,7 @@ public function testAssertRunWasStartedFailsIfNoRunWasStartedAtAll(): void $this->runner->assertRunWasStarted(TestSpider::class); } - /** - * @dataProvider runnerMethodProvider - */ + #[DataProvider('runnerMethodProvider')] public function testAssertRunWasStartedFailsIfNoRunWasStartedForTheGivenSpider(string $method): void { $this->runner->{$method}(TestSpider2::class); @@ -60,9 +57,7 @@ public function testAssertRunWasStartedFailsIfNoRunWasStartedForTheGivenSpider(s $this->runner->assertRunWasStarted(TestSpider::class); } - /** - * @dataProvider runnerMethodProvider - */ + #[DataProvider('runnerMethodProvider')] public function testAssertRunWasStartedPassesIfTheProvidedClosureReturnsTrue(string $method): void { $this->runner->{$method}(TestSpider::class); @@ -70,9 +65,7 @@ public function testAssertRunWasStartedPassesIfTheProvidedClosureReturnsTrue(str $this->runner->assertRunWasStarted(TestSpider::class, static fn () => true); } - /** - * @dataProvider runnerMethodProvider - */ + #[DataProvider('runnerMethodProvider')] public function testAssertRunWasStartedPassesIfCallbackReturnsTrueForAnyOfTheFoundRuns(string $method): void { $this->runner->{$method}(TestSpider::class, context: ['foo' => 'bar']); @@ -85,9 +78,7 @@ public function testAssertRunWasStartedPassesIfCallbackReturnsTrueForAnyOfTheFou ); } - /** - * @dataProvider runnerMethodProvider - */ + #[DataProvider('runnerMethodProvider')] public function testAssertRunWasStartedFailsIfTheProvidedClosureReturnsFalse(string $method): void { $this->runner->{$method}(TestSpider::class); @@ -96,9 +87,7 @@ public function testAssertRunWasStartedFailsIfTheProvidedClosureReturnsFalse(str $this->runner->assertRunWasStarted(TestSpider::class, static fn () => false); } - /** - * @dataProvider runnerMethodProvider - */ + #[DataProvider('runnerMethodProvider')] public function testAssertRunWasNotStartedPassesIfNoRunForTheGivenSpiderClassWasStarted(string $method): void { $this->runner->{$method}(TestSpider2::class); @@ -111,9 +100,7 @@ public function testAssertRunWasNotStartedPassesIfNoRunWasStartedAtAll(): void $this->runner->assertRunWasNotStarted(TestSpider::class); } - /** - * @dataProvider runnerMethodProvider - */ + #[DataProvider('runnerMethodProvider')] public function testAssertRunWasNotStartedFailsIfRunForSpiderWasStarted(string $method): void { $this->runner->{$method}(TestSpider::class);