diff --git a/composer.json b/composer.json index ec1d512445..f60f13c52e 100644 --- a/composer.json +++ b/composer.json @@ -4,7 +4,7 @@ "type": "project", "license": "AGPL-3.0-only", "require": { - "php": ">=8.1.0 <8.4.0", + "php": ">=8.1.0 <8.5.0", "ext-ctype": "*", "ext-dom": "*", "ext-gd": "*", @@ -12,8 +12,7 @@ "ext-json": "*", "ext-mysqli": "*", "ext-soap": "*", - "apereo/phpcas": "~1.6.0", - "firebase/php-jwt": "^6.4.0", + "apereo/phpcas": "dev-master", "guzzlehttp/guzzle": "^7.5.1", "league/oauth2-google": "^4.0.1", "nikic/php-parser": "^4.14.0", @@ -40,6 +39,12 @@ "symfony/stopwatch": "~6.4.0", "symfony/web-profiler-bundle": "~6.4.0" }, + "repositories": [ + { + "type": "vcs", + "url": "https://github.com/EsupPortail/phpCAS" + } + ], "suggest": { "ext-libsodium": "Required to use the AttributeEncryptedString.", "ext-openssl": "Can be used as a polyfill if libsodium is not installed", diff --git a/composer.lock b/composer.lock index cb66e47e42..e59227f3e5 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0da5da3b165955f386268e6dd8db2a8d", + "content-hash": "ceac38f6033afe07b7ab977fa39fe348", "packages": [ { "name": "apereo/phpcas", - "version": "1.6.1", + "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/apereo/phpCAS.git", - "reference": "c129708154852656aabb13d8606cd5b12dbbabac" + "url": "https://github.com/EsupPortail/phpCAS.git", + "reference": "57a7744146a963d8fa80192e0ab351051b711ff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/apereo/phpCAS/zipball/c129708154852656aabb13d8606cd5b12dbbabac", - "reference": "c129708154852656aabb13d8606cd5b12dbbabac", + "url": "https://api.github.com/repos/EsupPortail/phpCAS/zipball/57a7744146a963d8fa80192e0ab351051b711ff6", + "reference": "57a7744146a963d8fa80192e0ab351051b711ff6", "shasum": "" }, "require": { @@ -31,6 +31,7 @@ "phpstan/phpstan": "^1.5", "phpunit/phpunit": ">=7.5" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -45,15 +46,27 @@ "source/" ] }, - "notification-url": "https://packagist.org/downloads/", + "autoload-dev": { + "psr-4": { + "PhpCas\\": "test/CAS/" + } + }, + "scripts": { + "test": [ + "phpunit" + ], + "phpstan": [ + "phpstan" + ] + }, "license": [ "Apache-2.0" ], "authors": [ { "name": "Joachim Fritschi", - "email": "jfritschi@freenet.de", - "homepage": "https://github.com/jfritschi" + "homepage": "https://github.com/jfritschi", + "email": "jfritschi@freenet.de" }, { "name": "Adam Franco", @@ -72,10 +85,10 @@ "jasig" ], "support": { - "issues": "https://github.com/apereo/phpCAS/issues", - "source": "https://github.com/apereo/phpCAS/tree/1.6.1" + "source": "https://github.com/EsupPortail/phpCAS/tree/master", + "issues": "https://github.com/EsupPortail/phpCAS/issues" }, - "time": "2023-02-19T19:52:35+00:00" + "time": "2025-12-02T11:38:23+00:00" }, { "name": "doctrine/lexer", @@ -223,26 +236,26 @@ }, { "name": "firebase/php-jwt", - "version": "v6.10.0", + "version": "v7.0.2", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" + "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5645b43af647b6947daac1d0f659dd1fbe8d3b65", + "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65", "shasum": "" }, "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", + "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "psr/cache": "^1.0||^2.0", + "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" }, @@ -280,28 +293,28 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + "source": "https://github.com/firebase/php-jwt/tree/v7.0.2" }, - "time": "2023-12-01T16:26:39+00:00" + "time": "2025-12-16T22:17:28+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.8.1", + "version": "7.10.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.1", - "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -312,9 +325,9 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -392,7 +405,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + "source": "https://github.com/guzzle/guzzle/tree/7.10.0" }, "funding": [ { @@ -408,20 +421,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:35:24+00:00" + "time": "2025-08-23T22:36:01+00:00" }, { "name": "guzzlehttp/promises", - "version": "2.0.2", + "version": "2.3.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + "reference": "481557b130ef3790cf82b713667b43030dc9c957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", + "reference": "481557b130ef3790cf82b713667b43030dc9c957", "shasum": "" }, "require": { @@ -429,7 +442,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "type": "library", "extra": { @@ -475,7 +488,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.2" + "source": "https://github.com/guzzle/promises/tree/2.3.0" }, "funding": [ { @@ -491,20 +504,20 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:19:20+00:00" + "time": "2025-08-22T14:34:08+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.6.2", + "version": "2.8.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + "reference": "21dc724a0583619cd1652f673303492272778051" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", + "reference": "21dc724a0583619cd1652f673303492272778051", "shasum": "" }, "require": { @@ -519,8 +532,8 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" @@ -591,7 +604,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.6.2" + "source": "https://github.com/guzzle/psr7/tree/2.8.0" }, "funding": [ { @@ -607,39 +620,34 @@ "type": "tidelift" } ], - "time": "2023-12-03T20:05:35+00:00" + "time": "2025-08-23T21:21:41+00:00" }, { "name": "league/oauth2-client", - "version": "2.7.0", + "version": "2.9.0", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-client.git", - "reference": "160d6274b03562ebeb55ed18399281d8118b76c8" + "reference": "26e8c5da4f3d78cede7021e09b1330a0fc093d5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/160d6274b03562ebeb55ed18399281d8118b76c8", - "reference": "160d6274b03562ebeb55ed18399281d8118b76c8", + "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/26e8c5da4f3d78cede7021e09b1330a0fc093d5e", + "reference": "26e8c5da4f3d78cede7021e09b1330a0fc093d5e", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "^6.0 || ^7.0", - "paragonie/random_compat": "^1 || ^2 || ^9.99", - "php": "^5.6 || ^7.0 || ^8.0" + "ext-json": "*", + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", + "php": "^7.1 || >=8.0.0 <8.6.0" }, "require-dev": { "mockery/mockery": "^1.3.5", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpunit/phpunit": "^5.7 || ^6.0 || ^9.5", - "squizlabs/php_codesniffer": "^2.3 || ^3.0" + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "^3.11" }, "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.0.x-dev" - } - }, "autoload": { "psr-4": { "League\\OAuth2\\Client\\": "src/" @@ -675,22 +683,22 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-client/issues", - "source": "https://github.com/thephpleague/oauth2-client/tree/2.7.0" + "source": "https://github.com/thephpleague/oauth2-client/tree/2.9.0" }, - "time": "2023-04-16T18:19:15+00:00" + "time": "2025-11-25T22:17:17+00:00" }, { "name": "league/oauth2-google", - "version": "4.0.1", + "version": "4.1.0", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-google.git", - "reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76" + "reference": "8b9bb43740ac6d994aca881a35f7bacbe98c0ffb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/1b01ba18ba31b29e88771e3e0979e5c91d4afe76", - "reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76", + "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/8b9bb43740ac6d994aca881a35f7bacbe98c0ffb", + "reference": "8b9bb43740ac6d994aca881a35f7bacbe98c0ffb", "shasum": "" }, "require": { @@ -730,41 +738,36 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-google/issues", - "source": "https://github.com/thephpleague/oauth2-google/tree/4.0.1" + "source": "https://github.com/thephpleague/oauth2-google/tree/4.1.0" }, - "time": "2023-03-17T15:20:52+00:00" + "time": "2025-12-15T12:24:14+00:00" }, { "name": "nikic/php-parser", - "version": "v4.18.0", + "version": "v4.19.5", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", + "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.1" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" @@ -786,59 +789,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" - }, - "time": "2023-12-10T21:03:43+00:00" - }, - { - "name": "paragonie/random_compat", - "version": "v9.99.100", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", - "shasum": "" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.5" }, - "time": "2020-10-15T08:29:30+00:00" + "time": "2025-12-06T11:45:25+00:00" }, { "name": "pear/archive_tar", @@ -973,30 +926,31 @@ }, { "name": "pear/pear-core-minimal", - "version": "v1.10.11", + "version": "v1.10.18", "source": { "type": "git", "url": "https://github.com/pear/pear-core-minimal.git", - "reference": "68d0d32ada737153b7e93b8d3c710ebe70ac867d" + "reference": "c7b55789d01de0ce090d289b73f1bbd6a2f113b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/68d0d32ada737153b7e93b8d3c710ebe70ac867d", - "reference": "68d0d32ada737153b7e93b8d3c710ebe70ac867d", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/c7b55789d01de0ce090d289b73f1bbd6a2f113b1", + "reference": "c7b55789d01de0ce090d289b73f1bbd6a2f113b1", "shasum": "" }, "require": { "pear/console_getopt": "~1.4", - "pear/pear_exception": "~1.0" + "pear/pear_exception": "~1.0", + "php": ">=5.4" }, "replace": { "rsky/pear-core-min": "self.version" }, "type": "library", "autoload": { - "psr-0": { - "": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "include-path": [ @@ -1017,7 +971,7 @@ "issues": "http://pear.php.net/bugs/search.php?cmd=display&package_name[]=PEAR", "source": "https://github.com/pear/pear-core-minimal" }, - "time": "2021-08-10T22:31:03+00:00" + "time": "2025-12-14T20:37:07+00:00" }, { "name": "pear/pear_exception", @@ -1080,28 +1034,32 @@ }, { "name": "pelago/emogrifier", - "version": "v7.2.0", + "version": "v7.3.0", "source": { "type": "git", "url": "https://github.com/MyIntervals/emogrifier.git", - "reference": "727bdf7255b51798307f17dec52ff8a91f1c7de3" + "reference": "6e00d9d8235e8cc8eec857e8dcd6cfeefdfd0cd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/727bdf7255b51798307f17dec52ff8a91f1c7de3", - "reference": "727bdf7255b51798307f17dec52ff8a91f1c7de3", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/6e00d9d8235e8cc8eec857e8dcd6cfeefdfd0cd6", + "reference": "6e00d9d8235e8cc8eec857e8dcd6cfeefdfd0cd6", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", - "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", - "sabberworm/php-css-parser": "^8.4.0", + "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "sabberworm/php-css-parser": "^8.7.0", "symfony/css-selector": "^4.4.23 || ^5.4.0 || ^6.0.0 || ^7.0.0" }, "require-dev": { - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpunit/phpunit": "9.6.11", + "php-parallel-lint/php-parallel-lint": "1.4.0", + "phpstan/extension-installer": "1.4.3", + "phpstan/phpstan": "1.12.7", + "phpstan/phpstan-phpunit": "1.4.0", + "phpstan/phpstan-strict-rules": "1.6.1", + "phpunit/phpunit": "9.6.21", "rawr/cross-data-providers": "2.4.0" }, "type": "library", @@ -1134,7 +1092,7 @@ }, { "name": "Jake Hotson", - "email": "jake@qzdesign.co.uk" + "email": "jake.github@qzdesign.co.uk" }, { "name": "Cameron Brooks" @@ -1154,7 +1112,7 @@ "issues": "https://github.com/MyIntervals/emogrifier/issues", "source": "https://github.com/MyIntervals/emogrifier" }, - "time": "2023-12-06T02:00:20+00:00" + "time": "2024-10-28T16:12:26+00:00" }, { "name": "psr/cache", @@ -1362,20 +1320,20 @@ }, { "name": "psr/http-factory", - "version": "1.0.2", + "version": "1.1.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, "type": "library", @@ -1399,7 +1357,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -1411,9 +1369,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, - "time": "2023-04-10T20:10:41+00:00" + "time": "2024-04-15T12:06:14+00:00" }, { "name": "psr/http-message", @@ -1564,30 +1522,35 @@ }, { "name": "sabberworm/php-css-parser", - "version": "8.4.0", + "version": "v8.9.0", "source": { "type": "git", - "url": "https://github.com/sabberworm/PHP-CSS-Parser.git", - "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30" + "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git", + "reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/e41d2140031d533348b2192a83f02d8dd8a71d30", - "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30", + "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9", + "reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9", "shasum": "" }, "require": { "ext-iconv": "*", - "php": ">=5.6.20" + "php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "require-dev": { - "codacy/coverage": "^1.4", - "phpunit/phpunit": "^4.8.36" + "phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41", + "rawr/cross-data-providers": "^2.0.0" }, "suggest": { "ext-mbstring": "for parsing UTF-8 CSS" }, "type": "library", + "extra": { + "branch-alias": { + "dev-main": "9.0.x-dev" + } + }, "autoload": { "psr-4": { "Sabberworm\\CSS\\": "src/" @@ -1600,6 +1563,14 @@ "authors": [ { "name": "Raphael Schweikert" + }, + { + "name": "Oliver Klee", + "email": "github@oliverklee.de" + }, + { + "name": "Jake Hotson", + "email": "jake.github@qzdesign.co.uk" } ], "description": "Parser for CSS Files written in PHP", @@ -1610,23 +1581,23 @@ "stylesheet" ], "support": { - "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues", - "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0" + "issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues", + "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0" }, - "time": "2021-12-11T13:40:54+00:00" + "time": "2025-07-11T13:20:48+00:00" }, { "name": "scssphp/scssphp", - "version": "v1.12.1", + "version": "v1.13.0", "source": { "type": "git", "url": "https://github.com/scssphp/scssphp.git", - "reference": "394ed1e960138710a60d035c1a85d43d0bf0faeb" + "reference": "63d1157457e5554edf00b0c1fabab4c1511d2520" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scssphp/scssphp/zipball/394ed1e960138710a60d035c1a85d43d0bf0faeb", - "reference": "394ed1e960138710a60d035c1a85d43d0bf0faeb", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/63d1157457e5554edf00b0c1fabab4c1511d2520", + "reference": "63d1157457e5554edf00b0c1fabab4c1511d2520", "shasum": "" }, "require": { @@ -1655,8 +1626,8 @@ "type": "library", "extra": { "bamarni-bin": { - "forward-command": false, - "bin-links": false + "bin-links": false, + "forward-command": false } }, "autoload": { @@ -1691,9 +1662,9 @@ ], "support": { "issues": "https://github.com/scssphp/scssphp/issues", - "source": "https://github.com/scssphp/scssphp/tree/v1.12.1" + "source": "https://github.com/scssphp/scssphp/tree/v1.13.0" }, - "time": "2024-01-13T12:36:40+00:00" + "time": "2024-08-17T21:02:11+00:00" }, { "name": "soundasleep/html2text", @@ -1752,16 +1723,16 @@ }, { "name": "symfony/cache", - "version": "v6.4.12", + "version": "v6.4.33", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "a463451b7f6ac4a47b98dbfc78ec2d3560c759d8" + "reference": "5b088fa41eb9568748dc255c45e4054c387ba73b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/a463451b7f6ac4a47b98dbfc78ec2d3560c759d8", - "reference": "a463451b7f6ac4a47b98dbfc78ec2d3560c759d8", + "url": "https://api.github.com/repos/symfony/cache/zipball/5b088fa41eb9568748dc255c45e4054c387ba73b", + "reference": "5b088fa41eb9568748dc255c45e4054c387ba73b", "shasum": "" }, "require": { @@ -1828,7 +1799,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.4.12" + "source": "https://github.com/symfony/cache/tree/v6.4.33" }, "funding": [ { @@ -1839,12 +1810,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": "2024-09-16T16:01:33+00:00" + "time": "2026-01-27T15:05:20+00:00" }, { "name": "symfony/cache-contracts", @@ -1924,16 +1899,16 @@ }, { "name": "symfony/config", - "version": "v6.4.0", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "5d33e0fb707d603330e0edfd4691803a1253572e" + "reference": "d445badf0ad2c2a492e38c0378c39997a56ef97b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/5d33e0fb707d603330e0edfd4691803a1253572e", - "reference": "5d33e0fb707d603330e0edfd4691803a1253572e", + "url": "https://api.github.com/repos/symfony/config/zipball/d445badf0ad2c2a492e38c0378c39997a56ef97b", + "reference": "d445badf0ad2c2a492e38c0378c39997a56ef97b", "shasum": "" }, "require": { @@ -1979,7 +1954,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.4.0" + "source": "https://github.com/symfony/config/tree/v6.4.32" }, "funding": [ { @@ -1990,25 +1965,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": "2023-11-09T08:28:32+00:00" + "time": "2026-01-13T08:40:30+00:00" }, { "name": "symfony/console", - "version": "v6.4.2", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625" + "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0254811a143e6bc6c8deea08b589a7e68a37f625", - "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625", + "url": "https://api.github.com/repos/symfony/console/zipball/0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", + "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", "shasum": "" }, "require": { @@ -2073,7 +2052,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.2" + "source": "https://github.com/symfony/console/tree/v6.4.32" }, "funding": [ { @@ -2084,25 +2063,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": "2023-12-10T16:15:48+00:00" + "time": "2026-01-13T08:45:59+00:00" }, { "name": "symfony/css-selector", - "version": "v6.4.0", + "version": "v6.4.24", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4" + "reference": "9b784413143701aa3c94ac1869a159a9e53e8761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/d036c6c0d0b09e24a14a35f8292146a658f986e4", - "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/9b784413143701aa3c94ac1869a159a9e53e8761", + "reference": "9b784413143701aa3c94ac1869a159a9e53e8761", "shasum": "" }, "require": { @@ -2138,7 +2121,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.4.0" + "source": "https://github.com/symfony/css-selector/tree/v6.4.24" }, "funding": [ { @@ -2149,25 +2132,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": "2023-10-31T08:40:20+00:00" + "time": "2025-07-10T08:14:14+00:00" }, { "name": "symfony/dependency-injection", - "version": "v6.4.2", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "226ea431b1eda6f0d9f5a4b278757171960bb195" + "reference": "b17882e933c4c606620247b6708ab53aa3b88753" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/226ea431b1eda6f0d9f5a4b278757171960bb195", - "reference": "226ea431b1eda6f0d9f5a4b278757171960bb195", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b17882e933c4c606620247b6708ab53aa3b88753", + "reference": "b17882e933c4c606620247b6708ab53aa3b88753", "shasum": "" }, "require": { @@ -2175,7 +2162,7 @@ "psr/container": "^1.1|^2.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/service-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.2.10|^7.0" + "symfony/var-exporter": "^6.4.20|^7.2.5" }, "conflict": { "ext-psr": "<1.1|>=2", @@ -2219,7 +2206,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.2" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.32" }, "funding": [ { @@ -2230,12 +2217,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": "2023-12-28T19:16:56+00:00" + "time": "2026-01-23T10:54:33+00:00" }, { "name": "symfony/deprecation-contracts", @@ -2306,16 +2297,16 @@ }, { "name": "symfony/dotenv", - "version": "v6.4.2", + "version": "v6.4.30", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "835f8d2d1022934ac038519de40b88158798c96f" + "reference": "924edbc9631b75302def0258ed1697948b17baf6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/835f8d2d1022934ac038519de40b88158798c96f", - "reference": "835f8d2d1022934ac038519de40b88158798c96f", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/924edbc9631b75302def0258ed1697948b17baf6", + "reference": "924edbc9631b75302def0258ed1697948b17baf6", "shasum": "" }, "require": { @@ -2360,7 +2351,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v6.4.2" + "source": "https://github.com/symfony/dotenv/tree/v6.4.30" }, "funding": [ { @@ -2371,25 +2362,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": "2023-12-28T19:16:56+00:00" + "time": "2025-11-14T17:33:48+00:00" }, { "name": "symfony/error-handler", - "version": "v6.4.0", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "c873490a1c97b3a0a4838afc36ff36c112d02788" + "reference": "8c18400784fcb014dc73c8d5601a9576af7f8ad4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/c873490a1c97b3a0a4838afc36ff36c112d02788", - "reference": "c873490a1c97b3a0a4838afc36ff36c112d02788", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/8c18400784fcb014dc73c8d5601a9576af7f8ad4", + "reference": "8c18400784fcb014dc73c8d5601a9576af7f8ad4", "shasum": "" }, "require": { @@ -2435,7 +2430,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.0" + "source": "https://github.com/symfony/error-handler/tree/v6.4.32" }, "funding": [ { @@ -2446,25 +2441,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": "2023-10-18T09:43:34+00:00" + "time": "2026-01-19T19:28:19+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.4.25", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b0cf3162020603587363f0551cd3be43958611ff" + "reference": "99d7e101826e6610606b9433248f80c1997cd20b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b0cf3162020603587363f0551cd3be43958611ff", - "reference": "b0cf3162020603587363f0551cd3be43958611ff", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99d7e101826e6610606b9433248f80c1997cd20b", + "reference": "99d7e101826e6610606b9433248f80c1997cd20b", "shasum": "" }, "require": { @@ -2515,7 +2514,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/v6.4.25" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.32" }, "funding": [ { @@ -2535,7 +2534,7 @@ "type": "tidelift" } ], - "time": "2025-08-13T09:41:44+00:00" + "time": "2026-01-05T11:13:48+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -2615,16 +2614,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.0", + "version": "v6.4.30", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59" + "reference": "441c6b69f7222aadae7cbf5df588496d5ee37789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/952a8cb588c3bc6ce76f6023000fb932f16a6e59", - "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/441c6b69f7222aadae7cbf5df588496d5ee37789", + "reference": "441c6b69f7222aadae7cbf5df588496d5ee37789", "shasum": "" }, "require": { @@ -2632,6 +2631,9 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, "type": "library", "autoload": { "psr-4": { @@ -2658,7 +2660,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.0" + "source": "https://github.com/symfony/filesystem/tree/v6.4.30" }, "funding": [ { @@ -2669,25 +2671,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": "2023-07-26T17:27:13+00:00" + "time": "2025-11-26T14:43:45+00:00" }, { "name": "symfony/finder", - "version": "v6.4.0", + "version": "v6.4.33", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" + "reference": "24965ca011dac87431729640feef8bcf7b5523e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", + "url": "https://api.github.com/repos/symfony/finder/zipball/24965ca011dac87431729640feef8bcf7b5523e0", + "reference": "24965ca011dac87431729640feef8bcf7b5523e0", "shasum": "" }, "require": { @@ -2722,7 +2728,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.0" + "source": "https://github.com/symfony/finder/tree/v6.4.33" }, "funding": [ { @@ -2733,25 +2739,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": "2023-10-31T17:30:12+00:00" + "time": "2026-01-26T13:03:48+00:00" }, { "name": "symfony/framework-bundle", - "version": "v6.4.2", + "version": "v6.4.33", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "c26a221e0462027d1f9d4a802ed63f8ab07a43d0" + "reference": "9ef2d0b63b9e855ba351e770a603d89699115801" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/c26a221e0462027d1f9d4a802ed63f8ab07a43d0", - "reference": "c26a221e0462027d1f9d4a802ed63f8ab07a43d0", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/9ef2d0b63b9e855ba351e770a603d89699115801", + "reference": "9ef2d0b63b9e855ba351e770a603d89699115801", "shasum": "" }, "require": { @@ -2760,7 +2770,7 @@ "php": ">=8.1", "symfony/cache": "^5.4|^6.0|^7.0", "symfony/config": "^6.1|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4.12|^7.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.1|^7.0", "symfony/event-dispatcher": "^5.4|^6.0|^7.0", @@ -2790,7 +2800,8 @@ "symfony/mime": "<6.4", "symfony/property-access": "<5.4", "symfony/property-info": "<5.4", - "symfony/scheduler": "<6.4", + "symfony/runtime": "<5.4.45|>=6.0,<6.4.13|>=7.0,<7.1.6", + "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4", "symfony/security-core": "<5.4", "symfony/security-csrf": "<5.4", "symfony/serializer": "<6.4", @@ -2829,7 +2840,7 @@ "symfony/process": "^5.4|^6.0|^7.0", "symfony/property-info": "^5.4|^6.0|^7.0", "symfony/rate-limiter": "^5.4|^6.0|^7.0", - "symfony/scheduler": "^6.4|^7.0", + "symfony/scheduler": "^6.4.4|^7.0.4", "symfony/security-bundle": "^5.4|^6.0|^7.0", "symfony/semaphore": "^5.4|^6.0|^7.0", "symfony/serializer": "^6.4|^7.0", @@ -2842,7 +2853,7 @@ "symfony/web-link": "^5.4|^6.0|^7.0", "symfony/workflow": "^6.4|^7.0", "symfony/yaml": "^5.4|^6.0|^7.0", - "twig/twig": "^2.10|^3.0" + "twig/twig": "^2.10|^3.0.4" }, "type": "symfony-bundle", "autoload": { @@ -2870,7 +2881,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v6.4.2" + "source": "https://github.com/symfony/framework-bundle/tree/v6.4.33" }, "funding": [ { @@ -2881,25 +2892,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": "2023-12-29T15:34:34+00:00" + "time": "2026-01-26T14:46:41+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.4.29", + "version": "v6.4.33", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "b03d11e015552a315714c127d8d1e0f9e970ec88" + "reference": "f1a490cc9d595ba7ebe684220e625d1e472ad278" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b03d11e015552a315714c127d8d1e0f9e970ec88", - "reference": "b03d11e015552a315714c127d8d1e0f9e970ec88", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f1a490cc9d595ba7ebe684220e625d1e472ad278", + "reference": "f1a490cc9d595ba7ebe684220e625d1e472ad278", "shasum": "" }, "require": { @@ -2947,7 +2962,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.29" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.33" }, "funding": [ { @@ -2967,20 +2982,20 @@ "type": "tidelift" } ], - "time": "2025-11-08T16:40:12+00:00" + "time": "2026-01-27T15:04:55+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.4.2", + "version": "v6.4.33", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "13e8387320b5942d0dc408440c888e2d526efef4" + "reference": "73fa5c999d7f741ca544a97d3c791cc97890ae4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/13e8387320b5942d0dc408440c888e2d526efef4", - "reference": "13e8387320b5942d0dc408440c888e2d526efef4", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/73fa5c999d7f741ca544a97d3c791cc97890ae4d", + "reference": "73fa5c999d7f741ca544a97d3c791cc97890ae4d", "shasum": "" }, "require": { @@ -3029,12 +3044,13 @@ "symfony/process": "^5.4|^6.0|^7.0", "symfony/property-access": "^5.4.5|^6.0.5|^7.0", "symfony/routing": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.3|^7.0", + "symfony/serializer": "^6.4.4|^7.0.4", "symfony/stopwatch": "^5.4|^6.0|^7.0", "symfony/translation": "^5.4|^6.0|^7.0", "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^5.4|^6.0|^7.0", "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.4|^7.0", "symfony/var-exporter": "^6.2|^7.0", "twig/twig": "^2.13|^3.0.4" }, @@ -3064,7 +3080,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.2" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.33" }, "funding": [ { @@ -3075,25 +3091,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": "2023-12-30T15:31:44+00:00" + "time": "2026-01-28T10:02:13+00:00" }, { "name": "symfony/mailer", - "version": "v6.4.25", + "version": "v6.4.31", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2" + "reference": "8835f93333474780fda1b987cae37e33c3e026ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/628b43b45a3e6b15c8a633fb22df547ed9b492a2", - "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2", + "url": "https://api.github.com/repos/symfony/mailer/zipball/8835f93333474780fda1b987cae37e33c3e026ca", + "reference": "8835f93333474780fda1b987cae37e33c3e026ca", "shasum": "" }, "require": { @@ -3144,7 +3164,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.25" + "source": "https://github.com/symfony/mailer/tree/v6.4.31" }, "funding": [ { @@ -3164,20 +3184,20 @@ "type": "tidelift" } ], - "time": "2025-08-13T09:41:44+00:00" + "time": "2025-12-12T07:33:25+00:00" }, { "name": "symfony/mime", - "version": "v6.4.24", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7" + "reference": "7409686879ca36c09fc970a5fa8ff6e93504dba4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/664d5e844a2de5e11c8255d0aef6bc15a9660ac7", - "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7", + "url": "https://api.github.com/repos/symfony/mime/zipball/7409686879ca36c09fc970a5fa8ff6e93504dba4", + "reference": "7409686879ca36c09fc970a5fa8ff6e93504dba4", "shasum": "" }, "require": { @@ -3233,7 +3253,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.24" + "source": "https://github.com/symfony/mime/tree/v6.4.32" }, "funding": [ { @@ -3253,24 +3273,24 @@ "type": "tidelift" } ], - "time": "2025-07-15T12:02:45+00:00" + "time": "2026-01-04T11:53:14+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.28.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -3280,12 +3300,9 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3319,7 +3336,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" }, "funding": [ { @@ -3330,41 +3347,42 @@ "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": "2023-01-26T09:26:14+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.28.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "875e90aeea2777b6f135677f618529449334a612" + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", - "reference": "875e90aeea2777b6f135677f618529449334a612", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3400,7 +3418,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" }, "funding": [ { @@ -3411,12 +3429,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": "2023-01-26T09:26:14+00:00" + "time": "2025-06-27T09:58:17+00:00" }, { "name": "symfony/polyfill-intl-idn", @@ -3757,16 +3779,16 @@ }, { "name": "symfony/routing", - "version": "v6.4.2", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "98eab13a07fddc85766f1756129c69f207ffbc21" + "reference": "0dc6253e864e71b486e8ba4970a56ab849106ebe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/98eab13a07fddc85766f1756129c69f207ffbc21", - "reference": "98eab13a07fddc85766f1756129c69f207ffbc21", + "url": "https://api.github.com/repos/symfony/routing/zipball/0dc6253e864e71b486e8ba4970a56ab849106ebe", + "reference": "0dc6253e864e71b486e8ba4970a56ab849106ebe", "shasum": "" }, "require": { @@ -3820,7 +3842,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.2" + "source": "https://github.com/symfony/routing/tree/v6.4.32" }, "funding": [ { @@ -3831,25 +3853,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": "2023-12-29T15:34:34+00:00" + "time": "2026-01-12T08:31:19+00:00" }, { "name": "symfony/runtime", - "version": "v6.4.24", + "version": "v6.4.30", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "c1cc6721646f546627236c57f835272806087337" + "reference": "fb3149ee85d3b639dd3e49ea9dda05656f0537e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/c1cc6721646f546627236c57f835272806087337", - "reference": "c1cc6721646f546627236c57f835272806087337", + "url": "https://api.github.com/repos/symfony/runtime/zipball/fb3149ee85d3b639dd3e49ea9dda05656f0537e3", + "reference": "fb3149ee85d3b639dd3e49ea9dda05656f0537e3", "shasum": "" }, "require": { @@ -3899,7 +3925,7 @@ "runtime" ], "support": { - "source": "https://github.com/symfony/runtime/tree/v6.4.24" + "source": "https://github.com/symfony/runtime/tree/v6.4.30" }, "funding": [ { @@ -3919,7 +3945,7 @@ "type": "tidelift" } ], - "time": "2025-07-10T08:14:14+00:00" + "time": "2025-12-05T10:55:13+00:00" }, { "name": "symfony/service-contracts", @@ -4010,16 +4036,16 @@ }, { "name": "symfony/string", - "version": "v6.4.2", + "version": "v6.4.30", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "7cb80bc10bfcdf6b5492741c0b9357dac66940bc" + "reference": "50590a057841fa6bf69d12eceffce3465b9e32cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/7cb80bc10bfcdf6b5492741c0b9357dac66940bc", - "reference": "7cb80bc10bfcdf6b5492741c0b9357dac66940bc", + "url": "https://api.github.com/repos/symfony/string/zipball/50590a057841fa6bf69d12eceffce3465b9e32cb", + "reference": "50590a057841fa6bf69d12eceffce3465b9e32cb", "shasum": "" }, "require": { @@ -4033,7 +4059,6 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", "symfony/http-client": "^5.4|^6.0|^7.0", "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", @@ -4076,7 +4101,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.2" + "source": "https://github.com/symfony/string/tree/v6.4.30" }, "funding": [ { @@ -4087,25 +4112,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": "2023-12-10T16:15:48+00:00" + "time": "2025-11-21T18:03:05+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.4.0", + "version": "v3.6.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" + "reference": "65a8bc82080447fae78373aa10f8d13b38338977" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977", + "reference": "65a8bc82080447fae78373aa10f8d13b38338977", "shasum": "" }, "require": { @@ -4113,12 +4142,12 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "autoload": { @@ -4154,7 +4183,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.6.1" }, "funding": [ { @@ -4165,25 +4194,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": "2023-07-25T15:08:44+00:00" + "time": "2025-07-15T13:41:35+00:00" }, { "name": "symfony/twig-bridge", - "version": "v6.4.0", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf" + "reference": "1dcf980dd4f79885b986befdeb1c1bc0d6aedfc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf", - "reference": "142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/1dcf980dd4f79885b986befdeb1c1bc0d6aedfc8", + "reference": "1dcf980dd4f79885b986befdeb1c1bc0d6aedfc8", "shasum": "" }, "require": { @@ -4196,7 +4229,7 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/console": "<5.4", - "symfony/form": "<6.3", + "symfony/form": "<6.4.32|>7,<7.3.10|>7.4,<7.4.4", "symfony/http-foundation": "<5.4", "symfony/http-kernel": "<6.4", "symfony/mime": "<6.2", @@ -4214,7 +4247,7 @@ "symfony/dependency-injection": "^5.4|^6.0|^7.0", "symfony/expression-language": "^5.4|^6.0|^7.0", "symfony/finder": "^5.4|^6.0|^7.0", - "symfony/form": "^6.4|^7.0", + "symfony/form": "^6.4.32|~7.3.10|^7.4.4", "symfony/html-sanitizer": "^6.1|^7.0", "symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/http-kernel": "^6.4|^7.0", @@ -4227,7 +4260,7 @@ "symfony/security-core": "^5.4|^6.0|^7.0", "symfony/security-csrf": "^5.4|^6.0|^7.0", "symfony/security-http": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3", "symfony/stopwatch": "^5.4|^6.0|^7.0", "symfony/translation": "^6.1|^7.0", "symfony/web-link": "^5.4|^6.0|^7.0", @@ -4263,7 +4296,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v6.4.0" + "source": "https://github.com/symfony/twig-bridge/tree/v6.4.32" }, "funding": [ { @@ -4274,25 +4307,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": "2023-11-25T08:25:13+00:00" + "time": "2026-01-03T23:03:08+00:00" }, { "name": "symfony/twig-bundle", - "version": "v6.4.0", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "35d84393e598dfb774e6a2bf49e5229a8a6dbe4c" + "reference": "a5c8dcc11a5bf9c96320da20070d2e158a4e0b30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/35d84393e598dfb774e6a2bf49e5229a8a6dbe4c", - "reference": "35d84393e598dfb774e6a2bf49e5229a8a6dbe4c", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/a5c8dcc11a5bf9c96320da20070d2e158a4e0b30", + "reference": "a5c8dcc11a5bf9c96320da20070d2e158a4e0b30", "shasum": "" }, "require": { @@ -4347,7 +4384,7 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v6.4.0" + "source": "https://github.com/symfony/twig-bundle/tree/v6.4.32" }, "funding": [ { @@ -4358,25 +4395,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": "2023-11-07T14:57:07+00:00" + "time": "2026-01-05T12:44:39+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.4.2", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "68d6573ec98715ddcae5a0a85bee3c1c27a4c33f" + "reference": "131fc9915e0343052af5ed5040401b481ca192aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/68d6573ec98715ddcae5a0a85bee3c1c27a4c33f", - "reference": "68d6573ec98715ddcae5a0a85bee3c1c27a4c33f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/131fc9915e0343052af5ed5040401b481ca192aa", + "reference": "131fc9915e0343052af5ed5040401b481ca192aa", "shasum": "" }, "require": { @@ -4388,7 +4429,6 @@ "symfony/console": "<5.4" }, "require-dev": { - "ext-iconv": "*", "symfony/console": "^5.4|^6.0|^7.0", "symfony/error-handler": "^6.3|^7.0", "symfony/http-kernel": "^5.4|^6.0|^7.0", @@ -4432,7 +4472,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.2" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.32" }, "funding": [ { @@ -4443,12 +4483,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": "2023-12-28T19:16:56+00:00" + "time": "2026-01-01T13:34:06+00:00" }, { "name": "symfony/var-exporter", @@ -4533,16 +4577,16 @@ }, { "name": "symfony/yaml", - "version": "v6.4.0", + "version": "v6.4.30", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587" + "reference": "8207ae83da19ee3748d6d4f567b4d9a7c656e331" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587", - "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587", + "url": "https://api.github.com/repos/symfony/yaml/zipball/8207ae83da19ee3748d6d4f567b4d9a7c656e331", + "reference": "8207ae83da19ee3748d6d4f567b4d9a7c656e331", "shasum": "" }, "require": { @@ -4585,7 +4629,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.0" + "source": "https://github.com/symfony/yaml/tree/v6.4.30" }, "funding": [ { @@ -4596,25 +4640,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": "2023-11-06T11:00:25+00:00" + "time": "2025-12-02T11:50:18+00:00" }, { "name": "tecnickcom/tcpdf", - "version": "6.10.0", + "version": "6.10.1", "source": { "type": "git", "url": "https://github.com/tecnickcom/TCPDF.git", - "reference": "ca5b6de294512145db96bcbc94e61696599c391d" + "reference": "7a2701251e5d52fc3d508fd71704683eb54f5939" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/ca5b6de294512145db96bcbc94e61696599c391d", - "reference": "ca5b6de294512145db96bcbc94e61696599c391d", + "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/7a2701251e5d52fc3d508fd71704683eb54f5939", + "reference": "7a2701251e5d52fc3d508fd71704683eb54f5939", "shasum": "" }, "require": { @@ -4664,7 +4712,7 @@ ], "support": { "issues": "https://github.com/tecnickcom/TCPDF/issues", - "source": "https://github.com/tecnickcom/TCPDF/tree/6.10.0" + "source": "https://github.com/tecnickcom/TCPDF/tree/6.10.1" }, "funding": [ { @@ -4672,26 +4720,26 @@ "type": "custom" } ], - "time": "2025-05-27T18:02:28+00:00" + "time": "2025-11-21T10:58:21+00:00" }, { "name": "thenetworg/oauth2-azure", - "version": "v2.2.2", + "version": "v2.2.4", "source": { "type": "git", "url": "https://github.com/TheNetworg/oauth2-azure.git", - "reference": "be204a5135f016470a9c33e82ab48785bbc11af2" + "reference": "a897d60b6b127daa2f27b1b4e62e7af40829d02f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TheNetworg/oauth2-azure/zipball/be204a5135f016470a9c33e82ab48785bbc11af2", - "reference": "be204a5135f016470a9c33e82ab48785bbc11af2", + "url": "https://api.github.com/repos/TheNetworg/oauth2-azure/zipball/a897d60b6b127daa2f27b1b4e62e7af40829d02f", + "reference": "a897d60b6b127daa2f27b1b4e62e7af40829d02f", "shasum": "" }, "require": { "ext-json": "*", "ext-openssl": "*", - "firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0", + "firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0||~7.0", "league/oauth2-client": "~2.0", "php": "^7.1|^8.0" }, @@ -4730,22 +4778,22 @@ ], "support": { "issues": "https://github.com/TheNetworg/oauth2-azure/issues", - "source": "https://github.com/TheNetworg/oauth2-azure/tree/v2.2.2" + "source": "https://github.com/TheNetworg/oauth2-azure/tree/v2.2.4" }, - "time": "2023-12-19T12:10:48+00:00" + "time": "2026-01-29T12:43:59+00:00" }, { "name": "twig/twig", - "version": "v3.21.1", + "version": "v3.23.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d" + "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/285123877d4dd97dd7c11842ac5fb7e86e60d81d", - "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", + "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", "shasum": "" }, "require": { @@ -4799,7 +4847,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.21.1" + "source": "https://github.com/twigphp/Twig/tree/v3.23.0" }, "funding": [ { @@ -4811,22 +4859,22 @@ "type": "tidelift" } ], - "time": "2025-05-03T07:21:55+00:00" + "time": "2026-01-23T21:00:41+00:00" } ], "packages-dev": [ { "name": "symfony/debug-bundle", - "version": "v6.4.0", + "version": "v6.4.27", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", - "reference": "1e07027423d1d37125b60a50997ada26a9d9d202" + "reference": "21a61c55192d558a6b81cdb12e8c010fc9474fe0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/1e07027423d1d37125b60a50997ada26a9d9d202", - "reference": "1e07027423d1d37125b60a50997ada26a9d9d202", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/21a61c55192d558a6b81cdb12e8c010fc9474fe0", + "reference": "21a61c55192d558a6b81cdb12e8c010fc9474fe0", "shasum": "" }, "require": { @@ -4871,7 +4919,7 @@ "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug-bundle/tree/v6.4.0" + "source": "https://github.com/symfony/debug-bundle/tree/v6.4.27" }, "funding": [ { @@ -4882,25 +4930,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": "2023-11-01T12:07:38+00:00" + "time": "2025-10-11T17:35:31+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.4.0", + "version": "v6.4.24", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" + "reference": "b67e94e06a05d9572c2fa354483b3e13e3cb1898" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b67e94e06a05d9572c2fa354483b3e13e3cb1898", + "reference": "b67e94e06a05d9572c2fa354483b3e13e3cb1898", "shasum": "" }, "require": { @@ -4933,7 +4985,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.4.0" + "source": "https://github.com/symfony/stopwatch/tree/v6.4.24" }, "funding": [ { @@ -4944,25 +4996,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": "2023-02-16T10:14:28+00:00" + "time": "2025-07-10T08:14:14+00:00" }, { "name": "symfony/web-profiler-bundle", - "version": "v6.4.2", + "version": "v6.4.32", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "38462d16856740ec0d1ba2cb902eebf09100dde2" + "reference": "011f59e3f3d20f60d11b4e78b8dc63504f56e145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/38462d16856740ec0d1ba2cb902eebf09100dde2", - "reference": "38462d16856740ec0d1ba2cb902eebf09100dde2", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/011f59e3f3d20f60d11b4e78b8dc63504f56e145", + "reference": "011f59e3f3d20f60d11b4e78b8dc63504f56e145", "shasum": "" }, "require": { @@ -5015,7 +5071,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.2" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.32" }, "funding": [ { @@ -5026,21 +5082,27 @@ "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": "2023-12-27T08:18:35+00:00" + "time": "2026-01-06T09:13:42+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": {}, + "stability-flags": { + "apereo/phpcas": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=8.1.0 <8.4.0", + "php": ">=8.1.0 <8.5.0", "ext-ctype": "*", "ext-dom": "*", "ext-gd": "*", diff --git a/lib/apereo/phpcas/README.md b/lib/apereo/phpcas/README.md index d48128912e..05f3c7d170 100644 --- a/lib/apereo/phpcas/README.md +++ b/lib/apereo/phpcas/README.md @@ -13,7 +13,7 @@ Api documentation can be found here: https://apereo.github.io/phpCAS/api/ -[![Test](https://github.com/apereo/phpCAS/actions/workflows/test.yml/badge.svg)](https://github.com/apereo/phpCAS/actions/workflows/test.yml) +[![Test](https://github.com/EsupPortail/phpCAS/actions/workflows/test.yml/badge.svg)](https://github.com/EsupPortail/phpCAS/actions/workflows/test.yml) LICENSE ------- diff --git a/lib/apereo/phpcas/source/CAS.php b/lib/apereo/phpcas/source/CAS.php index 71c04755a8..bf75c551ef 100644 --- a/lib/apereo/phpcas/source/CAS.php +++ b/lib/apereo/phpcas/source/CAS.php @@ -57,7 +57,7 @@ /** * phpCAS version. accessible for the user by phpCAS::getVersion(). */ -define('PHPCAS_VERSION', '1.6.1'); +define('PHPCAS_VERSION', '1.6.1+'); /** * @addtogroup public @@ -303,7 +303,7 @@ class phpCAS /** * This variable is used to enable verbose mode - * This pevents debug info to be show to the user. Since it's a security + * This prevents debug info to be show to the user. Since it's a security * feature the default is false * * @hideinitializer @@ -338,7 +338,7 @@ class phpCAS * @param bool $changeSessionID Allow phpCAS to change the session_id * (Single Sign Out/handleLogoutRequests * is based on that change) - * @param \SessionHandlerInterface $sessionHandler the session handler + * @param \SessionHandlerInterface|null $sessionHandler the session handler * * @return void a newly created CAS_Client object * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be @@ -347,7 +347,7 @@ class phpCAS */ public static function client($server_version, $server_hostname, $server_port, $server_uri, $service_base_url, - $changeSessionID = true, \SessionHandlerInterface $sessionHandler = null + $changeSessionID = true, ?\SessionHandlerInterface $sessionHandler = null ) { phpCAS :: traceBegin(); if (is_object(self::$_PHPCAS_CLIENT)) { @@ -393,7 +393,7 @@ public static function client($server_version, $server_hostname, * @param bool $changeSessionID Allow phpCAS to change the session_id * (Single Sign Out/handleLogoutRequests * is based on that change) - * @param \SessionHandlerInterface $sessionHandler the session handler + * @param \SessionHandlerInterface|null $sessionHandler the session handler * * @return void a newly created CAS_Client object * @note Only one of the phpCAS::client() and phpCAS::proxy functions should be @@ -402,14 +402,14 @@ public static function client($server_version, $server_hostname, */ public static function proxy($server_version, $server_hostname, $server_port, $server_uri, $service_base_url, - $changeSessionID = true, \SessionHandlerInterface $sessionHandler = null + $changeSessionID = true, ?\SessionHandlerInterface $sessionHandler = null ) { phpCAS :: traceBegin(); if (is_object(self::$_PHPCAS_CLIENT)) { phpCAS :: error(self::$_PHPCAS_INIT_CALL['method'] . '() has already been called (at ' . self::$_PHPCAS_INIT_CALL['file'] . ':' . self::$_PHPCAS_INIT_CALL['line'] . ')'); } - // store where the initialzer is called from + // store where the initializer is called from $dbg = debug_backtrace(); self::$_PHPCAS_INIT_CALL = array ( 'done' => true, @@ -560,7 +560,7 @@ public static function log($str) $indent_str .= '| '; } - // allow for multiline output with proper identing. Usefull for + // allow for multiline output with proper identing. Useful for // dumping cas answers etc. $str2 = str_replace("\n", "\n" . self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str, $str); $str3 = self::$_PHPCAS_DEBUG['unique_id'] . ' ' . $indent_str . $str2; @@ -568,7 +568,7 @@ public static function log($str) self::$_PHPCAS_DEBUG['logger']->info($str3); } if (!empty(self::$_PHPCAS_DEBUG['filename'])) { - // Check if file exists and modifiy file permissions to be only + // Check if file exists and modify file permissions to be only // readable by the webserver if (!file_exists(self::$_PHPCAS_DEBUG['filename'])) { touch(self::$_PHPCAS_DEBUG['filename']); @@ -1769,7 +1769,7 @@ public static function setSessionIdSalt($salt) { /** * If you want your service to be proxied you have to enable it (default - * disabled) and define an accepable list of proxies that are allowed to + * disabled) and define an acceptable list of proxies that are allowed to * proxy your service. * * Add each allowed proxy definition object. For the normal CAS_ProxyChain @@ -1790,7 +1790,7 @@ public static function setSessionIdSalt($salt) { * 'http://client.example.com/' * ))); * - * For quick testing or in certain production screnarios you might want to + * For quick testing or in certain production scenarios you might want to * allow allow any other valid service to proxy your service. To do so, add * the "Any" chain: * phpCAS::allowProxyChain(new CAS_ProxyChain_Any); @@ -1897,7 +1897,7 @@ private static function _validateClientExists() } /** - * Checks of a proxy client aready exists + * Checks of a proxy client already exists * * @throws CAS_OutOfSequenceBeforeProxyException * diff --git a/lib/apereo/phpcas/source/CAS/Client.php b/lib/apereo/phpcas/source/CAS/Client.php index 8ca9711f43..7f7c7d111e 100644 --- a/lib/apereo/phpcas/source/CAS/Client.php +++ b/lib/apereo/phpcas/source/CAS/Client.php @@ -788,7 +788,7 @@ public function markAuthenticationCall ($auth) 'file' => $dbg[1]['file'], 'line' => $dbg[1]['line'], 'method' => $dbg[1]['class'] . '::' . $dbg[1]['function'], - 'result' => (boolean)$auth + 'result' => (bool)$auth ); } private $_authentication_caller; @@ -926,7 +926,7 @@ public function getAuthenticationCallerMethod () * CAS_ServiceBaseUrl_Interface for custom * behavior. Added in 1.6.0. Similar to * serverName config in other CAS clients. - * @param \SessionHandlerInterface $sessionHandler the session handler + * @param \SessionHandlerInterface|null $sessionHandler the session handler * * @return self a newly created CAS_Client object */ @@ -938,7 +938,7 @@ public function __construct( $server_uri, $service_base_url, $changeSessionID = true, - \SessionHandlerInterface $sessionHandler = null + ?\SessionHandlerInterface $sessionHandler = null ) { // Argument validation if (gettype($server_version) != 'string') @@ -3166,7 +3166,7 @@ public function getProxiedService ($type) $proxiedService->setCasClient($this); } return $proxiedService; - case PHPCAS_PROXIED_SERVICE_IMAP; + case PHPCAS_PROXIED_SERVICE_IMAP: $proxiedService = new CAS_ProxiedService_Imap($this->_getUser()); if ($proxiedService instanceof CAS_ProxiedService_Testable) { $proxiedService->setCasClient($this); diff --git a/lib/apereo/phpcas/source/CAS/PGTStorage/Db.php b/lib/apereo/phpcas/source/CAS/PGTStorage/Db.php index 2efe5a3e85..9f8baf37f0 100644 --- a/lib/apereo/phpcas/source/CAS/PGTStorage/Db.php +++ b/lib/apereo/phpcas/source/CAS/PGTStorage/Db.php @@ -316,7 +316,7 @@ public function createTable() try { $pdo->beginTransaction(); - $query = $pdo->query($this->createTableSQL()); + $query = $pdo->query($this->createTableSql()); $query->closeCursor(); $pdo->commit(); diff --git a/lib/apereo/phpcas/source/CAS/PGTStorage/File.php b/lib/apereo/phpcas/source/CAS/PGTStorage/File.php index fbacd3b7d2..213ab40b7a 100644 --- a/lib/apereo/phpcas/source/CAS/PGTStorage/File.php +++ b/lib/apereo/phpcas/source/CAS/PGTStorage/File.php @@ -127,6 +127,12 @@ function __construct($cas_parent,$path) if (!preg_match('`^[a-zA-Z]:`', $path)) { phpCAS::error('an absolute path is needed for PGT storage to file'); } + + // ensure that the directory separator on Windows is '/' for consistency with the rest of the phpcas code + $path = str_replace(DIRECTORY_SEPARATOR , '/', $path); + + // store the path (with a trailing '/') + $path = preg_replace('|([^/])$|', '$1/', $path); } else { diff --git a/lib/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php b/lib/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php index 850f6f0e4a..18a810ef98 100644 --- a/lib/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php +++ b/lib/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php @@ -139,7 +139,12 @@ public function send () $buf = curl_multi_getcontent($handles[$i]); $request->_storeResponseBody($buf); curl_multi_remove_handle($multiHandle, $handles[$i]); - curl_close($handles[$i]); + if (PHP_VERSION_ID < 80000) { + curl_close($handles[$i]); + } else { + // unreference it => it will be closed + unset($handles[$i]); + } } curl_multi_close($multiHandle); diff --git a/lib/apereo/phpcas/source/CAS/Request/CurlRequest.php b/lib/apereo/phpcas/source/CAS/Request/CurlRequest.php index e30dd0d193..ac7f0ec95e 100644 --- a/lib/apereo/phpcas/source/CAS/Request/CurlRequest.php +++ b/lib/apereo/phpcas/source/CAS/Request/CurlRequest.php @@ -86,7 +86,9 @@ protected function sendRequest () } // close the CURL session - curl_close($ch); + if (PHP_VERSION_ID < 80000) { + curl_close($ch); + } phpCAS::traceEnd($res); return $res; diff --git a/lib/bin/patch-type-declarations b/lib/bin/patch-type-declarations old mode 100644 new mode 100755 diff --git a/lib/bin/patch-type-declarations.bat b/lib/bin/patch-type-declarations.bat deleted file mode 100644 index 2b0707968a..0000000000 --- a/lib/bin/patch-type-declarations.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/patch-type-declarations -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/bin/php-parse b/lib/bin/php-parse old mode 100644 new mode 100755 diff --git a/lib/bin/php-parse.bat b/lib/bin/php-parse.bat deleted file mode 100644 index 2c5096dc39..0000000000 --- a/lib/bin/php-parse.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/php-parse -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/bin/pscss b/lib/bin/pscss old mode 100644 new mode 100755 diff --git a/lib/bin/pscss.bat b/lib/bin/pscss.bat deleted file mode 100644 index 6b83bf27c9..0000000000 --- a/lib/bin/pscss.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/pscss -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/bin/var-dump-server b/lib/bin/var-dump-server old mode 100644 new mode 100755 diff --git a/lib/bin/var-dump-server.bat b/lib/bin/var-dump-server.bat deleted file mode 100644 index 94333da54c..0000000000 --- a/lib/bin/var-dump-server.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/var-dump-server -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/bin/yaml-lint b/lib/bin/yaml-lint old mode 100644 new mode 100755 diff --git a/lib/bin/yaml-lint.bat b/lib/bin/yaml-lint.bat deleted file mode 100644 index fa76637484..0000000000 --- a/lib/bin/yaml-lint.bat +++ /dev/null @@ -1,5 +0,0 @@ -@ECHO OFF -setlocal DISABLEDELAYEDEXPANSION -SET BIN_TARGET=%~dp0/yaml-lint -SET COMPOSER_RUNTIME_BIN_DIR=%~dp0 -php "%BIN_TARGET%" %* diff --git a/lib/composer/autoload_classmap.php b/lib/composer/autoload_classmap.php index 87e682e8fe..f33a4ce8f2 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -958,6 +958,7 @@ 'PDF417' => $vendorDir . '/tecnickcom/tcpdf/include/barcodes/pdf417.php', 'PDFBulkExport' => $baseDir . '/core/pdfbulkexport.class.inc.php', 'PEAR' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php', + 'PEAR_Error' => $vendorDir . '/pear/pear-core-minimal/src/PEAR.php', 'PEAR_ErrorStack' => $vendorDir . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', 'PEAR_Exception' => $vendorDir . '/pear/pear_exception/PEAR/Exception.php', 'Pelago\\Emogrifier\\Caching\\SimpleStringCache' => $vendorDir . '/pelago/emogrifier/src/Caching/SimpleStringCache.php', @@ -1645,22 +1646,43 @@ 'Symfony\\Component\\Cache\\Psr16Cache' => $vendorDir . '/symfony/cache/Psr16Cache.php', 'Symfony\\Component\\Cache\\ResettableInterface' => $vendorDir . '/symfony/cache/ResettableInterface.php', 'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => $vendorDir . '/symfony/cache/Traits/AbstractAdapterTrait.php', + 'Symfony\\Component\\Cache\\Traits\\CachedValueInterface' => $vendorDir . '/symfony/cache/Traits/CachedValueInterface.php', 'Symfony\\Component\\Cache\\Traits\\ContractsTrait' => $vendorDir . '/symfony/cache/Traits/ContractsTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemCommonTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => $vendorDir . '/symfony/cache/Traits/FilesystemTrait.php', 'Symfony\\Component\\Cache\\Traits\\ProxyTrait' => $vendorDir . '/symfony/cache/Traits/ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\Redis5Proxy' => $vendorDir . '/symfony/cache/Traits/Redis5Proxy.php', + 'Symfony\\Component\\Cache\\Traits\\Redis61ProxyTrait' => $vendorDir . '/symfony/cache/Traits/Redis61ProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Redis62ProxyTrait' => $vendorDir . '/symfony/cache/Traits/Redis62ProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Redis63ProxyTrait' => $vendorDir . '/symfony/cache/Traits/Redis63ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\Redis6Proxy' => $vendorDir . '/symfony/cache/Traits/Redis6Proxy.php', - 'Symfony\\Component\\Cache\\Traits\\Redis6ProxyTrait' => $vendorDir . '/symfony/cache/Traits/Redis6ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\RedisCluster5Proxy' => $vendorDir . '/symfony/cache/Traits/RedisCluster5Proxy.php', + 'Symfony\\Component\\Cache\\Traits\\RedisCluster61ProxyTrait' => $vendorDir . '/symfony/cache/Traits/RedisCluster61ProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\RedisCluster62ProxyTrait' => $vendorDir . '/symfony/cache/Traits/RedisCluster62ProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\RedisCluster63ProxyTrait' => $vendorDir . '/symfony/cache/Traits/RedisCluster63ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\RedisCluster6Proxy' => $vendorDir . '/symfony/cache/Traits/RedisCluster6Proxy.php', - 'Symfony\\Component\\Cache\\Traits\\RedisCluster6ProxyTrait' => $vendorDir . '/symfony/cache/Traits/RedisCluster6ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\RedisClusterNodeProxy' => $vendorDir . '/symfony/cache/Traits/RedisClusterNodeProxy.php', 'Symfony\\Component\\Cache\\Traits\\RedisClusterProxy' => $vendorDir . '/symfony/cache/Traits/RedisClusterProxy.php', 'Symfony\\Component\\Cache\\Traits\\RedisProxy' => $vendorDir . '/symfony/cache/Traits/RedisProxy.php', 'Symfony\\Component\\Cache\\Traits\\RedisTrait' => $vendorDir . '/symfony/cache/Traits/RedisTrait.php', 'Symfony\\Component\\Cache\\Traits\\RelayProxy' => $vendorDir . '/symfony/cache/Traits/RelayProxy.php', 'Symfony\\Component\\Cache\\Traits\\RelayProxyTrait' => $vendorDir . '/symfony/cache/Traits/RelayProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\BgsaveTrait' => $vendorDir . '/symfony/cache/Traits/Relay/BgsaveTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\CopyTrait' => $vendorDir . '/symfony/cache/Traits/Relay/CopyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\FtTrait' => $vendorDir . '/symfony/cache/Traits/Relay/FtTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\GeosearchTrait' => $vendorDir . '/symfony/cache/Traits/Relay/GeosearchTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\GetWithMetaTrait' => $vendorDir . '/symfony/cache/Traits/Relay/GetWithMetaTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\GetrangeTrait' => $vendorDir . '/symfony/cache/Traits/Relay/GetrangeTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\HsetTrait' => $vendorDir . '/symfony/cache/Traits/Relay/HsetTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\IsTrackedTrait' => $vendorDir . '/symfony/cache/Traits/Relay/IsTrackedTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\MoveTrait' => $vendorDir . '/symfony/cache/Traits/Relay/MoveTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\NullableReturnTrait' => $vendorDir . '/symfony/cache/Traits/Relay/NullableReturnTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\PfcountTrait' => $vendorDir . '/symfony/cache/Traits/Relay/PfcountTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\Relay11Trait' => $vendorDir . '/symfony/cache/Traits/Relay/Relay11Trait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\Relay121Trait' => $vendorDir . '/symfony/cache/Traits/Relay/Relay121Trait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\Relay12Trait' => $vendorDir . '/symfony/cache/Traits/Relay/Relay12Trait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\Relay20Trait' => $vendorDir . '/symfony/cache/Traits/Relay/Relay20Trait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\SwapdbTrait' => $vendorDir . '/symfony/cache/Traits/Relay/SwapdbTrait.php', 'Symfony\\Component\\Config\\Builder\\ClassBuilder' => $vendorDir . '/symfony/config/Builder/ClassBuilder.php', 'Symfony\\Component\\Config\\Builder\\ConfigBuilderGenerator' => $vendorDir . '/symfony/config/Builder/ConfigBuilderGenerator.php', 'Symfony\\Component\\Config\\Builder\\ConfigBuilderGeneratorInterface' => $vendorDir . '/symfony/config/Builder/ConfigBuilderGeneratorInterface.php', @@ -1825,6 +1847,7 @@ 'Symfony\\Component\\Console\\Helper\\TableRows' => $vendorDir . '/symfony/console/Helper/TableRows.php', 'Symfony\\Component\\Console\\Helper\\TableSeparator' => $vendorDir . '/symfony/console/Helper/TableSeparator.php', 'Symfony\\Component\\Console\\Helper\\TableStyle' => $vendorDir . '/symfony/console/Helper/TableStyle.php', + 'Symfony\\Component\\Console\\Helper\\TerminalInputHelper' => $vendorDir . '/symfony/console/Helper/TerminalInputHelper.php', 'Symfony\\Component\\Console\\Input\\ArgvInput' => $vendorDir . '/symfony/console/Input/ArgvInput.php', 'Symfony\\Component\\Console\\Input\\ArrayInput' => $vendorDir . '/symfony/console/Input/ArrayInput.php', 'Symfony\\Component\\Console\\Input\\Input' => $vendorDir . '/symfony/console/Input/Input.php', @@ -2699,7 +2722,6 @@ 'Symfony\\Component\\VarDumper\\Cloner\\Cursor' => $vendorDir . '/symfony/var-dumper/Cloner/Cursor.php', 'Symfony\\Component\\VarDumper\\Cloner\\Data' => $vendorDir . '/symfony/var-dumper/Cloner/Data.php', 'Symfony\\Component\\VarDumper\\Cloner\\DumperInterface' => $vendorDir . '/symfony/var-dumper/Cloner/DumperInterface.php', - 'Symfony\\Component\\VarDumper\\Cloner\\Internal\\NoDefault' => $vendorDir . '/symfony/var-dumper/Cloner/Internal/NoDefault.php', 'Symfony\\Component\\VarDumper\\Cloner\\Stub' => $vendorDir . '/symfony/var-dumper/Cloner/Stub.php', 'Symfony\\Component\\VarDumper\\Cloner\\VarCloner' => $vendorDir . '/symfony/var-dumper/Cloner/VarCloner.php', 'Symfony\\Component\\VarDumper\\Command\\Descriptor\\CliDescriptor' => $vendorDir . '/symfony/var-dumper/Command/Descriptor/CliDescriptor.php', @@ -2854,6 +2876,7 @@ 'Twig\\ExpressionParser\\InfixExpressionParserInterface' => $vendorDir . '/twig/twig/src/ExpressionParser/InfixExpressionParserInterface.php', 'Twig\\ExpressionParser\\Infix\\ArgumentsTrait' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/ArgumentsTrait.php', 'Twig\\ExpressionParser\\Infix\\ArrowExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/ArrowExpressionParser.php', + 'Twig\\ExpressionParser\\Infix\\AssignmentExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/AssignmentExpressionParser.php', 'Twig\\ExpressionParser\\Infix\\BinaryOperatorExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/BinaryOperatorExpressionParser.php', 'Twig\\ExpressionParser\\Infix\\ConditionalTernaryExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/ConditionalTernaryExpressionParser.php', 'Twig\\ExpressionParser\\Infix\\DotExpressionParser' => $vendorDir . '/twig/twig/src/ExpressionParser/Infix/DotExpressionParser.php', @@ -2939,10 +2962,15 @@ 'Twig\\Node\\Expression\\Binary\\MulBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/MulBinary.php', 'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php', 'Twig\\Node\\Expression\\Binary\\NotInBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php', + 'Twig\\Node\\Expression\\Binary\\NotSameAsBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NotSameAsBinary.php', 'Twig\\Node\\Expression\\Binary\\NullCoalesceBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/NullCoalesceBinary.php', + 'Twig\\Node\\Expression\\Binary\\ObjectDestructuringSetBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/ObjectDestructuringSetBinary.php', 'Twig\\Node\\Expression\\Binary\\OrBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/OrBinary.php', 'Twig\\Node\\Expression\\Binary\\PowerBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php', 'Twig\\Node\\Expression\\Binary\\RangeBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php', + 'Twig\\Node\\Expression\\Binary\\SameAsBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SameAsBinary.php', + 'Twig\\Node\\Expression\\Binary\\SequenceDestructuringSetBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SequenceDestructuringSetBinary.php', + 'Twig\\Node\\Expression\\Binary\\SetBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SetBinary.php', 'Twig\\Node\\Expression\\Binary\\SpaceshipBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php', 'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php', 'Twig\\Node\\Expression\\Binary\\SubBinary' => $vendorDir . '/twig/twig/src/Node/Expression/Binary/SubBinary.php', @@ -2951,6 +2979,7 @@ 'Twig\\Node\\Expression\\CallExpression' => $vendorDir . '/twig/twig/src/Node/Expression/CallExpression.php', 'Twig\\Node\\Expression\\ConditionalExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConditionalExpression.php', 'Twig\\Node\\Expression\\ConstantExpression' => $vendorDir . '/twig/twig/src/Node/Expression/ConstantExpression.php', + 'Twig\\Node\\Expression\\EmptyExpression' => $vendorDir . '/twig/twig/src/Node/Expression/EmptyExpression.php', 'Twig\\Node\\Expression\\FilterExpression' => $vendorDir . '/twig/twig/src/Node/Expression/FilterExpression.php', 'Twig\\Node\\Expression\\Filter\\DefaultFilter' => $vendorDir . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php', 'Twig\\Node\\Expression\\Filter\\RawFilter' => $vendorDir . '/twig/twig/src/Node/Expression/Filter/RawFilter.php', diff --git a/lib/composer/autoload_namespaces.php b/lib/composer/autoload_namespaces.php index 6629b7e09b..b29b4a97fe 100644 --- a/lib/composer/autoload_namespaces.php +++ b/lib/composer/autoload_namespaces.php @@ -8,5 +8,4 @@ return array( 'Console' => array($vendorDir . '/pear/console_getopt'), 'Archive_Tar' => array($vendorDir . '/pear/archive_tar'), - '' => array($vendorDir . '/pear/pear-core-minimal/src'), ); diff --git a/lib/composer/autoload_static.php b/lib/composer/autoload_static.php index c157af7451..6e18001be5 100644 --- a/lib/composer/autoload_static.php +++ b/lib/composer/autoload_static.php @@ -360,10 +360,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f ), ); - public static $fallbackDirsPsr0 = array ( - 0 => __DIR__ . '/..' . '/pear/pear-core-minimal/src', - ); - public static $classMap = array ( 'AbstractApplicationObjectExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php', 'AbstractApplicationUIExtension' => __DIR__ . '/../..' . '/application/applicationextension.inc.php', @@ -1317,6 +1313,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'PDF417' => __DIR__ . '/..' . '/tecnickcom/tcpdf/include/barcodes/pdf417.php', 'PDFBulkExport' => __DIR__ . '/../..' . '/core/pdfbulkexport.class.inc.php', 'PEAR' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php', + 'PEAR_Error' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR.php', 'PEAR_ErrorStack' => __DIR__ . '/..' . '/pear/pear-core-minimal/src/PEAR/ErrorStack.php', 'PEAR_Exception' => __DIR__ . '/..' . '/pear/pear_exception/PEAR/Exception.php', 'Pelago\\Emogrifier\\Caching\\SimpleStringCache' => __DIR__ . '/..' . '/pelago/emogrifier/src/Caching/SimpleStringCache.php', @@ -2004,22 +2001,43 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Component\\Cache\\Psr16Cache' => __DIR__ . '/..' . '/symfony/cache/Psr16Cache.php', 'Symfony\\Component\\Cache\\ResettableInterface' => __DIR__ . '/..' . '/symfony/cache/ResettableInterface.php', 'Symfony\\Component\\Cache\\Traits\\AbstractAdapterTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/AbstractAdapterTrait.php', + 'Symfony\\Component\\Cache\\Traits\\CachedValueInterface' => __DIR__ . '/..' . '/symfony/cache/Traits/CachedValueInterface.php', 'Symfony\\Component\\Cache\\Traits\\ContractsTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ContractsTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemCommonTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemCommonTrait.php', 'Symfony\\Component\\Cache\\Traits\\FilesystemTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/FilesystemTrait.php', 'Symfony\\Component\\Cache\\Traits\\ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\Redis5Proxy' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis5Proxy.php', + 'Symfony\\Component\\Cache\\Traits\\Redis61ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis61ProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Redis62ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis62ProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Redis63ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis63ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\Redis6Proxy' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis6Proxy.php', - 'Symfony\\Component\\Cache\\Traits\\Redis6ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Redis6ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\RedisCluster5Proxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster5Proxy.php', + 'Symfony\\Component\\Cache\\Traits\\RedisCluster61ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster61ProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\RedisCluster62ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster62ProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\RedisCluster63ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster63ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\RedisCluster6Proxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster6Proxy.php', - 'Symfony\\Component\\Cache\\Traits\\RedisCluster6ProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisCluster6ProxyTrait.php', 'Symfony\\Component\\Cache\\Traits\\RedisClusterNodeProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisClusterNodeProxy.php', 'Symfony\\Component\\Cache\\Traits\\RedisClusterProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisClusterProxy.php', 'Symfony\\Component\\Cache\\Traits\\RedisProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisProxy.php', 'Symfony\\Component\\Cache\\Traits\\RedisTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RedisTrait.php', 'Symfony\\Component\\Cache\\Traits\\RelayProxy' => __DIR__ . '/..' . '/symfony/cache/Traits/RelayProxy.php', 'Symfony\\Component\\Cache\\Traits\\RelayProxyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/RelayProxyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\BgsaveTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/BgsaveTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\CopyTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/CopyTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\FtTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/FtTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\GeosearchTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/GeosearchTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\GetWithMetaTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/GetWithMetaTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\GetrangeTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/GetrangeTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\HsetTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/HsetTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\IsTrackedTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/IsTrackedTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\MoveTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/MoveTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\NullableReturnTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/NullableReturnTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\PfcountTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/PfcountTrait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\Relay11Trait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/Relay11Trait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\Relay121Trait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/Relay121Trait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\Relay12Trait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/Relay12Trait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\Relay20Trait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/Relay20Trait.php', + 'Symfony\\Component\\Cache\\Traits\\Relay\\SwapdbTrait' => __DIR__ . '/..' . '/symfony/cache/Traits/Relay/SwapdbTrait.php', 'Symfony\\Component\\Config\\Builder\\ClassBuilder' => __DIR__ . '/..' . '/symfony/config/Builder/ClassBuilder.php', 'Symfony\\Component\\Config\\Builder\\ConfigBuilderGenerator' => __DIR__ . '/..' . '/symfony/config/Builder/ConfigBuilderGenerator.php', 'Symfony\\Component\\Config\\Builder\\ConfigBuilderGeneratorInterface' => __DIR__ . '/..' . '/symfony/config/Builder/ConfigBuilderGeneratorInterface.php', @@ -2184,6 +2202,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Component\\Console\\Helper\\TableRows' => __DIR__ . '/..' . '/symfony/console/Helper/TableRows.php', 'Symfony\\Component\\Console\\Helper\\TableSeparator' => __DIR__ . '/..' . '/symfony/console/Helper/TableSeparator.php', 'Symfony\\Component\\Console\\Helper\\TableStyle' => __DIR__ . '/..' . '/symfony/console/Helper/TableStyle.php', + 'Symfony\\Component\\Console\\Helper\\TerminalInputHelper' => __DIR__ . '/..' . '/symfony/console/Helper/TerminalInputHelper.php', 'Symfony\\Component\\Console\\Input\\ArgvInput' => __DIR__ . '/..' . '/symfony/console/Input/ArgvInput.php', 'Symfony\\Component\\Console\\Input\\ArrayInput' => __DIR__ . '/..' . '/symfony/console/Input/ArrayInput.php', 'Symfony\\Component\\Console\\Input\\Input' => __DIR__ . '/..' . '/symfony/console/Input/Input.php', @@ -3058,7 +3077,6 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Symfony\\Component\\VarDumper\\Cloner\\Cursor' => __DIR__ . '/..' . '/symfony/var-dumper/Cloner/Cursor.php', 'Symfony\\Component\\VarDumper\\Cloner\\Data' => __DIR__ . '/..' . '/symfony/var-dumper/Cloner/Data.php', 'Symfony\\Component\\VarDumper\\Cloner\\DumperInterface' => __DIR__ . '/..' . '/symfony/var-dumper/Cloner/DumperInterface.php', - 'Symfony\\Component\\VarDumper\\Cloner\\Internal\\NoDefault' => __DIR__ . '/..' . '/symfony/var-dumper/Cloner/Internal/NoDefault.php', 'Symfony\\Component\\VarDumper\\Cloner\\Stub' => __DIR__ . '/..' . '/symfony/var-dumper/Cloner/Stub.php', 'Symfony\\Component\\VarDumper\\Cloner\\VarCloner' => __DIR__ . '/..' . '/symfony/var-dumper/Cloner/VarCloner.php', 'Symfony\\Component\\VarDumper\\Command\\Descriptor\\CliDescriptor' => __DIR__ . '/..' . '/symfony/var-dumper/Command/Descriptor/CliDescriptor.php', @@ -3213,6 +3231,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Twig\\ExpressionParser\\InfixExpressionParserInterface' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/InfixExpressionParserInterface.php', 'Twig\\ExpressionParser\\Infix\\ArgumentsTrait' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/ArgumentsTrait.php', 'Twig\\ExpressionParser\\Infix\\ArrowExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/ArrowExpressionParser.php', + 'Twig\\ExpressionParser\\Infix\\AssignmentExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/AssignmentExpressionParser.php', 'Twig\\ExpressionParser\\Infix\\BinaryOperatorExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/BinaryOperatorExpressionParser.php', 'Twig\\ExpressionParser\\Infix\\ConditionalTernaryExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/ConditionalTernaryExpressionParser.php', 'Twig\\ExpressionParser\\Infix\\DotExpressionParser' => __DIR__ . '/..' . '/twig/twig/src/ExpressionParser/Infix/DotExpressionParser.php', @@ -3298,10 +3317,15 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Twig\\Node\\Expression\\Binary\\MulBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/MulBinary.php', 'Twig\\Node\\Expression\\Binary\\NotEqualBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotEqualBinary.php', 'Twig\\Node\\Expression\\Binary\\NotInBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotInBinary.php', + 'Twig\\Node\\Expression\\Binary\\NotSameAsBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NotSameAsBinary.php', 'Twig\\Node\\Expression\\Binary\\NullCoalesceBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/NullCoalesceBinary.php', + 'Twig\\Node\\Expression\\Binary\\ObjectDestructuringSetBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/ObjectDestructuringSetBinary.php', 'Twig\\Node\\Expression\\Binary\\OrBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/OrBinary.php', 'Twig\\Node\\Expression\\Binary\\PowerBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/PowerBinary.php', 'Twig\\Node\\Expression\\Binary\\RangeBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/RangeBinary.php', + 'Twig\\Node\\Expression\\Binary\\SameAsBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SameAsBinary.php', + 'Twig\\Node\\Expression\\Binary\\SequenceDestructuringSetBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SequenceDestructuringSetBinary.php', + 'Twig\\Node\\Expression\\Binary\\SetBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SetBinary.php', 'Twig\\Node\\Expression\\Binary\\SpaceshipBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SpaceshipBinary.php', 'Twig\\Node\\Expression\\Binary\\StartsWithBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/StartsWithBinary.php', 'Twig\\Node\\Expression\\Binary\\SubBinary' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Binary/SubBinary.php', @@ -3310,6 +3334,7 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f 'Twig\\Node\\Expression\\CallExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/CallExpression.php', 'Twig\\Node\\Expression\\ConditionalExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConditionalExpression.php', 'Twig\\Node\\Expression\\ConstantExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/ConstantExpression.php', + 'Twig\\Node\\Expression\\EmptyExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/EmptyExpression.php', 'Twig\\Node\\Expression\\FilterExpression' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/FilterExpression.php', 'Twig\\Node\\Expression\\Filter\\DefaultFilter' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Filter/DefaultFilter.php', 'Twig\\Node\\Expression\\Filter\\RawFilter' => __DIR__ . '/..' . '/twig/twig/src/Node/Expression/Filter/RawFilter.php', @@ -3542,7 +3567,6 @@ public static function getInitializer(ClassLoader $loader) $loader->prefixLengthsPsr4 = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$prefixLengthsPsr4; $loader->prefixDirsPsr4 = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$prefixDirsPsr4; $loader->prefixesPsr0 = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$prefixesPsr0; - $loader->fallbackDirsPsr0 = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$fallbackDirsPsr0; $loader->classMap = ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f::$classMap; }, null, ClassLoader::class); diff --git a/lib/composer/installed.json b/lib/composer/installed.json index c59aaf0106..2bacb38f99 100644 --- a/lib/composer/installed.json +++ b/lib/composer/installed.json @@ -2,17 +2,17 @@ "packages": [ { "name": "apereo/phpcas", - "version": "1.6.1", - "version_normalized": "1.6.1.0", + "version": "dev-master", + "version_normalized": "dev-master", "source": { "type": "git", - "url": "https://github.com/apereo/phpCAS.git", - "reference": "c129708154852656aabb13d8606cd5b12dbbabac" + "url": "https://github.com/EsupPortail/phpCAS.git", + "reference": "57a7744146a963d8fa80192e0ab351051b711ff6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/apereo/phpCAS/zipball/c129708154852656aabb13d8606cd5b12dbbabac", - "reference": "c129708154852656aabb13d8606cd5b12dbbabac", + "url": "https://api.github.com/repos/EsupPortail/phpCAS/zipball/57a7744146a963d8fa80192e0ab351051b711ff6", + "reference": "57a7744146a963d8fa80192e0ab351051b711ff6", "shasum": "" }, "require": { @@ -26,7 +26,8 @@ "phpstan/phpstan": "^1.5", "phpunit/phpunit": ">=7.5" }, - "time": "2023-02-19T19:52:35+00:00", + "time": "2025-12-02T11:38:23+00:00", + "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -42,15 +43,27 @@ "source/" ] }, - "notification-url": "https://packagist.org/downloads/", + "autoload-dev": { + "psr-4": { + "PhpCas\\": "test/CAS/" + } + }, + "scripts": { + "test": [ + "phpunit" + ], + "phpstan": [ + "phpstan" + ] + }, "license": [ "Apache-2.0" ], "authors": [ { "name": "Joachim Fritschi", - "email": "jfritschi@freenet.de", - "homepage": "https://github.com/jfritschi" + "homepage": "https://github.com/jfritschi", + "email": "jfritschi@freenet.de" }, { "name": "Adam Franco", @@ -69,8 +82,8 @@ "jasig" ], "support": { - "issues": "https://github.com/apereo/phpCAS/issues", - "source": "https://github.com/apereo/phpCAS/tree/1.6.1" + "source": "https://github.com/EsupPortail/phpCAS/tree/master", + "issues": "https://github.com/EsupPortail/phpCAS/issues" }, "install-path": "../apereo/phpcas" }, @@ -226,27 +239,27 @@ }, { "name": "firebase/php-jwt", - "version": "v6.10.0", - "version_normalized": "6.10.0.0", + "version": "v7.0.2", + "version_normalized": "7.0.2.0", "source": { "type": "git", "url": "https://github.com/firebase/php-jwt.git", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff" + "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/firebase/php-jwt/zipball/a49db6f0a5033aef5143295342f1c95521b075ff", - "reference": "a49db6f0a5033aef5143295342f1c95521b075ff", + "url": "https://api.github.com/repos/firebase/php-jwt/zipball/5645b43af647b6947daac1d0f659dd1fbe8d3b65", + "reference": "5645b43af647b6947daac1d0f659dd1fbe8d3b65", "shasum": "" }, "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", + "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "psr/cache": "^1.0||^2.0", + "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" }, @@ -254,7 +267,7 @@ "ext-sodium": "Support EdDSA (Ed25519) signatures", "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present" }, - "time": "2023-12-01T16:26:39+00:00", + "time": "2025-12-16T22:17:28+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -286,29 +299,29 @@ ], "support": { "issues": "https://github.com/firebase/php-jwt/issues", - "source": "https://github.com/firebase/php-jwt/tree/v6.10.0" + "source": "https://github.com/firebase/php-jwt/tree/v7.0.2" }, "install-path": "../firebase/php-jwt" }, { "name": "guzzlehttp/guzzle", - "version": "7.8.1", - "version_normalized": "7.8.1.0", + "version": "7.10.0", + "version_normalized": "7.10.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104" + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/41042bc7ab002487b876a0683fc8dce04ddce104", - "reference": "41042bc7ab002487b876a0683fc8dce04ddce104", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", + "reference": "b51ac707cfa420b7bfd4e4d5e510ba8008e822b4", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.1", - "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" @@ -319,9 +332,9 @@ "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -329,7 +342,7 @@ "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, - "time": "2023-12-03T20:35:24+00:00", + "time": "2025-08-23T22:36:01+00:00", "type": "library", "extra": { "bamarni-bin": { @@ -401,7 +414,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.8.1" + "source": "https://github.com/guzzle/guzzle/tree/7.10.0" }, "funding": [ { @@ -421,17 +434,17 @@ }, { "name": "guzzlehttp/promises", - "version": "2.0.2", - "version_normalized": "2.0.2.0", + "version": "2.3.0", + "version_normalized": "2.3.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223" + "reference": "481557b130ef3790cf82b713667b43030dc9c957" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/bbff78d96034045e58e13dedd6ad91b5d1253223", - "reference": "bbff78d96034045e58e13dedd6ad91b5d1253223", + "url": "https://api.github.com/repos/guzzle/promises/zipball/481557b130ef3790cf82b713667b43030dc9c957", + "reference": "481557b130ef3790cf82b713667b43030dc9c957", "shasum": "" }, "require": { @@ -439,9 +452,9 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, - "time": "2023-12-03T20:19:20+00:00", + "time": "2025-08-22T14:34:08+00:00", "type": "library", "extra": { "bamarni-bin": { @@ -487,7 +500,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/2.0.2" + "source": "https://github.com/guzzle/promises/tree/2.3.0" }, "funding": [ { @@ -507,17 +520,17 @@ }, { "name": "guzzlehttp/psr7", - "version": "2.6.2", - "version_normalized": "2.6.2.0", + "version": "2.8.0", + "version_normalized": "2.8.0.0", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221" + "reference": "21dc724a0583619cd1652f673303492272778051" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/45b30f99ac27b5ca93cb4831afe16285f57b8221", - "reference": "45b30f99ac27b5ca93cb4831afe16285f57b8221", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/21dc724a0583619cd1652f673303492272778051", + "reference": "21dc724a0583619cd1652f673303492272778051", "shasum": "" }, "require": { @@ -532,13 +545,13 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, - "time": "2023-12-03T20:05:35+00:00", + "time": "2025-08-23T21:21:41+00:00", "type": "library", "extra": { "bamarni-bin": { @@ -606,7 +619,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.6.2" + "source": "https://github.com/guzzle/psr7/tree/2.8.0" }, "funding": [ { @@ -626,37 +639,32 @@ }, { "name": "league/oauth2-client", - "version": "2.7.0", - "version_normalized": "2.7.0.0", + "version": "2.9.0", + "version_normalized": "2.9.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-client.git", - "reference": "160d6274b03562ebeb55ed18399281d8118b76c8" + "reference": "26e8c5da4f3d78cede7021e09b1330a0fc093d5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/160d6274b03562ebeb55ed18399281d8118b76c8", - "reference": "160d6274b03562ebeb55ed18399281d8118b76c8", + "url": "https://api.github.com/repos/thephpleague/oauth2-client/zipball/26e8c5da4f3d78cede7021e09b1330a0fc093d5e", + "reference": "26e8c5da4f3d78cede7021e09b1330a0fc093d5e", "shasum": "" }, "require": { - "guzzlehttp/guzzle": "^6.0 || ^7.0", - "paragonie/random_compat": "^1 || ^2 || ^9.99", - "php": "^5.6 || ^7.0 || ^8.0" + "ext-json": "*", + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5", + "php": "^7.1 || >=8.0.0 <8.6.0" }, "require-dev": { "mockery/mockery": "^1.3.5", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpunit/phpunit": "^5.7 || ^6.0 || ^9.5", - "squizlabs/php_codesniffer": "^2.3 || ^3.0" + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "^3.11" }, - "time": "2023-04-16T18:19:15+00:00", + "time": "2025-11-25T22:17:17+00:00", "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.0.x-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -693,23 +701,23 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-client/issues", - "source": "https://github.com/thephpleague/oauth2-client/tree/2.7.0" + "source": "https://github.com/thephpleague/oauth2-client/tree/2.9.0" }, "install-path": "../league/oauth2-client" }, { "name": "league/oauth2-google", - "version": "4.0.1", - "version_normalized": "4.0.1.0", + "version": "4.1.0", + "version_normalized": "4.1.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/oauth2-google.git", - "reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76" + "reference": "8b9bb43740ac6d994aca881a35f7bacbe98c0ffb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/1b01ba18ba31b29e88771e3e0979e5c91d4afe76", - "reference": "1b01ba18ba31b29e88771e3e0979e5c91d4afe76", + "url": "https://api.github.com/repos/thephpleague/oauth2-google/zipball/8b9bb43740ac6d994aca881a35f7bacbe98c0ffb", + "reference": "8b9bb43740ac6d994aca881a35f7bacbe98c0ffb", "shasum": "" }, "require": { @@ -721,7 +729,7 @@ "phpunit/phpunit": "^8.0 || ^9.0", "squizlabs/php_codesniffer": "^3.0" }, - "time": "2023-03-17T15:20:52+00:00", + "time": "2025-12-15T12:24:14+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -751,43 +759,38 @@ ], "support": { "issues": "https://github.com/thephpleague/oauth2-google/issues", - "source": "https://github.com/thephpleague/oauth2-google/tree/4.0.1" + "source": "https://github.com/thephpleague/oauth2-google/tree/4.1.0" }, "install-path": "../league/oauth2-google" }, { "name": "nikic/php-parser", - "version": "v4.18.0", - "version_normalized": "4.18.0.0", + "version": "v4.19.5", + "version_normalized": "4.19.5.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999" + "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/1bcbb2179f97633e98bbbc87044ee2611c7d7999", - "reference": "1bcbb2179f97633e98bbbc87044ee2611c7d7999", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", + "reference": "51bd93cc741b7fc3d63d20b6bdcd99fdaa359837", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.1" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, - "time": "2023-12-10T21:03:43+00:00", + "time": "2025-12-06T11:45:25+00:00", "bin": [ "bin/php-parse" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -810,63 +813,10 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.18.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.5" }, "install-path": "../nikic/php-parser" }, - { - "name": "paragonie/random_compat", - "version": "v9.99.100", - "version_normalized": "9.99.100.0", - "source": { - "type": "git", - "url": "https://github.com/paragonie/random_compat.git", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/paragonie/random_compat/zipball/996434e5492cb4c3edcb9168db6fbb1359ef965a", - "reference": "996434e5492cb4c3edcb9168db6fbb1359ef965a", - "shasum": "" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "phpunit/phpunit": "4.*|5.*", - "vimeo/psalm": "^1" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - }, - "time": "2020-10-15T08:29:30+00:00", - "type": "library", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "polyfill", - "pseudorandom", - "random" - ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, - "install-path": "../paragonie/random_compat" - }, { "name": "pear/archive_tar", "version": "1.4.14", @@ -1006,33 +956,34 @@ }, { "name": "pear/pear-core-minimal", - "version": "v1.10.11", - "version_normalized": "1.10.11.0", + "version": "v1.10.18", + "version_normalized": "1.10.18.0", "source": { "type": "git", "url": "https://github.com/pear/pear-core-minimal.git", - "reference": "68d0d32ada737153b7e93b8d3c710ebe70ac867d" + "reference": "c7b55789d01de0ce090d289b73f1bbd6a2f113b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/68d0d32ada737153b7e93b8d3c710ebe70ac867d", - "reference": "68d0d32ada737153b7e93b8d3c710ebe70ac867d", + "url": "https://api.github.com/repos/pear/pear-core-minimal/zipball/c7b55789d01de0ce090d289b73f1bbd6a2f113b1", + "reference": "c7b55789d01de0ce090d289b73f1bbd6a2f113b1", "shasum": "" }, "require": { "pear/console_getopt": "~1.4", - "pear/pear_exception": "~1.0" + "pear/pear_exception": "~1.0", + "php": ">=5.4" }, "replace": { "rsky/pear-core-min": "self.version" }, - "time": "2021-08-10T22:31:03+00:00", + "time": "2025-12-14T20:37:07+00:00", "type": "library", "installation-source": "dist", "autoload": { - "psr-0": { - "": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "include-path": [ @@ -1119,32 +1070,36 @@ }, { "name": "pelago/emogrifier", - "version": "v7.2.0", - "version_normalized": "7.2.0.0", + "version": "v7.3.0", + "version_normalized": "7.3.0.0", "source": { "type": "git", "url": "https://github.com/MyIntervals/emogrifier.git", - "reference": "727bdf7255b51798307f17dec52ff8a91f1c7de3" + "reference": "6e00d9d8235e8cc8eec857e8dcd6cfeefdfd0cd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/727bdf7255b51798307f17dec52ff8a91f1c7de3", - "reference": "727bdf7255b51798307f17dec52ff8a91f1c7de3", + "url": "https://api.github.com/repos/MyIntervals/emogrifier/zipball/6e00d9d8235e8cc8eec857e8dcd6cfeefdfd0cd6", + "reference": "6e00d9d8235e8cc8eec857e8dcd6cfeefdfd0cd6", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", - "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0", - "sabberworm/php-css-parser": "^8.4.0", + "php": "~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0", + "sabberworm/php-css-parser": "^8.7.0", "symfony/css-selector": "^4.4.23 || ^5.4.0 || ^6.0.0 || ^7.0.0" }, "require-dev": { - "php-parallel-lint/php-parallel-lint": "1.3.2", - "phpunit/phpunit": "9.6.11", + "php-parallel-lint/php-parallel-lint": "1.4.0", + "phpstan/extension-installer": "1.4.3", + "phpstan/phpstan": "1.12.7", + "phpstan/phpstan-phpunit": "1.4.0", + "phpstan/phpstan-strict-rules": "1.6.1", + "phpunit/phpunit": "9.6.21", "rawr/cross-data-providers": "2.4.0" }, - "time": "2023-12-06T02:00:20+00:00", + "time": "2024-10-28T16:12:26+00:00", "type": "library", "extra": { "branch-alias": { @@ -1176,7 +1131,7 @@ }, { "name": "Jake Hotson", - "email": "jake@qzdesign.co.uk" + "email": "jake.github@qzdesign.co.uk" }, { "name": "Cameron Brooks" @@ -1416,24 +1371,24 @@ }, { "name": "psr/http-factory", - "version": "1.0.2", - "version_normalized": "1.0.2.0", + "version": "1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-factory.git", - "reference": "e616d01114759c4c489f93b099585439f795fe35" + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/e616d01114759c4c489f93b099585439f795fe35", - "reference": "e616d01114759c4c489f93b099585439f795fe35", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", "shasum": "" }, "require": { - "php": ">=7.0.0", + "php": ">=7.1", "psr/http-message": "^1.0 || ^2.0" }, - "time": "2023-04-10T20:10:41+00:00", + "time": "2024-04-15T12:06:14+00:00", "type": "library", "extra": { "branch-alias": { @@ -1456,7 +1411,7 @@ "homepage": "https://www.php-fig.org/" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", "keywords": [ "factory", "http", @@ -1468,7 +1423,7 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-factory/tree/1.0.2" + "source": "https://github.com/php-fig/http-factory" }, "install-path": "../psr/http-factory" }, @@ -1630,32 +1585,37 @@ }, { "name": "sabberworm/php-css-parser", - "version": "8.4.0", - "version_normalized": "8.4.0.0", + "version": "v8.9.0", + "version_normalized": "8.9.0.0", "source": { "type": "git", - "url": "https://github.com/sabberworm/PHP-CSS-Parser.git", - "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30" + "url": "https://github.com/MyIntervals/PHP-CSS-Parser.git", + "reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sabberworm/PHP-CSS-Parser/zipball/e41d2140031d533348b2192a83f02d8dd8a71d30", - "reference": "e41d2140031d533348b2192a83f02d8dd8a71d30", + "url": "https://api.github.com/repos/MyIntervals/PHP-CSS-Parser/zipball/d8e916507b88e389e26d4ab03c904a082aa66bb9", + "reference": "d8e916507b88e389e26d4ab03c904a082aa66bb9", "shasum": "" }, "require": { "ext-iconv": "*", - "php": ">=5.6.20" + "php": "^5.6.20 || ^7.0.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0" }, "require-dev": { - "codacy/coverage": "^1.4", - "phpunit/phpunit": "^4.8.36" + "phpunit/phpunit": "5.7.27 || 6.5.14 || 7.5.20 || 8.5.41", + "rawr/cross-data-providers": "^2.0.0" }, "suggest": { "ext-mbstring": "for parsing UTF-8 CSS" }, - "time": "2021-12-11T13:40:54+00:00", + "time": "2025-07-11T13:20:48+00:00", "type": "library", + "extra": { + "branch-alias": { + "dev-main": "9.0.x-dev" + } + }, "installation-source": "dist", "autoload": { "psr-4": { @@ -1669,6 +1629,14 @@ "authors": [ { "name": "Raphael Schweikert" + }, + { + "name": "Oliver Klee", + "email": "github@oliverklee.de" + }, + { + "name": "Jake Hotson", + "email": "jake.github@qzdesign.co.uk" } ], "description": "Parser for CSS Files written in PHP", @@ -1679,24 +1647,24 @@ "stylesheet" ], "support": { - "issues": "https://github.com/sabberworm/PHP-CSS-Parser/issues", - "source": "https://github.com/sabberworm/PHP-CSS-Parser/tree/8.4.0" + "issues": "https://github.com/MyIntervals/PHP-CSS-Parser/issues", + "source": "https://github.com/MyIntervals/PHP-CSS-Parser/tree/v8.9.0" }, "install-path": "../sabberworm/php-css-parser" }, { "name": "scssphp/scssphp", - "version": "v1.12.1", - "version_normalized": "1.12.1.0", + "version": "v1.13.0", + "version_normalized": "1.13.0.0", "source": { "type": "git", "url": "https://github.com/scssphp/scssphp.git", - "reference": "394ed1e960138710a60d035c1a85d43d0bf0faeb" + "reference": "63d1157457e5554edf00b0c1fabab4c1511d2520" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scssphp/scssphp/zipball/394ed1e960138710a60d035c1a85d43d0bf0faeb", - "reference": "394ed1e960138710a60d035c1a85d43d0bf0faeb", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/63d1157457e5554edf00b0c1fabab4c1511d2520", + "reference": "63d1157457e5554edf00b0c1fabab4c1511d2520", "shasum": "" }, "require": { @@ -1719,15 +1687,15 @@ "ext-iconv": "Can be used as fallback when ext-mbstring is not available", "ext-mbstring": "For best performance, mbstring should be installed as it is faster than ext-iconv" }, - "time": "2024-01-13T12:36:40+00:00", + "time": "2024-08-17T21:02:11+00:00", "bin": [ "bin/pscss" ], "type": "library", "extra": { "bamarni-bin": { - "forward-command": false, - "bin-links": false + "bin-links": false, + "forward-command": false } }, "installation-source": "dist", @@ -1763,7 +1731,7 @@ ], "support": { "issues": "https://github.com/scssphp/scssphp/issues", - "source": "https://github.com/scssphp/scssphp/tree/v1.12.1" + "source": "https://github.com/scssphp/scssphp/tree/v1.13.0" }, "install-path": "../scssphp/scssphp" }, @@ -1827,17 +1795,17 @@ }, { "name": "symfony/cache", - "version": "v6.4.12", - "version_normalized": "6.4.12.0", + "version": "v6.4.33", + "version_normalized": "6.4.33.0", "source": { "type": "git", "url": "https://github.com/symfony/cache.git", - "reference": "a463451b7f6ac4a47b98dbfc78ec2d3560c759d8" + "reference": "5b088fa41eb9568748dc255c45e4054c387ba73b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/a463451b7f6ac4a47b98dbfc78ec2d3560c759d8", - "reference": "a463451b7f6ac4a47b98dbfc78ec2d3560c759d8", + "url": "https://api.github.com/repos/symfony/cache/zipball/5b088fa41eb9568748dc255c45e4054c387ba73b", + "reference": "5b088fa41eb9568748dc255c45e4054c387ba73b", "shasum": "" }, "require": { @@ -1871,7 +1839,7 @@ "symfony/messenger": "^5.4|^6.0|^7.0", "symfony/var-dumper": "^5.4|^6.0|^7.0" }, - "time": "2024-09-16T16:01:33+00:00", + "time": "2026-01-27T15:05:20+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -1906,7 +1874,7 @@ "psr6" ], "support": { - "source": "https://github.com/symfony/cache/tree/v6.4.12" + "source": "https://github.com/symfony/cache/tree/v6.4.33" }, "funding": [ { @@ -1917,6 +1885,10 @@ "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" @@ -2005,17 +1977,17 @@ }, { "name": "symfony/config", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "5d33e0fb707d603330e0edfd4691803a1253572e" + "reference": "d445badf0ad2c2a492e38c0378c39997a56ef97b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/5d33e0fb707d603330e0edfd4691803a1253572e", - "reference": "5d33e0fb707d603330e0edfd4691803a1253572e", + "url": "https://api.github.com/repos/symfony/config/zipball/d445badf0ad2c2a492e38c0378c39997a56ef97b", + "reference": "d445badf0ad2c2a492e38c0378c39997a56ef97b", "shasum": "" }, "require": { @@ -2035,7 +2007,7 @@ "symfony/service-contracts": "^2.5|^3", "symfony/yaml": "^5.4|^6.0|^7.0" }, - "time": "2023-11-09T08:28:32+00:00", + "time": "2026-01-13T08:40:30+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2063,7 +2035,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/config/tree/v6.4.0" + "source": "https://github.com/symfony/config/tree/v6.4.32" }, "funding": [ { @@ -2074,6 +2046,10 @@ "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" @@ -2083,17 +2059,17 @@ }, { "name": "symfony/console", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625" + "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0254811a143e6bc6c8deea08b589a7e68a37f625", - "reference": "0254811a143e6bc6c8deea08b589a7e68a37f625", + "url": "https://api.github.com/repos/symfony/console/zipball/0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", + "reference": "0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3", "shasum": "" }, "require": { @@ -2126,7 +2102,7 @@ "symfony/stopwatch": "^5.4|^6.0|^7.0", "symfony/var-dumper": "^5.4|^6.0|^7.0" }, - "time": "2023-12-10T16:15:48+00:00", + "time": "2026-01-13T08:45:59+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2160,7 +2136,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.4.2" + "source": "https://github.com/symfony/console/tree/v6.4.32" }, "funding": [ { @@ -2171,6 +2147,10 @@ "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" @@ -2180,23 +2160,23 @@ }, { "name": "symfony/css-selector", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.24", + "version_normalized": "6.4.24.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4" + "reference": "9b784413143701aa3c94ac1869a159a9e53e8761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/d036c6c0d0b09e24a14a35f8292146a658f986e4", - "reference": "d036c6c0d0b09e24a14a35f8292146a658f986e4", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/9b784413143701aa3c94ac1869a159a9e53e8761", + "reference": "9b784413143701aa3c94ac1869a159a9e53e8761", "shasum": "" }, "require": { "php": ">=8.1" }, - "time": "2023-10-31T08:40:20+00:00", + "time": "2025-07-10T08:14:14+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2228,7 +2208,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.4.0" + "source": "https://github.com/symfony/css-selector/tree/v6.4.24" }, "funding": [ { @@ -2239,6 +2219,10 @@ "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" @@ -2248,17 +2232,17 @@ }, { "name": "symfony/debug-bundle", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.27", + "version_normalized": "6.4.27.0", "source": { "type": "git", "url": "https://github.com/symfony/debug-bundle.git", - "reference": "1e07027423d1d37125b60a50997ada26a9d9d202" + "reference": "21a61c55192d558a6b81cdb12e8c010fc9474fe0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/1e07027423d1d37125b60a50997ada26a9d9d202", - "reference": "1e07027423d1d37125b60a50997ada26a9d9d202", + "url": "https://api.github.com/repos/symfony/debug-bundle/zipball/21a61c55192d558a6b81cdb12e8c010fc9474fe0", + "reference": "21a61c55192d558a6b81cdb12e8c010fc9474fe0", "shasum": "" }, "require": { @@ -2277,7 +2261,7 @@ "symfony/config": "^5.4|^6.0|^7.0", "symfony/web-profiler-bundle": "^5.4|^6.0|^7.0" }, - "time": "2023-11-01T12:07:38+00:00", + "time": "2025-10-11T17:35:31+00:00", "type": "symfony-bundle", "installation-source": "dist", "autoload": { @@ -2305,7 +2289,7 @@ "description": "Provides a tight integration of the Symfony VarDumper component and the ServerLogCommand from MonologBridge into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/debug-bundle/tree/v6.4.0" + "source": "https://github.com/symfony/debug-bundle/tree/v6.4.27" }, "funding": [ { @@ -2316,6 +2300,10 @@ "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" @@ -2325,17 +2313,17 @@ }, { "name": "symfony/dependency-injection", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "226ea431b1eda6f0d9f5a4b278757171960bb195" + "reference": "b17882e933c4c606620247b6708ab53aa3b88753" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/226ea431b1eda6f0d9f5a4b278757171960bb195", - "reference": "226ea431b1eda6f0d9f5a4b278757171960bb195", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/b17882e933c4c606620247b6708ab53aa3b88753", + "reference": "b17882e933c4c606620247b6708ab53aa3b88753", "shasum": "" }, "require": { @@ -2343,7 +2331,7 @@ "psr/container": "^1.1|^2.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/service-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^6.2.10|^7.0" + "symfony/var-exporter": "^6.4.20|^7.2.5" }, "conflict": { "ext-psr": "<1.1|>=2", @@ -2361,7 +2349,7 @@ "symfony/expression-language": "^5.4|^6.0|^7.0", "symfony/yaml": "^5.4|^6.0|^7.0" }, - "time": "2023-12-28T19:16:56+00:00", + "time": "2026-01-23T10:54:33+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2389,7 +2377,7 @@ "description": "Allows you to standardize and centralize the way objects are constructed in your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dependency-injection/tree/v6.4.2" + "source": "https://github.com/symfony/dependency-injection/tree/v6.4.32" }, "funding": [ { @@ -2400,6 +2388,10 @@ "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" @@ -2479,17 +2471,17 @@ }, { "name": "symfony/dotenv", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.30", + "version_normalized": "6.4.30.0", "source": { "type": "git", "url": "https://github.com/symfony/dotenv.git", - "reference": "835f8d2d1022934ac038519de40b88158798c96f" + "reference": "924edbc9631b75302def0258ed1697948b17baf6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dotenv/zipball/835f8d2d1022934ac038519de40b88158798c96f", - "reference": "835f8d2d1022934ac038519de40b88158798c96f", + "url": "https://api.github.com/repos/symfony/dotenv/zipball/924edbc9631b75302def0258ed1697948b17baf6", + "reference": "924edbc9631b75302def0258ed1697948b17baf6", "shasum": "" }, "require": { @@ -2503,7 +2495,7 @@ "symfony/console": "^5.4|^6.0|^7.0", "symfony/process": "^5.4|^6.0|^7.0" }, - "time": "2023-12-28T19:16:56+00:00", + "time": "2025-11-14T17:33:48+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2536,7 +2528,7 @@ "environment" ], "support": { - "source": "https://github.com/symfony/dotenv/tree/v6.4.2" + "source": "https://github.com/symfony/dotenv/tree/v6.4.30" }, "funding": [ { @@ -2547,6 +2539,10 @@ "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" @@ -2556,17 +2552,17 @@ }, { "name": "symfony/error-handler", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "c873490a1c97b3a0a4838afc36ff36c112d02788" + "reference": "8c18400784fcb014dc73c8d5601a9576af7f8ad4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/c873490a1c97b3a0a4838afc36ff36c112d02788", - "reference": "c873490a1c97b3a0a4838afc36ff36c112d02788", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/8c18400784fcb014dc73c8d5601a9576af7f8ad4", + "reference": "8c18400784fcb014dc73c8d5601a9576af7f8ad4", "shasum": "" }, "require": { @@ -2583,7 +2579,7 @@ "symfony/http-kernel": "^6.4|^7.0", "symfony/serializer": "^5.4|^6.0|^7.0" }, - "time": "2023-10-18T09:43:34+00:00", + "time": "2026-01-19T19:28:19+00:00", "bin": [ "Resources/bin/patch-type-declarations" ], @@ -2614,7 +2610,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.4.0" + "source": "https://github.com/symfony/error-handler/tree/v6.4.32" }, "funding": [ { @@ -2625,6 +2621,10 @@ "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" @@ -2634,17 +2634,17 @@ }, { "name": "symfony/event-dispatcher", - "version": "v6.4.25", - "version_normalized": "6.4.25.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "b0cf3162020603587363f0551cd3be43958611ff" + "reference": "99d7e101826e6610606b9433248f80c1997cd20b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/b0cf3162020603587363f0551cd3be43958611ff", - "reference": "b0cf3162020603587363f0551cd3be43958611ff", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/99d7e101826e6610606b9433248f80c1997cd20b", + "reference": "99d7e101826e6610606b9433248f80c1997cd20b", "shasum": "" }, "require": { @@ -2669,7 +2669,7 @@ "symfony/service-contracts": "^2.5|^3", "symfony/stopwatch": "^5.4|^6.0|^7.0" }, - "time": "2025-08-13T09:41:44+00:00", + "time": "2026-01-05T11:13:48+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2697,7 +2697,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/v6.4.25" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.4.32" }, "funding": [ { @@ -2800,17 +2800,17 @@ }, { "name": "symfony/filesystem", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.30", + "version_normalized": "6.4.30.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59" + "reference": "441c6b69f7222aadae7cbf5df588496d5ee37789" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/952a8cb588c3bc6ce76f6023000fb932f16a6e59", - "reference": "952a8cb588c3bc6ce76f6023000fb932f16a6e59", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/441c6b69f7222aadae7cbf5df588496d5ee37789", + "reference": "441c6b69f7222aadae7cbf5df588496d5ee37789", "shasum": "" }, "require": { @@ -2818,7 +2818,10 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, - "time": "2023-07-26T17:27:13+00:00", + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, + "time": "2025-11-26T14:43:45+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2846,7 +2849,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.4.0" + "source": "https://github.com/symfony/filesystem/tree/v6.4.30" }, "funding": [ { @@ -2857,6 +2860,10 @@ "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" @@ -2866,17 +2873,17 @@ }, { "name": "symfony/finder", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.33", + "version_normalized": "6.4.33.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce" + "reference": "24965ca011dac87431729640feef8bcf7b5523e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/11d736e97f116ac375a81f96e662911a34cd50ce", - "reference": "11d736e97f116ac375a81f96e662911a34cd50ce", + "url": "https://api.github.com/repos/symfony/finder/zipball/24965ca011dac87431729640feef8bcf7b5523e0", + "reference": "24965ca011dac87431729640feef8bcf7b5523e0", "shasum": "" }, "require": { @@ -2885,7 +2892,7 @@ "require-dev": { "symfony/filesystem": "^6.0|^7.0" }, - "time": "2023-10-31T17:30:12+00:00", + "time": "2026-01-26T13:03:48+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -2913,7 +2920,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v6.4.0" + "source": "https://github.com/symfony/finder/tree/v6.4.33" }, "funding": [ { @@ -2924,6 +2931,10 @@ "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" @@ -2933,17 +2944,17 @@ }, { "name": "symfony/framework-bundle", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.33", + "version_normalized": "6.4.33.0", "source": { "type": "git", "url": "https://github.com/symfony/framework-bundle.git", - "reference": "c26a221e0462027d1f9d4a802ed63f8ab07a43d0" + "reference": "9ef2d0b63b9e855ba351e770a603d89699115801" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/c26a221e0462027d1f9d4a802ed63f8ab07a43d0", - "reference": "c26a221e0462027d1f9d4a802ed63f8ab07a43d0", + "url": "https://api.github.com/repos/symfony/framework-bundle/zipball/9ef2d0b63b9e855ba351e770a603d89699115801", + "reference": "9ef2d0b63b9e855ba351e770a603d89699115801", "shasum": "" }, "require": { @@ -2952,7 +2963,7 @@ "php": ">=8.1", "symfony/cache": "^5.4|^6.0|^7.0", "symfony/config": "^6.1|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4.12|^7.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.1|^7.0", "symfony/event-dispatcher": "^5.4|^6.0|^7.0", @@ -2982,7 +2993,8 @@ "symfony/mime": "<6.4", "symfony/property-access": "<5.4", "symfony/property-info": "<5.4", - "symfony/scheduler": "<6.4", + "symfony/runtime": "<5.4.45|>=6.0,<6.4.13|>=7.0,<7.1.6", + "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4", "symfony/security-core": "<5.4", "symfony/security-csrf": "<5.4", "symfony/serializer": "<6.4", @@ -3021,7 +3033,7 @@ "symfony/process": "^5.4|^6.0|^7.0", "symfony/property-info": "^5.4|^6.0|^7.0", "symfony/rate-limiter": "^5.4|^6.0|^7.0", - "symfony/scheduler": "^6.4|^7.0", + "symfony/scheduler": "^6.4.4|^7.0.4", "symfony/security-bundle": "^5.4|^6.0|^7.0", "symfony/semaphore": "^5.4|^6.0|^7.0", "symfony/serializer": "^6.4|^7.0", @@ -3034,9 +3046,9 @@ "symfony/web-link": "^5.4|^6.0|^7.0", "symfony/workflow": "^6.4|^7.0", "symfony/yaml": "^5.4|^6.0|^7.0", - "twig/twig": "^2.10|^3.0" + "twig/twig": "^2.10|^3.0.4" }, - "time": "2023-12-29T15:34:34+00:00", + "time": "2026-01-26T14:46:41+00:00", "type": "symfony-bundle", "installation-source": "dist", "autoload": { @@ -3064,7 +3076,7 @@ "description": "Provides a tight integration between Symfony components and the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/framework-bundle/tree/v6.4.2" + "source": "https://github.com/symfony/framework-bundle/tree/v6.4.33" }, "funding": [ { @@ -3075,6 +3087,10 @@ "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" @@ -3084,17 +3100,17 @@ }, { "name": "symfony/http-foundation", - "version": "v6.4.29", - "version_normalized": "6.4.29.0", + "version": "v6.4.33", + "version_normalized": "6.4.33.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "b03d11e015552a315714c127d8d1e0f9e970ec88" + "reference": "f1a490cc9d595ba7ebe684220e625d1e472ad278" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/b03d11e015552a315714c127d8d1e0f9e970ec88", - "reference": "b03d11e015552a315714c127d8d1e0f9e970ec88", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f1a490cc9d595ba7ebe684220e625d1e472ad278", + "reference": "f1a490cc9d595ba7ebe684220e625d1e472ad278", "shasum": "" }, "require": { @@ -3116,7 +3132,7 @@ "symfony/mime": "^5.4|^6.0|^7.0", "symfony/rate-limiter": "^5.4|^6.0|^7.0" }, - "time": "2025-11-08T16:40:12+00:00", + "time": "2026-01-27T15:04:55+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -3144,7 +3160,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.4.29" + "source": "https://github.com/symfony/http-foundation/tree/v6.4.33" }, "funding": [ { @@ -3168,17 +3184,17 @@ }, { "name": "symfony/http-kernel", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.33", + "version_normalized": "6.4.33.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "13e8387320b5942d0dc408440c888e2d526efef4" + "reference": "73fa5c999d7f741ca544a97d3c791cc97890ae4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/13e8387320b5942d0dc408440c888e2d526efef4", - "reference": "13e8387320b5942d0dc408440c888e2d526efef4", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/73fa5c999d7f741ca544a97d3c791cc97890ae4d", + "reference": "73fa5c999d7f741ca544a97d3c791cc97890ae4d", "shasum": "" }, "require": { @@ -3227,16 +3243,17 @@ "symfony/process": "^5.4|^6.0|^7.0", "symfony/property-access": "^5.4.5|^6.0.5|^7.0", "symfony/routing": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.3|^7.0", + "symfony/serializer": "^6.4.4|^7.0.4", "symfony/stopwatch": "^5.4|^6.0|^7.0", "symfony/translation": "^5.4|^6.0|^7.0", "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^5.4|^6.0|^7.0", "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^5.4|^6.4|^7.0", "symfony/var-exporter": "^6.2|^7.0", "twig/twig": "^2.13|^3.0.4" }, - "time": "2023-12-30T15:31:44+00:00", + "time": "2026-01-28T10:02:13+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -3264,7 +3281,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.4.2" + "source": "https://github.com/symfony/http-kernel/tree/v6.4.33" }, "funding": [ { @@ -3275,6 +3292,10 @@ "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" @@ -3284,17 +3305,17 @@ }, { "name": "symfony/mailer", - "version": "v6.4.25", - "version_normalized": "6.4.25.0", + "version": "v6.4.31", + "version_normalized": "6.4.31.0", "source": { "type": "git", "url": "https://github.com/symfony/mailer.git", - "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2" + "reference": "8835f93333474780fda1b987cae37e33c3e026ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mailer/zipball/628b43b45a3e6b15c8a633fb22df547ed9b492a2", - "reference": "628b43b45a3e6b15c8a633fb22df547ed9b492a2", + "url": "https://api.github.com/repos/symfony/mailer/zipball/8835f93333474780fda1b987cae37e33c3e026ca", + "reference": "8835f93333474780fda1b987cae37e33c3e026ca", "shasum": "" }, "require": { @@ -3319,7 +3340,7 @@ "symfony/messenger": "^6.2|^7.0", "symfony/twig-bridge": "^6.2|^7.0" }, - "time": "2025-08-13T09:41:44+00:00", + "time": "2025-12-12T07:33:25+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -3347,7 +3368,7 @@ "description": "Helps sending emails", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/mailer/tree/v6.4.25" + "source": "https://github.com/symfony/mailer/tree/v6.4.31" }, "funding": [ { @@ -3371,17 +3392,17 @@ }, { "name": "symfony/mime", - "version": "v6.4.24", - "version_normalized": "6.4.24.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7" + "reference": "7409686879ca36c09fc970a5fa8ff6e93504dba4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/664d5e844a2de5e11c8255d0aef6bc15a9660ac7", - "reference": "664d5e844a2de5e11c8255d0aef6bc15a9660ac7", + "url": "https://api.github.com/repos/symfony/mime/zipball/7409686879ca36c09fc970a5fa8ff6e93504dba4", + "reference": "7409686879ca36c09fc970a5fa8ff6e93504dba4", "shasum": "" }, "require": { @@ -3407,7 +3428,7 @@ "symfony/property-info": "^5.4|^6.0|^7.0", "symfony/serializer": "^6.4.3|^7.0.3" }, - "time": "2025-07-15T12:02:45+00:00", + "time": "2026-01-04T11:53:14+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -3439,7 +3460,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v6.4.24" + "source": "https://github.com/symfony/mime/tree/v6.4.32" }, "funding": [ { @@ -3463,21 +3484,21 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -3485,15 +3506,12 @@ "suggest": { "ext-ctype": "For best performance" }, - "time": "2023-01-26T09:26:14+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -3528,7 +3546,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" }, "funding": [ { @@ -3539,6 +3557,10 @@ "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" @@ -3548,34 +3570,31 @@ }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.28.0", - "version_normalized": "1.28.0.0", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "875e90aeea2777b6f135677f618529449334a612" + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", - "reference": "875e90aeea2777b6f135677f618529449334a612", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/380872130d3a5dd3ace2f4010d95125fde5d5c70", + "reference": "380872130d3a5dd3ace2f4010d95125fde5d5c70", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" }, - "time": "2023-01-26T09:26:14+00:00", + "time": "2025-06-27T09:58:17+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -3612,7 +3631,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.33.0" }, "funding": [ { @@ -3623,6 +3642,10 @@ "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" @@ -3981,17 +4004,17 @@ }, { "name": "symfony/routing", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "98eab13a07fddc85766f1756129c69f207ffbc21" + "reference": "0dc6253e864e71b486e8ba4970a56ab849106ebe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/98eab13a07fddc85766f1756129c69f207ffbc21", - "reference": "98eab13a07fddc85766f1756129c69f207ffbc21", + "url": "https://api.github.com/repos/symfony/routing/zipball/0dc6253e864e71b486e8ba4970a56ab849106ebe", + "reference": "0dc6253e864e71b486e8ba4970a56ab849106ebe", "shasum": "" }, "require": { @@ -4013,7 +4036,7 @@ "symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/yaml": "^5.4|^6.0|^7.0" }, - "time": "2023-12-29T15:34:34+00:00", + "time": "2026-01-12T08:31:19+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4047,7 +4070,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v6.4.2" + "source": "https://github.com/symfony/routing/tree/v6.4.32" }, "funding": [ { @@ -4058,6 +4081,10 @@ "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" @@ -4067,17 +4094,17 @@ }, { "name": "symfony/runtime", - "version": "v6.4.24", - "version_normalized": "6.4.24.0", + "version": "v6.4.30", + "version_normalized": "6.4.30.0", "source": { "type": "git", "url": "https://github.com/symfony/runtime.git", - "reference": "c1cc6721646f546627236c57f835272806087337" + "reference": "fb3149ee85d3b639dd3e49ea9dda05656f0537e3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/runtime/zipball/c1cc6721646f546627236c57f835272806087337", - "reference": "c1cc6721646f546627236c57f835272806087337", + "url": "https://api.github.com/repos/symfony/runtime/zipball/fb3149ee85d3b639dd3e49ea9dda05656f0537e3", + "reference": "fb3149ee85d3b639dd3e49ea9dda05656f0537e3", "shasum": "" }, "require": { @@ -4094,7 +4121,7 @@ "symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/http-kernel": "^5.4|^6.0|^7.0" }, - "time": "2025-07-10T08:14:14+00:00", + "time": "2025-12-05T10:55:13+00:00", "type": "composer-plugin", "extra": { "class": "Symfony\\Component\\Runtime\\Internal\\ComposerPlugin" @@ -4129,7 +4156,7 @@ "runtime" ], "support": { - "source": "https://github.com/symfony/runtime/tree/v6.4.24" + "source": "https://github.com/symfony/runtime/tree/v6.4.30" }, "funding": [ { @@ -4243,24 +4270,24 @@ }, { "name": "symfony/stopwatch", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.24", + "version_normalized": "6.4.24.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" + "reference": "b67e94e06a05d9572c2fa354483b3e13e3cb1898" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b67e94e06a05d9572c2fa354483b3e13e3cb1898", + "reference": "b67e94e06a05d9572c2fa354483b3e13e3cb1898", "shasum": "" }, "require": { "php": ">=8.1", "symfony/service-contracts": "^2.5|^3" }, - "time": "2023-02-16T10:14:28+00:00", + "time": "2025-07-10T08:14:14+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4288,7 +4315,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.4.0" + "source": "https://github.com/symfony/stopwatch/tree/v6.4.24" }, "funding": [ { @@ -4299,6 +4326,10 @@ "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" @@ -4308,17 +4339,17 @@ }, { "name": "symfony/string", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.30", + "version_normalized": "6.4.30.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "7cb80bc10bfcdf6b5492741c0b9357dac66940bc" + "reference": "50590a057841fa6bf69d12eceffce3465b9e32cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/7cb80bc10bfcdf6b5492741c0b9357dac66940bc", - "reference": "7cb80bc10bfcdf6b5492741c0b9357dac66940bc", + "url": "https://api.github.com/repos/symfony/string/zipball/50590a057841fa6bf69d12eceffce3465b9e32cb", + "reference": "50590a057841fa6bf69d12eceffce3465b9e32cb", "shasum": "" }, "require": { @@ -4332,13 +4363,12 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0|^7.0", "symfony/http-client": "^5.4|^6.0|^7.0", "symfony/intl": "^6.2|^7.0", "symfony/translation-contracts": "^2.5|^3.0", "symfony/var-exporter": "^5.4|^6.0|^7.0" }, - "time": "2023-12-10T16:15:48+00:00", + "time": "2025-11-21T18:03:05+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -4377,7 +4407,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.4.2" + "source": "https://github.com/symfony/string/tree/v6.4.30" }, "funding": [ { @@ -4388,6 +4418,10 @@ "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" @@ -4397,31 +4431,31 @@ }, { "name": "symfony/translation-contracts", - "version": "v3.4.0", - "version_normalized": "3.4.0.0", + "version": "v3.6.1", + "version_normalized": "3.6.1.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" + "reference": "65a8bc82080447fae78373aa10f8d13b38338977" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/65a8bc82080447fae78373aa10f8d13b38338977", + "reference": "65a8bc82080447fae78373aa10f8d13b38338977", "shasum": "" }, "require": { "php": ">=8.1" }, - "time": "2023-07-25T15:08:44+00:00", + "time": "2025-07-15T13:41:35+00:00", "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.4-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.6-dev" } }, "installation-source": "dist", @@ -4458,7 +4492,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.6.1" }, "funding": [ { @@ -4469,6 +4503,10 @@ "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" @@ -4478,17 +4516,17 @@ }, { "name": "symfony/twig-bridge", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/twig-bridge.git", - "reference": "142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf" + "reference": "1dcf980dd4f79885b986befdeb1c1bc0d6aedfc8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf", - "reference": "142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf", + "url": "https://api.github.com/repos/symfony/twig-bridge/zipball/1dcf980dd4f79885b986befdeb1c1bc0d6aedfc8", + "reference": "1dcf980dd4f79885b986befdeb1c1bc0d6aedfc8", "shasum": "" }, "require": { @@ -4501,7 +4539,7 @@ "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/console": "<5.4", - "symfony/form": "<6.3", + "symfony/form": "<6.4.32|>7,<7.3.10|>7.4,<7.4.4", "symfony/http-foundation": "<5.4", "symfony/http-kernel": "<6.4", "symfony/mime": "<6.2", @@ -4519,7 +4557,7 @@ "symfony/dependency-injection": "^5.4|^6.0|^7.0", "symfony/expression-language": "^5.4|^6.0|^7.0", "symfony/finder": "^5.4|^6.0|^7.0", - "symfony/form": "^6.4|^7.0", + "symfony/form": "^6.4.32|~7.3.10|^7.4.4", "symfony/html-sanitizer": "^6.1|^7.0", "symfony/http-foundation": "^5.4|^6.0|^7.0", "symfony/http-kernel": "^6.4|^7.0", @@ -4532,7 +4570,7 @@ "symfony/security-core": "^5.4|^6.0|^7.0", "symfony/security-csrf": "^5.4|^6.0|^7.0", "symfony/security-http": "^5.4|^6.0|^7.0", - "symfony/serializer": "^6.4|^7.0", + "symfony/serializer": "^6.4.3|^7.0.3", "symfony/stopwatch": "^5.4|^6.0|^7.0", "symfony/translation": "^6.1|^7.0", "symfony/web-link": "^5.4|^6.0|^7.0", @@ -4542,7 +4580,7 @@ "twig/inky-extra": "^2.12|^3", "twig/markdown-extra": "^2.12|^3" }, - "time": "2023-11-25T08:25:13+00:00", + "time": "2026-01-03T23:03:08+00:00", "type": "symfony-bridge", "installation-source": "dist", "autoload": { @@ -4570,7 +4608,7 @@ "description": "Provides integration for Twig with various Symfony components", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bridge/tree/v6.4.0" + "source": "https://github.com/symfony/twig-bridge/tree/v6.4.32" }, "funding": [ { @@ -4581,6 +4619,10 @@ "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" @@ -4590,17 +4632,17 @@ }, { "name": "symfony/twig-bundle", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/twig-bundle.git", - "reference": "35d84393e598dfb774e6a2bf49e5229a8a6dbe4c" + "reference": "a5c8dcc11a5bf9c96320da20070d2e158a4e0b30" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/35d84393e598dfb774e6a2bf49e5229a8a6dbe4c", - "reference": "35d84393e598dfb774e6a2bf49e5229a8a6dbe4c", + "url": "https://api.github.com/repos/symfony/twig-bundle/zipball/a5c8dcc11a5bf9c96320da20070d2e158a4e0b30", + "reference": "a5c8dcc11a5bf9c96320da20070d2e158a4e0b30", "shasum": "" }, "require": { @@ -4629,7 +4671,7 @@ "symfony/web-link": "^5.4|^6.0|^7.0", "symfony/yaml": "^5.4|^6.0|^7.0" }, - "time": "2023-11-07T14:57:07+00:00", + "time": "2026-01-05T12:44:39+00:00", "type": "symfony-bundle", "installation-source": "dist", "autoload": { @@ -4657,7 +4699,7 @@ "description": "Provides a tight integration of Twig into the Symfony full-stack framework", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/twig-bundle/tree/v6.4.0" + "source": "https://github.com/symfony/twig-bundle/tree/v6.4.32" }, "funding": [ { @@ -4668,6 +4710,10 @@ "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" @@ -4677,17 +4723,17 @@ }, { "name": "symfony/var-dumper", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "68d6573ec98715ddcae5a0a85bee3c1c27a4c33f" + "reference": "131fc9915e0343052af5ed5040401b481ca192aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/68d6573ec98715ddcae5a0a85bee3c1c27a4c33f", - "reference": "68d6573ec98715ddcae5a0a85bee3c1c27a4c33f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/131fc9915e0343052af5ed5040401b481ca192aa", + "reference": "131fc9915e0343052af5ed5040401b481ca192aa", "shasum": "" }, "require": { @@ -4699,7 +4745,6 @@ "symfony/console": "<5.4" }, "require-dev": { - "ext-iconv": "*", "symfony/console": "^5.4|^6.0|^7.0", "symfony/error-handler": "^6.3|^7.0", "symfony/http-kernel": "^5.4|^6.0|^7.0", @@ -4707,7 +4752,7 @@ "symfony/uid": "^5.4|^6.0|^7.0", "twig/twig": "^2.13|^3.0.4" }, - "time": "2023-12-28T19:16:56+00:00", + "time": "2026-01-01T13:34:06+00:00", "bin": [ "Resources/bin/var-dump-server" ], @@ -4745,7 +4790,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.4.2" + "source": "https://github.com/symfony/var-dumper/tree/v6.4.32" }, "funding": [ { @@ -4756,6 +4801,10 @@ "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" @@ -4849,17 +4898,17 @@ }, { "name": "symfony/web-profiler-bundle", - "version": "v6.4.2", - "version_normalized": "6.4.2.0", + "version": "v6.4.32", + "version_normalized": "6.4.32.0", "source": { "type": "git", "url": "https://github.com/symfony/web-profiler-bundle.git", - "reference": "38462d16856740ec0d1ba2cb902eebf09100dde2" + "reference": "011f59e3f3d20f60d11b4e78b8dc63504f56e145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/38462d16856740ec0d1ba2cb902eebf09100dde2", - "reference": "38462d16856740ec0d1ba2cb902eebf09100dde2", + "url": "https://api.github.com/repos/symfony/web-profiler-bundle/zipball/011f59e3f3d20f60d11b4e78b8dc63504f56e145", + "reference": "011f59e3f3d20f60d11b4e78b8dc63504f56e145", "shasum": "" }, "require": { @@ -4883,7 +4932,7 @@ "symfony/css-selector": "^5.4|^6.0|^7.0", "symfony/stopwatch": "^5.4|^6.0|^7.0" }, - "time": "2023-12-27T08:18:35+00:00", + "time": "2026-01-06T09:13:42+00:00", "type": "symfony-bundle", "installation-source": "dist", "autoload": { @@ -4914,7 +4963,7 @@ "dev" ], "support": { - "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.2" + "source": "https://github.com/symfony/web-profiler-bundle/tree/v6.4.32" }, "funding": [ { @@ -4925,6 +4974,10 @@ "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" @@ -4934,17 +4987,17 @@ }, { "name": "symfony/yaml", - "version": "v6.4.0", - "version_normalized": "6.4.0.0", + "version": "v6.4.30", + "version_normalized": "6.4.30.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587" + "reference": "8207ae83da19ee3748d6d4f567b4d9a7c656e331" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587", - "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587", + "url": "https://api.github.com/repos/symfony/yaml/zipball/8207ae83da19ee3748d6d4f567b4d9a7c656e331", + "reference": "8207ae83da19ee3748d6d4f567b4d9a7c656e331", "shasum": "" }, "require": { @@ -4958,7 +5011,7 @@ "require-dev": { "symfony/console": "^5.4|^6.0|^7.0" }, - "time": "2023-11-06T11:00:25+00:00", + "time": "2025-12-02T11:50:18+00:00", "bin": [ "Resources/bin/yaml-lint" ], @@ -4989,7 +5042,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.0" + "source": "https://github.com/symfony/yaml/tree/v6.4.30" }, "funding": [ { @@ -5000,6 +5053,10 @@ "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" @@ -5009,24 +5066,24 @@ }, { "name": "tecnickcom/tcpdf", - "version": "6.10.0", - "version_normalized": "6.10.0.0", + "version": "6.10.1", + "version_normalized": "6.10.1.0", "source": { "type": "git", "url": "https://github.com/tecnickcom/TCPDF.git", - "reference": "ca5b6de294512145db96bcbc94e61696599c391d" + "reference": "7a2701251e5d52fc3d508fd71704683eb54f5939" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/ca5b6de294512145db96bcbc94e61696599c391d", - "reference": "ca5b6de294512145db96bcbc94e61696599c391d", + "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/7a2701251e5d52fc3d508fd71704683eb54f5939", + "reference": "7a2701251e5d52fc3d508fd71704683eb54f5939", "shasum": "" }, "require": { "ext-curl": "*", "php": ">=7.1.0" }, - "time": "2025-05-27T18:02:28+00:00", + "time": "2025-11-21T10:58:21+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -5071,7 +5128,7 @@ ], "support": { "issues": "https://github.com/tecnickcom/TCPDF/issues", - "source": "https://github.com/tecnickcom/TCPDF/tree/6.10.0" + "source": "https://github.com/tecnickcom/TCPDF/tree/6.10.1" }, "funding": [ { @@ -5083,30 +5140,30 @@ }, { "name": "thenetworg/oauth2-azure", - "version": "v2.2.2", - "version_normalized": "2.2.2.0", + "version": "v2.2.4", + "version_normalized": "2.2.4.0", "source": { "type": "git", "url": "https://github.com/TheNetworg/oauth2-azure.git", - "reference": "be204a5135f016470a9c33e82ab48785bbc11af2" + "reference": "a897d60b6b127daa2f27b1b4e62e7af40829d02f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/TheNetworg/oauth2-azure/zipball/be204a5135f016470a9c33e82ab48785bbc11af2", - "reference": "be204a5135f016470a9c33e82ab48785bbc11af2", + "url": "https://api.github.com/repos/TheNetworg/oauth2-azure/zipball/a897d60b6b127daa2f27b1b4e62e7af40829d02f", + "reference": "a897d60b6b127daa2f27b1b4e62e7af40829d02f", "shasum": "" }, "require": { "ext-json": "*", "ext-openssl": "*", - "firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0", + "firebase/php-jwt": "~3.0||~4.0||~5.0||~6.0||~7.0", "league/oauth2-client": "~2.0", "php": "^7.1|^8.0" }, "require-dev": { "phpunit/phpunit": "^9.6" }, - "time": "2023-12-19T12:10:48+00:00", + "time": "2026-01-29T12:43:59+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -5140,23 +5197,23 @@ ], "support": { "issues": "https://github.com/TheNetworg/oauth2-azure/issues", - "source": "https://github.com/TheNetworg/oauth2-azure/tree/v2.2.2" + "source": "https://github.com/TheNetworg/oauth2-azure/tree/v2.2.4" }, "install-path": "../thenetworg/oauth2-azure" }, { "name": "twig/twig", - "version": "v3.21.1", - "version_normalized": "3.21.1.0", + "version": "v3.23.0", + "version_normalized": "3.23.0.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d" + "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/285123877d4dd97dd7c11842ac5fb7e86e60d81d", - "reference": "285123877d4dd97dd7c11842ac5fb7e86e60d81d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", + "reference": "a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9", "shasum": "" }, "require": { @@ -5170,7 +5227,7 @@ "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, - "time": "2025-05-03T07:21:55+00:00", + "time": "2026-01-23T21:00:41+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -5212,7 +5269,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.21.1" + "source": "https://github.com/twigphp/Twig/tree/v3.23.0" }, "funding": [ { diff --git a/lib/composer/installed.php b/lib/composer/installed.php index f7908990cf..f8012b9a7b 100644 --- a/lib/composer/installed.php +++ b/lib/composer/installed.php @@ -1,9 +1,9 @@ array( 'name' => 'combodo/itop', - 'pretty_version' => 'dev-develop', - 'version' => 'dev-develop', - 'reference' => 'd5706fcbef58868cb8bd6ee6f3af133ca4fdab3e', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -11,18 +11,20 @@ ), 'versions' => array( 'apereo/phpcas' => array( - 'pretty_version' => '1.6.1', - 'version' => '1.6.1.0', - 'reference' => 'c129708154852656aabb13d8606cd5b12dbbabac', + 'pretty_version' => 'dev-master', + 'version' => 'dev-master', + 'reference' => '57a7744146a963d8fa80192e0ab351051b711ff6', 'type' => 'library', 'install_path' => __DIR__ . '/../apereo/phpcas', - 'aliases' => array(), + 'aliases' => array( + 0 => '1.3.x-dev', + ), 'dev_requirement' => false, ), 'combodo/itop' => array( - 'pretty_version' => 'dev-develop', - 'version' => 'dev-develop', - 'reference' => 'd5706fcbef58868cb8bd6ee6f3af133ca4fdab3e', + 'pretty_version' => '1.0.0+no-version-set', + 'version' => '1.0.0.0', + 'reference' => null, 'type' => 'project', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -47,77 +49,68 @@ 'dev_requirement' => false, ), 'firebase/php-jwt' => array( - 'pretty_version' => 'v6.10.0', - 'version' => '6.10.0.0', - 'reference' => 'a49db6f0a5033aef5143295342f1c95521b075ff', + 'pretty_version' => 'v7.0.2', + 'version' => '7.0.2.0', + 'reference' => '5645b43af647b6947daac1d0f659dd1fbe8d3b65', 'type' => 'library', 'install_path' => __DIR__ . '/../firebase/php-jwt', 'aliases' => array(), 'dev_requirement' => false, ), 'guzzlehttp/guzzle' => array( - 'pretty_version' => '7.8.1', - 'version' => '7.8.1.0', - 'reference' => '41042bc7ab002487b876a0683fc8dce04ddce104', + 'pretty_version' => '7.10.0', + 'version' => '7.10.0.0', + 'reference' => 'b51ac707cfa420b7bfd4e4d5e510ba8008e822b4', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/guzzle', 'aliases' => array(), 'dev_requirement' => false, ), 'guzzlehttp/promises' => array( - 'pretty_version' => '2.0.2', - 'version' => '2.0.2.0', - 'reference' => 'bbff78d96034045e58e13dedd6ad91b5d1253223', + 'pretty_version' => '2.3.0', + 'version' => '2.3.0.0', + 'reference' => '481557b130ef3790cf82b713667b43030dc9c957', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/promises', 'aliases' => array(), 'dev_requirement' => false, ), 'guzzlehttp/psr7' => array( - 'pretty_version' => '2.6.2', - 'version' => '2.6.2.0', - 'reference' => '45b30f99ac27b5ca93cb4831afe16285f57b8221', + 'pretty_version' => '2.8.0', + 'version' => '2.8.0.0', + 'reference' => '21dc724a0583619cd1652f673303492272778051', 'type' => 'library', 'install_path' => __DIR__ . '/../guzzlehttp/psr7', 'aliases' => array(), 'dev_requirement' => false, ), 'league/oauth2-client' => array( - 'pretty_version' => '2.7.0', - 'version' => '2.7.0.0', - 'reference' => '160d6274b03562ebeb55ed18399281d8118b76c8', + 'pretty_version' => '2.9.0', + 'version' => '2.9.0.0', + 'reference' => '26e8c5da4f3d78cede7021e09b1330a0fc093d5e', 'type' => 'library', 'install_path' => __DIR__ . '/../league/oauth2-client', 'aliases' => array(), 'dev_requirement' => false, ), 'league/oauth2-google' => array( - 'pretty_version' => '4.0.1', - 'version' => '4.0.1.0', - 'reference' => '1b01ba18ba31b29e88771e3e0979e5c91d4afe76', + 'pretty_version' => '4.1.0', + 'version' => '4.1.0.0', + 'reference' => '8b9bb43740ac6d994aca881a35f7bacbe98c0ffb', 'type' => 'library', 'install_path' => __DIR__ . '/../league/oauth2-google', 'aliases' => array(), 'dev_requirement' => false, ), 'nikic/php-parser' => array( - 'pretty_version' => 'v4.18.0', - 'version' => '4.18.0.0', - 'reference' => '1bcbb2179f97633e98bbbc87044ee2611c7d7999', + 'pretty_version' => 'v4.19.5', + 'version' => '4.19.5.0', + 'reference' => '51bd93cc741b7fc3d63d20b6bdcd99fdaa359837', 'type' => 'library', 'install_path' => __DIR__ . '/../nikic/php-parser', 'aliases' => array(), 'dev_requirement' => false, ), - 'paragonie/random_compat' => array( - 'pretty_version' => 'v9.99.100', - 'version' => '9.99.100.0', - 'reference' => '996434e5492cb4c3edcb9168db6fbb1359ef965a', - 'type' => 'library', - 'install_path' => __DIR__ . '/../paragonie/random_compat', - 'aliases' => array(), - 'dev_requirement' => false, - ), 'pear/archive_tar' => array( 'pretty_version' => '1.4.14', 'version' => '1.4.14.0', @@ -137,9 +130,9 @@ 'dev_requirement' => false, ), 'pear/pear-core-minimal' => array( - 'pretty_version' => 'v1.10.11', - 'version' => '1.10.11.0', - 'reference' => '68d0d32ada737153b7e93b8d3c710ebe70ac867d', + 'pretty_version' => 'v1.10.18', + 'version' => '1.10.18.0', + 'reference' => 'c7b55789d01de0ce090d289b73f1bbd6a2f113b1', 'type' => 'library', 'install_path' => __DIR__ . '/../pear/pear-core-minimal', 'aliases' => array(), @@ -155,9 +148,9 @@ 'dev_requirement' => false, ), 'pelago/emogrifier' => array( - 'pretty_version' => 'v7.2.0', - 'version' => '7.2.0.0', - 'reference' => '727bdf7255b51798307f17dec52ff8a91f1c7de3', + 'pretty_version' => 'v7.3.0', + 'version' => '7.3.0.0', + 'reference' => '6e00d9d8235e8cc8eec857e8dcd6cfeefdfd0cd6', 'type' => 'library', 'install_path' => __DIR__ . '/../pelago/emogrifier', 'aliases' => array(), @@ -224,9 +217,9 @@ ), ), 'psr/http-factory' => array( - 'pretty_version' => '1.0.2', - 'version' => '1.0.2.0', - 'reference' => 'e616d01114759c4c489f93b099585439f795fe35', + 'pretty_version' => '1.1.0', + 'version' => '1.1.0.0', + 'reference' => '2b4765fddfe3b508ac62f829e852b1501d3f6e8a', 'type' => 'library', 'install_path' => __DIR__ . '/../psr/http-factory', 'aliases' => array(), @@ -286,22 +279,22 @@ 'rsky/pear-core-min' => array( 'dev_requirement' => false, 'replaced' => array( - 0 => 'v1.10.11', + 0 => 'v1.10.18', ), ), 'sabberworm/php-css-parser' => array( - 'pretty_version' => '8.4.0', - 'version' => '8.4.0.0', - 'reference' => 'e41d2140031d533348b2192a83f02d8dd8a71d30', + 'pretty_version' => 'v8.9.0', + 'version' => '8.9.0.0', + 'reference' => 'd8e916507b88e389e26d4ab03c904a082aa66bb9', 'type' => 'library', 'install_path' => __DIR__ . '/../sabberworm/php-css-parser', 'aliases' => array(), 'dev_requirement' => false, ), 'scssphp/scssphp' => array( - 'pretty_version' => 'v1.12.1', - 'version' => '1.12.1.0', - 'reference' => '394ed1e960138710a60d035c1a85d43d0bf0faeb', + 'pretty_version' => 'v1.13.0', + 'version' => '1.13.0.0', + 'reference' => '63d1157457e5554edf00b0c1fabab4c1511d2520', 'type' => 'library', 'install_path' => __DIR__ . '/../scssphp/scssphp', 'aliases' => array(), @@ -317,9 +310,9 @@ 'dev_requirement' => false, ), 'symfony/cache' => array( - 'pretty_version' => 'v6.4.12', - 'version' => '6.4.12.0', - 'reference' => 'a463451b7f6ac4a47b98dbfc78ec2d3560c759d8', + 'pretty_version' => 'v6.4.33', + 'version' => '6.4.33.0', + 'reference' => '5b088fa41eb9568748dc255c45e4054c387ba73b', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/cache', 'aliases' => array(), @@ -341,45 +334,45 @@ ), ), 'symfony/config' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => '5d33e0fb707d603330e0edfd4691803a1253572e', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => 'd445badf0ad2c2a492e38c0378c39997a56ef97b', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/config', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/console' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => '0254811a143e6bc6c8deea08b589a7e68a37f625', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => '0bc2199c6c1f05276b05956f1ddc63f6d7eb5fc3', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/console', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/css-selector' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => 'd036c6c0d0b09e24a14a35f8292146a658f986e4', + 'pretty_version' => 'v6.4.24', + 'version' => '6.4.24.0', + 'reference' => '9b784413143701aa3c94ac1869a159a9e53e8761', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/css-selector', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/debug-bundle' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => '1e07027423d1d37125b60a50997ada26a9d9d202', + 'pretty_version' => 'v6.4.27', + 'version' => '6.4.27.0', + 'reference' => '21a61c55192d558a6b81cdb12e8c010fc9474fe0', 'type' => 'symfony-bundle', 'install_path' => __DIR__ . '/../symfony/debug-bundle', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/dependency-injection' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => '226ea431b1eda6f0d9f5a4b278757171960bb195', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => 'b17882e933c4c606620247b6708ab53aa3b88753', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/dependency-injection', 'aliases' => array(), @@ -395,27 +388,27 @@ 'dev_requirement' => false, ), 'symfony/dotenv' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => '835f8d2d1022934ac038519de40b88158798c96f', + 'pretty_version' => 'v6.4.30', + 'version' => '6.4.30.0', + 'reference' => '924edbc9631b75302def0258ed1697948b17baf6', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/dotenv', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/error-handler' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => 'c873490a1c97b3a0a4838afc36ff36c112d02788', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => '8c18400784fcb014dc73c8d5601a9576af7f8ad4', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/error-handler', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/event-dispatcher' => array( - 'pretty_version' => 'v6.4.25', - 'version' => '6.4.25.0', - 'reference' => 'b0cf3162020603587363f0551cd3be43958611ff', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => '99d7e101826e6610606b9433248f80c1997cd20b', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/event-dispatcher', 'aliases' => array(), @@ -437,81 +430,81 @@ ), ), 'symfony/filesystem' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => '952a8cb588c3bc6ce76f6023000fb932f16a6e59', + 'pretty_version' => 'v6.4.30', + 'version' => '6.4.30.0', + 'reference' => '441c6b69f7222aadae7cbf5df588496d5ee37789', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/finder' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => '11d736e97f116ac375a81f96e662911a34cd50ce', + 'pretty_version' => 'v6.4.33', + 'version' => '6.4.33.0', + 'reference' => '24965ca011dac87431729640feef8bcf7b5523e0', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/finder', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/framework-bundle' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => 'c26a221e0462027d1f9d4a802ed63f8ab07a43d0', + 'pretty_version' => 'v6.4.33', + 'version' => '6.4.33.0', + 'reference' => '9ef2d0b63b9e855ba351e770a603d89699115801', 'type' => 'symfony-bundle', 'install_path' => __DIR__ . '/../symfony/framework-bundle', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/http-foundation' => array( - 'pretty_version' => 'v6.4.29', - 'version' => '6.4.29.0', - 'reference' => 'b03d11e015552a315714c127d8d1e0f9e970ec88', + 'pretty_version' => 'v6.4.33', + 'version' => '6.4.33.0', + 'reference' => 'f1a490cc9d595ba7ebe684220e625d1e472ad278', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/http-foundation', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/http-kernel' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => '13e8387320b5942d0dc408440c888e2d526efef4', + 'pretty_version' => 'v6.4.33', + 'version' => '6.4.33.0', + 'reference' => '73fa5c999d7f741ca544a97d3c791cc97890ae4d', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/http-kernel', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/mailer' => array( - 'pretty_version' => 'v6.4.25', - 'version' => '6.4.25.0', - 'reference' => '628b43b45a3e6b15c8a633fb22df547ed9b492a2', + 'pretty_version' => 'v6.4.31', + 'version' => '6.4.31.0', + 'reference' => '8835f93333474780fda1b987cae37e33c3e026ca', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/mailer', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/mime' => array( - 'pretty_version' => 'v6.4.24', - 'version' => '6.4.24.0', - 'reference' => '664d5e844a2de5e11c8255d0aef6bc15a9660ac7', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => '7409686879ca36c09fc970a5fa8ff6e93504dba4', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/mime', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-ctype' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => 'ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb', + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => 'a3cc8b044a6ea513310cbd48ef7333b384945638', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-ctype', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-intl-grapheme' => array( - 'pretty_version' => 'v1.28.0', - 'version' => '1.28.0.0', - 'reference' => '875e90aeea2777b6f135677f618529449334a612', + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '380872130d3a5dd3ace2f4010d95125fde5d5c70', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-intl-grapheme', 'aliases' => array(), @@ -554,18 +547,18 @@ 'dev_requirement' => false, ), 'symfony/routing' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => '98eab13a07fddc85766f1756129c69f207ffbc21', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => '0dc6253e864e71b486e8ba4970a56ab849106ebe', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/routing', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/runtime' => array( - 'pretty_version' => 'v6.4.24', - 'version' => '6.4.24.0', - 'reference' => 'c1cc6721646f546627236c57f835272806087337', + 'pretty_version' => 'v6.4.30', + 'version' => '6.4.30.0', + 'reference' => 'fb3149ee85d3b639dd3e49ea9dda05656f0537e3', 'type' => 'composer-plugin', 'install_path' => __DIR__ . '/../symfony/runtime', 'aliases' => array(), @@ -587,54 +580,54 @@ ), ), 'symfony/stopwatch' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => 'fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2', + 'pretty_version' => 'v6.4.24', + 'version' => '6.4.24.0', + 'reference' => 'b67e94e06a05d9572c2fa354483b3e13e3cb1898', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/stopwatch', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/string' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => '7cb80bc10bfcdf6b5492741c0b9357dac66940bc', + 'pretty_version' => 'v6.4.30', + 'version' => '6.4.30.0', + 'reference' => '50590a057841fa6bf69d12eceffce3465b9e32cb', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/string', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/translation-contracts' => array( - 'pretty_version' => 'v3.4.0', - 'version' => '3.4.0.0', - 'reference' => 'dee0c6e5b4c07ce851b462530088e64b255ac9c5', + 'pretty_version' => 'v3.6.1', + 'version' => '3.6.1.0', + 'reference' => '65a8bc82080447fae78373aa10f8d13b38338977', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/translation-contracts', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/twig-bridge' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => '142bc3ad4a61d7eedf7cc21d8ef2bd8a8e7417bf', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => '1dcf980dd4f79885b986befdeb1c1bc0d6aedfc8', 'type' => 'symfony-bridge', 'install_path' => __DIR__ . '/../symfony/twig-bridge', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/twig-bundle' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => '35d84393e598dfb774e6a2bf49e5229a8a6dbe4c', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => 'a5c8dcc11a5bf9c96320da20070d2e158a4e0b30', 'type' => 'symfony-bundle', 'install_path' => __DIR__ . '/../symfony/twig-bundle', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/var-dumper' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => '68d6573ec98715ddcae5a0a85bee3c1c27a4c33f', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => '131fc9915e0343052af5ed5040401b481ca192aa', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/var-dumper', 'aliases' => array(), @@ -650,45 +643,45 @@ 'dev_requirement' => false, ), 'symfony/web-profiler-bundle' => array( - 'pretty_version' => 'v6.4.2', - 'version' => '6.4.2.0', - 'reference' => '38462d16856740ec0d1ba2cb902eebf09100dde2', + 'pretty_version' => 'v6.4.32', + 'version' => '6.4.32.0', + 'reference' => '011f59e3f3d20f60d11b4e78b8dc63504f56e145', 'type' => 'symfony-bundle', 'install_path' => __DIR__ . '/../symfony/web-profiler-bundle', 'aliases' => array(), 'dev_requirement' => true, ), 'symfony/yaml' => array( - 'pretty_version' => 'v6.4.0', - 'version' => '6.4.0.0', - 'reference' => '4f9237a1bb42455d609e6687d2613dde5b41a587', + 'pretty_version' => 'v6.4.30', + 'version' => '6.4.30.0', + 'reference' => '8207ae83da19ee3748d6d4f567b4d9a7c656e331', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/yaml', 'aliases' => array(), 'dev_requirement' => false, ), 'tecnickcom/tcpdf' => array( - 'pretty_version' => '6.10.0', - 'version' => '6.10.0.0', - 'reference' => 'ca5b6de294512145db96bcbc94e61696599c391d', + 'pretty_version' => '6.10.1', + 'version' => '6.10.1.0', + 'reference' => '7a2701251e5d52fc3d508fd71704683eb54f5939', 'type' => 'library', 'install_path' => __DIR__ . '/../tecnickcom/tcpdf', 'aliases' => array(), 'dev_requirement' => false, ), 'thenetworg/oauth2-azure' => array( - 'pretty_version' => 'v2.2.2', - 'version' => '2.2.2.0', - 'reference' => 'be204a5135f016470a9c33e82ab48785bbc11af2', + 'pretty_version' => 'v2.2.4', + 'version' => '2.2.4.0', + 'reference' => 'a897d60b6b127daa2f27b1b4e62e7af40829d02f', 'type' => 'library', 'install_path' => __DIR__ . '/../thenetworg/oauth2-azure', 'aliases' => array(), 'dev_requirement' => false, ), 'twig/twig' => array( - 'pretty_version' => 'v3.21.1', - 'version' => '3.21.1.0', - 'reference' => '285123877d4dd97dd7c11842ac5fb7e86e60d81d', + 'pretty_version' => 'v3.23.0', + 'version' => '3.23.0.0', + 'reference' => 'a64dc5d2cc7d6cafb9347f6cd802d0d06d0351c9', 'type' => 'library', 'install_path' => __DIR__ . '/../twig/twig', 'aliases' => array(), diff --git a/lib/firebase/php-jwt/CHANGELOG.md b/lib/firebase/php-jwt/CHANGELOG.md index 644fa0beaf..263760760d 100644 --- a/lib/firebase/php-jwt/CHANGELOG.md +++ b/lib/firebase/php-jwt/CHANGELOG.md @@ -1,5 +1,64 @@ # Changelog +## [7.0.2](https://github.com/firebase/php-jwt/compare/v7.0.1...v7.0.2) (2025-12-16) + + +### Bug Fixes + +* add key length validation for ec keys ([#615](https://github.com/firebase/php-jwt/issues/615)) ([7044f9a](https://github.com/firebase/php-jwt/commit/7044f9ae7e7d175d28cca71714feb236f1c0e252)) + +## [7.0.0](https://github.com/firebase/php-jwt/compare/v6.11.1...v7.0.0) (2025-12-15) + + +### ⚠️ ⚠️ ⚠️ Security Fixes ⚠️ ⚠️ ⚠️ + * add key size validation ([#613](https://github.com/firebase/php-jwt/issues/613)) ([6b80341](https://github.com/firebase/php-jwt/commit/6b80341bf57838ea2d011487917337901cd71576)) + **NOTE**: This fix will cause keys with a size below the minimally allowed size to break. + +### Features + +* add SensitiveParameter attribute to security-critical parameters ([#603](https://github.com/firebase/php-jwt/issues/603)) ([4dbfac0](https://github.com/firebase/php-jwt/commit/4dbfac0260eeb0e9e643063c99998e3219cc539b)) +* store timestamp in `ExpiredException` ([#604](https://github.com/firebase/php-jwt/issues/604)) ([f174826](https://github.com/firebase/php-jwt/commit/f1748260d218a856b6a0c23715ac7fae1d7ca95b)) + + +### Bug Fixes + +* validate iat and nbf on payload ([#568](https://github.com/firebase/php-jwt/issues/568)) ([953b2c8](https://github.com/firebase/php-jwt/commit/953b2c88bb445b7e3bb82a5141928f13d7343afd)) + +## [6.11.1](https://github.com/firebase/php-jwt/compare/v6.11.0...v6.11.1) (2025-04-09) + + +### Bug Fixes + +* update error text for consistency ([#528](https://github.com/firebase/php-jwt/issues/528)) ([c11113a](https://github.com/firebase/php-jwt/commit/c11113afa13265e016a669e75494b9203b8a7775)) + +## [6.11.0](https://github.com/firebase/php-jwt/compare/v6.10.2...v6.11.0) (2025-01-23) + + +### Features + +* support octet typed JWK ([#587](https://github.com/firebase/php-jwt/issues/587)) ([7cb8a26](https://github.com/firebase/php-jwt/commit/7cb8a265fa81edf2fa6ef8098f5bc5ae573c33ad)) + + +### Bug Fixes + +* refactor constructor Key to use PHP 8.0 syntax ([#577](https://github.com/firebase/php-jwt/issues/577)) ([29fa2ce](https://github.com/firebase/php-jwt/commit/29fa2ce9e0582cd397711eec1e80c05ce20fabca)) + +## [6.10.2](https://github.com/firebase/php-jwt/compare/v6.10.1...v6.10.2) (2024-11-24) + + +### Bug Fixes + +* Mitigate PHP8.4 deprecation warnings ([#570](https://github.com/firebase/php-jwt/issues/570)) ([76808fa](https://github.com/firebase/php-jwt/commit/76808fa227f3811aa5cdb3bf81233714b799a5b5)) +* support php 8.4 ([#583](https://github.com/firebase/php-jwt/issues/583)) ([e3d68b0](https://github.com/firebase/php-jwt/commit/e3d68b044421339443c74199edd020e03fb1887e)) + +## [6.10.1](https://github.com/firebase/php-jwt/compare/v6.10.0...v6.10.1) (2024-05-18) + + +### Bug Fixes + +* ensure ratelimit expiry is set every time ([#556](https://github.com/firebase/php-jwt/issues/556)) ([09cb208](https://github.com/firebase/php-jwt/commit/09cb2081c2c3bc0f61e2f2a5fbea5741f7498648)) +* ratelimit cache expiration ([#550](https://github.com/firebase/php-jwt/issues/550)) ([dda7250](https://github.com/firebase/php-jwt/commit/dda725033585ece30ff8cae8937320d7e9f18bae)) + ## [6.10.0](https://github.com/firebase/php-jwt/compare/v6.9.0...v6.10.0) (2023-11-28) diff --git a/lib/firebase/php-jwt/README.md b/lib/firebase/php-jwt/README.md index 701de23a82..65b6c8609d 100644 --- a/lib/firebase/php-jwt/README.md +++ b/lib/firebase/php-jwt/README.md @@ -17,7 +17,7 @@ composer require firebase/php-jwt ``` Optionally, install the `paragonie/sodium_compat` package from composer if your -php is < 7.2 or does not have libsodium installed: +php env does not have libsodium installed: ```bash composer require paragonie/sodium_compat @@ -48,7 +48,8 @@ $decoded = JWT::decode($jwt, new Key($key, 'HS256')); print_r($decoded); // Pass a stdClass in as the third parameter to get the decoded header values -$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers = new stdClass()); +$headers = new stdClass(); +$decoded = JWT::decode($jwt, new Key($key, 'HS256'), $headers); print_r($headers); /* @@ -185,7 +186,7 @@ $passphrase = '[YOUR_PASSPHRASE]'; // Can be generated with "ssh-keygen -t rsa -m pem" $privateKeyFile = '/path/to/key-with-passphrase.pem'; -// Create a private key of type "resource" +/** @var OpenSSLAsymmetricKey $privateKey */ $privateKey = openssl_pkey_get_private( file_get_contents($privateKeyFile), $passphrase @@ -290,7 +291,7 @@ $jwks = ['keys' => []]; // JWK::parseKeySet($jwks) returns an associative array of **kid** to Firebase\JWT\Key // objects. Pass this as the second parameter to JWT::decode. -JWT::decode($payload, JWK::parseKeySet($jwks)); +JWT::decode($jwt, JWK::parseKeySet($jwks)); ``` Using Cached Key Sets @@ -349,7 +350,7 @@ use InvalidArgumentException; use UnexpectedValueException; try { - $decoded = JWT::decode($payload, $keys); + $decoded = JWT::decode($jwt, $keys); } catch (InvalidArgumentException $e) { // provided key/key-array is empty or malformed. } catch (DomainException $e) { @@ -379,7 +380,7 @@ like this: use Firebase\JWT\JWT; use UnexpectedValueException; try { - $decoded = JWT::decode($payload, $keys); + $decoded = JWT::decode($jwt, $keys); } catch (LogicException $e) { // errors having to do with environmental setup or malformed JWT Keys } catch (UnexpectedValueException $e) { @@ -394,7 +395,7 @@ instead, you can do the following: ```php // return type is stdClass -$decoded = JWT::decode($payload, $keys); +$decoded = JWT::decode($jwt, $keys); // cast to array $decoded = json_decode(json_encode($decoded), true); diff --git a/lib/firebase/php-jwt/composer.json b/lib/firebase/php-jwt/composer.json index e23dfe378d..816cfd0bd9 100644 --- a/lib/firebase/php-jwt/composer.json +++ b/lib/firebase/php-jwt/composer.json @@ -20,7 +20,7 @@ ], "license": "BSD-3-Clause", "require": { - "php": "^7.4||^8.0" + "php": "^8.0" }, "suggest": { "paragonie/sodium_compat": "Support EdDSA (Ed25519) signatures when libsodium is not present", @@ -32,10 +32,10 @@ } }, "require-dev": { - "guzzlehttp/guzzle": "^6.5||^7.4", + "guzzlehttp/guzzle": "^7.4", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "psr/cache": "^1.0||^2.0", + "psr/cache": "^2.0||^3.0", "psr/http-client": "^1.0", "psr/http-factory": "^1.0" } diff --git a/lib/firebase/php-jwt/src/CachedKeySet.php b/lib/firebase/php-jwt/src/CachedKeySet.php index ee529f9f50..8e8e8d68ca 100644 --- a/lib/firebase/php-jwt/src/CachedKeySet.php +++ b/lib/firebase/php-jwt/src/CachedKeySet.php @@ -80,9 +80,9 @@ public function __construct( ClientInterface $httpClient, RequestFactoryInterface $httpFactory, CacheItemPoolInterface $cache, - int $expiresAfter = null, + ?int $expiresAfter = null, bool $rateLimit = false, - string $defaultAlg = null + ?string $defaultAlg = null ) { $this->jwksUri = $jwksUri; $this->httpClient = $httpClient; @@ -180,7 +180,7 @@ private function keyIdExists(string $keyId): bool $jwksResponse = $this->httpClient->sendRequest($request); if ($jwksResponse->getStatusCode() !== 200) { throw new UnexpectedValueException( - sprintf('HTTP Error: %d %s for URI "%s"', + \sprintf('HTTP Error: %d %s for URI "%s"', $jwksResponse->getStatusCode(), $jwksResponse->getReasonPhrase(), $this->jwksUri, @@ -212,15 +212,21 @@ private function rateLimitExceeded(): bool } $cacheItem = $this->cache->getItem($this->rateLimitCacheKey); - if (!$cacheItem->isHit()) { - $cacheItem->expiresAfter(1); // # of calls are cached each minute + + $cacheItemData = []; + if ($cacheItem->isHit() && \is_array($data = $cacheItem->get())) { + $cacheItemData = $data; } - $callsPerMinute = (int) $cacheItem->get(); + $callsPerMinute = $cacheItemData['callsPerMinute'] ?? 0; + $expiry = $cacheItemData['expiry'] ?? new \DateTime('+60 seconds', new \DateTimeZone('UTC')); + if (++$callsPerMinute > $this->maxCallsPerMinute) { return true; } - $cacheItem->set($callsPerMinute); + + $cacheItem->set(['expiry' => $expiry, 'callsPerMinute' => $callsPerMinute]); + $cacheItem->expiresAt($expiry); $this->cache->save($cacheItem); return false; } diff --git a/lib/firebase/php-jwt/src/ExpiredException.php b/lib/firebase/php-jwt/src/ExpiredException.php index 12fef09448..25f445132d 100644 --- a/lib/firebase/php-jwt/src/ExpiredException.php +++ b/lib/firebase/php-jwt/src/ExpiredException.php @@ -6,6 +6,8 @@ class ExpiredException extends \UnexpectedValueException implements JWTException { private object $payload; + private ?int $timestamp = null; + public function setPayload(object $payload): void { $this->payload = $payload; @@ -15,4 +17,14 @@ public function getPayload(): object { return $this->payload; } + + public function setTimestamp(int $timestamp): void + { + $this->timestamp = $timestamp; + } + + public function getTimestamp(): ?int + { + return $this->timestamp; + } } diff --git a/lib/firebase/php-jwt/src/JWK.php b/lib/firebase/php-jwt/src/JWK.php index 63fb2484b3..d5175b2170 100644 --- a/lib/firebase/php-jwt/src/JWK.php +++ b/lib/firebase/php-jwt/src/JWK.php @@ -52,7 +52,7 @@ class JWK * * @uses parseKey */ - public static function parseKeySet(array $jwks, string $defaultAlg = null): array + public static function parseKeySet(#[\SensitiveParameter] array $jwks, ?string $defaultAlg = null): array { $keys = []; @@ -93,7 +93,7 @@ public static function parseKeySet(array $jwks, string $defaultAlg = null): arra * * @uses createPemFromModulusAndExponent */ - public static function parseKey(array $jwk, string $defaultAlg = null): ?Key + public static function parseKey(#[\SensitiveParameter] array $jwk, ?string $defaultAlg = null): ?Key { if (empty($jwk)) { throw new InvalidArgumentException('JWK must not be empty'); @@ -172,6 +172,12 @@ public static function parseKey(array $jwk, string $defaultAlg = null): ?Key // This library works internally with EdDSA keys (Ed25519) encoded in standard base64. $publicKey = JWT::convertBase64urlToBase64($jwk['x']); return new Key($publicKey, $jwk['alg']); + case 'oct': + if (!isset($jwk['k'])) { + throw new UnexpectedValueException('k not set'); + } + + return new Key(JWT::urlsafeB64Decode($jwk['k']), $jwk['alg']); default: break; } @@ -212,7 +218,7 @@ private static function createPemFromCrvAndXYCoordinates(string $crv, string $x, ) ); - return sprintf( + return \sprintf( "-----BEGIN PUBLIC KEY-----\n%s\n-----END PUBLIC KEY-----\n", wordwrap(base64_encode($pem), 64, "\n", true) ); diff --git a/lib/firebase/php-jwt/src/JWT.php b/lib/firebase/php-jwt/src/JWT.php index 263492068c..c18e4cc062 100644 --- a/lib/firebase/php-jwt/src/JWT.php +++ b/lib/firebase/php-jwt/src/JWT.php @@ -31,6 +31,8 @@ class JWT private const ASN1_SEQUENCE = 0x10; private const ASN1_BIT_STRING = 0x03; + private const RSA_KEY_MIN_LENGTH=2048; + /** * When checking nbf, iat or expiration times, * we want to provide some extra leeway time to @@ -95,8 +97,8 @@ class JWT */ public static function decode( string $jwt, - $keyOrKeyArray, - stdClass &$headers = null + #[\SensitiveParameter] $keyOrKeyArray, + ?stdClass &$headers = null ): stdClass { // Validate JWT $timestamp = \is_null(static::$timestamp) ? \time() : static::$timestamp; @@ -127,6 +129,16 @@ public static function decode( if (!$payload instanceof stdClass) { throw new UnexpectedValueException('Payload must be a JSON object'); } + if (isset($payload->iat) && !\is_numeric($payload->iat)) { + throw new UnexpectedValueException('Payload iat must be a number'); + } + if (isset($payload->nbf) && !\is_numeric($payload->nbf)) { + throw new UnexpectedValueException('Payload nbf must be a number'); + } + if (isset($payload->exp) && !\is_numeric($payload->exp)) { + throw new UnexpectedValueException('Payload exp must be a number'); + } + $sig = static::urlsafeB64Decode($cryptob64); if (empty($header->alg)) { throw new UnexpectedValueException('Empty algorithm'); @@ -154,7 +166,7 @@ public static function decode( // token can actually be used. If it's not yet that time, abort. if (isset($payload->nbf) && floor($payload->nbf) > ($timestamp + static::$leeway)) { $ex = new BeforeValidException( - 'Cannot handle token with nbf prior to ' . \date(DateTime::ISO8601, (int) $payload->nbf) + 'Cannot handle token with nbf prior to ' . \date(DateTime::ATOM, (int) floor($payload->nbf)) ); $ex->setPayload($payload); throw $ex; @@ -165,7 +177,7 @@ public static function decode( // correctly used the nbf claim). if (!isset($payload->nbf) && isset($payload->iat) && floor($payload->iat) > ($timestamp + static::$leeway)) { $ex = new BeforeValidException( - 'Cannot handle token with iat prior to ' . \date(DateTime::ISO8601, (int) $payload->iat) + 'Cannot handle token with iat prior to ' . \date(DateTime::ATOM, (int) floor($payload->iat)) ); $ex->setPayload($payload); throw $ex; @@ -175,6 +187,7 @@ public static function decode( if (isset($payload->exp) && ($timestamp - static::$leeway) >= $payload->exp) { $ex = new ExpiredException('Expired token'); $ex->setPayload($payload); + $ex->setTimestamp($timestamp); throw $ex; } @@ -185,7 +198,7 @@ public static function decode( * Converts and signs a PHP array into a JWT string. * * @param array $payload PHP array - * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. + * @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. * @param string $alg Supported algorithms are 'ES384','ES256', 'ES256K', 'HS256', * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * @param string $keyId @@ -198,13 +211,13 @@ public static function decode( */ public static function encode( array $payload, - $key, + #[\SensitiveParameter] $key, string $alg, - string $keyId = null, - array $head = null + ?string $keyId = null, + ?array $head = null ): string { $header = ['typ' => 'JWT']; - if (isset($head) && \is_array($head)) { + if (isset($head)) { $header = \array_merge($header, $head); } $header['alg'] = $alg; @@ -226,7 +239,7 @@ public static function encode( * Sign a string with a given key and algorithm. * * @param string $msg The message to sign - * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. + * @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $key The secret key. * @param string $alg Supported algorithms are 'EdDSA', 'ES384', 'ES256', 'ES256K', 'HS256', * 'HS384', 'HS512', 'RS256', 'RS384', and 'RS512' * @@ -236,7 +249,7 @@ public static function encode( */ public static function sign( string $msg, - $key, + #[\SensitiveParameter] $key, string $alg ): string { if (empty(static::$supported_algs[$alg])) { @@ -248,10 +261,19 @@ public static function sign( if (!\is_string($key)) { throw new InvalidArgumentException('key must be a string when using hmac'); } + self::validateHmacKeyLength($key, $algorithm); return \hash_hmac($algorithm, $msg, $key, true); case 'openssl': $signature = ''; - $success = \openssl_sign($msg, $signature, $key, $algorithm); // @phpstan-ignore-line + if (!$key = openssl_pkey_get_private($key)) { + throw new DomainException('OpenSSL unable to validate key'); + } + if (str_starts_with($alg, 'RS')) { + self::validateRsaKeyLength($key); + } elseif (str_starts_with($alg, 'ES')) { + self::validateEcKeyLength($key, $alg); + } + $success = \openssl_sign($msg, $signature, $key, $algorithm); if (!$success) { throw new DomainException('OpenSSL unable to sign data'); } @@ -290,7 +312,7 @@ public static function sign( * * @param string $msg The original message (header and body) * @param string $signature The original signature - * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey + * @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial For Ed*, ES*, HS*, a string key works. for RS*, must be an instance of OpenSSLAsymmetricKey * @param string $alg The algorithm * * @return bool @@ -300,7 +322,7 @@ public static function sign( private static function verify( string $msg, string $signature, - $keyMaterial, + #[\SensitiveParameter] $keyMaterial, string $alg ): bool { if (empty(static::$supported_algs[$alg])) { @@ -310,7 +332,15 @@ private static function verify( list($function, $algorithm) = static::$supported_algs[$alg]; switch ($function) { case 'openssl': - $success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); // @phpstan-ignore-line + if (!$key = openssl_pkey_get_public($keyMaterial)) { + throw new DomainException('OpenSSL unable to validate key'); + } + if (str_starts_with($alg, 'RS')) { + self::validateRsaKeyLength($key); + } elseif (str_starts_with($alg, 'ES')) { + self::validateEcKeyLength($key, $alg); + } + $success = \openssl_verify($msg, $signature, $keyMaterial, $algorithm); if ($success === 1) { return true; } @@ -347,6 +377,7 @@ private static function verify( if (!\is_string($keyMaterial)) { throw new InvalidArgumentException('key must be a string when using hmac'); } + self::validateHmacKeyLength($keyMaterial, $algorithm); $hash = \hash_hmac($algorithm, $msg, $keyMaterial, true); return self::constantTimeEquals($hash, $signature); } @@ -384,12 +415,7 @@ public static function jsonDecode(string $input) */ public static function jsonEncode(array $input): string { - if (PHP_VERSION_ID >= 50400) { - $json = \json_encode($input, \JSON_UNESCAPED_SLASHES); - } else { - // PHP 5.3 only - $json = \json_encode($input); - } + $json = \json_encode($input, \JSON_UNESCAPED_SLASHES); if ($errno = \json_last_error()) { self::handleJsonError($errno); } elseif ($json === 'null') { @@ -459,7 +485,7 @@ public static function urlsafeB64Encode(string $input): string * @return Key */ private static function getKey( - $keyOrKeyArray, + #[\SensitiveParameter] $keyOrKeyArray, ?string $kid ): Key { if ($keyOrKeyArray instanceof Key) { @@ -666,4 +692,57 @@ private static function readDER(string $der, int $offset = 0): array return [$pos, $data]; } + + /** + * Validate HMAC key length + * + * @param string $key HMAC key material + * @param string $algorithm The algorithm + * + * @throws DomainException Provided key is too short + */ + private static function validateHmacKeyLength(string $key, string $algorithm): void + { + $keyLength = \strlen($key) * 8; + $minKeyLength = (int) \str_replace('SHA', '', $algorithm); + if ($keyLength < $minKeyLength) { + throw new DomainException('Provided key is too short'); + } + } + + /** + * Validate RSA key length + * + * @param OpenSSLAsymmetricKey $key RSA key material + * @throws DomainException Provided key is too short + */ + private static function validateRsaKeyLength(#[\SensitiveParameter] OpenSSLAsymmetricKey $key): void + { + if (!$keyDetails = openssl_pkey_get_details($key)) { + throw new DomainException('Unable to validate key'); + } + if ($keyDetails['bits'] < self::RSA_KEY_MIN_LENGTH) { + throw new DomainException('Provided key is too short'); + } + } + + /** + * Validate RSA key length + * + * @param OpenSSLAsymmetricKey $key RSA key material + * @param string $algorithm The algorithm + * @throws DomainException Provided key is too short + */ + private static function validateEcKeyLength( + #[\SensitiveParameter] OpenSSLAsymmetricKey $key, + string $algorithm + ): void { + if (!$keyDetails = openssl_pkey_get_details($key)) { + throw new DomainException('Unable to validate key'); + } + $minKeyLength = (int) \str_replace('ES', '', $algorithm); + if ($keyDetails['bits'] < $minKeyLength) { + throw new DomainException('Provided key is too short'); + } + } } diff --git a/lib/firebase/php-jwt/src/Key.php b/lib/firebase/php-jwt/src/Key.php index 00cf7f2edf..694d3b13b9 100644 --- a/lib/firebase/php-jwt/src/Key.php +++ b/lib/firebase/php-jwt/src/Key.php @@ -9,26 +9,20 @@ class Key { - /** @var string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate */ - private $keyMaterial; - /** @var string */ - private $algorithm; - /** - * @param string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial + * @param string|OpenSSLAsymmetricKey|OpenSSLCertificate $keyMaterial * @param string $algorithm */ public function __construct( - $keyMaterial, - string $algorithm + #[\SensitiveParameter] private $keyMaterial, + private string $algorithm ) { if ( !\is_string($keyMaterial) && !$keyMaterial instanceof OpenSSLAsymmetricKey && !$keyMaterial instanceof OpenSSLCertificate - && !\is_resource($keyMaterial) ) { - throw new TypeError('Key material must be a string, resource, or OpenSSLAsymmetricKey'); + throw new TypeError('Key material must be a string, OpenSSLCertificate, or OpenSSLAsymmetricKey'); } if (empty($keyMaterial)) { @@ -38,10 +32,6 @@ public function __construct( if (empty($algorithm)) { throw new InvalidArgumentException('Algorithm must not be empty'); } - - // TODO: Remove in PHP 8.0 in favor of class constructor property promotion - $this->keyMaterial = $keyMaterial; - $this->algorithm = $algorithm; } /** @@ -55,7 +45,7 @@ public function getAlgorithm(): string } /** - * @return string|resource|OpenSSLAsymmetricKey|OpenSSLCertificate + * @return string|OpenSSLAsymmetricKey|OpenSSLCertificate */ public function getKeyMaterial() { diff --git a/lib/guzzlehttp/guzzle/CHANGELOG.md b/lib/guzzlehttp/guzzle/CHANGELOG.md index 13709d1b8a..5fe721e033 100644 --- a/lib/guzzlehttp/guzzle/CHANGELOG.md +++ b/lib/guzzlehttp/guzzle/CHANGELOG.md @@ -2,6 +2,56 @@ Please refer to [UPGRADING](UPGRADING.md) guide for upgrading to a major version. +## 7.10.0 - 2025-08-23 + +### Added + +- Support for PHP 8.5 + +### Changed + +- Adjusted `guzzlehttp/promises` version constraint to `^2.3` +- Adjusted `guzzlehttp/psr7` version constraint to `^2.8` + + +## 7.9.3 - 2025-03-27 + +### Changed + +- Remove explicit content-length header for GET requests +- Improve compatibility with bad servers for boolean cookie values + + +## 7.9.2 - 2024-07-24 + +### Fixed + +- Adjusted handler selection to use cURL if its version is 7.21.2 or higher, rather than 7.34.0 + + +## 7.9.1 - 2024-07-19 + +### Fixed + +- Fix TLS 1.3 check for HTTP/2 requests + + +## 7.9.0 - 2024-07-18 + +### Changed + +- Improve protocol version checks to provide feedback around unsupported protocols +- Only select the cURL handler by default if 7.34.0 or higher is linked +- Improved `CurlMultiHandler` to avoid busy wait if possible +- Dropped support for EOL `guzzlehttp/psr7` v1 +- Improved URI user info redaction in errors + +## 7.8.2 - 2024-07-18 + +### Added + +- Support for PHP 8.4 + ## 7.8.1 - 2023-12-03 diff --git a/lib/guzzlehttp/guzzle/README.md b/lib/guzzlehttp/guzzle/README.md index 6d78a9309c..cdaebee3ff 100644 --- a/lib/guzzlehttp/guzzle/README.md +++ b/lib/guzzlehttp/guzzle/README.md @@ -62,11 +62,11 @@ composer require guzzlehttp/guzzle | Version | Status | Packagist | Namespace | Repo | Docs | PSR-7 | PHP Version | |---------|---------------------|---------------------|--------------|---------------------|---------------------|-------|--------------| -| 3.x | EOL | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<7.0 | -| 4.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 | -| 5.x | EOL | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 | -| 6.x | Security fixes only | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 | -| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.4 | +| 3.x | EOL (2016-10-31) | `guzzle/guzzle` | `Guzzle` | [v3][guzzle-3-repo] | [v3][guzzle-3-docs] | No | >=5.3.3,<7.0 | +| 4.x | EOL (2016-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v4][guzzle-4-repo] | N/A | No | >=5.4,<7.0 | +| 5.x | EOL (2019-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v5][guzzle-5-repo] | [v5][guzzle-5-docs] | No | >=5.4,<7.4 | +| 6.x | EOL (2023-10-31) | `guzzlehttp/guzzle` | `GuzzleHttp` | [v6][guzzle-6-repo] | [v6][guzzle-6-docs] | Yes | >=5.5,<8.0 | +| 7.x | Latest | `guzzlehttp/guzzle` | `GuzzleHttp` | [v7][guzzle-7-repo] | [v7][guzzle-7-docs] | Yes | >=7.2.5,<8.5 | [guzzle-3-repo]: https://github.com/guzzle/guzzle3 [guzzle-4-repo]: https://github.com/guzzle/guzzle/tree/4.x diff --git a/lib/guzzlehttp/guzzle/composer.json b/lib/guzzlehttp/guzzle/composer.json index 69583d7cc2..0db75a950f 100644 --- a/lib/guzzlehttp/guzzle/composer.json +++ b/lib/guzzlehttp/guzzle/composer.json @@ -50,11 +50,39 @@ "homepage": "https://github.com/Tobion" } ], + "repositories": [ + { + "type": "package", + "package": { + "name": "guzzle/client-integration-tests", + "version": "v3.0.2", + "dist": { + "url": "https://codeload.github.com/guzzle/client-integration-tests/zip/2c025848417c1135031fdf9c728ee53d0a7ceaee", + "type": "zip" + }, + "require": { + "php": "^7.2.5 || ^8.0", + "phpunit/phpunit": "^7.5.20 || ^8.5.8 || ^9.3.11", + "php-http/message": "^1.0 || ^2.0", + "guzzlehttp/psr7": "^1.7 || ^2.0", + "th3n3rd/cartesian-product": "^0.3" + }, + "autoload": { + "psr-4": { + "Http\\Client\\Tests\\": "src/" + } + }, + "bin": [ + "bin/http_test_server" + ] + } + } + ], "require": { "php": "^7.2.5 || ^8.0", "ext-json": "*", - "guzzlehttp/promises": "^1.5.3 || ^2.0.1", - "guzzlehttp/psr7": "^1.9.1 || ^2.5.1", + "guzzlehttp/promises": "^2.3", + "guzzlehttp/psr7": "^2.8", "psr/http-client": "^1.0", "symfony/deprecation-contracts": "^2.2 || ^3.0" }, @@ -64,9 +92,9 @@ "require-dev": { "ext-curl": "*", "bamarni/composer-bin-plugin": "^1.8.2", - "php-http/client-integration-tests": "dev-master#2c025848417c1135031fdf9c728ee53d0a7ceaee as 3.0.999", + "guzzle/client-integration-tests": "3.0.2", "php-http/message-factory": "^1.1", - "phpunit/phpunit": "^8.5.36 || ^9.6.15", + "phpunit/phpunit": "^8.5.39 || ^9.6.20", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { diff --git a/lib/guzzlehttp/guzzle/src/BodySummarizer.php b/lib/guzzlehttp/guzzle/src/BodySummarizer.php index 6eca94ef97..761506dd07 100644 --- a/lib/guzzlehttp/guzzle/src/BodySummarizer.php +++ b/lib/guzzlehttp/guzzle/src/BodySummarizer.php @@ -11,7 +11,7 @@ final class BodySummarizer implements BodySummarizerInterface */ private $truncateAt; - public function __construct(int $truncateAt = null) + public function __construct(?int $truncateAt = null) { $this->truncateAt = $truncateAt; } @@ -22,7 +22,7 @@ public function __construct(int $truncateAt = null) public function summarize(MessageInterface $message): ?string { return $this->truncateAt === null - ? \GuzzleHttp\Psr7\Message::bodySummary($message) - : \GuzzleHttp\Psr7\Message::bodySummary($message, $this->truncateAt); + ? Psr7\Message::bodySummary($message) + : Psr7\Message::bodySummary($message, $this->truncateAt); } } diff --git a/lib/guzzlehttp/guzzle/src/Client.php b/lib/guzzlehttp/guzzle/src/Client.php index bc6efc90fc..c78919a4fc 100644 --- a/lib/guzzlehttp/guzzle/src/Client.php +++ b/lib/guzzlehttp/guzzle/src/Client.php @@ -52,7 +52,7 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface * * @param array $config Client configuration settings. * - * @see \GuzzleHttp\RequestOptions for a list of available request options. + * @see RequestOptions for a list of available request options. */ public function __construct(array $config = []) { @@ -202,7 +202,7 @@ public function request(string $method, $uri = '', array $options = []): Respons * * @deprecated Client::getConfig will be removed in guzzlehttp/guzzle:8.0. */ - public function getConfig(string $option = null) + public function getConfig(?string $option = null) { return $option === null ? $this->config diff --git a/lib/guzzlehttp/guzzle/src/ClientInterface.php b/lib/guzzlehttp/guzzle/src/ClientInterface.php index 1788e16ab3..6aaee61afc 100644 --- a/lib/guzzlehttp/guzzle/src/ClientInterface.php +++ b/lib/guzzlehttp/guzzle/src/ClientInterface.php @@ -80,5 +80,5 @@ public function requestAsync(string $method, $uri, array $options = []): Promise * * @deprecated ClientInterface::getConfig will be removed in guzzlehttp/guzzle:8.0. */ - public function getConfig(string $option = null); + public function getConfig(?string $option = null); } diff --git a/lib/guzzlehttp/guzzle/src/Cookie/CookieJar.php b/lib/guzzlehttp/guzzle/src/Cookie/CookieJar.php index c29b4b7e91..b616cf2ed6 100644 --- a/lib/guzzlehttp/guzzle/src/Cookie/CookieJar.php +++ b/lib/guzzlehttp/guzzle/src/Cookie/CookieJar.php @@ -103,7 +103,7 @@ public function toArray(): array }, $this->getIterator()->getArrayCopy()); } - public function clear(string $domain = null, string $path = null, string $name = null): void + public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void { if (!$domain) { $this->cookies = []; diff --git a/lib/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php b/lib/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php index 8c55cc6f70..93ada58d22 100644 --- a/lib/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php +++ b/lib/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php @@ -62,7 +62,7 @@ public function setCookie(SetCookie $cookie): bool; * @param string|null $path Clears cookies matching a domain and path * @param string|null $name Clears cookies matching a domain, path, and name */ - public function clear(string $domain = null, string $path = null, string $name = null): void; + public function clear(?string $domain = null, ?string $path = null, ?string $name = null): void; /** * Discard all sessions cookies. diff --git a/lib/guzzlehttp/guzzle/src/Cookie/SetCookie.php b/lib/guzzlehttp/guzzle/src/Cookie/SetCookie.php index c9806da882..47c4d10aea 100644 --- a/lib/guzzlehttp/guzzle/src/Cookie/SetCookie.php +++ b/lib/guzzlehttp/guzzle/src/Cookie/SetCookie.php @@ -62,6 +62,10 @@ public static function fromString(string $cookie): self if (is_numeric($value)) { $data[$search] = (int) $value; } + } elseif ($search === 'Secure' || $search === 'Discard' || $search === 'HttpOnly') { + if ($value) { + $data[$search] = true; + } } else { $data[$search] = $value; } diff --git a/lib/guzzlehttp/guzzle/src/Exception/BadResponseException.php b/lib/guzzlehttp/guzzle/src/Exception/BadResponseException.php index a80956c9d2..ba67ad498c 100644 --- a/lib/guzzlehttp/guzzle/src/Exception/BadResponseException.php +++ b/lib/guzzlehttp/guzzle/src/Exception/BadResponseException.php @@ -14,7 +14,7 @@ public function __construct( string $message, RequestInterface $request, ResponseInterface $response, - \Throwable $previous = null, + ?\Throwable $previous = null, array $handlerContext = [] ) { parent::__construct($message, $request, $response, $previous, $handlerContext); diff --git a/lib/guzzlehttp/guzzle/src/Exception/ConnectException.php b/lib/guzzlehttp/guzzle/src/Exception/ConnectException.php index e1a31519cf..eab51ca177 100644 --- a/lib/guzzlehttp/guzzle/src/Exception/ConnectException.php +++ b/lib/guzzlehttp/guzzle/src/Exception/ConnectException.php @@ -25,7 +25,7 @@ class ConnectException extends TransferException implements NetworkExceptionInte public function __construct( string $message, RequestInterface $request, - \Throwable $previous = null, + ?\Throwable $previous = null, array $handlerContext = [] ) { parent::__construct($message, 0, $previous); diff --git a/lib/guzzlehttp/guzzle/src/Exception/RequestException.php b/lib/guzzlehttp/guzzle/src/Exception/RequestException.php index c2d0a9cccf..b42c88abfa 100644 --- a/lib/guzzlehttp/guzzle/src/Exception/RequestException.php +++ b/lib/guzzlehttp/guzzle/src/Exception/RequestException.php @@ -7,7 +7,6 @@ use Psr\Http\Client\RequestExceptionInterface; use Psr\Http\Message\RequestInterface; use Psr\Http\Message\ResponseInterface; -use Psr\Http\Message\UriInterface; /** * HTTP Request exception @@ -32,8 +31,8 @@ class RequestException extends TransferException implements RequestExceptionInte public function __construct( string $message, RequestInterface $request, - ResponseInterface $response = null, - \Throwable $previous = null, + ?ResponseInterface $response = null, + ?\Throwable $previous = null, array $handlerContext = [] ) { // Set the code of the exception if the response is set and not future. @@ -63,10 +62,10 @@ public static function wrapException(RequestInterface $request, \Throwable $e): */ public static function create( RequestInterface $request, - ResponseInterface $response = null, - \Throwable $previous = null, + ?ResponseInterface $response = null, + ?\Throwable $previous = null, array $handlerContext = [], - BodySummarizerInterface $bodySummarizer = null + ?BodySummarizerInterface $bodySummarizer = null ): self { if (!$response) { return new self( @@ -90,8 +89,7 @@ public static function create( $className = __CLASS__; } - $uri = $request->getUri(); - $uri = static::obfuscateUri($uri); + $uri = \GuzzleHttp\Psr7\Utils::redactUserInfo($request->getUri()); // Client Error: `GET /` resulted in a `404 Not Found` response: // ... (truncated) @@ -113,20 +111,6 @@ public static function create( return new $className($message, $request, $response, $previous, $handlerContext); } - /** - * Obfuscates URI if there is a username and a password present - */ - private static function obfuscateUri(UriInterface $uri): UriInterface - { - $userInfo = $uri->getUserInfo(); - - if (false !== ($pos = \strpos($userInfo, ':'))) { - return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***'); - } - - return $uri; - } - /** * Get the request that caused the exception */ diff --git a/lib/guzzlehttp/guzzle/src/Handler/CurlFactory.php b/lib/guzzlehttp/guzzle/src/Handler/CurlFactory.php index 16a9422321..3c1fa9c13f 100644 --- a/lib/guzzlehttp/guzzle/src/Handler/CurlFactory.php +++ b/lib/guzzlehttp/guzzle/src/Handler/CurlFactory.php @@ -11,6 +11,7 @@ use GuzzleHttp\TransferStats; use GuzzleHttp\Utils; use Psr\Http\Message\RequestInterface; +use Psr\Http\Message\UriInterface; /** * Creates curl resources from a request @@ -46,6 +47,16 @@ public function __construct(int $maxHandles) public function create(RequestInterface $request, array $options): EasyHandle { + $protocolVersion = $request->getProtocolVersion(); + + if ('2' === $protocolVersion || '2.0' === $protocolVersion) { + if (!self::supportsHttp2()) { + throw new ConnectException('HTTP/2 is supported by the cURL handler, however libcurl is built without HTTP/2 support.', $request); + } + } elseif ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) { + throw new ConnectException(sprintf('HTTP/%s is not supported by the cURL handler.', $protocolVersion), $request); + } + if (isset($options['curl']['body_as_string'])) { $options['_body_as_string'] = $options['curl']['body_as_string']; unset($options['curl']['body_as_string']); @@ -72,13 +83,51 @@ public function create(RequestInterface $request, array $options): EasyHandle return $easy; } + private static function supportsHttp2(): bool + { + static $supportsHttp2 = null; + + if (null === $supportsHttp2) { + $supportsHttp2 = self::supportsTls12() + && defined('CURL_VERSION_HTTP2') + && (\CURL_VERSION_HTTP2 & \curl_version()['features']); + } + + return $supportsHttp2; + } + + private static function supportsTls12(): bool + { + static $supportsTls12 = null; + + if (null === $supportsTls12) { + $supportsTls12 = \CURL_SSLVERSION_TLSv1_2 & \curl_version()['features']; + } + + return $supportsTls12; + } + + private static function supportsTls13(): bool + { + static $supportsTls13 = null; + + if (null === $supportsTls13) { + $supportsTls13 = defined('CURL_SSLVERSION_TLSv1_3') + && (\CURL_SSLVERSION_TLSv1_3 & \curl_version()['features']); + } + + return $supportsTls13; + } + public function release(EasyHandle $easy): void { $resource = $easy->handle; unset($easy->handle); if (\count($this->handles) >= $this->maxHandles) { - \curl_close($resource); + if (PHP_VERSION_ID < 80000) { + \curl_close($resource); + } } else { // Remove all callback functions as they can hold onto references // and are not cleaned up by curl_reset. Using curl_setopt_array @@ -147,7 +196,7 @@ private static function finishError(callable $handler, EasyHandle $easy, CurlFac 'error' => \curl_error($easy->handle), 'appconnect_time' => \curl_getinfo($easy->handle, \CURLINFO_APPCONNECT_TIME), ] + \curl_getinfo($easy->handle); - $ctx[self::CURL_VERSION_STR] = \curl_version()['version']; + $ctx[self::CURL_VERSION_STR] = self::getCurlVersion(); $factory->release($easy); // Retry when nothing is present or when curl failed to rewind. @@ -158,6 +207,17 @@ private static function finishError(callable $handler, EasyHandle $easy, CurlFac return self::createRejection($easy, $ctx); } + private static function getCurlVersion(): string + { + static $curlVersion = null; + + if (null === $curlVersion) { + $curlVersion = \curl_version()['version']; + } + + return $curlVersion; + } + private static function createRejection(EasyHandle $easy, array $ctx): PromiseInterface { static $connectionErrors = [ @@ -194,15 +254,22 @@ private static function createRejection(EasyHandle $easy, array $ctx): PromiseIn ); } + $uri = $easy->request->getUri(); + + $sanitizedError = self::sanitizeCurlError($ctx['error'] ?? '', $uri); + $message = \sprintf( 'cURL error %s: %s (%s)', $ctx['errno'], - $ctx['error'], + $sanitizedError, 'see https://curl.haxx.se/libcurl/c/libcurl-errors.html' ); - $uriString = (string) $easy->request->getUri(); - if ($uriString !== '' && false === \strpos($ctx['error'], $uriString)) { - $message .= \sprintf(' for %s', $uriString); + + if ('' !== $sanitizedError) { + $redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($uri)->__toString(); + if ($redactedUriString !== '' && false === \strpos($sanitizedError, $redactedUriString)) { + $message .= \sprintf(' for %s', $redactedUriString); + } } // Create a connection exception if it was a specific error code. @@ -213,6 +280,24 @@ private static function createRejection(EasyHandle $easy, array $ctx): PromiseIn return P\Create::rejectionFor($error); } + private static function sanitizeCurlError(string $error, UriInterface $uri): string + { + if ('' === $error) { + return $error; + } + + $baseUri = $uri->withQuery('')->withFragment(''); + $baseUriString = $baseUri->__toString(); + + if ('' === $baseUriString) { + return $error; + } + + $redactedUriString = \GuzzleHttp\Psr7\Utils::redactUserInfo($baseUri)->__toString(); + + return str_replace($baseUriString, $redactedUriString, $error); + } + /** * @return array */ @@ -232,10 +317,11 @@ private function getDefaultConf(EasyHandle $easy): array } $version = $easy->request->getProtocolVersion(); - if ($version == 1.1) { - $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; - } elseif ($version == 2.0) { + + if ('2' === $version || '2.0' === $version) { $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_2_0; + } elseif ('1.1' === $version) { + $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_1; } else { $conf[\CURLOPT_HTTP_VERSION] = \CURL_HTTP_VERSION_1_0; } @@ -390,8 +476,10 @@ private function applyHandlerOptions(EasyHandle $easy, array &$conf): void // The empty string enables all available decoders and implicitly // sets a matching 'Accept-Encoding' header. $conf[\CURLOPT_ENCODING] = ''; - // But as the user did not specify any acceptable encodings we need - // to overwrite this implicit header with an empty one. + // But as the user did not specify any encoding preference, + // let's leave it up to server by preventing curl from sending + // the header, which will be interpreted as 'Accept-Encoding: *'. + // https://www.rfc-editor.org/rfc/rfc9110#field.accept-encoding $conf[\CURLOPT_HTTPHEADER][] = 'Accept-Encoding:'; } } @@ -455,23 +543,35 @@ private function applyHandlerOptions(EasyHandle $easy, array &$conf): void } if (isset($options['crypto_method'])) { - if (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) { - if (!defined('CURL_SSLVERSION_TLSv1_0')) { - throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.0 not supported by your version of cURL'); + $protocolVersion = $easy->request->getProtocolVersion(); + + // If HTTP/2, upgrade TLS 1.0 and 1.1 to 1.2 + if ('2' === $protocolVersion || '2.0' === $protocolVersion) { + if ( + \STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method'] + || \STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method'] + || \STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method'] + ) { + $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2; + } elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) { + if (!self::supportsTls13()) { + throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL'); + } + $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3; + } else { + throw new \InvalidArgumentException('Invalid crypto_method request option: unknown version provided'); } + } elseif (\STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT === $options['crypto_method']) { $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_0; } elseif (\STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT === $options['crypto_method']) { - if (!defined('CURL_SSLVERSION_TLSv1_1')) { - throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.1 not supported by your version of cURL'); - } $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_1; } elseif (\STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT === $options['crypto_method']) { - if (!defined('CURL_SSLVERSION_TLSv1_2')) { + if (!self::supportsTls12()) { throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.2 not supported by your version of cURL'); } $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_2; } elseif (defined('STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT') && \STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT === $options['crypto_method']) { - if (!defined('CURL_SSLVERSION_TLSv1_3')) { + if (!self::supportsTls13()) { throw new \InvalidArgumentException('Invalid crypto_method request option: TLS 1.3 not supported by your version of cURL'); } $conf[\CURLOPT_SSLVERSION] = \CURL_SSLVERSION_TLSv1_3; @@ -631,7 +731,10 @@ private function createHeaderFn(EasyHandle $easy): callable public function __destruct() { foreach ($this->handles as $id => $handle) { - \curl_close($handle); + if (PHP_VERSION_ID < 80000) { + \curl_close($handle); + } + unset($this->handles[$id]); } } diff --git a/lib/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php b/lib/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php index a64e1821a9..21abbedf35 100644 --- a/lib/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php +++ b/lib/guzzlehttp/guzzle/src/Handler/CurlMultiHandler.php @@ -2,6 +2,7 @@ namespace GuzzleHttp\Handler; +use Closure; use GuzzleHttp\Promise as P; use GuzzleHttp\Promise\Promise; use GuzzleHttp\Promise\PromiseInterface; @@ -159,6 +160,9 @@ public function tick(): void } } + // Run curl_multi_exec in the queue to enable other async tasks to run + P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue'])); + // Step through the task queue which may add additional requests. P\Utils::queue()->run(); @@ -169,11 +173,24 @@ public function tick(): void } while (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) { + // Prevent busy looping for slow HTTP requests. + \curl_multi_select($this->_mh, $this->selectTimeout); } $this->processMessages(); } + /** + * Runs \curl_multi_exec() inside the event loop, to prevent busy looping + */ + private function tickInQueue(): void + { + if (\curl_multi_exec($this->_mh, $this->active) === \CURLM_CALL_MULTI_PERFORM) { + \curl_multi_select($this->_mh, 0); + P\Utils::queue()->add(Closure::fromCallable([$this, 'tickInQueue'])); + } + } + /** * Runs until all outstanding connections have completed. */ @@ -223,7 +240,10 @@ private function cancel($id): bool $handle = $this->handles[$id]['easy']->handle; unset($this->delays[$id], $this->handles[$id]); \curl_multi_remove_handle($this->_mh, $handle); - \curl_close($handle); + + if (PHP_VERSION_ID < 80000) { + \curl_close($handle); + } return true; } diff --git a/lib/guzzlehttp/guzzle/src/Handler/MockHandler.php b/lib/guzzlehttp/guzzle/src/Handler/MockHandler.php index 77ffed5210..3ecd5964de 100644 --- a/lib/guzzlehttp/guzzle/src/Handler/MockHandler.php +++ b/lib/guzzlehttp/guzzle/src/Handler/MockHandler.php @@ -52,21 +52,21 @@ class MockHandler implements \Countable * @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled. * @param callable|null $onRejected Callback to invoke when the return value is rejected. */ - public static function createWithMiddleware(array $queue = null, callable $onFulfilled = null, callable $onRejected = null): HandlerStack + public static function createWithMiddleware(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null): HandlerStack { return HandlerStack::create(new self($queue, $onFulfilled, $onRejected)); } /** * The passed in value must be an array of - * {@see \Psr\Http\Message\ResponseInterface} objects, Exceptions, + * {@see ResponseInterface} objects, Exceptions, * callables, or Promises. * * @param array|null $queue The parameters to be passed to the append function, as an indexed array. * @param callable|null $onFulfilled Callback to invoke when the return value is fulfilled. * @param callable|null $onRejected Callback to invoke when the return value is rejected. */ - public function __construct(array $queue = null, callable $onFulfilled = null, callable $onRejected = null) + public function __construct(?array $queue = null, ?callable $onFulfilled = null, ?callable $onRejected = null) { $this->onFulfilled = $onFulfilled; $this->onRejected = $onRejected; @@ -200,7 +200,7 @@ public function reset(): void private function invokeStats( RequestInterface $request, array $options, - ResponseInterface $response = null, + ?ResponseInterface $response = null, $reason = null ): void { if (isset($options['on_stats'])) { diff --git a/lib/guzzlehttp/guzzle/src/Handler/Proxy.php b/lib/guzzlehttp/guzzle/src/Handler/Proxy.php index f045b526c5..9df70cf23b 100644 --- a/lib/guzzlehttp/guzzle/src/Handler/Proxy.php +++ b/lib/guzzlehttp/guzzle/src/Handler/Proxy.php @@ -17,10 +17,10 @@ class Proxy * Sends synchronous requests to a specific handler while sending all other * requests to another handler. * - * @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for normal responses - * @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $sync Handler used for synchronous responses. + * @param callable(RequestInterface, array): PromiseInterface $default Handler used for normal responses + * @param callable(RequestInterface, array): PromiseInterface $sync Handler used for synchronous responses. * - * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler. + * @return callable(RequestInterface, array): PromiseInterface Returns the composed handler. */ public static function wrapSync(callable $default, callable $sync): callable { @@ -37,10 +37,10 @@ public static function wrapSync(callable $default, callable $sync): callable * performance benefits of curl while still supporting true streaming * through the StreamHandler. * - * @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $default Handler used for non-streaming responses - * @param callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface $streaming Handler used for streaming responses + * @param callable(RequestInterface, array): PromiseInterface $default Handler used for non-streaming responses + * @param callable(RequestInterface, array): PromiseInterface $streaming Handler used for streaming responses * - * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the composed handler. + * @return callable(RequestInterface, array): PromiseInterface Returns the composed handler. */ public static function wrapStreaming(callable $default, callable $streaming): callable { diff --git a/lib/guzzlehttp/guzzle/src/Handler/StreamHandler.php b/lib/guzzlehttp/guzzle/src/Handler/StreamHandler.php index 61632f5649..f24921f470 100644 --- a/lib/guzzlehttp/guzzle/src/Handler/StreamHandler.php +++ b/lib/guzzlehttp/guzzle/src/Handler/StreamHandler.php @@ -40,6 +40,12 @@ public function __invoke(RequestInterface $request, array $options): PromiseInte \usleep($options['delay'] * 1000); } + $protocolVersion = $request->getProtocolVersion(); + + if ('1.0' !== $protocolVersion && '1.1' !== $protocolVersion) { + throw new ConnectException(sprintf('HTTP/%s is not supported by the stream handler.', $protocolVersion), $request); + } + $startTime = isset($options['on_stats']) ? Utils::currentTime() : null; try { @@ -47,8 +53,14 @@ public function __invoke(RequestInterface $request, array $options): PromiseInte $request = $request->withoutHeader('Expect'); // Append a content-length header if body size is zero to match - // cURL's behavior. - if (0 === $request->getBody()->getSize()) { + // the behavior of `CurlHandler` + if ( + ( + 0 === \strcasecmp('PUT', $request->getMethod()) + || 0 === \strcasecmp('POST', $request->getMethod()) + ) + && 0 === $request->getBody()->getSize() + ) { $request = $request->withHeader('Content-Length', '0'); } @@ -83,8 +95,8 @@ private function invokeStats( array $options, RequestInterface $request, ?float $startTime, - ResponseInterface $response = null, - \Throwable $error = null + ?ResponseInterface $response = null, + ?\Throwable $error = null ): void { if (isset($options['on_stats'])) { $stats = new TransferStats($request, $response, Utils::currentTime() - $startTime, $error, []); @@ -273,7 +285,7 @@ private function createStream(RequestInterface $request, array $options) // HTTP/1.1 streams using the PHP stream wrapper require a // Connection: close header - if ($request->getProtocolVersion() == '1.1' + if ($request->getProtocolVersion() === '1.1' && !$request->hasHeader('Connection') ) { $request = $request->withHeader('Connection', 'close'); @@ -321,8 +333,15 @@ static function () use ($context, $params) { ); return $this->createResource( - function () use ($uri, &$http_response_header, $contextResource, $context, $options, $request) { + function () use ($uri, $contextResource, $context, $options, $request) { $resource = @\fopen((string) $uri, 'r', false, $contextResource); + + // See https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_the_http_response_header_predefined_variable + if (function_exists('http_get_last_response_headers')) { + /** @var array|null */ + $http_response_header = \http_get_last_response_headers(); + } + $this->lastHeaders = $http_response_header ?? []; if (false === $resource) { diff --git a/lib/guzzlehttp/guzzle/src/HandlerStack.php b/lib/guzzlehttp/guzzle/src/HandlerStack.php index 6cb12f07ab..03f9a18ffd 100644 --- a/lib/guzzlehttp/guzzle/src/HandlerStack.php +++ b/lib/guzzlehttp/guzzle/src/HandlerStack.php @@ -44,7 +44,7 @@ class HandlerStack * handler is provided, the best handler for your * system will be utilized. */ - public static function create(callable $handler = null): self + public static function create(?callable $handler = null): self { $stack = new self($handler ?: Utils::chooseHandler()); $stack->push(Middleware::httpErrors(), 'http_errors'); @@ -58,7 +58,7 @@ public static function create(callable $handler = null): self /** * @param (callable(RequestInterface, array): PromiseInterface)|null $handler Underlying HTTP handler. */ - public function __construct(callable $handler = null) + public function __construct(?callable $handler = null) { $this->handler = $handler; } @@ -131,7 +131,7 @@ public function hasHandler(): bool * @param callable(callable): callable $middleware Middleware function * @param string $name Name to register for this middleware. */ - public function unshift(callable $middleware, string $name = null): void + public function unshift(callable $middleware, ?string $name = null): void { \array_unshift($this->stack, [$middleware, $name]); $this->cached = null; diff --git a/lib/guzzlehttp/guzzle/src/MessageFormatter.php b/lib/guzzlehttp/guzzle/src/MessageFormatter.php index 04e9eb37a4..9b77eee832 100644 --- a/lib/guzzlehttp/guzzle/src/MessageFormatter.php +++ b/lib/guzzlehttp/guzzle/src/MessageFormatter.php @@ -68,7 +68,7 @@ public function __construct(?string $template = self::CLF) * @param ResponseInterface|null $response Response that was received * @param \Throwable|null $error Exception that was received */ - public function format(RequestInterface $request, ResponseInterface $response = null, \Throwable $error = null): string + public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string { $cache = []; diff --git a/lib/guzzlehttp/guzzle/src/MessageFormatterInterface.php b/lib/guzzlehttp/guzzle/src/MessageFormatterInterface.php index 47934614a0..a39ac248ee 100644 --- a/lib/guzzlehttp/guzzle/src/MessageFormatterInterface.php +++ b/lib/guzzlehttp/guzzle/src/MessageFormatterInterface.php @@ -14,5 +14,5 @@ interface MessageFormatterInterface * @param ResponseInterface|null $response Response that was received * @param \Throwable|null $error Exception that was received */ - public function format(RequestInterface $request, ResponseInterface $response = null, \Throwable $error = null): string; + public function format(RequestInterface $request, ?ResponseInterface $response = null, ?\Throwable $error = null): string; } diff --git a/lib/guzzlehttp/guzzle/src/Middleware.php b/lib/guzzlehttp/guzzle/src/Middleware.php index 7e3eb6b3a0..9901da44a6 100644 --- a/lib/guzzlehttp/guzzle/src/Middleware.php +++ b/lib/guzzlehttp/guzzle/src/Middleware.php @@ -55,7 +55,7 @@ static function (ResponseInterface $response) use ($cookieJar, $request): Respon * * @return callable(callable): callable Returns a function that accepts the next handler. */ - public static function httpErrors(BodySummarizerInterface $bodySummarizer = null): callable + public static function httpErrors(?BodySummarizerInterface $bodySummarizer = null): callable { return static function (callable $handler) use ($bodySummarizer): callable { return static function ($request, array $options) use ($handler, $bodySummarizer) { @@ -132,7 +132,7 @@ static function ($reason) use ($request, &$container, $options) { * * @return callable Returns a function that accepts the next handler. */ - public static function tap(callable $before = null, callable $after = null): callable + public static function tap(?callable $before = null, ?callable $after = null): callable { return static function (callable $handler) use ($before, $after): callable { return static function (RequestInterface $request, array $options) use ($handler, $before, $after) { @@ -176,7 +176,7 @@ public static function redirect(): callable * * @return callable Returns a function that accepts the next handler. */ - public static function retry(callable $decider, callable $delay = null): callable + public static function retry(callable $decider, ?callable $delay = null): callable { return static function (callable $handler) use ($decider, $delay): RetryMiddleware { return new RetryMiddleware($decider, $handler, $delay); @@ -187,12 +187,12 @@ public static function retry(callable $decider, callable $delay = null): callabl * Middleware that logs requests, responses, and errors using a message * formatter. * - * @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests. - * * @param LoggerInterface $logger Logs messages. * @param MessageFormatterInterface|MessageFormatter $formatter Formatter used to create message strings. * @param string $logLevel Level at which to log requests. * + * @phpstan-param \Psr\Log\LogLevel::* $logLevel Level at which to log requests. + * * @return callable Returns a function that accepts the next handler. */ public static function log(LoggerInterface $logger, $formatter, string $logLevel = 'info'): callable diff --git a/lib/guzzlehttp/guzzle/src/Pool.php b/lib/guzzlehttp/guzzle/src/Pool.php index 6277c61fbc..ddc304bb1b 100644 --- a/lib/guzzlehttp/guzzle/src/Pool.php +++ b/lib/guzzlehttp/guzzle/src/Pool.php @@ -86,7 +86,7 @@ public function promise(): PromiseInterface * @param ClientInterface $client Client used to send the requests * @param array|\Iterator $requests Requests to send concurrently. * @param array $options Passes through the options available in - * {@see \GuzzleHttp\Pool::__construct} + * {@see Pool::__construct} * * @return array Returns an array containing the response or an exception * in the same order that the requests were sent. diff --git a/lib/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php b/lib/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php index 0a8de81289..7dde6c5f46 100644 --- a/lib/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php +++ b/lib/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php @@ -76,8 +76,8 @@ private function addExpectHeader(RequestInterface $request, array $options, arra $expect = $options['expect'] ?? null; - // Return if disabled or if you're not using HTTP/1.1 or HTTP/2.0 - if ($expect === false || $request->getProtocolVersion() < 1.1) { + // Return if disabled or using HTTP/1.0 + if ($expect === false || $request->getProtocolVersion() === '1.0') { return; } diff --git a/lib/guzzlehttp/guzzle/src/RequestOptions.php b/lib/guzzlehttp/guzzle/src/RequestOptions.php index a38768c0c1..84a3500e44 100644 --- a/lib/guzzlehttp/guzzle/src/RequestOptions.php +++ b/lib/guzzlehttp/guzzle/src/RequestOptions.php @@ -61,7 +61,7 @@ final class RequestOptions * Specifies whether or not cookies are used in a request or what cookie * jar to use or what cookies to send. This option only works if your * handler has the `cookie` middleware. Valid values are `false` and - * an instance of {@see \GuzzleHttp\Cookie\CookieJarInterface}. + * an instance of {@see Cookie\CookieJarInterface}. */ public const COOKIES = 'cookies'; diff --git a/lib/guzzlehttp/guzzle/src/RetryMiddleware.php b/lib/guzzlehttp/guzzle/src/RetryMiddleware.php index 8f4d93ac44..65f49cb759 100644 --- a/lib/guzzlehttp/guzzle/src/RetryMiddleware.php +++ b/lib/guzzlehttp/guzzle/src/RetryMiddleware.php @@ -40,7 +40,7 @@ class RetryMiddleware * and returns the number of * milliseconds to delay. */ - public function __construct(callable $decider, callable $nextHandler, callable $delay = null) + public function __construct(callable $decider, callable $nextHandler, ?callable $delay = null) { $this->decider = $decider; $this->nextHandler = $nextHandler; @@ -110,7 +110,7 @@ private function onRejected(RequestInterface $req, array $options): callable }; } - private function doRetry(RequestInterface $request, array $options, ResponseInterface $response = null): PromiseInterface + private function doRetry(RequestInterface $request, array $options, ?ResponseInterface $response = null): PromiseInterface { $options['delay'] = ($this->delay)(++$options['retries'], $response, $request); diff --git a/lib/guzzlehttp/guzzle/src/TransferStats.php b/lib/guzzlehttp/guzzle/src/TransferStats.php index 2ce9e38f27..93fa334c8d 100644 --- a/lib/guzzlehttp/guzzle/src/TransferStats.php +++ b/lib/guzzlehttp/guzzle/src/TransferStats.php @@ -46,8 +46,8 @@ final class TransferStats */ public function __construct( RequestInterface $request, - ResponseInterface $response = null, - float $transferTime = null, + ?ResponseInterface $response = null, + ?float $transferTime = null, $handlerErrorData = null, array $handlerStats = [] ) { diff --git a/lib/guzzlehttp/guzzle/src/Utils.php b/lib/guzzlehttp/guzzle/src/Utils.php index 93d6d39cd9..c6a5893dda 100644 --- a/lib/guzzlehttp/guzzle/src/Utils.php +++ b/lib/guzzlehttp/guzzle/src/Utils.php @@ -71,7 +71,7 @@ public static function debugResource($value = null) return \STDOUT; } - return \GuzzleHttp\Psr7\Utils::tryFopen('php://output', 'w'); + return Psr7\Utils::tryFopen('php://output', 'w'); } /** @@ -79,7 +79,7 @@ public static function debugResource($value = null) * * The returned handler is not wrapped by any default middlewares. * - * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system. + * @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system. * * @throws \RuntimeException if no viable Handler is available. */ @@ -87,7 +87,7 @@ public static function chooseHandler(): callable { $handler = null; - if (\defined('CURLOPT_CUSTOMREQUEST')) { + if (\defined('CURLOPT_CUSTOMREQUEST') && \function_exists('curl_version') && version_compare(curl_version()['version'], '7.21.2') >= 0) { if (\function_exists('curl_multi_exec') && \function_exists('curl_exec')) { $handler = Proxy::wrapSync(new CurlMultiHandler(), new CurlHandler()); } elseif (\function_exists('curl_exec')) { diff --git a/lib/guzzlehttp/guzzle/src/functions.php b/lib/guzzlehttp/guzzle/src/functions.php index 5edc66ab1c..9ab4b96499 100644 --- a/lib/guzzlehttp/guzzle/src/functions.php +++ b/lib/guzzlehttp/guzzle/src/functions.php @@ -50,7 +50,7 @@ function debug_resource($value = null) * * The returned handler is not wrapped by any default middlewares. * - * @return callable(\Psr\Http\Message\RequestInterface, array): \GuzzleHttp\Promise\PromiseInterface Returns the best handler for the given system. + * @return callable(\Psr\Http\Message\RequestInterface, array): Promise\PromiseInterface Returns the best handler for the given system. * * @throws \RuntimeException if no viable Handler is available. * diff --git a/lib/guzzlehttp/promises/CHANGELOG.md b/lib/guzzlehttp/promises/CHANGELOG.md index c73afb903d..7df9c0ae6f 100644 --- a/lib/guzzlehttp/promises/CHANGELOG.md +++ b/lib/guzzlehttp/promises/CHANGELOG.md @@ -1,6 +1,41 @@ # CHANGELOG +## 2.3.0 - 2025-08-22 + +### Added + +- PHP 8.5 support + + +## 2.2.0 - 2025-03-27 + +### Fixed + +- Revert "Allow an empty EachPromise to be resolved by running the queue" + + +## 2.1.0 - 2025-03-27 + +### Added + +- Allow an empty EachPromise to be resolved by running the queue + + +## 2.0.4 - 2024-10-17 + +### Fixed + +- Once settled, don't allow further rejection of additional promises + + +## 2.0.3 - 2024-07-18 + +### Changed + +- PHP 8.4 support + + ## 2.0.2 - 2023-12-03 ### Changed diff --git a/lib/guzzlehttp/promises/README.md b/lib/guzzlehttp/promises/README.md index a32d3d29c7..493a9315b5 100644 --- a/lib/guzzlehttp/promises/README.md +++ b/lib/guzzlehttp/promises/README.md @@ -38,10 +38,10 @@ composer require guzzlehttp/promises ## Version Guidance -| Version | Status | PHP Version | -|---------|------------------------|--------------| -| 1.x | Bug and security fixes | >=5.5,<8.3 | -| 2.x | Latest | >=7.2.5,<8.4 | +| Version | Status | PHP Version | +|---------|---------------------|--------------| +| 1.x | Security fixes only | >=5.5,<8.3 | +| 2.x | Latest | >=7.2.5,<8.6 | ## Quick Start diff --git a/lib/guzzlehttp/promises/composer.json b/lib/guzzlehttp/promises/composer.json index 6c5bdd662a..9d6e85678b 100644 --- a/lib/guzzlehttp/promises/composer.json +++ b/lib/guzzlehttp/promises/composer.json @@ -30,7 +30,7 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "autoload": { "psr-4": { diff --git a/lib/guzzlehttp/promises/src/Coroutine.php b/lib/guzzlehttp/promises/src/Coroutine.php index 0b5b9c0a40..0da0228344 100644 --- a/lib/guzzlehttp/promises/src/Coroutine.php +++ b/lib/guzzlehttp/promises/src/Coroutine.php @@ -84,8 +84,8 @@ public static function of(callable $generatorFn): self } public function then( - callable $onFulfilled = null, - callable $onRejected = null + ?callable $onFulfilled = null, + ?callable $onRejected = null ): PromiseInterface { return $this->result->then($onFulfilled, $onRejected); } diff --git a/lib/guzzlehttp/promises/src/Each.php b/lib/guzzlehttp/promises/src/Each.php index c09d23c60b..dd72c8310b 100644 --- a/lib/guzzlehttp/promises/src/Each.php +++ b/lib/guzzlehttp/promises/src/Each.php @@ -23,8 +23,8 @@ final class Each */ public static function of( $iterable, - callable $onFulfilled = null, - callable $onRejected = null + ?callable $onFulfilled = null, + ?callable $onRejected = null ): PromiseInterface { return (new EachPromise($iterable, [ 'fulfilled' => $onFulfilled, @@ -46,8 +46,8 @@ public static function of( public static function ofLimit( $iterable, $concurrency, - callable $onFulfilled = null, - callable $onRejected = null + ?callable $onFulfilled = null, + ?callable $onRejected = null ): PromiseInterface { return (new EachPromise($iterable, [ 'fulfilled' => $onFulfilled, @@ -67,7 +67,7 @@ public static function ofLimit( public static function ofLimitAll( $iterable, $concurrency, - callable $onFulfilled = null + ?callable $onFulfilled = null ): PromiseInterface { return self::ofLimit( $iterable, diff --git a/lib/guzzlehttp/promises/src/FulfilledPromise.php b/lib/guzzlehttp/promises/src/FulfilledPromise.php index ab7129659d..727ec315c4 100644 --- a/lib/guzzlehttp/promises/src/FulfilledPromise.php +++ b/lib/guzzlehttp/promises/src/FulfilledPromise.php @@ -31,8 +31,8 @@ public function __construct($value) } public function then( - callable $onFulfilled = null, - callable $onRejected = null + ?callable $onFulfilled = null, + ?callable $onRejected = null ): PromiseInterface { // Return itself if there is no onFulfilled function. if (!$onFulfilled) { diff --git a/lib/guzzlehttp/promises/src/Promise.php b/lib/guzzlehttp/promises/src/Promise.php index 1b07bdc9a1..c0c5be2c09 100644 --- a/lib/guzzlehttp/promises/src/Promise.php +++ b/lib/guzzlehttp/promises/src/Promise.php @@ -25,16 +25,16 @@ class Promise implements PromiseInterface * @param callable $cancelFn Fn that when invoked cancels the promise. */ public function __construct( - callable $waitFn = null, - callable $cancelFn = null + ?callable $waitFn = null, + ?callable $cancelFn = null ) { $this->waitFn = $waitFn; $this->cancelFn = $cancelFn; } public function then( - callable $onFulfilled = null, - callable $onRejected = null + ?callable $onFulfilled = null, + ?callable $onRejected = null ): PromiseInterface { if ($this->state === self::PENDING) { $p = new Promise(null, [$this, 'cancel']); diff --git a/lib/guzzlehttp/promises/src/PromiseInterface.php b/lib/guzzlehttp/promises/src/PromiseInterface.php index 2824802bb2..c11721e4d9 100644 --- a/lib/guzzlehttp/promises/src/PromiseInterface.php +++ b/lib/guzzlehttp/promises/src/PromiseInterface.php @@ -27,8 +27,8 @@ interface PromiseInterface * @param callable $onRejected Invoked when the promise is rejected. */ public function then( - callable $onFulfilled = null, - callable $onRejected = null + ?callable $onFulfilled = null, + ?callable $onRejected = null ): PromiseInterface; /** diff --git a/lib/guzzlehttp/promises/src/RejectedPromise.php b/lib/guzzlehttp/promises/src/RejectedPromise.php index d947da1f50..1ebf0b2a62 100644 --- a/lib/guzzlehttp/promises/src/RejectedPromise.php +++ b/lib/guzzlehttp/promises/src/RejectedPromise.php @@ -31,8 +31,8 @@ public function __construct($reason) } public function then( - callable $onFulfilled = null, - callable $onRejected = null + ?callable $onFulfilled = null, + ?callable $onRejected = null ): PromiseInterface { // If there's no onRejected callback then just return self. if (!$onRejected) { diff --git a/lib/guzzlehttp/promises/src/RejectionException.php b/lib/guzzlehttp/promises/src/RejectionException.php index 72a81ba20d..47dca86248 100644 --- a/lib/guzzlehttp/promises/src/RejectionException.php +++ b/lib/guzzlehttp/promises/src/RejectionException.php @@ -18,7 +18,7 @@ class RejectionException extends \RuntimeException * @param mixed $reason Rejection reason. * @param string|null $description Optional description. */ - public function __construct($reason, string $description = null) + public function __construct($reason, ?string $description = null) { $this->reason = $reason; diff --git a/lib/guzzlehttp/promises/src/Utils.php b/lib/guzzlehttp/promises/src/Utils.php index e1570d727a..3193d2a120 100644 --- a/lib/guzzlehttp/promises/src/Utils.php +++ b/lib/guzzlehttp/promises/src/Utils.php @@ -21,7 +21,7 @@ final class Utils * * @param TaskQueueInterface|null $assign Optionally specify a new queue instance. */ - public static function queue(TaskQueueInterface $assign = null): TaskQueueInterface + public static function queue(?TaskQueueInterface $assign = null): TaskQueueInterface { static $queue; @@ -144,7 +144,9 @@ function ($value, $idx) use (&$results): void { $results[$idx] = $value; }, function ($reason, $idx, Promise $aggregate): void { - $aggregate->reject($reason); + if (Is::pending($aggregate)) { + $aggregate->reject($reason); + } } )->then(function () use (&$results) { ksort($results); diff --git a/lib/guzzlehttp/psr7/CHANGELOG.md b/lib/guzzlehttp/psr7/CHANGELOG.md index fe3eda70ab..4a2a121941 100644 --- a/lib/guzzlehttp/psr7/CHANGELOG.md +++ b/lib/guzzlehttp/psr7/CHANGELOG.md @@ -5,6 +5,43 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## 2.8.0 - 2025-08-23 + +### Added + +- Allow empty lists as header values + +### Changed + +- PHP 8.5 support + +## 2.7.1 - 2025-03-27 + +### Fixed + +- Fixed uppercase IPv6 addresses in URI + +### Changed + +- Improve uploaded file error message + +## 2.7.0 - 2024-07-18 + +### Added + +- Add `Utils::redactUserInfo()` method +- Add ability to encode bools as ints in `Query::build` + +## 2.6.3 - 2024-07-18 + +### Fixed + +- Make `StreamWrapper::stream_stat()` return `false` if inner stream's size is `null` + +### Changed + +- PHP 8.4 support + ## 2.6.2 - 2023-12-03 ### Fixed diff --git a/lib/guzzlehttp/psr7/README.md b/lib/guzzlehttp/psr7/README.md index 850fa9d70e..24aad86051 100644 --- a/lib/guzzlehttp/psr7/README.md +++ b/lib/guzzlehttp/psr7/README.md @@ -24,8 +24,8 @@ composer require guzzlehttp/psr7 | Version | Status | PHP Version | |---------|---------------------|--------------| -| 1.x | Security fixes only | >=5.4,<8.1 | -| 2.x | Latest | >=7.2.5,<8.4 | +| 1.x | EOL (2024-06-30) | >=5.4,<8.2 | +| 2.x | Latest | >=7.2.5,<8.6 | ## AppendStream @@ -436,7 +436,7 @@ will be parsed into `['foo[a]' => '1', 'foo[b]' => '2'])`. ## `GuzzleHttp\Psr7\Query::build` -`public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986): string` +`public static function build(array $params, int|false $encoding = PHP_QUERY_RFC3986, bool $treatBoolsAsInts = true): string` Build a query string from an array of key value pairs. @@ -498,11 +498,18 @@ a message. ## `GuzzleHttp\Psr7\Utils::readLine` -`public static function readLine(StreamInterface $stream, int $maxLength = null): string` +`public static function readLine(StreamInterface $stream, ?int $maxLength = null): string` Read a line from the stream up to the maximum allowed buffer length. +## `GuzzleHttp\Psr7\Utils::redactUserInfo` + +`public static function redactUserInfo(UriInterface $uri): UriInterface` + +Redact the password in the user info part of a URI. + + ## `GuzzleHttp\Psr7\Utils::streamFor` `public static function streamFor(resource|string|null|int|float|bool|StreamInterface|callable|\Iterator $resource = '', array $options = []): StreamInterface` @@ -674,7 +681,7 @@ termed a relative-path reference. ### `GuzzleHttp\Psr7\Uri::isSameDocumentReference` -`public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool` +`public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null): bool` Whether the URI is a same-document reference. A same-document reference refers to a URI that is, aside from its fragment component, identical to the base URI. When no base URI is given, only an empty URI reference diff --git a/lib/guzzlehttp/psr7/composer.json b/lib/guzzlehttp/psr7/composer.json index 70293fc406..96098f536c 100644 --- a/lib/guzzlehttp/psr7/composer.json +++ b/lib/guzzlehttp/psr7/composer.json @@ -61,8 +61,8 @@ }, "require-dev": { "bamarni/composer-bin-plugin": "^1.8.2", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.36 || ^9.6.15" + "http-interop/http-factory-tests": "0.9.0", + "phpunit/phpunit": "^8.5.44 || ^9.6.25" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" diff --git a/lib/guzzlehttp/psr7/src/CachingStream.php b/lib/guzzlehttp/psr7/src/CachingStream.php index f34722cff5..7e4554d5c7 100644 --- a/lib/guzzlehttp/psr7/src/CachingStream.php +++ b/lib/guzzlehttp/psr7/src/CachingStream.php @@ -33,7 +33,7 @@ final class CachingStream implements StreamInterface */ public function __construct( StreamInterface $stream, - StreamInterface $target = null + ?StreamInterface $target = null ) { $this->remoteStream = $stream; $this->stream = $target ?: new Stream(Utils::tryFopen('php://temp', 'r+')); diff --git a/lib/guzzlehttp/psr7/src/HttpFactory.php b/lib/guzzlehttp/psr7/src/HttpFactory.php index 73d17e3378..3ef15103a7 100644 --- a/lib/guzzlehttp/psr7/src/HttpFactory.php +++ b/lib/guzzlehttp/psr7/src/HttpFactory.php @@ -27,10 +27,10 @@ final class HttpFactory implements RequestFactoryInterface, ResponseFactoryInter { public function createUploadedFile( StreamInterface $stream, - int $size = null, + ?int $size = null, int $error = \UPLOAD_ERR_OK, - string $clientFilename = null, - string $clientMediaType = null + ?string $clientFilename = null, + ?string $clientMediaType = null ): UploadedFileInterface { if ($size === null) { $size = $stream->getSize(); diff --git a/lib/guzzlehttp/psr7/src/MessageTrait.php b/lib/guzzlehttp/psr7/src/MessageTrait.php index 65dbc4ba0a..c15ee63fc0 100644 --- a/lib/guzzlehttp/psr7/src/MessageTrait.php +++ b/lib/guzzlehttp/psr7/src/MessageTrait.php @@ -174,10 +174,6 @@ private function normalizeHeaderValue($value): array return $this->trimAndValidateHeaderValues([$value]); } - if (count($value) === 0) { - throw new \InvalidArgumentException('Header value can not be an empty array.'); - } - return $this->trimAndValidateHeaderValues($value); } diff --git a/lib/guzzlehttp/psr7/src/MultipartStream.php b/lib/guzzlehttp/psr7/src/MultipartStream.php index d23fba8a3a..43d718f658 100644 --- a/lib/guzzlehttp/psr7/src/MultipartStream.php +++ b/lib/guzzlehttp/psr7/src/MultipartStream.php @@ -32,7 +32,7 @@ final class MultipartStream implements StreamInterface * * @throws \InvalidArgumentException */ - public function __construct(array $elements = [], string $boundary = null) + public function __construct(array $elements = [], ?string $boundary = null) { $this->boundary = $boundary ?: bin2hex(random_bytes(20)); $this->stream = $this->createStream($elements); diff --git a/lib/guzzlehttp/psr7/src/Query.php b/lib/guzzlehttp/psr7/src/Query.php index 8b94927973..ccf867a0bd 100644 --- a/lib/guzzlehttp/psr7/src/Query.php +++ b/lib/guzzlehttp/psr7/src/Query.php @@ -63,12 +63,15 @@ public static function parse(string $str, $urlEncoding = true): array * string. This function does not modify the provided keys when an array is * encountered (like `http_build_query()` would). * - * @param array $params Query string parameters. - * @param int|false $encoding Set to false to not encode, PHP_QUERY_RFC3986 - * to encode using RFC3986, or PHP_QUERY_RFC1738 - * to encode using RFC1738. + * @param array $params Query string parameters. + * @param int|false $encoding Set to false to not encode, + * PHP_QUERY_RFC3986 to encode using + * RFC3986, or PHP_QUERY_RFC1738 to + * encode using RFC1738. + * @param bool $treatBoolsAsInts Set to true to encode as 0/1, and + * false as false/true. */ - public static function build(array $params, $encoding = PHP_QUERY_RFC3986): string + public static function build(array $params, $encoding = PHP_QUERY_RFC3986, bool $treatBoolsAsInts = true): string { if (!$params) { return ''; @@ -86,12 +89,14 @@ public static function build(array $params, $encoding = PHP_QUERY_RFC3986): stri throw new \InvalidArgumentException('Invalid type'); } + $castBool = $treatBoolsAsInts ? static function ($v) { return (int) $v; } : static function ($v) { return $v ? 'true' : 'false'; }; + $qs = ''; foreach ($params as $k => $v) { $k = $encoder((string) $k); if (!is_array($v)) { $qs .= $k; - $v = is_bool($v) ? (int) $v : $v; + $v = is_bool($v) ? $castBool($v) : $v; if ($v !== null) { $qs .= '='.$encoder((string) $v); } @@ -99,7 +104,7 @@ public static function build(array $params, $encoding = PHP_QUERY_RFC3986): stri } else { foreach ($v as $vv) { $qs .= $k; - $vv = is_bool($vv) ? (int) $vv : $vv; + $vv = is_bool($vv) ? $castBool($vv) : $vv; if ($vv !== null) { $qs .= '='.$encoder((string) $vv); } diff --git a/lib/guzzlehttp/psr7/src/Response.php b/lib/guzzlehttp/psr7/src/Response.php index 00f16e2d9a..34e612fda5 100644 --- a/lib/guzzlehttp/psr7/src/Response.php +++ b/lib/guzzlehttp/psr7/src/Response.php @@ -96,7 +96,7 @@ public function __construct( array $headers = [], $body = null, string $version = '1.1', - string $reason = null + ?string $reason = null ) { $this->assertStatusCodeRange($status); diff --git a/lib/guzzlehttp/psr7/src/StreamWrapper.php b/lib/guzzlehttp/psr7/src/StreamWrapper.php index ae85388142..77b04d7471 100644 --- a/lib/guzzlehttp/psr7/src/StreamWrapper.php +++ b/lib/guzzlehttp/psr7/src/StreamWrapper.php @@ -69,7 +69,7 @@ public static function register(): void } } - public function stream_open(string $path, string $mode, int $options, string &$opened_path = null): bool + public function stream_open(string $path, string $mode, int $options, ?string &$opened_path = null): bool { $options = stream_context_get_options($this->context); @@ -136,10 +136,14 @@ public function stream_cast(int $cast_as) * ctime: int, * blksize: int, * blocks: int - * } + * }|false */ - public function stream_stat(): array + public function stream_stat() { + if ($this->stream->getSize() === null) { + return false; + } + static $modeMap = [ 'r' => 33060, 'rb' => 33060, diff --git a/lib/guzzlehttp/psr7/src/UploadedFile.php b/lib/guzzlehttp/psr7/src/UploadedFile.php index b267199376..d9b779f13c 100644 --- a/lib/guzzlehttp/psr7/src/UploadedFile.php +++ b/lib/guzzlehttp/psr7/src/UploadedFile.php @@ -11,15 +11,15 @@ class UploadedFile implements UploadedFileInterface { - private const ERRORS = [ - UPLOAD_ERR_OK, - UPLOAD_ERR_INI_SIZE, - UPLOAD_ERR_FORM_SIZE, - UPLOAD_ERR_PARTIAL, - UPLOAD_ERR_NO_FILE, - UPLOAD_ERR_NO_TMP_DIR, - UPLOAD_ERR_CANT_WRITE, - UPLOAD_ERR_EXTENSION, + private const ERROR_MAP = [ + UPLOAD_ERR_OK => 'UPLOAD_ERR_OK', + UPLOAD_ERR_INI_SIZE => 'UPLOAD_ERR_INI_SIZE', + UPLOAD_ERR_FORM_SIZE => 'UPLOAD_ERR_FORM_SIZE', + UPLOAD_ERR_PARTIAL => 'UPLOAD_ERR_PARTIAL', + UPLOAD_ERR_NO_FILE => 'UPLOAD_ERR_NO_FILE', + UPLOAD_ERR_NO_TMP_DIR => 'UPLOAD_ERR_NO_TMP_DIR', + UPLOAD_ERR_CANT_WRITE => 'UPLOAD_ERR_CANT_WRITE', + UPLOAD_ERR_EXTENSION => 'UPLOAD_ERR_EXTENSION', ]; /** @@ -64,8 +64,8 @@ public function __construct( $streamOrFile, ?int $size, int $errorStatus, - string $clientFilename = null, - string $clientMediaType = null + ?string $clientFilename = null, + ?string $clientMediaType = null ) { $this->setError($errorStatus); $this->size = $size; @@ -104,7 +104,7 @@ private function setStreamOrFile($streamOrFile): void */ private function setError(int $error): void { - if (false === in_array($error, UploadedFile::ERRORS, true)) { + if (!isset(UploadedFile::ERROR_MAP[$error])) { throw new InvalidArgumentException( 'Invalid error status for UploadedFile' ); @@ -137,7 +137,7 @@ public function isMoved(): bool private function validateActive(): void { if (false === $this->isOk()) { - throw new RuntimeException('Cannot retrieve stream due to upload error'); + throw new RuntimeException(\sprintf('Cannot retrieve stream due to upload error (%s)', self::ERROR_MAP[$this->error])); } if ($this->isMoved()) { diff --git a/lib/guzzlehttp/psr7/src/Uri.php b/lib/guzzlehttp/psr7/src/Uri.php index f1feee8714..a7cdfb0034 100644 --- a/lib/guzzlehttp/psr7/src/Uri.php +++ b/lib/guzzlehttp/psr7/src/Uri.php @@ -107,7 +107,7 @@ private static function parse(string $url) { // If IPv6 $prefix = ''; - if (preg_match('%^(.*://\[[0-9:a-f]+\])(.*?)$%', $url, $matches)) { + if (preg_match('%^(.*://\[[0-9:a-fA-F]+\])(.*?)$%', $url, $matches)) { /** @var array{0:string, 1:string, 2:string} $matches */ $prefix = $matches[1]; $url = $matches[2]; @@ -279,7 +279,7 @@ public static function isRelativePathReference(UriInterface $uri): bool * * @see https://datatracker.ietf.org/doc/html/rfc3986#section-4.4 */ - public static function isSameDocumentReference(UriInterface $uri, UriInterface $base = null): bool + public static function isSameDocumentReference(UriInterface $uri, ?UriInterface $base = null): bool { if ($base !== null) { $uri = UriResolver::resolve($base, $uri); diff --git a/lib/guzzlehttp/psr7/src/Utils.php b/lib/guzzlehttp/psr7/src/Utils.php index bf5ea9dba8..5451e3dcd5 100644 --- a/lib/guzzlehttp/psr7/src/Utils.php +++ b/lib/guzzlehttp/psr7/src/Utils.php @@ -231,7 +231,7 @@ public static function modifyRequest(RequestInterface $request, array $changes): * @param StreamInterface $stream Stream to read from * @param int|null $maxLength Maximum buffer length */ - public static function readLine(StreamInterface $stream, int $maxLength = null): string + public static function readLine(StreamInterface $stream, ?int $maxLength = null): string { $buffer = ''; $size = 0; @@ -250,6 +250,20 @@ public static function readLine(StreamInterface $stream, int $maxLength = null): return $buffer; } + /** + * Redact the password in the user info part of a URI. + */ + public static function redactUserInfo(UriInterface $uri): UriInterface + { + $userInfo = $uri->getUserInfo(); + + if (false !== ($pos = \strpos($userInfo, ':'))) { + return $uri->withUserInfo(\substr($userInfo, 0, $pos), '***'); + } + + return $uri; + } + /** * Create a new stream based on the input type. * @@ -383,7 +397,7 @@ public static function tryFopen(string $filename, string $mode) restore_error_handler(); if ($ex) { - /** @var $ex \RuntimeException */ + /** @var \RuntimeException $ex */ throw $ex; } @@ -430,7 +444,7 @@ public static function tryGetContents($stream): string restore_error_handler(); if ($ex) { - /** @var $ex \RuntimeException */ + /** @var \RuntimeException $ex */ throw $ex; } diff --git a/lib/league/oauth2-client/LICENSE b/lib/league/oauth2-client/LICENSE index 7dfa39b7ce..9c8958afc1 100644 --- a/lib/league/oauth2-client/LICENSE +++ b/lib/league/oauth2-client/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2013-2020 Alex Bilbie +Copyright (c) 2013-2023 Alex Bilbie Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/league/oauth2-client/README.md b/lib/league/oauth2-client/README.md index cbb449d484..05c8d457e6 100644 --- a/lib/league/oauth2-client/README.md +++ b/lib/league/oauth2-client/README.md @@ -24,14 +24,16 @@ This package is compliant with [PSR-1][], [PSR-2][], [PSR-4][], and [PSR-7][]. I We support the following versions of PHP: +* PHP 8.5 +* PHP 8.4 +* PHP 8.3 +* PHP 8.2 * PHP 8.1 * PHP 8.0 * PHP 7.4 * PHP 7.3 * PHP 7.2 * PHP 7.1 -* PHP 7.0 -* PHP 5.6 ## Provider Clients diff --git a/lib/league/oauth2-client/composer.json b/lib/league/oauth2-client/composer.json index 59201f48fb..5dcc58355b 100644 --- a/lib/league/oauth2-client/composer.json +++ b/lib/league/oauth2-client/composer.json @@ -6,15 +6,15 @@ "sort-packages": true }, "require": { - "php": "^5.6 || ^7.0 || ^8.0", - "guzzlehttp/guzzle": "^6.0 || ^7.0", - "paragonie/random_compat": "^1 || ^2 || ^9.99" + "php": "^7.1 || >=8.0.0 <8.6.0", + "ext-json": "*", + "guzzlehttp/guzzle": "^6.5.8 || ^7.4.5" }, "require-dev": { "mockery/mockery": "^1.3.5", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpunit/phpunit": "^5.7 || ^6.0 || ^9.5", - "squizlabs/php_codesniffer": "^2.3 || ^3.0" + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpunit/phpunit": "^7 || ^8 || ^9 || ^10 || ^11", + "squizlabs/php_codesniffer": "^3.11" }, "keywords": [ "oauth", @@ -49,10 +49,5 @@ "psr-4": { "League\\OAuth2\\Client\\Test\\": "test/src/" } - }, - "extra": { - "branch-alias": { - "dev-2.x": "2.0.x-dev" - } } } diff --git a/lib/league/oauth2-client/src/Provider/AbstractProvider.php b/lib/league/oauth2-client/src/Provider/AbstractProvider.php index 293a54d6e6..eb62417648 100644 --- a/lib/league/oauth2-client/src/Provider/AbstractProvider.php +++ b/lib/league/oauth2-client/src/Provider/AbstractProvider.php @@ -17,6 +17,7 @@ use GuzzleHttp\Client as HttpClient; use GuzzleHttp\ClientInterface as HttpClientInterface; use GuzzleHttp\Exception\BadResponseException; +use GuzzleHttp\Exception\GuzzleException; use InvalidArgumentException; use League\OAuth2\Client\Grant\AbstractGrant; use League\OAuth2\Client\Grant\GrantFactory; @@ -405,6 +406,7 @@ protected function getPkceMethod() * * @param array $options * @return array Authorization parameters + * @throws InvalidArgumentException */ protected function getAuthorizationParameters(array $options) { @@ -476,6 +478,7 @@ protected function getAuthorizationQuery(array $params) * * @param array $options * @return string Authorization URL + * @throws InvalidArgumentException */ public function getAuthorizationUrl(array $options = []) { @@ -492,10 +495,11 @@ public function getAuthorizationUrl(array $options = []) * @param array $options * @param callable|null $redirectHandler * @return mixed + * @throws InvalidArgumentException */ public function authorize( array $options = [], - callable $redirectHandler = null + ?callable $redirectHandler = null ) { $url = $this->getAuthorizationUrl($options); if ($redirectHandler) { @@ -613,13 +617,20 @@ protected function getAccessTokenRequest(array $params) * * @param mixed $grant * @param array $options - * @throws IdentityProviderException * @return AccessTokenInterface + * @throws IdentityProviderException + * @throws UnexpectedValueException + * @throws GuzzleException */ public function getAccessToken($grant, array $options = []) { $grant = $this->verifyGrant($grant); + if (isset($options['scope']) && is_array($options['scope'])) { + $separator = $this->getScopeSeparator(); + $options['scope'] = implode($separator, $options['scope']); + } + $params = [ 'client_id' => $this->clientId, 'client_secret' => $this->clientSecret, @@ -700,6 +711,7 @@ protected function createRequest($method, $url, $token, array $options) * * @param RequestInterface $request * @return ResponseInterface + * @throws GuzzleException */ public function getResponse(RequestInterface $request) { @@ -710,8 +722,10 @@ public function getResponse(RequestInterface $request) * Sends a request and returns the parsed response. * * @param RequestInterface $request - * @throws IdentityProviderException * @return mixed + * @throws IdentityProviderException + * @throws UnexpectedValueException + * @throws GuzzleException */ public function getParsedResponse(RequestInterface $request) { @@ -757,7 +771,7 @@ protected function parseJson($content) */ protected function getContentType(ResponseInterface $response) { - return join(';', (array) $response->getHeader('content-type')); + return implode(';', $response->getHeader('content-type')); } /** @@ -815,7 +829,7 @@ abstract protected function checkResponse(ResponseInterface $response, $data); * Custom mapping of expiration, etc should be done here. Always call the * parent method when overloading this method. * - * @param mixed $result + * @param array $result * @return array */ protected function prepareAccessTokenResponse(array $result) @@ -859,6 +873,9 @@ abstract protected function createResourceOwner(array $response, AccessToken $to * * @param AccessToken $token * @return ResourceOwnerInterface + * @throws IdentityProviderException + * @throws UnexpectedValueException + * @throws GuzzleException */ public function getResourceOwner(AccessToken $token) { @@ -872,6 +889,9 @@ public function getResourceOwner(AccessToken $token) * * @param AccessToken $token * @return mixed + * @throws IdentityProviderException + * @throws UnexpectedValueException + * @throws GuzzleException */ protected function fetchResourceOwnerDetails(AccessToken $token) { diff --git a/lib/league/oauth2-client/src/Token/AccessToken.php b/lib/league/oauth2-client/src/Token/AccessToken.php index 81533c3072..331b0ace69 100644 --- a/lib/league/oauth2-client/src/Token/AccessToken.php +++ b/lib/league/oauth2-client/src/Token/AccessToken.php @@ -22,7 +22,7 @@ * * @link http://tools.ietf.org/html/rfc6749#section-1.4 Access Token (RFC 6749, §1.4) */ -class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInterface +class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInterface, SettableRefreshTokenInterface { /** * @var string @@ -118,7 +118,7 @@ public function __construct(array $options = []) } elseif (!empty($options['expires'])) { // Some providers supply the seconds until expiration rather than // the exact timestamp. Take a best guess at which we received. - $expires = $options['expires']; + $expires = (int) $options['expires']; if (!$this->isExpirationTimestamp($expires)) { $expires += $this->getTimeNow(); @@ -169,6 +169,14 @@ public function getRefreshToken() return $this->refreshToken; } + /** + * @inheritdoc + */ + public function setRefreshToken($refreshToken) + { + $this->refreshToken = $refreshToken; + } + /** * @inheritdoc */ @@ -196,7 +204,7 @@ public function hasExpired() throw new RuntimeException('"expires" is not set on the token'); } - return $expires < time(); + return $expires < $this->getTimeNow(); } /** diff --git a/lib/league/oauth2-google/CHANGELOG.md b/lib/league/oauth2-google/CHANGELOG.md index d82a2ae17c..d41761f513 100644 --- a/lib/league/oauth2-google/CHANGELOG.md +++ b/lib/league/oauth2-google/CHANGELOG.md @@ -1,5 +1,12 @@ OAuth 2.0 Google Provider Changelog + +## 4.1.0 - 2025-12-15 + +### Added + +- Added getEmailVerified(), isEmailTrustworthy() to user definition, #132 by @dt-thomas-durand + ## 4.0.1 - 2022-03-17 ### Changed diff --git a/lib/league/oauth2-google/README.md b/lib/league/oauth2-google/README.md index 38792d4af1..e951f309b6 100644 --- a/lib/league/oauth2-google/README.md +++ b/lib/league/oauth2-google/README.md @@ -1,6 +1,6 @@ # Google Provider for OAuth 2.0 Client -[![Build Status](https://img.shields.io/github/workflow/status/thephpleague/oauth2-google/test/main)](https://github.com/thephpleague/oauth2-google/actions/workflows/test.yaml) +[![Build Status](https://img.shields.io/github/actions/workflow/status/thephpleague/oauth2-google/ci.yml?branch=main)](https://github.com/thephpleague/oauth2-google/actions/workflows/ci.yml) [![Code Coverage](https://img.shields.io/codecov/c/gh/thephpleague/oauth2-google)](https://app.codecov.io/gh/thephpleague/oauth2-google) [![License](https://img.shields.io/packagist/l/league/oauth2-google)](https://github.com/thephpleague/oauth2-google/blob/main/LICENSE) [![Latest Stable Version](https://img.shields.io/packagist/v/league/oauth2-google)](https://packagist.org/packages/league/oauth2-google) @@ -22,6 +22,8 @@ The following versions of PHP are supported. * PHP 7.4 * PHP 8.0 * PHP 8.1 +* PHP 8.2 +* PHP 8.3 This package uses [OpenID Connect][openid-connect] to authenticate users with Google accounts. diff --git a/lib/league/oauth2-google/src/Provider/GoogleUser.php b/lib/league/oauth2-google/src/Provider/GoogleUser.php index d004e3c6d9..58f0538d2f 100644 --- a/lib/league/oauth2-google/src/Provider/GoogleUser.php +++ b/lib/league/oauth2-google/src/Provider/GoogleUser.php @@ -72,6 +72,36 @@ public function getEmail(): ?string return $this->getResponseValue('email'); } + /** + * Get email_verified attribute. + * + * @return bool|null + */ + public function getEmailVerified(): ?bool + { + return $this->getResponseValue('email_verified'); + } + + /** + * Returns whether the email is trustable enough to be used for authentication purpose. + * + * @see https://developers.google.com/identity/gsi/web/guides/verify-google-id-token + */ + public function isEmailTrustworthy(): bool + { + $email = $this->getEmail(); + if (! $email) { + return false; + } + if ('@gmail.com' === substr($email, -10)) { + return true; + } + if ($this->getHostedDomain() && $this->getEmailVerified()) { + return true; + } + return false; + } + /** * Get hosted domain. * diff --git a/lib/nikic/php-parser/README.md b/lib/nikic/php-parser/README.md index 36de23cde1..3bca288b92 100644 --- a/lib/nikic/php-parser/README.md +++ b/lib/nikic/php-parser/README.md @@ -6,7 +6,7 @@ PHP Parser This is a PHP 5.2 to PHP 8.2 parser written in PHP. Its purpose is to simplify static code analysis and manipulation. -[**Documentation for version 4.x**][doc_4_x] (stable; for running on PHP >= 7.0; for parsing PHP 5.2 to PHP 8.2). +[**Documentation for version 4.x**][doc_4_x] (stable; for running on PHP >= 7.1; for parsing PHP 5.2 to PHP 8.2). [Documentation for version 3.x][doc_3_x] (unsupported; for running on PHP >= 5.5; for parsing PHP 5.2 to PHP 7.2). diff --git a/lib/nikic/php-parser/composer.json b/lib/nikic/php-parser/composer.json index 2fd064a212..ef416d9420 100644 --- a/lib/nikic/php-parser/composer.json +++ b/lib/nikic/php-parser/composer.json @@ -13,18 +13,13 @@ } ], "require": { - "php": ">=7.0", + "php": ">=7.1", "ext-tokenizer": "*" }, "require-dev": { - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", "ircmaxell/php-yacc": "^0.0.7" }, - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, "autoload": { "psr-4": { "PhpParser\\": "lib/PhpParser" diff --git a/lib/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php b/lib/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php index a7fe129b0b..7c1512d079 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php +++ b/lib/nikic/php-parser/lib/PhpParser/Builder/ClassConst.php @@ -26,7 +26,7 @@ class ClassConst implements PhpParser\Builder * Creates a class constant builder * * @param string|Identifier $name Name - * @param Node\Expr|bool|null|int|float|string|array $value Value + * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value */ public function __construct($name, $value) { $this->constants = [new Const_($name, BuilderHelpers::normalizeValue($value))]; @@ -36,7 +36,7 @@ public function __construct($name, $value) { * Add another constant to const group * * @param string|Identifier $name Name - * @param Node\Expr|bool|null|int|float|string|array $value Value + * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value Value * * @return $this The builder instance (for fluid interface) */ diff --git a/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php b/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php index af010e028a..0aae8738ce 100644 --- a/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php +++ b/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php @@ -213,7 +213,7 @@ public function enumCase($name) : Builder\EnumCase { /** * Creates node a for a literal value. * - * @param Expr|bool|null|int|float|string|array $value $value + * @param Expr|bool|null|int|float|string|array|\UnitEnum $value $value * * @return Expr */ diff --git a/lib/nikic/php-parser/lib/PhpParser/BuilderHelpers.php b/lib/nikic/php-parser/lib/PhpParser/BuilderHelpers.php index af6ceb9968..05e7868f47 100644 --- a/lib/nikic/php-parser/lib/PhpParser/BuilderHelpers.php +++ b/lib/nikic/php-parser/lib/PhpParser/BuilderHelpers.php @@ -6,6 +6,7 @@ use PhpParser\Node\Expr; use PhpParser\Node\Identifier; use PhpParser\Node\Name; +use PhpParser\Node\Name\FullyQualified; use PhpParser\Node\NullableType; use PhpParser\Node\Scalar; use PhpParser\Node\Stmt; @@ -215,7 +216,7 @@ public static function normalizeType($type) { * Normalizes a value: Converts nulls, booleans, integers, * floats, strings and arrays into their respective nodes * - * @param Node\Expr|bool|null|int|float|string|array $value The value to normalize + * @param Node\Expr|bool|null|int|float|string|array|\UnitEnum $value The value to normalize * * @return Expr The normalized value */ @@ -269,6 +270,10 @@ public static function normalizeValue($value) : Expr { return new Expr\Array_($items); } + if ($value instanceof \UnitEnum) { + return new Expr\ClassConstFetch(new FullyQualified(\get_class($value)), new Identifier($value->name)); + } + throw new \LogicException('Invalid value'); } diff --git a/lib/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php b/lib/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php index 7131c3d255..ceb3f11f3d 100644 --- a/lib/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php +++ b/lib/nikic/php-parser/lib/PhpParser/ConstExprEvaluator.php @@ -37,7 +37,7 @@ class ConstExprEvaluator * * @param callable|null $fallbackEvaluator To call if subexpression cannot be evaluated */ - public function __construct(callable $fallbackEvaluator = null) { + public function __construct(?callable $fallbackEvaluator = null) { $this->fallbackEvaluator = $fallbackEvaluator ?? function(Expr $expr) { throw new ConstExprEvaluationException( "Expression of type {$expr->getType()} cannot be evaluated" diff --git a/lib/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php b/lib/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php index 6763227014..fc276ecb92 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php +++ b/lib/nikic/php-parser/lib/PhpParser/Internal/PrintableNewAnonClassNode.php @@ -31,7 +31,7 @@ class PrintableNewAnonClassNode extends Expr public $stmts; public function __construct( - array $attrGroups, int $flags, array $args, Node\Name $extends = null, array $implements, + array $attrGroups, int $flags, array $args, ?Node\Name $extends, array $implements, array $stmts, array $attributes ) { parent::__construct($attributes); diff --git a/lib/nikic/php-parser/lib/PhpParser/Lexer.php b/lib/nikic/php-parser/lib/PhpParser/Lexer.php index e15dd0a5d2..60b809b8b1 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Lexer.php +++ b/lib/nikic/php-parser/lib/PhpParser/Lexer.php @@ -69,7 +69,7 @@ public function __construct(array $options = []) { * @param ErrorHandler|null $errorHandler Error handler to use for lexing errors. Defaults to * ErrorHandler\Throwing */ - public function startLexing(string $code, ErrorHandler $errorHandler = null) { + public function startLexing(string $code, ?ErrorHandler $errorHandler = null) { if (null === $errorHandler) { $errorHandler = new ErrorHandler\Throwing(); } diff --git a/lib/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php b/lib/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php index b0929f3ccb..a0e781d04d 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php +++ b/lib/nikic/php-parser/lib/PhpParser/Lexer/Emulative.php @@ -74,7 +74,7 @@ public function __construct(array $options = []) } } - public function startLexing(string $code, ErrorHandler $errorHandler = null) { + public function startLexing(string $code, ?ErrorHandler $errorHandler = null) { $emulators = array_filter($this->emulators, function($emulator) use($code) { return $emulator->isEmulationNeeded($code); }); diff --git a/lib/nikic/php-parser/lib/PhpParser/NameContext.php b/lib/nikic/php-parser/lib/PhpParser/NameContext.php index 777a4afdee..82c5acc2c7 100644 --- a/lib/nikic/php-parser/lib/PhpParser/NameContext.php +++ b/lib/nikic/php-parser/lib/PhpParser/NameContext.php @@ -36,7 +36,7 @@ public function __construct(ErrorHandler $errorHandler) { * * @param Name|null $namespace Null is the global namespace */ - public function startNamespace(Name $namespace = null) { + public function startNamespace(?Name $namespace = null) { $this->namespace = $namespace; $this->origAliases = $this->aliases = [ Stmt\Use_::TYPE_NORMAL => [], diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Arg.php b/lib/nikic/php-parser/lib/PhpParser/Node/Arg.php index bcf130e68c..17e6802607 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Arg.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Arg.php @@ -27,7 +27,7 @@ class Arg extends NodeAbstract */ public function __construct( Expr $value, bool $byRef = false, bool $unpack = false, array $attributes = [], - Identifier $name = null + ?Identifier $name = null ) { $this->attributes = $attributes; $this->name = $name; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php index 71694478e9..46db975c4c 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayDimFetch.php @@ -18,7 +18,7 @@ class ArrayDimFetch extends Expr * @param null|Expr $dim Array index / dim * @param array $attributes Additional attributes */ - public function __construct(Expr $var, Expr $dim = null, array $attributes = []) { + public function __construct(Expr $var, ?Expr $dim = null, array $attributes = []) { $this->attributes = $attributes; $this->var = $var; $this->dim = $dim; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php index 1b078f8218..5aaa9867ee 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/ArrayItem.php @@ -23,7 +23,7 @@ class ArrayItem extends Expr * @param bool $byRef Whether to assign by reference * @param array $attributes Additional attributes */ - public function __construct(Expr $value, Expr $key = null, bool $byRef = false, array $attributes = [], bool $unpack = false) { + public function __construct(Expr $value, ?Expr $key = null, bool $byRef = false, array $attributes = [], bool $unpack = false) { $this->attributes = $attributes; $this->key = $key; $this->value = $value; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php index b88a8f7e6f..5469b8e4ca 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Exit_.php @@ -19,7 +19,7 @@ class Exit_ extends Expr * @param null|Expr $expr Expression * @param array $attributes Additional attributes */ - public function __construct(Expr $expr = null, array $attributes = []) { + public function __construct(?Expr $expr = null, array $attributes = []) { $this->attributes = $attributes; $this->expr = $expr; } diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php index aef8fc333d..f15336edeb 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Expr/Yield_.php @@ -18,7 +18,7 @@ class Yield_ extends Expr * @param null|Expr $key Key expression * @param array $attributes Additional attributes */ - public function __construct(Expr $value = null, Expr $key = null, array $attributes = []) { + public function __construct(?Expr $value = null, ?Expr $key = null, array $attributes = []) { $this->attributes = $attributes; $this->key = $key; $this->value = $value; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Name.php b/lib/nikic/php-parser/lib/PhpParser/Node/Name.php index f0a564ff0b..0d6e4b1ff5 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Name.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Name.php @@ -162,7 +162,7 @@ public function __toString() : string { * * @return static|null Sliced name */ - public function slice(int $offset, int $length = null) { + public function slice(int $offset, ?int $length = null) { $numParts = count($this->parts); $realOffset = $offset < 0 ? $offset + $numParts : $offset; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Param.php b/lib/nikic/php-parser/lib/PhpParser/Node/Param.php index 1e90b79441..dfb77f6290 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Param.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Param.php @@ -34,7 +34,7 @@ class Param extends NodeAbstract * @param AttributeGroup[] $attrGroups PHP attribute groups */ public function __construct( - $var, Expr $default = null, $type = null, + $var, ?Expr $default = null, $type = null, bool $byRef = false, bool $variadic = false, array $attributes = [], int $flags = 0, diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php index 6690a16bfb..df2f6c1b6e 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Scalar/String_.php @@ -120,7 +120,7 @@ function($matches) { } elseif ('u' === $str[0]) { return self::codePointToUtf8(hexdec($matches[2])); } else { - return chr(octdec($str)); + return chr(octdec($str) & 255); } }, $str diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php index 6adc5a6c6f..d9464a1ae8 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Break_.php @@ -15,7 +15,7 @@ class Break_ extends Node\Stmt * @param null|Node\Expr $num Number of loops to break * @param array $attributes Additional attributes */ - public function __construct(Node\Expr $num = null, array $attributes = []) { + public function __construct(?Node\Expr $num = null, array $attributes = []) { $this->attributes = $attributes; $this->num = $num; } diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php index 9b9c094782..5d7b5c0168 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Catch_.php @@ -23,7 +23,7 @@ class Catch_ extends Node\Stmt * @param array $attributes Additional attributes */ public function __construct( - array $types, Expr\Variable $var = null, array $stmts = [], array $attributes = [] + array $types, ?Expr\Variable $var = null, array $stmts = [], array $attributes = [] ) { $this->attributes = $attributes; $this->types = $types; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php index 24882683b3..f2b30d79f5 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Continue_.php @@ -15,7 +15,7 @@ class Continue_ extends Node\Stmt * @param null|Node\Expr $num Number of loops to continue * @param array $attributes Additional attributes */ - public function __construct(Node\Expr $num = null, array $attributes = []) { + public function __construct(?Node\Expr $num = null, array $attributes = []) { $this->attributes = $attributes; $this->num = $num; } diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php index f46ff0bafd..a3a5bfaa59 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Declare_.php @@ -18,7 +18,7 @@ class Declare_ extends Node\Stmt * @param Node\Stmt[]|null $stmts Statements * @param array $attributes Additional attributes */ - public function __construct(array $declares, array $stmts = null, array $attributes = []) { + public function __construct(array $declares, ?array $stmts = null, array $attributes = []) { $this->attributes = $attributes; $this->declares = $declares; $this->stmts = $stmts; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php index 5beff8b39f..4b1079bcd7 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/EnumCase.php @@ -20,7 +20,7 @@ class EnumCase extends Node\Stmt * @param AttributeGroup[] $attrGroups PHP attribute groups * @param array $attributes Additional attributes */ - public function __construct($name, Node\Expr $expr = null, array $attrGroups = [], array $attributes = []) { + public function __construct($name, ?Node\Expr $expr = null, array $attrGroups = [], array $attributes = []) { parent::__construct($attributes); $this->name = \is_string($name) ? new Node\Identifier($name) : $name; $this->expr = $expr; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php index c63204577c..fc249161a9 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Namespace_.php @@ -22,7 +22,7 @@ class Namespace_ extends Node\Stmt * @param null|Node\Stmt[] $stmts Statements * @param array $attributes Additional attributes */ - public function __construct(Node\Name $name = null, $stmts = [], array $attributes = []) { + public function __construct(?Node\Name $name = null, $stmts = [], array $attributes = []) { $this->attributes = $attributes; $this->name = $name; $this->stmts = $stmts; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php index 205731e20e..286b42961c 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/PropertyProperty.php @@ -18,7 +18,7 @@ class PropertyProperty extends Node\Stmt * @param null|Node\Expr $default Default value * @param array $attributes Additional attributes */ - public function __construct($name, Node\Expr $default = null, array $attributes = []) { + public function __construct($name, ?Node\Expr $default = null, array $attributes = []) { $this->attributes = $attributes; $this->name = \is_string($name) ? new Node\VarLikeIdentifier($name) : $name; $this->default = $default; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php index efc578c58f..53731254c0 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/Return_.php @@ -15,7 +15,7 @@ class Return_ extends Node\Stmt * @param null|Node\Expr $expr Expression * @param array $attributes Additional attributes */ - public function __construct(Node\Expr $expr = null, array $attributes = []) { + public function __construct(?Node\Expr $expr = null, array $attributes = []) { $this->attributes = $attributes; $this->expr = $expr; } diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php index 29584560d3..0cc47b4122 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/StaticVar.php @@ -20,7 +20,7 @@ class StaticVar extends Node\Stmt * @param array $attributes Additional attributes */ public function __construct( - Expr\Variable $var, Node\Expr $default = null, array $attributes = [] + Expr\Variable $var, ?Node\Expr $default = null, array $attributes = [] ) { $this->attributes = $attributes; $this->var = $var; diff --git a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php index 7fc158c570..74e004380b 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php +++ b/lib/nikic/php-parser/lib/PhpParser/Node/Stmt/TryCatch.php @@ -21,7 +21,7 @@ class TryCatch extends Node\Stmt * @param null|Finally_ $finally Optional finally node * @param array $attributes Additional attributes */ - public function __construct(array $stmts, array $catches, Finally_ $finally = null, array $attributes = []) { + public function __construct(array $stmts, array $catches, ?Finally_ $finally = null, array $attributes = []) { $this->attributes = $attributes; $this->stmts = $stmts; $this->catches = $catches; diff --git a/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php b/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php index ba622efd12..e0c7f783ad 100644 --- a/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php +++ b/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php @@ -39,7 +39,7 @@ public function __construct(array $options = []) { * * @return string Dumped value */ - public function dump($node, string $code = null) : string { + public function dump($node, ?string $code = null) : string { $this->code = $code; return $this->dumpRecursive($node); } diff --git a/lib/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php b/lib/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php index 83f3ea831c..dd2e9ca766 100644 --- a/lib/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php +++ b/lib/nikic/php-parser/lib/PhpParser/NodeVisitor/NameResolver.php @@ -35,7 +35,7 @@ class NameResolver extends NodeVisitorAbstract * @param ErrorHandler|null $errorHandler Error handler * @param array $options Options */ - public function __construct(ErrorHandler $errorHandler = null, array $options = []) { + public function __construct(?ErrorHandler $errorHandler = null, array $options = []) { $this->nameContext = new NameContext($errorHandler ?? new ErrorHandler\Throwing); $this->preserveOriginalNames = $options['preserveOriginalNames'] ?? false; $this->replaceNodes = $options['replaceNodes'] ?? true; @@ -164,7 +164,7 @@ public function enterNode(Node $node) { return null; } - private function addAlias(Stmt\UseUse $use, int $type, Name $prefix = null) { + private function addAlias(Stmt\UseUse $use, int $type, ?Name $prefix = null) { // Add prefix for group uses $name = $prefix ? Name::concat($prefix, $use->name) : $use->name; // Type is determined either by individual element or whole use declaration diff --git a/lib/nikic/php-parser/lib/PhpParser/Parser.php b/lib/nikic/php-parser/lib/PhpParser/Parser.php index 8956c76718..7236c68e2a 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Parser.php +++ b/lib/nikic/php-parser/lib/PhpParser/Parser.php @@ -14,5 +14,5 @@ interface Parser * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and * the parser was unable to recover from an error). */ - public function parse(string $code, ErrorHandler $errorHandler = null); + public function parse(string $code, ?ErrorHandler $errorHandler = null); } diff --git a/lib/nikic/php-parser/lib/PhpParser/Parser/Multiple.php b/lib/nikic/php-parser/lib/PhpParser/Parser/Multiple.php index 77fd1f3fbb..083ff465d3 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Parser/Multiple.php +++ b/lib/nikic/php-parser/lib/PhpParser/Parser/Multiple.php @@ -24,7 +24,7 @@ public function __construct(array $parsers) { $this->parsers = $parsers; } - public function parse(string $code, ErrorHandler $errorHandler = null) { + public function parse(string $code, ?ErrorHandler $errorHandler = null) { if (null === $errorHandler) { $errorHandler = new ErrorHandler\Throwing; } diff --git a/lib/nikic/php-parser/lib/PhpParser/Parser/Php5.php b/lib/nikic/php-parser/lib/PhpParser/Parser/Php5.php index 59bd1e8cf5..80ebdfb37c 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Parser/Php5.php +++ b/lib/nikic/php-parser/lib/PhpParser/Parser/Php5.php @@ -27,7 +27,7 @@ class Php5 extends \PhpParser\ParserAbstract protected $unexpectedTokenRule = 32767; protected $YY2TBLSTATE = 415; - protected $numNonLeafStates = 663; + protected $numNonLeafStates = 664; protected $symbolToName = array( "EOF", @@ -244,116 +244,116 @@ class Php5 extends \PhpParser\ParserAbstract ); protected $action = array( - 700, 670, 671, 672, 673, 674, 286, 675, 676, 677, - 713, 714, 223, 224, 225, 226, 227, 228, 229, 230, + 701, 671, 672, 673, 674, 675, 286, 676, 677, 678, + 714, 715, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 0, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244,-32766,-32766,-32766,-32766,-32766, -32766,-32766,-32766,-32766,-32767,-32767,-32767,-32767, 245, 246, - 242, 243, 244,-32766,-32766, 678,-32766,-32766,-32766,-32766, - -32766,-32766,-32766,-32766,-32766, 1229, 245, 246, 1230, 679, - 680, 681, 682, 683, 684, 685, 899, 900, 747,-32766, - -32766,-32766,-32766,-32766,-32766, 686, 687, 688, 689, 690, - 691, 692, 693, 694, 695, 696, 716, 739, 717, 718, - 719, 720, 708, 709, 710, 738, 711, 712, 697, 698, - 699, 701, 702, 703, 741, 742, 743, 744, 745, 746, - 875, 704, 705, 706, 707, 737, 728, 726, 727, 723, - 724, 1046, 715, 721, 722, 729, 730, 732, 731, 733, - 734, 55, 56, 425, 57, 58, 725, 736, 735, 755, + 242, 243, 244,-32766,-32766, 679,-32766,-32766,-32766,-32766, + -32766,-32766,-32766,-32766,-32766, 1230, 245, 246, 1231, 680, + 681, 682, 683, 684, 685, 686, 900, 901, 748,-32766, + -32766,-32766,-32766,-32766,-32766, 687, 688, 689, 690, 691, + 692, 693, 694, 695, 696, 697, 717, 740, 718, 719, + 720, 721, 709, 710, 711, 739, 712, 713, 698, 699, + 700, 702, 703, 704, 742, 743, 744, 745, 746, 747, + 876, 705, 706, 707, 708, 738, 729, 727, 728, 724, + 725, 1047, 716, 722, 723, 730, 731, 733, 732, 734, + 735, 55, 56, 425, 57, 58, 726, 737, 736, 756, 59, 60, -226, 61,-32766,-32766,-32766,-32766,-32766,-32766, -32766,-32766,-32766,-32766, 337,-32767,-32767,-32767,-32767, 29, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 620,-32766,-32766,-32766,-32766, 62, 63, - 1046,-32766,-32766,-32766, 64, 419, 65, 294, 295, 66, - 67, 68, 69, 70, 71, 72, 73, 823, 25, 302, - 74, 418, 984, 986, 669, 668, 1100, 1101, 1078, 755, - 755, 767, 1220, 768, 470,-32766,-32766,-32766, 341, 749, - 824, 54,-32767,-32767,-32767,-32767, 98, 99, 100, 101, - 102, 220, 221, 222, 362, 876,-32766, 27,-32766,-32766, - -32766,-32766,-32766, 1046, 493, 126, 1080, 1079, 1081, 370, - 1068, 930, 207, 478, 479, 952, 953, 954, 951, 950, - 949, 128, 480, 481, 803, 1106, 1107, 1108, 1109, 1103, - 1104, 319, 32, 297, 10, 211, -515, 1110, 1105, 669, - 668, 1080, 1079, 1081, 220, 221, 222, 41, 364, 341, - 334, 421, 336, 426, -128, -128, -128, 313, 1046, 469, - -4, 824, 54, 812, 770, 207, 40, 21, 427, -128, - 471, -128, 472, -128, 473, -128, 1046, 428, 220, 221, + 117, 118, 119, 621,-32766,-32766,-32766,-32766, 62, 63, + 1047,-32766,-32766,-32766, 64, 419, 65, 294, 295, 66, + 67, 68, 69, 70, 71, 72, 73, 824, 25, 302, + 74, 418, 985, 987, 670, 669, 1101, 1102, 1079, 756, + 756, 768, 1221, 769, 470,-32766,-32766,-32766, 341, 750, + 825, 54,-32767,-32767,-32767,-32767, 98, 99, 100, 101, + 102, 220, 221, 222, 362, 877,-32766, 27,-32766,-32766, + -32766,-32766,-32766, 1047, 492, 126, 1081, 1080, 1082, 370, + 1069, 931, 207, 478, 479, 953, 954, 955, 952, 951, + 950, 128, 480, 481, 804, 1107, 1108, 1109, 1110, 1104, + 1105, 319, 32, 297, 10, 211, -515, 1111, 1106, 670, + 669, 1081, 1080, 1082, 220, 221, 222, 41, 364, 341, + 334, 421, 336, 426, -128, -128, -128, 313, 1047, 469, + -4, 825, 54, 813, 597, 207, 40, 21, 427, -128, + 471, -128, 472, -128, 473, -128, 1047, 428, 220, 221, 222,-32766, 33, 34, 429, 361, 327, 52, 35, 474, -32766,-32766,-32766, 342, 357, 358, 475, 476, 48, 207, - 249, 669, 668, 477, 443, 300, 795, 846, 430, 431, - 28,-32766, 814,-32766,-32766,-32766,-32766,-32766,-32766,-32766, - -32767,-32767,-32767,-32767,-32767, 952, 953, 954, 951, 950, - 949, 422, 755, 424, 426, 826, 634, -128,-32766,-32766, - 469, 824, 54, 288, 812, 1151, 755, 40, 21, 427, - 317, 471, 345, 472, 129, 473, 9, 1186, 428, 769, - 360, 324, 905, 33, 34, 429, 361, 1046, 415, 35, - 474, 944, 1068, 315, 125, 357, 358, 475, 476,-32766, - -32766,-32766, 926, 302, 477, 121, 1068, 759, 846, 430, - 431, 669, 668, 423, 755, 1152, 809, 1046, 480, 766, - -32766, 805,-32766,-32766,-32766,-32766, -261, 127, 347, 436, - 841, 341, 1078, 1200, 426, 446, 826, 634, -4, 807, - 469, 824, 54, 436, 812, 341, 755, 40, 21, 427, - 444, 471, 130, 472, 1068, 473, 346, 767, 428, 768, - -211, -211, -211, 33, 34, 429, 361, 308, 1076, 35, - 474,-32766,-32766,-32766, 1046, 357, 358, 475, 476,-32766, - -32766,-32766, 906, 120, 477, 539, 1068, 795, 846, 430, - 431, 436,-32766, 341,-32766,-32766,-32766, 1046, 480, 810, - -32766, 925,-32766,-32766, 754, 1080, 1079, 1081, 49,-32766, - -32766,-32766, 749, 751, 426, 1201, 826, 634, -211, 30, - 469, 669, 668, 436, 812, 341, 75, 40, 21, 427, - -32766, 471, 1064, 472, 124, 473, 669, 668, 428, 212, - -210, -210, -210, 33, 34, 429, 361, 51, 1186, 35, - 474, 755,-32766,-32766,-32766, 357, 358, 475, 476, 213, - 824, 54, 221, 222, 477, 20, 581, 795, 846, 430, - 431, 220, 221, 222, 755, 222, 247, 78, 79, 80, - 81, 341, 207, 517, 103, 104, 105, 752, 307, 131, - 637, 1068, 207, 341, 207, 122, 826, 634, -210, 36, + 249, 670, 669, 477, 443, 300, 796, 847, 430, 431, + 28,-32766, 815,-32766,-32766,-32766,-32766,-32766,-32766,-32766, + -32767,-32767,-32767,-32767,-32767, 953, 954, 955, 952, 951, + 950, 422, 756, 424, 426, 827, 635, -128,-32766,-32766, + 469, 825, 54, 288, 813, 1152, 756, 40, 21, 427, + 317, 471, 345, 472, 129, 473, 9, 1187, 428, 612, + 360, 324, 906, 33, 34, 429, 361, 1047, 415, 35, + 474, 945, 1069, 315, 125, 357, 358, 475, 476,-32766, + -32766,-32766, 927, 302, 477, 121, 1069, 760, 847, 430, + 431, 670, 669, 423, 756, 1153, 810, 1047, 480, 767, + -32766, 806,-32766,-32766,-32766,-32766, -261, 127, 347, 436, + 842, 341, 1079, 1201, 426, 446, 827, 635, -4, 808, + 469, 825, 54, 436, 813, 341, 756, 40, 21, 427, + 444, 471, 130, 472, 1069, 473, 346, 768, 428, 769, + -211, -211, -211, 33, 34, 429, 361, 308, 1077, 35, + 474,-32766,-32766,-32766, 1047, 357, 358, 475, 476,-32766, + -32766,-32766, 907, 120, 477, 538, 1069, 796, 847, 430, + 431, 436,-32766, 341,-32766,-32766,-32766, 1047, 480, 811, + -32766, 926,-32766,-32766, 755, 1081, 1080, 1082, 49,-32766, + -32766,-32766, 750, 752, 426, 1202, 827, 635, -211, 30, + 469, 670, 669, 436, 813, 341, 75, 40, 21, 427, + -32766, 471, 1065, 472, 124, 473, 670, 669, 428, 212, + -210, -210, -210, 33, 34, 429, 361, 51, 1187, 35, + 474, 756,-32766,-32766,-32766, 357, 358, 475, 476, 213, + 825, 54, 221, 222, 477, 20, 580, 796, 847, 430, + 431, 220, 221, 222, 756, 222, 247, 78, 79, 80, + 81, 341, 207, 516, 103, 104, 105, 753, 307, 131, + 638, 1069, 207, 341, 207, 122, 827, 635, -210, 36, 106, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 1112, 307, 346, 436, 214, - 341, 824, 54, 426, 123, 250, 129, 134, 106, 469, - -32766, 572, 1112, 812, 245, 246, 40, 21, 427, 251, - 471, 252, 472, 341, 473, 453, 22, 428, 207, 899, - 900, 638, 33, 34, 429, 824, 54, -86, 35, 474, + 101, 102, 103, 104, 105, 1113, 307, 346, 436, 214, + 341, 825, 54, 426, 123, 250, 129, 134, 106, 469, + -32766, 571, 1113, 813, 245, 246, 40, 21, 427, 251, + 471, 252, 472, 341, 473, 453, 22, 428, 207, 900, + 901, 639, 33, 34, 429, 825, 54, -86, 35, 474, 220, 221, 222, 314, 357, 358, 100, 101, 102, 239, - 240, 241, 645, 477, -230, 458, 589, 135, 374, 596, - 597, 207, 760, 640, 648, 642, 941, 654, 929, 662, - 822, 133, 307, 837, 426,-32766, 106, 749, 43, 44, - 469, 45, 442, 46, 812, 826, 634, 40, 21, 427, + 240, 241, 646, 477, -230, 458, 588, 135, 374, 595, + 596, 207, 761, 641, 649, 643, 942, 655, 930, 663, + 823, 133, 307, 838, 426,-32766, 106, 750, 43, 44, + 469, 45, 442, 46, 813, 827, 635, 40, 21, 427, 47, 471, 50, 472, 53, 473, 132, 608, 428, 302, - 604, -280,-32766, 33, 34, 429, 824, 54, 426, 35, - 474, 755, 957, -84, 469, 357, 358, 521, 812, 628, - 363, 40, 21, 427, 477, 471, 575, 472, -515, 473, - 847, 616, 428, -423,-32766, 11, 646, 33, 34, 429, - 824, 54, 445, 35, 474, 462, 285, 578, 1111, 357, - 358, 593, 369, 848, 594, 290, 826, 634, 477, 0, - 0, 532, 0, 0, 325, 0, 0, 0, 0, 0, - 651, 0, 0, 0, 322, 326, 0, 0, 0, 426, - 0, 0, 0, 0, 323, 469, 316, 318, -516, 812, - 862, 634, 40, 21, 427, 0, 471, 0, 472, 0, - 473, 1158, 0, 428, 0, -414, 6, 7, 33, 34, - 429, 824, 54, 426, 35, 474, 12, 14, 373, 469, - 357, 358, -424, 812, 563, 754, 40, 21, 427, 477, - 471, 248, 472, 839, 473, 38, 39, 428, 657, 658, - 765, 813, 33, 34, 429, 821, 800, 815, 35, 474, - 215, 216, 878, 869, 357, 358, 217, 870, 218, 798, - 863, 826, 634, 477, 860, 858, 936, 937, 934, 820, - 209, 804, 806, 808, 811, 933, 763, 764, 1100, 1101, - 935, 659, 78, 335, 426, 359, 1102, 635, 639, 641, - 469, 643, 644, 647, 812, 826, 634, 40, 21, 427, - 649, 471, 650, 472, 652, 473, 653, 636, 428, 796, - 1226, 1228, 762, 33, 34, 429, 215, 216, 845, 35, - 474, 761, 217, 844, 218, 357, 358, 1227, 843, 1060, - 831, 1048, 842, 1049, 477, 559, 209, 1106, 1107, 1108, - 1109, 1103, 1104, 398, 1100, 1101, 829, 942, 867, 1110, - 1105, 868, 1102, 457, 1225, 1194, 1192, 1177, 1157, 219, - 1190, 1091, 917, 1198, 1188, 0, 826, 634, 24, -433, - 26, 31, 37, 42, 76, 77, 210, 287, 292, 293, + 604, -280,-32766, 33, 34, 429, 825, 54, 426, 35, + 474, 756, 958, -84, 469, 357, 358, 520, 813, 629, + 363, 40, 21, 427, 477, 471, 574, 472, -515, 473, + 848, 617, 428, -423,-32766, 11, 647, 33, 34, 429, + 825, 54, 445, 35, 474, 462, 285, 577, 1112, 357, + 358, 592, 369, 849, 593, 290, 827, 635, 477, 0, + 0, 531, 0, 0, 325, 0, 0, 0, 0, 0, + 652, 0, 0, 0, 322, 326, 0, 0, 0, 426, + 0, 0, 0, 0, 323, 469, 316, 318, -516, 813, + 863, 635, 40, 21, 427, 0, 471, 0, 472, 0, + 473, 1159, 0, 428, 0, -414, 6, 7, 33, 34, + 429, 825, 54, 426, 35, 474, 12, 14, 373, 469, + 357, 358, -424, 813, 562, 755, 40, 21, 427, 477, + 471, 248, 472, 840, 473, 38, 39, 428, 658, 659, + 814, 822, 33, 34, 429, 801, 816, 879, 35, 474, + 215, 216, 870, 871, 357, 358, 217, 771, 218, 799, + 864, 827, 635, 477, 770, 861, 859, 937, 938, 935, + 209, 821, 805, 807, 809, 812, 934, 764, 1101, 1102, + 765, 936, 24, 78, 426, 335, 1103, 359, 636, 640, + 469, 642, 644, 645, 813, 827, 635, 40, 21, 427, + 648, 471, 650, 472, 651, 473, 653, 654, 428, 637, + 26, 660, 797, 33, 34, 429, 215, 216, 1227, 35, + 474, 1229, 217, 763, 218, 357, 358, 846, 762, 845, + 1228, 844, 1061, 832, 477, 558, 209, 1107, 1108, 1109, + 1110, 1104, 1105, 398, 1101, 1102, 1049, 843, 1050, 1111, + 1106, 830, 1103, 943, 868, 869, 457, 1226, 1158, 219, + 1195, 1193, 1178, 1191, 1092, 918, 827, 635, 31, 1199, + 1189, 1056, 37, 42, 76, 77, 210, 287, 292, 293, 308, 309, 310, 311, 339, 356, 416, 0, -227, -226, - 16, 17, 18, 393, 454, 461, 463, 467, 553, 625, - 1051, 559, 1054, 1106, 1107, 1108, 1109, 1103, 1104, 398, - 907, 1116, 1050, 1026, 564, 1110, 1105, 1025, 1093, 1055, - 0, 1044, 0, 1057, 1056, 219, 1059, 1058, 1075, 0, - 1191, 1176, 1172, 1189, 1090, 1223, 1117, 1171, 600 + 16, 17, 18, 393, 454, 461, 463, 467, 552, 626, + 1052, 558, 1055, 1107, 1108, 1109, 1110, 1104, 1105, 398, + 908, 1117, 1051, 1027, 563, 1111, 1106, 1026, 1094, 1058, + 0, -433, 1045, 0, 1057, 219, 1060, 1059, 1076, 0, + 1192, 1177, 1173, 1190, 1091, 1224, 1118, 1172, 600 ); protected $actionCheck = array( @@ -451,26 +451,26 @@ class Php5 extends \PhpParser\ParserAbstract 50, 51, 156, 156, 115, 116, 56, 156, 58, 156, 156, 156, 157, 124, 156, 156, 156, 156, 156, 156, 70, 156, 156, 156, 156, 156, 156, 156, 78, 79, - 156, 158, 157, 157, 74, 157, 86, 157, 157, 157, + 156, 156, 159, 157, 74, 157, 86, 157, 157, 157, 80, 157, 157, 157, 84, 156, 157, 87, 88, 89, - 157, 91, 157, 93, 157, 95, 157, 157, 98, 158, - 158, 158, 158, 103, 104, 105, 50, 51, 158, 109, + 157, 91, 157, 93, 157, 95, 157, 157, 98, 157, + 159, 158, 158, 103, 104, 105, 50, 51, 158, 109, 110, 158, 56, 158, 58, 115, 116, 158, 158, 158, 158, 158, 158, 158, 124, 135, 70, 137, 138, 139, 140, 141, 142, 143, 78, 79, 158, 158, 158, 149, 150, 158, 86, 158, 158, 158, 158, 158, 164, 159, - 158, 158, 158, 158, 158, -1, 156, 157, 159, 162, - 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, + 158, 158, 158, 158, 158, 158, 156, 157, 159, 158, + 158, 163, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, 159, -1, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 135, 160, 137, 138, 139, 140, 141, 142, 143, 160, 160, 160, 160, 160, 149, 150, 160, 160, 163, - -1, 162, -1, 163, 163, 159, 163, 163, 163, -1, + -1, 162, 162, -1, 163, 159, 163, 163, 163, -1, 163, 163, 163, 163, 163, 163, 163, 163, 163 ); protected $actionBase = array( - 0, 229, 310, 390, 470, 103, 325, 325, 784, -2, + 0, 229, 310, 390, 470, 103, 325, 325, 785, -2, -2, 149, -2, -2, -2, 660, 765, 799, 765, 589, 694, 870, 870, 870, 252, 404, 404, 404, 514, 177, 177, 918, 434, 118, 295, 313, 240, 491, 491, 491, @@ -483,9 +483,9 @@ class Php5 extends \PhpParser\ParserAbstract 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, 491, - 491, 491, 491, 491, 491, 491, 89, 206, 773, 550, - 535, 775, 776, 777, 912, 709, 913, 856, 857, 700, - 858, 859, 862, 863, 864, 855, 865, 935, 866, 599, + 491, 491, 491, 491, 491, 491, 89, 206, 775, 550, + 535, 776, 777, 778, 912, 709, 913, 859, 862, 700, + 863, 864, 865, 866, 867, 858, 871, 935, 872, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 322, 592, 285, 319, 232, 44, 691, 691, 691, 691, 691, 691, 691, 182, 182, 182, 182, 182, 182, @@ -504,43 +504,44 @@ class Php5 extends \PhpParser\ParserAbstract 554, 554, 679, -59, -59, 381, 462, 462, 462, 528, 717, 854, 382, 382, 382, 382, 382, 382, 561, 561, 561, -3, -3, -3, 692, 115, 137, 115, 137, 678, - 732, 450, 732, 338, 677, -15, 510, 810, 468, 707, - 850, 711, 853, 572, 735, 267, 529, 654, 674, 463, + 732, 450, 732, 338, 677, -15, 510, 812, 468, 707, + 856, 711, 857, 572, 735, 267, 529, 654, 674, 463, 529, 529, 529, 529, 654, 610, 640, 608, 463, 529, - 463, 718, 323, 496, 89, 570, 507, 675, 778, 293, - 670, 780, 290, 373, 332, 566, 278, 435, 733, 781, + 463, 718, 323, 496, 89, 570, 507, 675, 779, 293, + 670, 781, 290, 373, 332, 566, 278, 435, 733, 784, 914, 917, 385, 715, 675, 675, 675, 352, 511, 278, -8, 605, 605, 605, 605, 156, 605, 605, 605, 605, - 251, 276, 375, 402, 779, 657, 657, 690, 872, 869, - 869, 657, 689, 657, 690, 874, 874, 874, 874, 657, - 657, 657, 657, 869, 869, 869, 688, 869, 239, 703, - 704, 704, 874, 742, 743, 657, 657, 712, 869, 869, - 869, 712, 695, 874, 701, 741, 277, 869, 874, 672, + 251, 276, 375, 402, 780, 657, 657, 690, 869, 783, + 783, 657, 689, 657, 690, 874, 874, 874, 874, 657, + 657, 657, 657, 783, 783, 783, 688, 783, 239, 703, + 704, 704, 874, 742, 743, 657, 657, 712, 783, 783, + 783, 712, 695, 874, 701, 741, 277, 783, 874, 672, 689, 672, 657, 701, 672, 689, 689, 672, 22, 666, - 668, 873, 875, 887, 790, 662, 685, 879, 880, 876, - 878, 871, 699, 744, 745, 497, 669, 671, 673, 680, - 719, 682, 713, 674, 667, 667, 667, 655, 720, 655, - 667, 667, 667, 667, 667, 667, 667, 667, 916, 646, - 731, 714, 653, 749, 553, 573, 791, 664, 811, 900, - 893, 867, 919, 881, 898, 655, 920, 739, 247, 643, - 882, 783, 786, 655, 883, 655, 792, 655, 902, 812, - 686, 813, 814, 667, 910, 921, 923, 924, 925, 927, - 928, 929, 930, 684, 931, 750, 696, 894, 299, 877, - 718, 729, 705, 788, 751, 820, 328, 932, 823, 655, - 655, 794, 785, 655, 795, 756, 740, 890, 757, 895, - 933, 664, 708, 896, 655, 706, 825, 934, 328, 681, - 683, 888, 661, 761, 886, 911, 885, 796, 649, 663, - 829, 830, 831, 693, 763, 891, 892, 889, 764, 803, - 665, 805, 697, 832, 807, 884, 768, 833, 834, 899, - 676, 730, 710, 698, 687, 809, 835, 897, 769, 770, - 771, 848, 772, 849, 0, 0, 0, 0, 0, 0, + 668, 873, 875, 887, 791, 662, 685, 879, 880, 876, + 878, 811, 699, 744, 497, 669, 671, 673, 680, 719, + 682, 713, 674, 667, 667, 667, 655, 720, 655, 667, + 667, 667, 667, 667, 667, 667, 667, 868, 646, 731, + 714, 653, 745, 553, 573, 792, 664, 814, 900, 893, + 919, 920, 881, 898, 655, 916, 739, 247, 643, 882, + 813, 788, 655, 883, 655, 794, 655, 902, 820, 686, + 823, 825, 667, 910, 921, 923, 924, 925, 927, 928, + 929, 930, 684, 931, 749, 696, 894, 299, 877, 718, + 729, 705, 790, 750, 829, 328, 932, 830, 655, 655, + 795, 786, 655, 796, 751, 740, 890, 756, 895, 933, + 664, 708, 896, 655, 706, 831, 934, 328, 681, 683, + 888, 661, 757, 886, 911, 885, 803, 761, 649, 663, + 832, 833, 834, 693, 763, 891, 892, 889, 764, 805, + 665, 807, 768, 697, 835, 809, 884, 769, 848, 849, + 899, 676, 730, 710, 698, 687, 810, 850, 897, 770, + 771, 772, 853, 773, 855, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 138, 138, 138, 138, -2, -2, - -2, -2, 0, 0, -2, 0, 0, 0, 138, 138, + 0, 0, 0, 0, 0, 138, 138, 138, 138, -2, + -2, -2, -2, 0, 0, -2, 0, 0, 0, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 0, 0, 138, 138, 138, 138, + 138, 138, 138, 138, 138, 0, 0, 138, 138, 138, + 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, @@ -549,35 +550,34 @@ class Php5 extends \PhpParser\ParserAbstract 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, 138, - 138, 138, 138, 138, 138, 138, 138, 138, 138, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, - 599, 599, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 599, -21, -21, -21, -21, 599, - -21, -21, -21, -21, -21, -21, -21, 599, 599, 599, + 599, 599, 599, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 599, -21, -21, -21, -21, + 599, -21, -21, -21, -21, -21, -21, -21, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, 599, - 599, 599, 599, 599, 599, -21, 599, 599, 599, -21, - 382, -21, 382, 382, 382, 382, 382, 382, 382, 382, + 599, 599, 599, 599, 599, 599, -21, 599, 599, 599, + -21, 382, -21, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 599, 0, 0, 599, - -21, 599, -21, 599, -21, -21, 599, 599, 599, 599, - 599, 599, 599, -21, -21, -21, -21, -21, -21, 0, - 561, 561, 561, 561, -21, -21, -21, -21, 382, 382, - 382, 382, 382, 382, 259, 382, 382, 382, 382, 382, - 382, 382, 382, 382, 382, 382, 561, 561, -3, -3, - 382, 382, 382, 382, 382, 259, 382, 382, 463, 689, - 689, 689, 137, 137, 137, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 137, 463, 0, - 463, 0, 382, 463, 689, 463, 657, 137, 689, 689, - 463, 869, 616, 616, 616, 616, 328, 278, 0, 0, - 689, 689, 0, 0, 0, 0, 0, 689, 0, 0, - 0, 0, 0, 0, 869, 0, 0, 0, 0, 0, - 667, 247, 0, 705, 335, 0, 0, 0, 0, 0, - 0, 705, 335, 347, 347, 0, 684, 667, 667, 667, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 328 + 382, 382, 382, 382, 382, 382, 382, 599, 0, 0, + 599, -21, 599, -21, 599, -21, -21, 599, 599, 599, + 599, 599, 599, 599, -21, -21, -21, -21, -21, -21, + 0, 561, 561, 561, 561, -21, -21, -21, -21, 382, + 382, 382, 382, 382, 382, 259, 382, 382, 382, 382, + 382, 382, 382, 382, 382, 382, 382, 561, 561, -3, + -3, 382, 382, 382, 382, 382, 259, 382, 382, 463, + 689, 689, 689, 137, 137, 137, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 137, 463, + 0, 463, 0, 382, 463, 689, 463, 657, 137, 689, + 689, 463, 783, 616, 616, 616, 616, 328, 278, 0, + 0, 689, 689, 0, 0, 0, 0, 0, 689, 0, + 0, 0, 0, 0, 0, 783, 0, 0, 0, 0, + 0, 667, 247, 0, 705, 335, 0, 0, 0, 0, + 0, 0, 705, 335, 347, 347, 0, 684, 667, 667, + 667, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 328 ); protected $actionDefault = array( @@ -629,90 +629,90 @@ class Php5 extends \PhpParser\ParserAbstract 32767, 190, 173,32767, 400, 175, 498,32767,32767, 240, 32767, 240,32767, 400, 240,32767,32767, 240,32767, 415, 439,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767, 379, 380, 493, 506, - 32767, 507,32767, 413, 343, 344, 346, 322,32767, 324, - 369, 370, 371, 372, 373, 374, 375, 377,32767, 419, - 32767, 422,32767,32767,32767, 257,32767, 557,32767,32767, - 306, 557,32767,32767,32767, 551,32767,32767, 300,32767, - 32767,32767,32767, 253,32767, 169,32767, 541,32767, 558, - 32767, 515,32767, 342,32767,32767,32767,32767,32767,32767, - 32767,32767,32767, 516,32767,32767,32767,32767, 229,32767, - 452,32767, 116,32767,32767,32767, 189,32767,32767, 304, - 248,32767,32767, 550,32767,32767,32767,32767,32767,32767, - 32767,32767, 114,32767, 170,32767,32767,32767, 191,32767, - 32767, 515,32767,32767,32767,32767,32767,32767,32767, 295, + 32767,32767,32767,32767,32767, 379, 380, 493, 506,32767, + 507,32767, 413, 343, 344, 346, 322,32767, 324, 369, + 370, 371, 372, 373, 374, 375, 377,32767, 419,32767, + 422,32767,32767,32767, 257,32767, 557,32767,32767, 306, + 557,32767,32767,32767, 551,32767,32767, 300,32767,32767, + 32767,32767, 253,32767, 169,32767, 541,32767, 558,32767, + 515,32767, 342,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 516,32767,32767,32767,32767, 229,32767, 452, + 32767, 116,32767,32767,32767, 189,32767,32767, 304, 248, + 32767,32767, 550,32767,32767,32767,32767,32767,32767,32767, + 32767, 114,32767, 170,32767,32767,32767, 191,32767,32767, + 515,32767,32767,32767,32767,32767,32767,32767,32767, 295, 32767,32767,32767,32767,32767,32767,32767, 515,32767,32767, 233,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 415,32767, 276,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767, 127, 127, 3, 127, 127, 260, - 3, 260, 127, 260, 260, 127, 127, 127, 127, 127, - 127, 127, 127, 127, 127, 216, 219, 208, 208, 164, - 127, 127, 268 + 32767, 415,32767, 276,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767, 127, 127, 3, 127, 127, + 260, 3, 260, 127, 260, 260, 127, 127, 127, 127, + 127, 127, 127, 127, 127, 127, 216, 219, 208, 208, + 164, 127, 127, 268 ); protected $goto = array( 166, 140, 140, 140, 166, 187, 168, 144, 147, 141, 142, 143, 149, 163, 163, 163, 163, 144, 144, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, 165, - 138, 159, 160, 161, 162, 184, 139, 185, 494, 495, - 377, 496, 500, 501, 502, 503, 504, 505, 506, 507, - 970, 164, 145, 146, 148, 171, 176, 186, 203, 253, + 138, 159, 160, 161, 162, 184, 139, 185, 493, 494, + 377, 495, 499, 500, 501, 502, 503, 504, 505, 506, + 971, 164, 145, 146, 148, 171, 176, 186, 203, 253, 256, 258, 260, 263, 264, 265, 266, 267, 268, 269, 277, 278, 279, 280, 303, 304, 328, 329, 330, 394, - 395, 396, 543, 188, 189, 190, 191, 192, 193, 194, + 395, 396, 542, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 150, 151, 152, 167, 153, 169, 154, 204, 170, 155, 156, 157, 205, - 158, 136, 621, 561, 757, 561, 561, 561, 561, 561, - 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, - 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, - 561, 561, 561, 561, 561, 561, 561, 561, 561, 561, - 561, 561, 561, 561, 561, 561, 561, 561, 561, 1113, - 629, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, - 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, 1113, - 1113, 1113, 1113, 1113, 1113, 758, 520, 531, 509, 656, - 556, 1183, 750, 509, 592, 786, 1183, 888, 612, 613, - 884, 617, 618, 624, 626, 631, 633, 817, 855, 855, - 855, 855, 850, 856, 174, 891, 891, 1205, 1205, 177, + 158, 136, 622, 560, 758, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, + 560, 560, 560, 560, 560, 560, 560, 560, 560, 1114, + 630, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, 1114, + 1114, 1114, 1114, 1114, 1114, 759, 519, 530, 508, 657, + 555, 1184, 350, 508, 591, 787, 1184, 889, 613, 614, + 885, 618, 619, 625, 627, 632, 634, 751, 856, 856, + 856, 856, 851, 857, 174, 892, 892, 1206, 1206, 177, 178, 179, 401, 402, 403, 404, 173, 202, 206, 208, 257, 259, 261, 262, 270, 271, 272, 273, 274, 275, 281, 282, 283, 284, 305, 306, 331, 332, 333, 406, 407, 408, 409, 175, 180, 254, 255, 181, 182, 183, - 498, 498, 498, 498, 498, 498, 861, 498, 498, 498, - 498, 498, 498, 498, 498, 498, 498, 510, 586, 538, - 601, 602, 510, 545, 546, 547, 548, 549, 550, 551, - 552, 554, 587, 1209, 560, 350, 560, 560, 560, 560, - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, - 560, 560, 560, 560, 560, 560, 560, 560, 560, 560, - 400, 607, 537, 537, 569, 533, 909, 535, 535, 497, - 499, 525, 541, 570, 573, 584, 591, 298, 296, 296, - 296, 298, 289, 299, 611, 378, 511, 614, 595, 947, - 375, 511, 437, 437, 437, 437, 437, 437, 1163, 437, - 437, 437, 437, 437, 437, 437, 437, 437, 437, 1077, - 948, 338, 1175, 321, 1077, 898, 898, 898, 898, 606, - 898, 898, 1217, 1217, 1202, 753, 576, 605, 756, 1077, - 1077, 1077, 1077, 1077, 1077, 1069, 384, 384, 384, 391, - 1217, 877, 859, 857, 859, 655, 466, 512, 886, 881, - 753, 384, 753, 384, 968, 384, 895, 385, 588, 353, - 414, 384, 1231, 1019, 542, 1197, 1197, 1197, 568, 1094, - 386, 386, 386, 904, 915, 515, 1029, 19, 15, 372, - 389, 915, 940, 448, 450, 632, 340, 1216, 1216, 1114, - 615, 938, 840, 555, 775, 386, 913, 1070, 1073, 1074, - 399, 1069, 1182, 660, 23, 1216, 773, 1182, 544, 603, - 1066, 1219, 1071, 1174, 1071, 519, 1199, 1199, 1199, 1089, - 1088, 1072, 343, 523, 534, 519, 519, 772, 351, 352, - 13, 579, 583, 627, 1061, 388, 782, 562, 771, 515, - 783, 1181, 3, 4, 918, 956, 865, 451, 574, 1160, + 497, 497, 497, 497, 497, 497, 818, 497, 497, 497, + 497, 497, 497, 497, 497, 497, 497, 509, 585, 862, + 601, 602, 509, 544, 545, 546, 547, 548, 549, 550, + 551, 553, 586, 338, 559, 321, 559, 559, 559, 559, + 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, + 559, 559, 559, 559, 559, 559, 559, 559, 559, 559, + 400, 607, 536, 536, 568, 532, 537, 534, 534, 496, + 498, 524, 540, 569, 572, 583, 590, 298, 296, 296, + 296, 298, 289, 299, 611, 1210, 510, 615, 910, 948, + 375, 510, 437, 437, 437, 437, 437, 437, 594, 437, + 437, 437, 437, 437, 437, 437, 437, 437, 437, 1078, + 949, 388, 1176, 561, 1078, 899, 899, 899, 899, 378, + 899, 899, 1218, 1218, 1164, 754, 351, 352, 757, 1078, + 1078, 1078, 1078, 1078, 1078, 1070, 384, 384, 384, 606, + 1218, 878, 860, 858, 860, 656, 466, 511, 887, 882, + 754, 384, 754, 384, 969, 384, 391, 385, 587, 353, + 414, 384, 1232, 1203, 541, 1198, 1198, 1198, 567, 1095, + 386, 386, 386, 1020, 916, 514, 1030, 19, 15, 372, + 776, 916, 941, 448, 450, 633, 896, 1217, 1217, 1115, + 616, 939, 841, 554, 905, 386, 340, 1071, 1074, 1075, + 399, 1070, 1183, 914, 23, 1217, 774, 1183, 543, 603, + 389, 1220, 1072, 1175, 1072, 518, 1200, 1200, 1200, 575, + 605, 1073, 343, 522, 533, 518, 518, 773, 1090, 1089, + 13, 578, 582, 628, 3, 4, 783, 1067, 772, 514, + 1062, 1182, 784, 661, 919, 451, 866, 573, 957, 1161, 464, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 514, 529, 0, 0, 0, 0, - 514, 0, 529, 0, 0, 0, 0, 610, 513, 516, - 439, 440, 1067, 619, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 780, 1224, 0, 0, 0, 0, - 0, 524, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 778, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 513, 528, 0, 0, 0, 0, + 513, 0, 528, 0, 0, 0, 0, 610, 512, 515, + 439, 440, 1068, 620, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 781, 1225, 0, 0, 0, 0, + 0, 523, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 779, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 301, 301 ); @@ -739,40 +739,40 @@ class Php5 extends \PhpParser\ParserAbstract 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 16, 102, 32, 69, 32, - 32, 120, 6, 69, 32, 29, 120, 32, 32, 32, - 32, 32, 32, 32, 32, 32, 32, 50, 69, 69, + 32, 120, 72, 69, 32, 29, 120, 32, 32, 32, + 32, 32, 32, 32, 32, 32, 32, 6, 69, 69, 69, 69, 69, 69, 27, 77, 77, 77, 77, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, - 119, 119, 119, 119, 119, 119, 33, 119, 119, 119, - 119, 119, 119, 119, 119, 119, 119, 119, 67, 110, + 119, 119, 119, 119, 119, 119, 50, 119, 119, 119, + 119, 119, 119, 119, 119, 119, 119, 119, 67, 33, 67, 67, 119, 111, 111, 111, 111, 111, 111, 111, - 111, 111, 111, 142, 57, 72, 57, 57, 57, 57, + 111, 111, 111, 127, 57, 127, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 51, 51, 51, 51, 51, 51, 84, 51, 51, 51, + 51, 51, 51, 51, 51, 51, 110, 51, 51, 51, 51, 51, 51, 51, 51, 51, 51, 5, 5, 5, - 5, 5, 5, 5, 63, 46, 124, 63, 129, 98, - 63, 124, 57, 57, 57, 57, 57, 57, 133, 57, + 5, 5, 5, 5, 63, 142, 124, 63, 84, 98, + 63, 124, 57, 57, 57, 57, 57, 57, 129, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 98, 127, 82, 127, 57, 57, 57, 57, 57, 49, - 57, 57, 144, 144, 140, 11, 40, 40, 14, 57, - 57, 57, 57, 57, 57, 82, 13, 13, 13, 48, + 98, 12, 82, 12, 57, 57, 57, 57, 57, 46, + 57, 57, 144, 144, 133, 11, 72, 72, 14, 57, + 57, 57, 57, 57, 57, 82, 13, 13, 13, 49, 144, 14, 14, 14, 14, 14, 57, 14, 14, 14, - 11, 13, 11, 13, 102, 13, 79, 11, 70, 70, - 70, 13, 13, 103, 2, 9, 9, 9, 2, 34, - 125, 125, 125, 81, 13, 13, 34, 34, 34, 34, - 17, 13, 8, 8, 8, 8, 18, 143, 143, 8, - 8, 8, 9, 34, 25, 125, 85, 82, 82, 82, - 125, 82, 121, 74, 34, 143, 24, 121, 47, 34, - 116, 143, 82, 82, 82, 47, 121, 121, 121, 126, - 126, 82, 58, 58, 58, 47, 47, 23, 72, 72, - 58, 62, 62, 62, 114, 12, 23, 12, 23, 13, - 26, 121, 30, 30, 86, 100, 71, 65, 66, 132, + 11, 13, 11, 13, 102, 13, 48, 11, 70, 70, + 70, 13, 13, 140, 2, 9, 9, 9, 2, 34, + 125, 125, 125, 103, 13, 13, 34, 34, 34, 34, + 25, 13, 8, 8, 8, 8, 79, 143, 143, 8, + 8, 8, 9, 34, 81, 125, 18, 82, 82, 82, + 125, 82, 121, 85, 34, 143, 24, 121, 47, 34, + 17, 143, 82, 82, 82, 47, 121, 121, 121, 40, + 40, 82, 58, 58, 58, 47, 47, 23, 126, 126, + 58, 62, 62, 62, 30, 30, 23, 116, 23, 13, + 114, 121, 26, 74, 86, 65, 71, 66, 100, 132, 109, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 9, 9, -1, -1, -1, -1, 9, -1, 9, -1, -1, -1, -1, 13, 9, 9, @@ -785,39 +785,39 @@ class Php5 extends \PhpParser\ParserAbstract ); protected $gotoBase = array( - 0, 0, -172, 0, 0, 353, 201, 0, 477, 149, - 0, 110, 195, 117, 426, 112, 203, 140, 171, 0, - 0, 0, 0, 168, 164, 157, 119, 27, 0, 205, - -118, 0, -428, 266, 51, 0, 0, 0, 0, 0, - 388, 0, 0, -24, 0, 0, 345, 484, 146, 133, - 209, 75, 0, 0, 0, 0, 0, 107, 161, 0, - 0, 0, 222, -77, 0, 106, 97, -343, 0, -94, - 135, 123, -129, 0, 129, 0, 0, -50, 0, 143, - 0, 159, 64, 0, 338, 132, 122, 0, 0, 0, + 0, 0, -173, 0, 0, 353, 216, 0, 477, 149, + 0, 110, 71, 117, 426, 112, 203, 170, 181, 0, + 0, 0, 0, 168, 164, 143, 121, 27, 0, 205, + -127, 0, -429, 279, 51, 0, 0, 0, 0, 0, + 481, 0, 0, -24, 0, 0, 379, 484, 163, 153, + 268, 75, 0, 0, 0, 0, 0, 107, 161, 0, + 0, 0, 222, -77, 0, 104, 96, -344, 0, -94, + 135, 123, -232, 0, 169, 0, 0, -50, 0, 173, + 0, 180, 64, 0, 360, 139, 122, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 98, 0, - 121, 0, 165, 156, 0, 0, 0, 0, 0, 87, - 273, 259, 0, 0, 114, 0, 150, 0, 0, -5, - -91, 200, 0, 0, 84, 154, 202, 77, -48, 178, - 0, 0, 93, 187, 0, 0, 0, 0, 0, 0, - 136, 0, 286, 167, 102, 0, 0 + 124, 0, 165, 166, 0, 0, 0, 0, 0, 87, + 340, 259, 0, 0, 120, 0, 177, 0, 0, -5, + -91, 200, 0, 0, 84, 154, 211, -21, -48, 188, + 0, 0, 93, 213, 0, 0, 0, 0, 0, 0, + 175, 0, 358, 167, 102, 0, 0 ); protected $gotoDefault = array( - -32768, 468, 664, 2, 665, 835, 740, 748, 598, 482, - 630, 582, 380, 1193, 792, 793, 794, 381, 368, 483, - 379, 410, 405, 781, 774, 776, 784, 172, 411, 787, - 1, 789, 518, 825, 1020, 365, 797, 366, 590, 799, - 527, 801, 802, 137, 382, 383, 528, 484, 390, 577, - 816, 276, 387, 818, 367, 819, 828, 371, 465, 455, - 460, 530, 557, 609, 432, 447, 571, 565, 536, 1086, - 566, 864, 349, 872, 661, 880, 883, 485, 558, 894, - 452, 902, 1099, 397, 908, 914, 919, 291, 922, 417, - 412, 585, 927, 928, 5, 932, 622, 623, 8, 312, - 955, 599, 969, 420, 1039, 1041, 486, 487, 522, 459, - 508, 526, 488, 1062, 441, 413, 1065, 433, 489, 490, - 434, 435, 1083, 355, 1168, 354, 449, 320, 1155, 580, - 1118, 456, 1208, 1164, 348, 491, 492, 376, 1187, 392, - 1203, 438, 1210, 1218, 344, 540, 567 + -32768, 468, 665, 2, 666, 836, 741, 749, 598, 482, + 631, 581, 380, 1194, 793, 794, 795, 381, 368, 766, + 379, 410, 405, 782, 775, 777, 785, 172, 411, 788, + 1, 790, 517, 826, 1021, 365, 798, 366, 589, 800, + 526, 802, 803, 137, 382, 383, 527, 483, 390, 576, + 817, 276, 387, 819, 367, 820, 829, 371, 465, 455, + 460, 529, 556, 609, 432, 447, 570, 564, 535, 1087, + 565, 865, 349, 873, 662, 881, 884, 484, 557, 895, + 452, 903, 1100, 397, 909, 915, 920, 291, 923, 417, + 412, 584, 928, 929, 5, 933, 623, 624, 8, 312, + 956, 599, 970, 420, 1040, 1042, 485, 486, 521, 459, + 507, 525, 487, 1063, 441, 413, 1066, 433, 488, 489, + 434, 435, 1084, 355, 1169, 354, 449, 320, 1156, 579, + 1119, 456, 1209, 1165, 348, 490, 491, 376, 1188, 392, + 1204, 438, 1211, 1219, 344, 539, 566 ); protected $ruleToNonTerminal = array( @@ -891,7 +891,7 @@ class Php5 extends \PhpParser\ParserAbstract 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 5, 4, - 3, 4, 2, 3, 1, 1, 7, 6, 3, 1, + 3, 4, 1, 3, 1, 1, 8, 7, 3, 1, 3, 1, 3, 1, 1, 3, 1, 3, 1, 2, 3, 1, 3, 3, 1, 3, 2, 0, 1, 1, 1, 1, 1, 3, 5, 8, 3, 5, 9, 3, @@ -1256,7 +1256,7 @@ protected function initReduceCallbacks() { $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 102 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(2-1)]; + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 103 => function ($stackPos) { $this->semValue = new Stmt\Const_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); @@ -1268,10 +1268,10 @@ protected function initReduceCallbacks() { $this->semValue = Stmt\Use_::TYPE_CONSTANT; }, 106 => function ($stackPos) { - $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos-(7-3)], $this->semStack[$stackPos-(7-6)], $this->semStack[$stackPos-(7-2)], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos-(8-3)], $this->semStack[$stackPos-(8-6)], $this->semStack[$stackPos-(8-2)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); }, 107 => function ($stackPos) { - $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos-(7-2)], $this->semStack[$stackPos-(7-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); }, 108 => function ($stackPos) { $this->semStack[$stackPos-(3-1)][] = $this->semStack[$stackPos-(3-3)]; $this->semValue = $this->semStack[$stackPos-(3-1)]; diff --git a/lib/nikic/php-parser/lib/PhpParser/Parser/Php7.php b/lib/nikic/php-parser/lib/PhpParser/Parser/Php7.php index 6d2b4b0f9c..d41bb83695 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Parser/Php7.php +++ b/lib/nikic/php-parser/lib/PhpParser/Parser/Php7.php @@ -26,8 +26,8 @@ class Php7 extends \PhpParser\ParserAbstract protected $defaultAction = -32766; protected $unexpectedTokenRule = 32767; - protected $YY2TBLSTATE = 434; - protected $numNonLeafStates = 736; + protected $YY2TBLSTATE = 435; + protected $numNonLeafStates = 737; protected $symbolToName = array( "EOF", @@ -244,130 +244,130 @@ class Php7 extends \PhpParser\ParserAbstract ); protected $action = array( - 133, 134, 135, 579, 136, 137, 0, 748, 749, 750, + 133, 134, 135, 580, 136, 137, 0, 749, 750, 751, 138, 38, 327,-32766,-32766,-32766,-32766,-32766,-32766,-32767, - -32767,-32767,-32767, 102, 103, 104, 105, 106, 1109, 1110, - 1111, 1108, 1107, 1106, 1112, 742, 741,-32766, 1232,-32766, + -32767,-32767,-32767, 102, 103, 104, 105, 106, 1110, 1111, + 1112, 1109, 1108, 1107, 1113, 743, 742,-32766, 1233,-32766, -32766,-32766,-32766,-32766,-32766,-32766,-32767,-32767,-32767,-32767, - -32767, 2, 107, 108, 109, 751, 274, 381, 380,-32766, - -32766,-32766,-32766, 104, 105, 106, 1024, 422, 110, 265, - 139, 403, 755, 756, 757, 758, 466, 467, 428, 938, - 291,-32766, 287,-32766,-32766, 759, 760, 761, 762, 763, - 764, 765, 766, 767, 768, 769, 789, 580, 790, 791, - 792, 793, 781, 782, 344, 345, 784, 785, 770, 771, - 772, 774, 775, 776, 355, 816, 817, 818, 819, 820, - 581, 777, 778, 582, 583, 810, 801, 799, 800, 813, - 796, 797, 687, -545, 584, 585, 795, 586, 587, 588, - 589, 590, 591, -328, -593, -367, 1234, -367, 798, 592, - 593, -593, 140,-32766,-32766,-32766, 133, 134, 135, 579, - 136, 137, 1057, 748, 749, 750, 138, 38, 688, 1020, - 1019, 1018, 1021, 390,-32766, 7,-32766,-32766,-32766,-32766, - -32766,-32766,-32766,-32766,-32766,-32766, 379, 380, 1033, 689, - 690, 742, 741,-32766,-32766,-32766, 422, -545, -545, -590, - -32766,-32766,-32766, 1032,-32766, 127, -590, 1236, 1235, 1237, - 1318, 751, -545, 290,-32766, 283,-32766,-32766,-32766,-32766, - -32766, 1236, 1235, 1237, -545, 265, 139, 403, 755, 756, - 757, 758, 16, 481, 428, 458, 459, 460, 298, 722, - 35, 759, 760, 761, 762, 763, 764, 765, 766, 767, - 768, 769, 789, 580, 790, 791, 792, 793, 781, 782, - 344, 345, 784, 785, 770, 771, 772, 774, 775, 776, - 355, 816, 817, 818, 819, 820, 581, 777, 778, 582, - 583, 810, 801, 799, 800, 813, 796, 797, 129, 824, - 584, 585, 795, 586, 587, 588, 589, 590, 591, -328, - 83, 84, 85, -593, 798, 592, 593, -593, 149, 773, - 743, 744, 745, 746, 747, 824, 748, 749, 750, 786, - 787, 37, 145, 86, 87, 88, 89, 90, 91, 92, + -32767, 2, 107, 108, 109, 752, 274, 381, 380,-32766, + -32766,-32766,-32766, 104, 105, 106, 1025, 423, 110, 265, + 139, 402, 756, 757, 758, 759, 467, 468, 429, 939, + 291,-32766, 287,-32766,-32766, 760, 761, 762, 763, 764, + 765, 766, 767, 768, 769, 770, 790, 581, 791, 792, + 793, 794, 782, 783, 344, 345, 785, 786, 771, 772, + 773, 775, 776, 777, 355, 817, 818, 819, 820, 821, + 582, 778, 779, 583, 584, 811, 802, 800, 801, 814, + 797, 798, 688, -545, 585, 586, 796, 587, 588, 589, + 590, 591, 592, -328, -593, -367, 1235, -367, 799, 593, + 594, -593, 140,-32766,-32766,-32766, 133, 134, 135, 580, + 136, 137, 1058, 749, 750, 751, 138, 38, 689, 1021, + 1020, 1019, 1022, 390,-32766, 7,-32766,-32766,-32766,-32766, + -32766,-32766,-32766,-32766,-32766,-32766, 379, 380, 1034, 690, + 691, 743, 742,-32766,-32766,-32766, 423, -545, -545, -590, + -32766,-32766,-32766, 1033,-32766, 127, -590, 1237, 1236, 1238, + 1319, 752, -545, 290,-32766, 283,-32766,-32766,-32766,-32766, + -32766, 1237, 1236, 1238, -545, 265, 139, 402, 756, 757, + 758, 759, 16, 482, 429, 459, 460, 461, 298, 723, + 35, 760, 761, 762, 763, 764, 765, 766, 767, 768, + 769, 770, 790, 581, 791, 792, 793, 794, 782, 783, + 344, 345, 785, 786, 771, 772, 773, 775, 776, 777, + 355, 817, 818, 819, 820, 821, 582, 778, 779, 583, + 584, 811, 802, 800, 801, 814, 797, 798, 129, 825, + 585, 586, 796, 587, 588, 589, 590, 591, 592, -328, + 83, 84, 85, -593, 799, 593, 594, -593, 149, 774, + 744, 745, 746, 747, 748, 825, 749, 750, 751, 787, + 788, 37, 145, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 291, 274, 835, - 254, 1109, 1110, 1111, 1108, 1107, 1106, 1112, -590, 860, - 110, 861, -590, 482, 751,-32766,-32766,-32766,-32766,-32766, - 142, 603, 1085, 742, 741, 1262, 326, 987, 752, 753, - 754, 755, 756, 757, 758, 309,-32766, 822,-32766,-32766, - -32766,-32766, 242, 553, 759, 760, 761, 762, 763, 764, - 765, 766, 767, 768, 769, 789, 812, 790, 791, 792, - 793, 781, 782, 783, 811, 784, 785, 770, 771, 772, - 774, 775, 776, 815, 816, 817, 818, 819, 820, 821, - 777, 778, 779, 780, 810, 801, 799, 800, 813, 796, - 797, 311, 940, 788, 794, 795, 802, 803, 805, 804, - 806, 807, 323, 609, 1274, 1033, 833, 798, 809, 808, - 50, 51, 52, 512, 53, 54, 860, 241, 861, 918, - 55, 56, -111, 57,-32766,-32766,-32766, -111, 826, -111, - 290, 1302, 1347, 356, 305, 1348, 339, -111, -111, -111, + 103, 104, 105, 106, 107, 108, 109, 291, 274, 836, + 254, 1110, 1111, 1112, 1109, 1108, 1107, 1113, -590, 861, + 110, 862, -590, 483, 752,-32766,-32766,-32766,-32766,-32766, + 142, 604, 1086, 743, 742, 1263, 326, 988, 753, 754, + 755, 756, 757, 758, 759, 309,-32766, 823,-32766,-32766, + -32766,-32766, 242, 554, 760, 761, 762, 763, 764, 765, + 766, 767, 768, 769, 770, 790, 813, 791, 792, 793, + 794, 782, 783, 784, 812, 785, 786, 771, 772, 773, + 775, 776, 777, 816, 817, 818, 819, 820, 821, 822, + 778, 779, 780, 781, 811, 802, 800, 801, 814, 797, + 798, 311, 941, 789, 795, 796, 803, 804, 806, 805, + 807, 808, 323, 610, 1275, 1034, 834, 799, 810, 809, + 50, 51, 52, 513, 53, 54, 861, 241, 862, 919, + 55, 56, -111, 57,-32766,-32766,-32766, -111, 827, -111, + 290, 1303, 1348, 356, 305, 1349, 339, -111, -111, -111, -111, -111, -111, -111, -111,-32766, -194,-32766,-32766,-32766, - -193, 956, 957, 829, -86, 988, 958, 834, 58, 59, - 340, 428, 952, -544, 60, 832, 61, 247, 248, 62, - 63, 64, 65, 66, 67, 68, 69, 1241, 28, 267, - 70, 444, 513, -342,-32766, 141, 1268, 1269, 514, 918, - 833, 326, -272, 918, 1266, 42, 25, 515, 940, 516, - 14, 517, 908, 518, 828, 369, 519, 520, 373, 709, - 1033, 44, 45, 445, 376, 375, 388, 46, 521, 712, - -86, 440, 1101, 367, 338, -543, 441, -544, -544, 830, - 1227, 442, 523, 524, 525, 290, 1236, 1235, 1237, 361, - 1030, 443, -544, 1087, 526, 527, 839, 1255, 1256, 1257, - 1258, 1252, 1253, 297, -544, 151, -550, -584, 833, 1259, - 1254, -584, 1033, 1236, 1235, 1237, 298, -154, -154, -154, - 152, 71, 908, 321, 322, 326, 908, 920, 1030, 707, - 833, 154, -154, 1337, -154, 155, -154, 283, -154, -543, - -543, 82, 1232, 1086, 1322, 734, 156, 326, 374, 158, - 1033, 1321, -194, -79, -543, -88, -193, 742, 741, 956, - 957, 653, 26,-32766, 522, -51, -543, 33, -549, 894, - 952, -111, -111, -111, 32, 111, 112, 113, 114, 115, + -193, 957, 958, 830, -86, 989, 959, 835, 58, 59, + 340, 429, 953, -544, 60, 833, 61, 247, 248, 62, + 63, 64, 65, 66, 67, 68, 69, 1242, 28, 267, + 70, 445, 514, -342,-32766, 141, 1269, 1270, 515, 919, + 834, 326, -272, 919, 1267, 42, 25, 516, 941, 517, + 14, 518, 909, 519, 829, 369, 520, 521, 373, 710, + 1034, 44, 45, 446, 376, 375, 388, 46, 522, 713, + -86, 441, 1102, 367, 338, -543, 442, -544, -544, 831, + 1228, 443, 524, 525, 526, 290, 1237, 1236, 1238, 361, + 1031, 444, -544, 1088, 527, 528, 840, 1256, 1257, 1258, + 1259, 1253, 1254, 297, -544, 151, -550, -584, 834, 1260, + 1255, -584, 1034, 1237, 1236, 1238, 298, -154, -154, -154, + 152, 71, 909, 321, 322, 326, 909, 921, 1031, 708, + 834, 154, -154, 1338, -154, 155, -154, 283, -154, -543, + -543, 82, 1233, 1087, 1323, 735, 156, 326, 374, 158, + 1034, 1322, -194, -79, -543, -88, -193, 743, 742, 957, + 958, 654, 26,-32766, 523, -51, -543, 33, -549, 895, + 953, -111, -111, -111, 32, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, -59, 75, - 28, 672, 673, 326, -58, 36, 250, 920, 124, 707, - 125, 920, 833, 707, -154, 130, 1266, 131,-32766, -547, - 144, -542, 150, 406, 1234, 377, 378, 1146, 1148, 382, - 383,-32766,-32766,-32766, -85,-32766, 1056,-32766, -542,-32766, - 644, 645,-32766, 159, 160, 161, 1232,-32766,-32766,-32766, - 162, -79, 1227,-32766,-32766, 742, 741, 163, -302,-32766, - 419, -75, -4, 918, -73, 287, 526, 527,-32766, 1255, - 1256, 1257, 1258, 1252, 1253, -72, -71, -70, -69, -68, - -67, 1259, 1254, -547, -547, -542, -542, 742, 741, -66, - -47, -18,-32766, 73, 148, 918, 322, 326, 1234, 273, - -542, 284, -542, -542, 723,-32766,-32766,-32766, 726,-32766, - -547,-32766, -542,-32766, 917, 147,-32766, -542, 288, 289, - -298,-32766,-32766,-32766,-32766, 713, 279,-32766,-32766, -542, - 1234, 280, 285,-32766, 419, 48, 286,-32766,-32766,-32766, - 332,-32766,-32766,-32766, 292,-32766, 908, 293,-32766, 934, - 274, 1030, 918,-32766,-32766,-32766, 110, 682, 132,-32766, - -32766, 833, 146,-32766, 559,-32766, 419, 659, 374, 824, - 435, 1349, 74, 1033,-32766, 296, 654, 1116, 908, 956, - 957, 306, 714, 698, 522, 555, 303, 13, 310, 852, - 952, -111, -111, -111, 700, 463, 492, 953, 283, 299, - 300,-32766, 49, 675, 918, 304, 660, 1234, 676, 936, - 1273,-32766, 10, 1263,-32766,-32766,-32766, 642,-32766, 918, - -32766, 920,-32766, 707, -4,-32766, 126, 34, 918, 565, - -32766,-32766,-32766,-32766, 0, 908,-32766,-32766, 0, 1234, - 918, 0,-32766, 419, 0, 0,-32766,-32766,-32766, 717, - -32766,-32766,-32766, 920,-32766, 707, 1033,-32766, 724, 1275, - 0, 487,-32766,-32766,-32766,-32766, 301, 302,-32766,-32766, - -507, 1234, 571, -497,-32766, 419, 607, 8,-32766,-32766, - -32766, 372,-32766,-32766,-32766, 17,-32766, 908, 371,-32766, - 832, 298, 320, 128,-32766,-32766,-32766, 40, 370, 41, - -32766,-32766, 908, -250, -250, -250,-32766, 419, 731, 374, - 973, 908, 707, 732, 899,-32766, 997, 974, 728, 981, - 956, 957, 971, 908, 982, 522, 897, 969, 1090, 1093, - 894, 952, -111, -111, -111, 28, 1094, 1091, 1092, -249, - -249, -249, 1241, 1098, 708, 374, 844, 833, 1288, 1306, - 1340, 1266, 647, 1267, 711, 715, 956, 957, 716, 1241, - 718, 522, 920, 719, 707, -250, 894, 952, -111, -111, - -111, 720, -16, 721, 725, 710, -511, 920, 895, 707, - -578, 1232, 1344, 1346, 855, 854, 920, 1227, 707, -577, - 863, 946, 989, 862, 1345, 945, 943, 944, 920, 947, - 707, -249, 527, 1218, 1255, 1256, 1257, 1258, 1252, 1253, - 927, 937, 925, 979, 980, 631, 1259, 1254, 1343, 1300, - -32766, 1289, 1307, 833, 1316, -275, 1234, -576, 73, -550, + 28, 673, 674, 326, -58, 36, 250, 921, 124, 708, + 125, 921, 834, 708, -154, 130, 1267, 131,-32766, -547, + 144, -542, 150, 406, 1235, 377, 378, 1147, 1149, 382, + 383,-32766,-32766,-32766, -85,-32766, 1057,-32766, -542,-32766, + 645, 646,-32766, 159, 160, 161, 1233,-32766,-32766,-32766, + 162, -79, 1228,-32766,-32766, 743, 742, 163, -302,-32766, + 420, -75, -4, 919, -73, 287, 527, 528,-32766, 1256, + 1257, 1258, 1259, 1253, 1254, -72, -71, -70, -69, -68, + -67, 1260, 1255, -547, -547, -542, -542, 743, 742, -66, + -47, -18,-32766, 73, 148, 919, 322, 326, 1235, 273, + -542, 284, -542, -542, 724,-32766,-32766,-32766, 727,-32766, + -547,-32766, -542,-32766, 918, 147,-32766, -542, 288, 289, + -298,-32766,-32766,-32766,-32766, 714, 279,-32766,-32766, -542, + 1235, 280, 285,-32766, 420, 48, 286,-32766,-32766,-32766, + 332,-32766,-32766,-32766, 292,-32766, 909, 293,-32766, 935, + 274, 1031, 919,-32766,-32766,-32766, 110, 683, 132,-32766, + -32766, 834, 146,-32766, 560,-32766, 420, 660, 374, 825, + 436, 1350, 74, 1034,-32766, 296, 655, 1117, 909, 957, + 958, 306, 715, 699, 523, 556, 303, 13, 310, 853, + 953, -111, -111, -111, 701, 464, 493, 954, 283, 299, + 300,-32766, 49, 676, 919, 304, 661, 1235, 677, 937, + 1274,-32766, 10, 1264,-32766,-32766,-32766, 643,-32766, 919, + -32766, 921,-32766, 708, -4,-32766, 126, 34, 919, 566, + -32766,-32766,-32766,-32766, 0, 909,-32766,-32766, 0, 1235, + 919, 0,-32766, 420, 0, 0,-32766,-32766,-32766, 718, + -32766,-32766,-32766, 921,-32766, 708, 1034,-32766, 725, 1276, + 0, 488,-32766,-32766,-32766,-32766, 301, 302,-32766,-32766, + -507, 1235, 572, -497,-32766, 420, 608, 8,-32766,-32766, + -32766, 372,-32766,-32766,-32766, 17,-32766, 909, 371,-32766, + 833, 298, 320, 128,-32766,-32766,-32766, 40, 370, 41, + -32766,-32766, 909, -250, -250, -250,-32766, 420, 732, 374, + 974, 909, 708, 733, 900,-32766, 998, 975, 405, 982, + 957, 958, 972, 909, 983, 523, 898, 970, 1091, 1094, + 895, 953, -111, -111, -111, 28, 1095, 1092, 1093, -249, + -249, -249, 1242, 1099, 709, 374, 845, 834, 1289, 1307, + 1341, 1267, 648, 1268, 712, 716, 957, 958, 717, 1242, + 719, 523, 921, 720, 708, -250, 895, 953, -111, -111, + -111, 721, -16, 722, 726, 711, -511, 921, 409, 708, + -578, 1233, 729, 896, 1345, 1347, 921, 1228, 708, -577, + 856, 855, 947, 990, 1346, 946, 944, 945, 921, 948, + 708, -249, 528, 1219, 1256, 1257, 1258, 1259, 1253, 1254, + 928, 938, 926, 980, 981, 632, 1260, 1255, 1344, 1301, + -32766, 1290, 1308, 834, 1317, -275, 1235, -576, 73, -550, -549, 322, 326,-32766,-32766,-32766, -548,-32766, -491,-32766, - 833,-32766, 1, 29,-32766, 30, 39, 43, 47,-32766, - -32766,-32766, 72, 76, 77,-32766,-32766, 1232, -111, -111, - 78,-32766, 419, -111, 79, 80, 81, 143, 153, -111, - -32766, 157, 246, 328, 1232, -111, -111, 356,-32766, 357, + 834,-32766, 1, 29,-32766, 30, 39, 43, 47,-32766, + -32766,-32766, 72, 76, 77,-32766,-32766, 1233, -111, -111, + 78,-32766, 420, -111, 79, 80, 81, 143, 153, -111, + -32766, 157, 246, 328, 1233, -111, -111, 356,-32766, 357, -111, 358, 359, 360, 361, 362, -111, 363, 364, 365, - 366, 368, 436, 0, -273,-32766, -272, 19, 20, 298, - 21, 22, 24, 405, 75, 1203, 483, 484, 326, 491, - 0, 494, 495, 496, 497, 501, 298, 502, 503, 510, - 693, 75, 0, 1245, 1186, 326, 1264, 1059, 1058, 1039, - 1222, 1035, -277, -103, 18, 23, 27, 295, 404, 600, - 604, 633, 699, 1190, 1240, 1187, 1319, 0, 0, 0, + 366, 368, 437, 0, -273,-32766, -272, 19, 20, 298, + 21, 22, 24, 404, 75, 1204, 484, 485, 326, 492, + 0, 495, 496, 497, 498, 502, 298, 503, 504, 511, + 694, 75, 0, 1246, 1187, 326, 1265, 1060, 1059, 1040, + 1223, 1036, -277, -103, 18, 23, 27, 295, 403, 601, + 605, 634, 700, 1191, 1241, 1188, 1320, 0, 0, 0, 326 ); @@ -539,43 +539,43 @@ class Php7 extends \PhpParser\ParserAbstract 1058, 1058, 1058, 1058, 1058, 1058, 1058, 1073, 336, 1059, 423, 1073, 1073, 1073, 336, 336, 336, 336, 336, 336, 336, 336, 336, 336, 619, 423, 586, 616, 423, 795, - 336, 348, 814, 348, 348, 348, 348, 348, 348, 348, - 348, 348, 348, 750, 202, 348, 346, 78, 78, 484, - 65, 78, 78, 78, 78, 348, 348, 348, 348, 609, - 783, 766, 613, 813, 492, 783, 783, 783, 473, 135, - 378, 488, 713, 775, 67, 779, 779, 785, 969, 969, - 779, 769, 779, 785, 975, 779, 779, 969, 969, 823, - 280, 563, 478, 550, 568, 969, 377, 779, 779, 779, - 779, 746, 573, 779, 342, 314, 779, 779, 746, 744, - 760, 43, 762, 969, 969, 969, 746, 547, 762, 762, - 762, 839, 844, 794, 758, 444, 433, 588, 232, 801, - 758, 758, 779, 558, 794, 758, 794, 758, 745, 758, - 758, 758, 794, 758, 769, 502, 758, 717, 583, 224, - 758, 6, 979, 980, 624, 981, 973, 987, 1019, 991, - 992, 873, 965, 999, 974, 993, 972, 970, 773, 682, - 684, 818, 811, 963, 777, 777, 777, 956, 777, 777, - 777, 777, 777, 777, 777, 777, 682, 743, 829, 765, - 1006, 689, 691, 754, 906, 901, 1030, 1004, 1049, 994, - 828, 694, 1028, 1008, 846, 821, 1009, 1010, 1029, 1050, - 1052, 910, 782, 911, 912, 876, 1012, 883, 777, 979, - 992, 693, 974, 993, 972, 970, 748, 739, 737, 738, - 736, 735, 723, 734, 753, 1053, 954, 907, 878, 1011, - 957, 682, 879, 1023, 756, 1032, 1033, 827, 788, 778, - 880, 913, 1014, 1015, 1016, 884, 1054, 887, 830, 1024, - 951, 1035, 789, 918, 1037, 1038, 1039, 1040, 889, 919, - 892, 916, 900, 845, 776, 1020, 761, 920, 591, 787, - 791, 800, 1018, 606, 1000, 902, 921, 922, 1041, 1043, - 1044, 923, 924, 995, 847, 1026, 799, 1027, 1022, 848, - 850, 617, 797, 1055, 781, 786, 772, 621, 632, 925, - 927, 931, 998, 763, 770, 853, 855, 1056, 771, 1057, - 938, 635, 857, 718, 939, 1046, 719, 724, 637, 678, - 672, 731, 792, 903, 826, 757, 780, 1017, 724, 767, - 858, 940, 859, 860, 867, 1045, 868, 0, 0, 0, + 336, 814, 348, 348, 348, 348, 348, 348, 348, 348, + 348, 348, 750, 202, 348, 348, 346, 78, 78, 348, + 484, 65, 78, 78, 78, 78, 348, 348, 348, 348, + 609, 783, 766, 613, 813, 492, 783, 783, 783, 473, + 135, 378, 488, 713, 775, 67, 779, 779, 785, 969, + 969, 779, 769, 779, 785, 975, 779, 779, 969, 969, + 823, 280, 563, 478, 550, 568, 969, 377, 779, 779, + 779, 779, 746, 573, 779, 342, 314, 779, 779, 746, + 744, 760, 43, 762, 969, 969, 969, 746, 547, 762, + 762, 762, 839, 844, 794, 758, 444, 433, 588, 232, + 801, 758, 758, 779, 558, 794, 758, 794, 758, 745, + 758, 758, 758, 794, 758, 769, 502, 758, 717, 583, + 224, 758, 6, 979, 980, 624, 981, 973, 987, 1019, + 991, 992, 873, 965, 999, 974, 993, 972, 970, 773, + 682, 684, 818, 811, 963, 777, 777, 777, 956, 777, + 777, 777, 777, 777, 777, 777, 777, 682, 743, 829, + 765, 1006, 689, 691, 754, 911, 901, 1030, 1004, 1049, + 994, 828, 694, 1028, 1008, 910, 821, 1009, 1010, 1029, + 1050, 1052, 912, 782, 913, 918, 876, 1012, 883, 777, + 979, 992, 693, 974, 993, 972, 970, 748, 739, 737, + 738, 736, 735, 723, 734, 753, 1053, 954, 907, 878, + 1011, 957, 682, 879, 1023, 756, 1032, 1033, 827, 788, + 778, 880, 919, 1014, 1015, 1016, 884, 1054, 887, 830, + 1024, 951, 1035, 789, 846, 1037, 1038, 1039, 1040, 889, + 920, 892, 916, 900, 845, 776, 1020, 761, 921, 591, + 787, 791, 800, 1018, 606, 1000, 902, 906, 922, 1041, + 1043, 1044, 923, 924, 995, 847, 1026, 799, 1027, 1022, + 848, 850, 617, 797, 1055, 781, 786, 772, 621, 632, + 925, 927, 931, 998, 763, 770, 853, 855, 1056, 771, + 1057, 938, 635, 857, 718, 939, 1046, 719, 724, 637, + 678, 672, 731, 792, 903, 826, 757, 780, 1017, 724, + 767, 858, 940, 859, 860, 867, 1045, 868, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 458, 458, 458, - 458, 458, 458, 307, 307, 307, 307, 307, 307, 307, - 0, 0, 307, 0, 458, 458, 458, 458, 458, 458, + 0, 0, 0, 0, 0, 0, 0, 0, 458, 458, + 458, 458, 458, 458, 307, 307, 307, 307, 307, 307, + 307, 0, 0, 307, 0, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, @@ -590,33 +590,34 @@ class Php7 extends \PhpParser\ParserAbstract 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, 458, + 458, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 0, 0, 0, 0, 0, 0, + 291, 291, 291, 291, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 291, 291, 291, 291, 291, 291, 291, 291, 291, + 0, 0, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, 291, - 291, 291, 291, 291, 291, 291, 291, 66, 66, 291, - 291, 291, 66, 66, 66, 66, 66, 66, 66, 66, - 66, 66, 0, 291, 291, 291, 291, 291, 291, 291, - 291, 66, 823, 66, -1, -1, -1, -1, 66, 66, - 66, -88, -88, 66, 384, 66, 66, -1, -1, 66, + 291, 291, 291, 291, 291, 291, 291, 291, 66, 66, + 291, 291, 291, 66, 66, 66, 66, 66, 66, 66, + 66, 66, 66, 0, 291, 291, 291, 291, 291, 291, + 291, 291, 66, 823, 66, -1, -1, -1, -1, 66, + 66, 66, -88, -88, 66, 384, 66, 66, -1, -1, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, - 0, 0, 423, 548, 66, 769, 769, 769, 769, 66, - 66, 66, 66, 548, 548, 66, 66, 66, 0, 0, - 0, 0, 0, 0, 0, 0, 423, 548, 0, 423, - 0, 0, 769, 769, 66, 384, 823, 643, 66, 0, - 0, 0, 0, 423, 769, 423, 336, 779, 548, 779, - 336, 336, 78, 348, 643, 611, 611, 611, 611, 0, - 0, 609, 823, 823, 823, 823, 823, 823, 823, 823, - 823, 823, 823, 769, 0, 823, 0, 769, 769, 769, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 769, 0, 0, 969, 0, + 66, 0, 0, 423, 548, 66, 769, 769, 769, 769, + 66, 66, 66, 66, 548, 548, 66, 66, 66, 0, + 0, 0, 0, 0, 0, 0, 0, 423, 548, 0, + 423, 0, 0, 769, 769, 66, 384, 823, 643, 66, + 0, 0, 0, 0, 423, 769, 423, 336, 779, 548, + 779, 336, 336, 78, 348, 643, 611, 611, 611, 611, + 0, 0, 609, 823, 823, 823, 823, 823, 823, 823, + 823, 823, 823, 823, 769, 0, 823, 0, 769, 769, + 769, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 769, 0, 969, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 975, - 0, 0, 0, 0, 0, 0, 769, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 777, 788, 0, 788, - 0, 777, 777, 777, 0, 0, 0, 0, 797, 771 + 0, 0, 0, 0, 0, 0, 0, 0, 769, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 777, 788, + 0, 788, 0, 777, 777, 777, 0, 0, 0, 0, + 797, 771 ); protected $actionDefault = array( @@ -659,102 +660,102 @@ class Php7 extends \PhpParser\ParserAbstract 111, 111, 111, 111, 111, 111, 111,32767, 195, 111, 32767,32767,32767, 101, 195, 195, 195, 195, 195, 195, 195, 195, 195, 195, 190,32767, 268, 270, 103, 557, - 195,32767, 515,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767, 508,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767,32767, 496, - 434, 139,32767, 139, 542, 426, 427, 428, 498, 542, - 542, 542, 312, 289,32767,32767,32767,32767, 513, 513, - 101, 101, 101, 101, 508,32767,32767,32767,32767, 112, - 100, 100, 100, 100, 100, 104, 102,32767,32767,32767, - 32767, 223, 100,32767, 102, 102,32767,32767, 223, 225, - 212, 102, 227,32767, 561, 562, 223, 102, 227, 227, - 227, 247, 247, 485, 318, 102, 100, 102, 102, 197, - 318, 318,32767, 102, 485, 318, 485, 318, 199, 318, - 318, 318, 485, 318,32767, 102, 318, 214, 100, 100, - 318,32767,32767,32767, 498,32767,32767,32767,32767,32767, - 32767,32767, 222,32767,32767,32767,32767,32767,32767,32767, - 529,32767, 546, 559, 432, 433, 435, 544, 457, 458, - 459, 460, 461, 462, 463, 465, 591,32767, 502,32767, - 32767,32767, 338, 601,32767, 601,32767,32767,32767,32767, + 195, 515,32767,32767,32767,32767,32767,32767,32767,32767, + 32767,32767, 508,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, + 496, 434, 139,32767, 139, 542, 426, 427, 428, 498, + 542, 542, 542, 312, 289,32767,32767,32767,32767, 513, + 513, 101, 101, 101, 101, 508,32767,32767,32767,32767, + 112, 100, 100, 100, 100, 100, 104, 102,32767,32767, + 32767,32767, 223, 100,32767, 102, 102,32767,32767, 223, + 225, 212, 102, 227,32767, 561, 562, 223, 102, 227, + 227, 227, 247, 247, 485, 318, 102, 100, 102, 102, + 197, 318, 318,32767, 102, 485, 318, 485, 318, 199, + 318, 318, 318, 485, 318,32767, 102, 318, 214, 100, + 100, 318,32767,32767,32767, 498,32767,32767,32767,32767, + 32767,32767,32767, 222,32767,32767,32767,32767,32767,32767, + 32767, 529,32767, 546, 559, 432, 433, 435, 544, 457, + 458, 459, 460, 461, 462, 463, 465, 591,32767, 502, + 32767,32767,32767, 338, 601,32767, 601,32767,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767, 602,32767, 542,32767,32767,32767,32767, 431, 9, - 76, 491, 43, 44, 52, 58, 519, 520, 521, 522, - 516, 517, 523, 518,32767,32767, 524, 567,32767,32767, - 543, 594,32767,32767,32767,32767,32767,32767, 139,32767, + 32767,32767, 602,32767, 542,32767,32767,32767,32767, 431, + 9, 76, 491, 43, 44, 52, 58, 519, 520, 521, + 522, 516, 517, 523, 518,32767,32767, 524, 567,32767, + 32767, 543, 594,32767,32767,32767,32767,32767,32767, 139, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 529,32767, 137,32767,32767,32767,32767,32767,32767,32767, - 32767, 525,32767,32767,32767, 542,32767,32767,32767,32767, - 314, 311,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767,32767, 542,32767, - 32767,32767,32767,32767, 291,32767, 308,32767,32767,32767, + 32767, 529,32767, 137,32767,32767,32767,32767,32767,32767, + 32767,32767, 525,32767,32767,32767, 542,32767,32767,32767, + 32767, 314, 311,32767,32767,32767,32767,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767,32767, 542, + 32767,32767,32767,32767,32767, 291,32767, 308,32767,32767, 32767,32767,32767,32767,32767,32767,32767,32767,32767,32767, - 32767,32767,32767, 286,32767,32767, 381, 498, 294, 296, - 297,32767,32767,32767,32767, 360,32767,32767,32767,32767, - 32767,32767,32767,32767,32767,32767,32767, 153, 153, 3, - 3, 341, 153, 153, 153, 341, 341, 153, 341, 341, - 341, 153, 153, 153, 153, 153, 153, 280, 185, 262, - 265, 247, 247, 153, 352, 153 + 32767,32767,32767,32767, 286,32767,32767, 381, 498, 294, + 296, 297,32767,32767,32767,32767, 360,32767,32767,32767, + 32767,32767,32767,32767,32767,32767,32767,32767, 153, 153, + 3, 3, 341, 153, 153, 153, 341, 341, 153, 341, + 341, 341, 153, 153, 153, 153, 153, 153, 280, 185, + 262, 265, 247, 247, 153, 352, 153 ); protected $goto = array( - 196, 196, 1031, 703, 694, 430, 658, 1062, 1334, 1334, - 424, 313, 314, 335, 573, 319, 429, 336, 431, 635, - 651, 652, 850, 669, 670, 671, 1334, 167, 167, 167, + 196, 196, 1032, 704, 695, 431, 659, 1063, 1335, 1335, + 425, 313, 314, 335, 574, 319, 430, 336, 432, 636, + 652, 653, 851, 670, 671, 672, 1335, 167, 167, 167, 167, 221, 197, 193, 193, 177, 179, 216, 193, 193, 193, 193, 193, 194, 194, 194, 194, 194, 194, 188, - 189, 190, 191, 192, 218, 216, 219, 534, 535, 420, - 536, 538, 539, 540, 541, 542, 543, 544, 545, 1132, + 189, 190, 191, 192, 218, 216, 219, 535, 536, 421, + 537, 539, 540, 541, 542, 543, 544, 545, 546, 1133, 168, 169, 170, 195, 171, 172, 173, 166, 174, 175, 176, 178, 215, 217, 220, 238, 243, 244, 245, 257, 258, 259, 260, 261, 262, 263, 264, 268, 269, 270, - 271, 281, 282, 316, 317, 318, 425, 426, 427, 578, + 271, 281, 282, 316, 317, 318, 426, 427, 428, 579, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 180, 237, 181, 198, 199, - 200, 239, 188, 189, 190, 191, 192, 218, 1132, 201, + 200, 239, 188, 189, 190, 191, 192, 218, 1133, 201, 182, 183, 184, 202, 198, 185, 240, 203, 201, 165, 204, 205, 186, 206, 207, 208, 187, 209, 210, 211, - 212, 213, 214, 853, 851, 278, 278, 278, 278, 418, - 620, 620, 350, 570, 597, 1265, 1265, 1265, 1265, 1265, - 1265, 1265, 1265, 1265, 1265, 1283, 1283, 831, 618, 655, - 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, 1283, - 353, 353, 353, 353, 866, 557, 550, 858, 825, 907, - 902, 903, 916, 859, 904, 856, 905, 906, 857, 878, - 457, 910, 865, 884, 546, 546, 546, 546, 831, 601, - 831, 1084, 1079, 1080, 1081, 341, 550, 557, 566, 567, - 343, 576, 599, 613, 614, 407, 408, 972, 465, 465, - 667, 15, 668, 1323, 411, 412, 413, 465, 681, 348, - 1233, 414, 1233, 478, 569, 346, 439, 1031, 1031, 1233, - 993, 480, 1031, 393, 1031, 1031, 1104, 1105, 1031, 1031, - 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1031, 1315, - 1315, 1315, 1315, 1233, 657, 1333, 1333, 1055, 1233, 1233, - 1233, 1233, 1037, 1036, 1233, 1233, 1233, 1034, 1034, 1181, - 354, 678, 949, 1333, 437, 1026, 1042, 1043, 337, 691, - 354, 354, 827, 923, 691, 1040, 1041, 924, 691, 663, - 1336, 939, 871, 939, 354, 354, 1281, 1281, 354, 679, - 1350, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, 1281, - 1281, 552, 537, 537, 911, 354, 912, 537, 537, 537, - 537, 537, 537, 537, 537, 537, 537, 548, 564, 548, - 574, 611, 730, 634, 636, 849, 548, 656, 475, 1308, - 1309, 680, 684, 1007, 692, 701, 1003, 252, 252, 996, - 970, 970, 968, 970, 729, 843, 549, 1005, 1000, 423, - 455, 608, 1294, 846, 955, 966, 966, 966, 966, 325, - 308, 455, 960, 967, 249, 249, 249, 249, 251, 253, - 402, 351, 352, 683, 868, 551, 561, 449, 449, 449, - 551, 1305, 561, 1305, 612, 396, 461, 1010, 1010, 1224, - 1305, 395, 398, 558, 598, 602, 1015, 468, 577, 469, - 470, 1310, 1311, 876, 552, 846, 1341, 1342, 964, 409, - 702, 733, 324, 275, 324, 1317, 1317, 1317, 1317, 606, - 621, 624, 625, 626, 627, 648, 649, 650, 705, 1068, - 596, 1097, 874, 706, 476, 1228, 507, 697, 880, 1095, - 1115, 432, 1301, 628, 630, 632, 432, 879, 867, 1067, - 1071, 5, 1072, 6, 1038, 1038, 977, 0, 975, 662, - 1049, 1045, 1046, 0, 0, 0, 0, 1226, 449, 449, - 449, 449, 449, 449, 449, 449, 449, 449, 449, 928, - 1120, 449, 965, 1070, 0, 0, 616, 1303, 1303, 1070, - 1229, 1230, 1012, 499, 0, 500, 0, 0, 841, 0, - 870, 506, 661, 991, 1113, 883, 1212, 941, 864, 0, - 1213, 1216, 942, 1217, 0, 0, 1231, 1291, 1292, 0, - 1223, 0, 0, 0, 846, 0, 0, 0, 0, 0, + 212, 213, 214, 854, 619, 656, 278, 278, 278, 278, + 852, 621, 621, 350, 419, 598, 1266, 1266, 1266, 1266, + 1266, 1266, 1266, 1266, 1266, 1266, 1284, 1284, 832, 1105, + 1106, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, 1284, + 1284, 353, 353, 353, 353, 826, 558, 551, 908, 903, + 904, 917, 860, 905, 857, 906, 907, 858, 1035, 1035, + 911, 864, 679, 950, 458, 863, 1027, 1043, 1044, 832, + 885, 832, 1085, 1080, 1081, 1082, 341, 551, 558, 567, + 568, 343, 577, 600, 614, 615, 547, 547, 547, 547, + 973, 602, 15, 394, 397, 559, 599, 603, 1213, 942, + 1234, 571, 1234, 1214, 1217, 943, 1218, 1032, 1032, 1234, + 440, 912, 1032, 913, 1032, 1032, 1038, 1037, 1032, 1032, + 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1032, 1316, + 1316, 1316, 1316, 1234, 476, 1309, 1310, 348, 1234, 1234, + 1234, 1234, 407, 408, 1234, 1234, 1234, 668, 1324, 669, + 354, 412, 413, 414, 867, 682, 466, 466, 415, 994, + 354, 354, 346, 924, 424, 466, 609, 925, 5, 879, + 6, 940, 866, 940, 354, 354, 1282, 1282, 354, 392, + 1351, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, 1282, + 1282, 553, 538, 538, 570, 354, 658, 538, 538, 538, + 538, 538, 538, 538, 538, 538, 538, 549, 565, 549, + 1041, 1042, 731, 635, 637, 850, 549, 657, 965, 410, + 703, 681, 685, 1008, 693, 702, 1004, 252, 252, 997, + 971, 971, 969, 971, 730, 1056, 550, 1006, 1001, 1182, + 456, 847, 1295, 1334, 1334, 967, 967, 967, 967, 325, + 308, 456, 961, 968, 249, 249, 249, 249, 251, 253, + 438, 1334, 351, 352, 684, 680, 552, 562, 450, 450, + 450, 552, 1306, 562, 1306, 479, 395, 462, 1337, 1311, + 1312, 1306, 664, 481, 500, 337, 501, 844, 469, 578, + 470, 471, 507, 847, 877, 553, 872, 1342, 1343, 1011, + 1011, 575, 612, 324, 275, 324, 1318, 1318, 1318, 1318, + 607, 622, 625, 626, 627, 628, 649, 650, 651, 706, + 956, 401, 692, 875, 1229, 828, 869, 692, 629, 631, + 633, 692, 433, 1302, 1225, 734, 613, 433, 880, 868, + 1068, 1072, 1069, 1016, 477, 1039, 1039, 881, 0, 976, + 663, 1050, 1046, 1047, 1073, 1116, 978, 0, 1227, 450, + 450, 450, 450, 450, 450, 450, 450, 450, 450, 450, + 929, 1121, 450, 966, 1071, 0, 0, 617, 1304, 1304, + 1071, 1230, 1231, 1013, 0, 0, 0, 0, 0, 842, + 0, 871, 0, 662, 992, 1114, 884, 597, 1098, 865, + 707, 0, 0, 508, 698, 0, 1096, 1232, 1292, 1293, + 0, 1224, 0, 847, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -779,48 +780,48 @@ class Php7 extends \PhpParser\ParserAbstract 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, 42, - 42, 42, 42, 15, 27, 23, 23, 23, 23, 43, - 107, 107, 96, 170, 129, 107, 107, 107, 107, 107, - 107, 107, 107, 107, 107, 168, 168, 12, 55, 55, - 168, 168, 168, 168, 168, 168, 168, 168, 168, 168, - 24, 24, 24, 24, 35, 75, 75, 15, 6, 15, - 15, 15, 15, 15, 15, 15, 15, 15, 15, 35, - 82, 15, 35, 45, 106, 106, 106, 106, 12, 106, - 12, 15, 15, 15, 15, 75, 75, 75, 75, 75, - 75, 75, 75, 75, 75, 81, 81, 49, 148, 148, - 81, 75, 81, 179, 81, 81, 81, 148, 81, 177, - 72, 81, 72, 83, 103, 81, 82, 72, 72, 72, - 102, 83, 72, 61, 72, 72, 143, 143, 72, 72, + 42, 42, 42, 15, 55, 55, 23, 23, 23, 23, + 27, 107, 107, 96, 43, 129, 107, 107, 107, 107, + 107, 107, 107, 107, 107, 107, 168, 168, 12, 143, + 143, 168, 168, 168, 168, 168, 168, 168, 168, 168, + 168, 24, 24, 24, 24, 6, 75, 75, 15, 15, + 15, 15, 15, 15, 15, 15, 15, 15, 88, 88, + 15, 15, 88, 88, 82, 15, 88, 88, 88, 12, + 45, 12, 15, 15, 15, 15, 75, 75, 75, 75, + 75, 75, 75, 75, 75, 75, 106, 106, 106, 106, + 49, 106, 75, 58, 58, 58, 58, 58, 78, 78, + 72, 170, 72, 78, 78, 78, 78, 72, 72, 72, + 82, 64, 72, 64, 72, 72, 117, 117, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 72, 9, - 9, 9, 9, 72, 63, 180, 180, 113, 72, 72, - 72, 72, 117, 117, 72, 72, 72, 88, 88, 150, - 14, 88, 88, 180, 112, 88, 88, 88, 29, 7, - 14, 14, 7, 72, 7, 118, 118, 72, 7, 119, - 180, 9, 39, 9, 14, 14, 169, 169, 14, 115, + 9, 9, 9, 72, 174, 174, 174, 177, 72, 72, + 72, 72, 81, 81, 72, 72, 72, 81, 179, 81, + 14, 81, 81, 81, 35, 81, 148, 148, 81, 102, + 14, 14, 81, 72, 13, 148, 13, 72, 46, 35, + 46, 9, 35, 9, 14, 14, 169, 169, 14, 61, 14, 169, 169, 169, 169, 169, 169, 169, 169, 169, - 169, 14, 171, 171, 64, 14, 64, 171, 171, 171, + 169, 14, 171, 171, 103, 14, 63, 171, 171, 171, 171, 171, 171, 171, 171, 171, 171, 19, 48, 19, - 2, 2, 48, 48, 48, 25, 19, 48, 174, 174, - 174, 48, 48, 48, 48, 48, 48, 5, 5, 25, - 25, 25, 25, 25, 25, 18, 25, 25, 25, 13, - 19, 13, 14, 22, 91, 19, 19, 19, 19, 167, + 118, 118, 48, 48, 48, 25, 19, 48, 92, 92, + 92, 48, 48, 48, 48, 48, 48, 5, 5, 25, + 25, 25, 25, 25, 25, 113, 25, 25, 25, 150, + 19, 22, 14, 180, 180, 19, 19, 19, 19, 167, 167, 19, 19, 19, 5, 5, 5, 5, 5, 5, - 28, 96, 96, 14, 37, 9, 9, 23, 23, 23, - 9, 129, 9, 129, 79, 9, 9, 106, 106, 159, - 129, 58, 58, 58, 58, 58, 109, 9, 9, 9, - 9, 176, 176, 9, 14, 22, 9, 9, 92, 92, - 92, 98, 24, 24, 24, 129, 129, 129, 129, 80, - 80, 80, 80, 80, 80, 80, 80, 80, 80, 128, - 8, 8, 9, 8, 156, 20, 8, 8, 41, 8, - 146, 116, 129, 84, 84, 84, 116, 16, 16, 16, - 16, 46, 131, 46, 116, 116, 95, -1, 16, 116, - 116, 116, 116, -1, -1, -1, -1, 14, 23, 23, - 23, 23, 23, 23, 23, 23, 23, 23, 23, 17, - 17, 23, 16, 129, -1, -1, 17, 129, 129, 129, - 20, 20, 17, 154, -1, 154, -1, -1, 20, -1, - 17, 154, 17, 17, 16, 16, 78, 78, 17, -1, - 78, 78, 78, 78, -1, -1, 20, 20, 20, -1, - 17, -1, -1, -1, 22, -1, -1, -1, -1, -1, + 112, 180, 96, 96, 14, 115, 9, 9, 23, 23, + 23, 9, 129, 9, 129, 83, 9, 9, 180, 176, + 176, 129, 119, 83, 154, 29, 154, 18, 9, 9, + 9, 9, 154, 22, 9, 14, 39, 9, 9, 106, + 106, 2, 2, 24, 24, 24, 129, 129, 129, 129, + 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, + 91, 28, 7, 9, 20, 7, 37, 7, 84, 84, + 84, 7, 116, 129, 159, 98, 79, 116, 16, 16, + 16, 16, 128, 109, 156, 116, 116, 41, -1, 16, + 116, 116, 116, 116, 131, 146, 95, -1, 14, 23, + 23, 23, 23, 23, 23, 23, 23, 23, 23, 23, + 17, 17, 23, 16, 129, -1, -1, 17, 129, 129, + 129, 20, 20, 17, -1, -1, -1, -1, -1, 20, + -1, 17, -1, 17, 17, 16, 16, 8, 8, 17, + 8, -1, -1, 8, 8, -1, 8, 20, 20, 20, + -1, 17, -1, 22, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, @@ -829,47 +830,47 @@ class Php7 extends \PhpParser\ParserAbstract ); protected $gotoBase = array( - 0, 0, -339, 0, 0, 386, 195, 312, 472, -10, - 0, 0, -109, 62, 13, -184, 46, 65, 86, 102, - 93, 0, 125, 162, 197, 371, 18, 160, 83, 22, - 0, 0, 0, 0, 0, -166, 0, 85, 0, 9, - 0, 48, -1, 157, 0, 207, -232, 0, -340, 223, - 0, 0, 0, 0, 0, 148, 0, 0, 396, 0, - 0, 231, 0, 52, 334, -236, 0, 0, 0, 0, - 0, 0, -5, 0, 0, -139, 0, 0, 149, 91, - 112, -245, -58, -205, 15, -695, 0, 0, 28, 0, - 0, 75, 154, 0, 0, 64, -310, 0, 55, 0, - 0, 0, 235, 221, 0, 0, 196, -71, 0, 77, - 0, 0, 37, 24, 0, 56, 219, 23, 40, 39, - 0, 0, 0, 0, 0, 0, 5, 0, 106, 166, - 0, 61, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 1, 0, 0, 47, 0, 214, 0, - 35, 0, 0, 0, 49, 0, 45, 0, 0, 71, - 0, 0, 0, 0, 0, 0, 0, 88, -56, 95, - 144, 111, 0, 0, 78, 0, 80, 229, 0, 222, - -12, -299, 0, 0 + 0, 0, -249, 0, 0, 386, 192, 475, 549, -10, + 0, 0, -108, -13, 13, -184, 46, 65, 138, 102, + 93, 0, 123, 163, 198, 371, 18, 166, 144, 149, + 0, 0, 0, 0, 0, -56, 0, 147, 0, 133, + 0, 66, -1, 162, 0, 214, -406, 0, -341, 226, + 0, 0, 0, 0, 0, 124, 0, 0, 208, 0, + 0, 297, 0, 114, 251, -236, 0, 0, 0, 0, + 0, 0, -5, 0, 0, -138, 0, 0, -149, 153, + 113, -189, -54, -34, 9, -696, 0, 0, -61, 0, + 0, 151, 74, 0, 0, 73, -310, 0, 89, 0, + 0, 0, 284, 311, 0, 0, 218, -70, 0, 134, + 0, 0, 143, 122, 0, 142, 220, -3, 85, 152, + 0, 0, 0, 0, 0, 0, 5, 0, 129, 167, + 0, 72, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, -86, 0, 0, 71, 0, 282, 0, + 125, 0, 0, 0, -51, 0, 64, 0, 0, 126, + 0, 0, 0, 0, 0, 0, 0, 88, -55, 95, + 232, 111, 0, 0, -6, 0, 68, 267, 0, 277, + 96, -299, 0, 0 ); protected $gotoDefault = array( - -32768, 511, 737, 4, 738, 932, 814, 823, 594, 528, - 704, 347, 622, 421, 1299, 909, 1119, 575, 842, 1242, - 1250, 456, 845, 330, 727, 891, 892, 893, 399, 385, - 391, 397, 646, 623, 493, 877, 452, 869, 485, 872, - 451, 881, 164, 417, 509, 885, 3, 888, 554, 919, - 386, 896, 387, 674, 898, 560, 900, 901, 394, 400, - 401, 1124, 568, 619, 913, 256, 562, 914, 384, 915, - 922, 389, 392, 685, 464, 504, 498, 410, 1099, 563, - 605, 643, 446, 472, 617, 629, 615, 479, 433, 415, - 329, 954, 962, 486, 462, 976, 349, 984, 735, 1131, - 637, 488, 992, 638, 999, 1002, 529, 530, 477, 1014, - 272, 1017, 489, 12, 664, 1028, 1029, 665, 639, 1051, - 640, 666, 641, 1053, 471, 595, 1061, 453, 1069, 1287, - 454, 1073, 266, 1076, 277, 416, 434, 1082, 1083, 9, - 1089, 695, 696, 11, 276, 508, 1114, 686, 450, 1130, - 438, 1200, 1202, 556, 490, 1220, 1219, 677, 505, 1225, - 447, 1290, 448, 531, 473, 315, 532, 307, 333, 312, - 547, 294, 334, 533, 474, 1296, 1304, 331, 31, 1324, - 1335, 342, 572, 610 + -32768, 512, 738, 4, 739, 933, 815, 824, 595, 529, + 705, 347, 623, 422, 1300, 910, 1120, 576, 843, 1243, + 1251, 457, 846, 330, 728, 892, 893, 894, 398, 385, + 859, 396, 647, 624, 494, 878, 453, 870, 486, 873, + 452, 882, 164, 418, 510, 886, 3, 889, 555, 920, + 386, 897, 387, 675, 899, 561, 901, 902, 393, 399, + 400, 1125, 569, 620, 914, 256, 563, 915, 384, 916, + 923, 389, 391, 686, 465, 505, 499, 411, 1100, 564, + 606, 644, 447, 473, 618, 630, 616, 480, 434, 416, + 329, 955, 963, 487, 463, 977, 349, 985, 736, 1132, + 638, 489, 993, 639, 1000, 1003, 530, 531, 478, 1015, + 272, 1018, 490, 12, 665, 1029, 1030, 666, 640, 1052, + 641, 667, 642, 1054, 472, 596, 1062, 454, 1070, 1288, + 455, 1074, 266, 1077, 277, 417, 435, 1083, 1084, 9, + 1090, 696, 697, 11, 276, 509, 1115, 687, 451, 1131, + 439, 1201, 1203, 557, 491, 1221, 1220, 678, 506, 1226, + 448, 1291, 449, 532, 474, 315, 533, 307, 333, 312, + 548, 294, 334, 534, 475, 1297, 1305, 331, 31, 1325, + 1336, 342, 573, 611 ); protected $ruleToNonTerminal = array( @@ -950,7 +951,7 @@ class Php7 extends \PhpParser\ParserAbstract 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 2, 1, 3, 4, 1, 2, 0, 1, 1, 1, 1, 1, 3, 5, 4, - 3, 4, 2, 3, 1, 1, 7, 6, 2, 3, + 3, 4, 1, 3, 1, 1, 8, 7, 2, 3, 1, 2, 3, 1, 2, 3, 1, 1, 3, 1, 3, 1, 2, 2, 3, 1, 3, 2, 3, 1, 3, 3, 2, 0, 1, 1, 1, 1, 1, 3, @@ -1378,7 +1379,7 @@ protected function initReduceCallbacks() { $this->semValue = new Stmt\Use_($this->semStack[$stackPos-(4-3)], $this->semStack[$stackPos-(4-2)], $this->startAttributeStack[$stackPos-(4-1)] + $this->endAttributes); }, 122 => function ($stackPos) { - $this->semValue = $this->semStack[$stackPos-(2-1)]; + $this->semValue = $this->semStack[$stackPos-(1-1)]; }, 123 => function ($stackPos) { $this->semValue = new Stmt\Const_($this->semStack[$stackPos-(3-2)], $this->startAttributeStack[$stackPos-(3-1)] + $this->endAttributes); @@ -1390,10 +1391,10 @@ protected function initReduceCallbacks() { $this->semValue = Stmt\Use_::TYPE_CONSTANT; }, 126 => function ($stackPos) { - $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos-(7-3)], $this->semStack[$stackPos-(7-6)], $this->semStack[$stackPos-(7-2)], $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); + $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos-(8-3)], $this->semStack[$stackPos-(8-6)], $this->semStack[$stackPos-(8-2)], $this->startAttributeStack[$stackPos-(8-1)] + $this->endAttributes); }, 127 => function ($stackPos) { - $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos-(6-2)], $this->semStack[$stackPos-(6-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(6-1)] + $this->endAttributes); + $this->semValue = new Stmt\GroupUse($this->semStack[$stackPos-(7-2)], $this->semStack[$stackPos-(7-5)], Stmt\Use_::TYPE_UNKNOWN, $this->startAttributeStack[$stackPos-(7-1)] + $this->endAttributes); }, 128 => function ($stackPos) { $this->semValue = $this->semStack[$stackPos-(2-1)]; diff --git a/lib/nikic/php-parser/lib/PhpParser/ParserAbstract.php b/lib/nikic/php-parser/lib/PhpParser/ParserAbstract.php index 9f9d00c763..567e09a975 100644 --- a/lib/nikic/php-parser/lib/PhpParser/ParserAbstract.php +++ b/lib/nikic/php-parser/lib/PhpParser/ParserAbstract.php @@ -155,7 +155,7 @@ public function __construct(Lexer $lexer, array $options = []) { * @return Node\Stmt[]|null Array of statements (or null non-throwing error handler is used and * the parser was unable to recover from an error). */ - public function parse(string $code, ErrorHandler $errorHandler = null) { + public function parse(string $code, ?ErrorHandler $errorHandler = null) { $this->errorHandler = $errorHandler ?: new ErrorHandler\Throwing; $this->lexer->startLexing($code, $this->errorHandler); diff --git a/lib/nikic/php-parser/lib/PhpParser/ParserFactory.php b/lib/nikic/php-parser/lib/PhpParser/ParserFactory.php index baba23bdb4..98b0aee343 100644 --- a/lib/nikic/php-parser/lib/PhpParser/ParserFactory.php +++ b/lib/nikic/php-parser/lib/PhpParser/ParserFactory.php @@ -21,7 +21,7 @@ class ParserFactory * * @return Parser The parser instance */ - public function create(int $kind, Lexer $lexer = null, array $parserOptions = []) : Parser { + public function create(int $kind, ?Lexer $lexer = null, array $parserOptions = []) : Parser { if (null === $lexer) { $lexer = new Lexer\Emulative(); } diff --git a/lib/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php b/lib/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php index 7c32e5a3c5..b8115d00a7 100644 --- a/lib/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php +++ b/lib/nikic/php-parser/lib/PhpParser/PrettyPrinter/Standard.php @@ -223,7 +223,7 @@ protected function pScalar_DNumber(Scalar\DNumber $node) { // Try to find a short full-precision representation $stringValue = sprintf('%.16G', $node->value); - if ($node->value !== (double) $stringValue) { + if ($node->value !== (float) $stringValue) { $stringValue = sprintf('%.17G', $node->value); } diff --git a/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php b/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php index 770d500928..5d87e5ce8d 100644 --- a/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php +++ b/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php @@ -658,7 +658,7 @@ protected function p(Node $node, $parentFormatPreserved = false) : string { $result .= $extraLeft; $origIndentLevel = $this->indentLevel; - $this->setIndentLevel($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment); + $this->setIndentLevel(max($this->origTokens->getIndentationBefore($subStartPos) + $indentAdjustment, 0)); // If it's the same node that was previously in this position, it certainly doesn't // need fixup. It's important to check this here, because our fixup checks are more @@ -761,7 +761,7 @@ protected function pArray( \assert($itemStartPos >= 0 && $itemEndPos >= 0 && $itemStartPos >= $pos); $origIndentLevel = $this->indentLevel; - $lastElemIndentLevel = $this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment; + $lastElemIndentLevel = max($this->origTokens->getIndentationBefore($itemStartPos) + $indentAdjustment, 0); $this->setIndentLevel($lastElemIndentLevel); $comments = $arrItem->getComments(); diff --git a/lib/paragonie/random_compat/LICENSE b/lib/paragonie/random_compat/LICENSE deleted file mode 100644 index 45c7017dfb..0000000000 --- a/lib/paragonie/random_compat/LICENSE +++ /dev/null @@ -1,22 +0,0 @@ -The MIT License (MIT) - -Copyright (c) 2015 Paragon Initiative Enterprises - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - diff --git a/lib/paragonie/random_compat/build-phar.sh b/lib/paragonie/random_compat/build-phar.sh deleted file mode 100644 index b4a5ba31cc..0000000000 --- a/lib/paragonie/random_compat/build-phar.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env bash - -basedir=$( dirname $( readlink -f ${BASH_SOURCE[0]} ) ) - -php -dphar.readonly=0 "$basedir/other/build_phar.php" $* \ No newline at end of file diff --git a/lib/paragonie/random_compat/composer.json b/lib/paragonie/random_compat/composer.json deleted file mode 100644 index f2b9c4e510..0000000000 --- a/lib/paragonie/random_compat/composer.json +++ /dev/null @@ -1,34 +0,0 @@ -{ - "name": "paragonie/random_compat", - "description": "PHP 5.x polyfill for random_bytes() and random_int() from PHP 7", - "keywords": [ - "csprng", - "random", - "polyfill", - "pseudorandom" - ], - "license": "MIT", - "type": "library", - "authors": [ - { - "name": "Paragon Initiative Enterprises", - "email": "security@paragonie.com", - "homepage": "https://paragonie.com" - } - ], - "support": { - "issues": "https://github.com/paragonie/random_compat/issues", - "email": "info@paragonie.com", - "source": "https://github.com/paragonie/random_compat" - }, - "require": { - "php": ">= 7" - }, - "require-dev": { - "vimeo/psalm": "^1", - "phpunit/phpunit": "4.*|5.*" - }, - "suggest": { - "ext-libsodium": "Provides a modern crypto API that can be used to generate random bytes." - } -} diff --git a/lib/paragonie/random_compat/dist/random_compat.phar.pubkey b/lib/paragonie/random_compat/dist/random_compat.phar.pubkey deleted file mode 100644 index eb50ebfcd6..0000000000 --- a/lib/paragonie/random_compat/dist/random_compat.phar.pubkey +++ /dev/null @@ -1,5 +0,0 @@ ------BEGIN PUBLIC KEY----- -MHYwEAYHKoZIzj0CAQYFK4EEACIDYgAEEd+wCqJDrx5B4OldM0dQE0ZMX+lx1ZWm -pui0SUqD4G29L3NGsz9UhJ/0HjBdbnkhIK5xviT0X5vtjacF6ajgcCArbTB+ds+p -+h7Q084NuSuIpNb6YPfoUFgC/CL9kAoc ------END PUBLIC KEY----- diff --git a/lib/paragonie/random_compat/dist/random_compat.phar.pubkey.asc b/lib/paragonie/random_compat/dist/random_compat.phar.pubkey.asc deleted file mode 100644 index 6a1d7f3006..0000000000 --- a/lib/paragonie/random_compat/dist/random_compat.phar.pubkey.asc +++ /dev/null @@ -1,11 +0,0 @@ ------BEGIN PGP SIGNATURE----- -Version: GnuPG v2.0.22 (MingW32) - -iQEcBAABAgAGBQJWtW1hAAoJEGuXocKCZATaJf0H+wbZGgskK1dcRTsuVJl9IWip -QwGw/qIKI280SD6/ckoUMxKDCJiFuPR14zmqnS36k7N5UNPnpdTJTS8T11jttSpg -1LCmgpbEIpgaTah+cELDqFCav99fS+bEiAL5lWDAHBTE/XPjGVCqeehyPYref4IW -NDBIEsvnHPHPLsn6X5jq4+Yj5oUixgxaMPiR+bcO4Sh+RzOVB6i2D0upWfRXBFXA -NNnsg9/zjvoC7ZW73y9uSH+dPJTt/Vgfeiv52/v41XliyzbUyLalf02GNPY+9goV -JHG1ulEEBJOCiUD9cE1PUIJwHA/HqyhHIvV350YoEFiHl8iSwm7SiZu5kPjaq74= -=B6+8 ------END PGP SIGNATURE----- diff --git a/lib/paragonie/random_compat/lib/random.php b/lib/paragonie/random_compat/lib/random.php deleted file mode 100644 index c7731a56ff..0000000000 --- a/lib/paragonie/random_compat/lib/random.php +++ /dev/null @@ -1,32 +0,0 @@ -buildFromDirectory(dirname(__DIR__).'/lib'); -rename( - dirname(__DIR__).'/lib/index.php', - dirname(__DIR__).'/lib/random.php' -); - -/** - * If we pass an (optional) path to a private key as a second argument, we will - * sign the Phar with OpenSSL. - * - * If you leave this out, it will produce an unsigned .phar! - */ -if ($argc > 1) { - if (!@is_readable($argv[1])) { - echo 'Could not read the private key file:', $argv[1], "\n"; - exit(255); - } - $pkeyFile = file_get_contents($argv[1]); - - $private = openssl_get_privatekey($pkeyFile); - if ($private !== false) { - $pkey = ''; - openssl_pkey_export($private, $pkey); - $phar->setSignatureAlgorithm(Phar::OPENSSL, $pkey); - - /** - * Save the corresponding public key to the file - */ - if (!@is_readable($dist.'/random_compat.phar.pubkey')) { - $details = openssl_pkey_get_details($private); - file_put_contents( - $dist.'/random_compat.phar.pubkey', - $details['key'] - ); - } - } else { - echo 'An error occurred reading the private key from OpenSSL.', "\n"; - exit(255); - } -} diff --git a/lib/paragonie/random_compat/psalm-autoload.php b/lib/paragonie/random_compat/psalm-autoload.php deleted file mode 100644 index d71d1b818c..0000000000 --- a/lib/paragonie/random_compat/psalm-autoload.php +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - - - - - - - - - diff --git a/lib/pear/pear-core-minimal/README.rst b/lib/pear/pear-core-minimal/README.rst index 9e412fbd18..1804e16faa 100644 --- a/lib/pear/pear-core-minimal/README.rst +++ b/lib/pear/pear-core-minimal/README.rst @@ -17,10 +17,5 @@ Included files ============== - ``OS/Guess.php`` - ``PEAR.php`` -- ``PEAR/Error.php`` - ``PEAR/ErrorStack.php`` - ``System.php`` - - -``PEAR/Error.php`` is a dummy file that only includes ``PEAR.php``, -to make autoloaders work without problems. diff --git a/lib/pear/pear-core-minimal/composer.json b/lib/pear/pear-core-minimal/composer.json index d805f56ae8..5233056037 100644 --- a/lib/pear/pear-core-minimal/composer.json +++ b/lib/pear/pear-core-minimal/composer.json @@ -10,9 +10,9 @@ } ], "autoload": { - "psr-0": { - "": "src/" - } + "classmap": [ + "src/" + ] }, "include-path": [ "src/" @@ -23,6 +23,7 @@ }, "type": "library", "require": { + "php": ">=5.4", "pear/console_getopt": "~1.4", "pear/pear_exception": "~1.0" }, diff --git a/lib/pear/pear-core-minimal/src/OS/Guess.php b/lib/pear/pear-core-minimal/src/OS/Guess.php index 88cd659102..0e37a0956a 100644 --- a/lib/pear/pear-core-minimal/src/OS/Guess.php +++ b/lib/pear/pear-core-minimal/src/OS/Guess.php @@ -245,7 +245,7 @@ function _readGlibCVersionFromFeaturesHeaderFile() return array(); } if (!@file_exists('/usr/bin/cpp') || !@is_executable('/usr/bin/cpp')) { - return $this-_parseFeaturesHeaderFile($features_header_file); + return $this->_parseFeaturesHeaderFile($features_header_file); } // no cpp return $this->_fromGlibCTest(); diff --git a/lib/pear/pear-core-minimal/src/PEAR.php b/lib/pear/pear-core-minimal/src/PEAR.php index fee6638f44..0c9ab56949 100644 --- a/lib/pear/pear-core-minimal/src/PEAR.php +++ b/lib/pear/pear-core-minimal/src/PEAR.php @@ -49,7 +49,9 @@ $GLOBALS['_PEAR_shutdown_funcs'] = array(); $GLOBALS['_PEAR_error_handler_stack'] = array(); -@ini_set('track_errors', true); +if(function_exists('ini_set')) { + @ini_set('track_errors', true); +} /** * Base class for other PEAR classes. Provides rudimentary @@ -214,12 +216,16 @@ function _PEAR() { public function __call($method, $arguments) { if (!isset(self::$bivalentMethods[$method])) { - trigger_error( - 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR - ); + if (PHP_VERSION_ID < 70000) { + trigger_error( + 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR + ); + } else { + throw new Error('Call to undefined method PEAR::' . $method . '()'); + } } return call_user_func_array( - array(get_class(), '_' . $method), + array(__CLASS__, '_' . $method), array_merge(array($this), $arguments) ); } @@ -227,12 +233,16 @@ public function __call($method, $arguments) public static function __callStatic($method, $arguments) { if (!isset(self::$bivalentMethods[$method])) { - trigger_error( - 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR - ); + if (PHP_VERSION_ID < 70000) { + trigger_error( + 'Call to undefined method PEAR::' . $method . '()', E_USER_ERROR + ); + } else { + throw new Error('Call to undefined method PEAR::' . $method . '()'); + } } return call_user_func_array( - array(get_class(), '_' . $method), + array(__CLASS__, '_' . $method), array_merge(array(null), $arguments) ); } @@ -859,6 +869,7 @@ class PEAR_Error var $message = ''; var $userinfo = ''; var $backtrace = null; + var $callback = null; /** * PEAR_Error constructor diff --git a/lib/pear/pear-core-minimal/src/PEAR/Error.php b/lib/pear/pear-core-minimal/src/PEAR/Error.php deleted file mode 100644 index 96efff75da..0000000000 --- a/lib/pear/pear-core-minimal/src/PEAR/Error.php +++ /dev/null @@ -1,14 +0,0 @@ - - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @link http://pear.php.net/package/PEAR - */ -require_once __DIR__ . '/../PEAR.php'; -?> \ No newline at end of file diff --git a/lib/pelago/emogrifier/CHANGELOG.md b/lib/pelago/emogrifier/CHANGELOG.md index f6145abac6..62ff649c08 100644 --- a/lib/pelago/emogrifier/CHANGELOG.md +++ b/lib/pelago/emogrifier/CHANGELOG.md @@ -3,6 +3,9 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](https://semver.org/). +Please also have a look at our +[API and deprecation policy](docs/API-and-deprecation-policy.md). + ## x.y.z ### Added @@ -15,84 +18,123 @@ This project adheres to [Semantic Versioning](https://semver.org/). ### Fixed +## 7.3.0: Add support for PHP 8.4 and CSS custom properties + +### Added + +- Add support for PHP 8.4 (#1278) +- Support CSS custom properties (variables) (#1336) +- Support `:root` pseudo-class (#1306) +- Add CSS selectors exclusion feature (#1236) + +### Changed + +- Require `sabberworm/php-css-parser:^8.7.0` (#1355) + +### Fixed + +- Preserve case of CSS custom property (variable) names (#1332) + +### Documentation + +- Add an API and deprecation policy (#1323) + ## 7.2.0: Add support for Symfony 7 ### Added + - Add support for Symfony 7 (#1243) ## 7.1.0: Add support for PHP 8.3 ### Added + - Add support for PHP 8.3 (#1218) ### Changed + - Disable HTML formatting by default (#1214) ## 7.0.0 ### Added + - Add support for PHP 8.2 (#1155) ### Changed + - Throw exception with invalid CSS in debug mode (#1142) - Only support up to 69 atomic expressions in a selector (#1113) - Require `sabberworm/php-css-parser:^8.4.0` (#1134) - Upgrade to PHPUnit 9 (#1112) ### Deprecated + - Support for PHP 7.3 will be removed in Emogrifier 8.0. ### Removed + - Drop support for Symfony 3.x and 5.3 (#1120, #1162) - Drop support for PHP 7.2 (#1111) ### Fixed + - Bump the minimum Symfony 4.4 version to avoid PHP deprecation warnings (#1187) ## 6.0.0 ### Added + - Test with Symfony 6-dev (#1109) - Add support for PHP 8.1 (#1103) - Add a dedicated class for caching (#1097) - Allow installation together with Symfony 6 (#1065) - Support more file types in the `.editorconfig` (#1035) -- Set `align` attribute of `` elements with `CssToAttributeConverter` (#1008) +- Set `align` attribute of `` elements with `CssToAttributeConverter` + (#1008) ### Changed + - Use `sabberworm/php-css-parser` to parse the CSS (#1015) - Also check the unit test code with Psalm (#1003) ### Deprecated + - Support for PHP 7.2 will be removed in Emogrifier 7.0. ### Removed + - Remove a redundant CSS data cache (#1018) - Drop support for Symfony 5.1 and 5.2 (#972, #1104) - Drop support for PHP 7.1 (#967) ### Fixed + - Allow `@import` after ignored invalid `@charset` (@1081) - Allow line feeds within `` tag (#987) ## 5.0.1 ### Changed + - Switch the default branch from `master` to `main` (#951) ### Fixed + - Ignore `http-equiv` `Content-Type` in `` (#961) - Allow "Content-Type" in content (#959) ## 5.0.0 ### Added + - Add an `.editorconfig` file (#940) - Support PHP 8.0 (#926) - Run the CI build once a week (#933) - Move more development tools to PHIVE (#894, #907) ### Changed + - Automatically add a backslash for global functions (#909) - Update the development tools (#898, #895) - Upgrade to PHPUnit 7.5 (#888) @@ -101,14 +143,17 @@ This project adheres to [Semantic Versioning](https://semver.org/). - Make use of PHP 7.1 language features (#883) ### Deprecated + - Support for PHP 7.1 will be removed in Emogrifier 6.0. ### Removed + - Drop support for Symfony 4.3 and 5.0 (#936) - Stop checking `tests/` with Psalm (#885) - Drop support for PHP 7.0 (#880) ### Fixed + - Fix a nonsensical code example in the README (#920, #935) - Remove `!important` from `style` attributes also when uppercase, mixed case or having whitespace after `!` (#911) @@ -122,35 +167,43 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## 4.0.0 ### Added + - Extract and inject `@font-face` rules into head (#870) - Test tag omission in conformant supplied HTML (#868) - Check for missing return type hint annotations in the code sniffs (#860) - Support `:only-of-type` (with a type) (#849, #856) -- Configuration setting methods now all return `$this` to allow chaining (#824, #854) +- Configuration setting methods now all return `$this` to allow chaining + (#824, #854) - Disable php-cs-fixer Yoda conditions (#791, #794) - Check the code with psalm (#537, #779) - Composer script to run tests with `--stop-on-failure` (#782) - Test universal selector with combinators (#776) ### Changed -- Normalize DOCTYPE declaration according to polyglot markup recommendation (#866) + +- Normalize DOCTYPE declaration according to polyglot markup recommendation + (#866) - Upgrade to V2 of the PHP setup GitHub action (#861) - Move the development tools to PHIVE (#850, #851) - Switch the parallel linting to a maintained fork (#842) -- Move continuous integration from Travis CI to GitHub actions (#832, #834, #838, #839, #840, #841, #843, #846, #849) +- Move continuous integration from Travis CI to GitHub actions + (#832, #834, #838, #839, #840, #841, #843, #846, #849) - Clean up the folder structure and autoloading configuration (#529, #785) - Use `self` as the return type for `fromHtml` (#784) - Make use of PHP 7.0 language features (#777) ### Deprecated + - Support for PHP 7.0 will be removed in Emogrifier 5.0. ### Removed + - Drop support for Symfony versions that have reached their end of life (#847) - Drop the `Emogrifier` class (#774) - Drop support for PHP 5.6 (#773) ### Fixed + - Allow `:last-of-type` etc. without type, without causing exception (#875) - Make sure to use the Composer-installed development tools (#862, #865) - Add missing `` element when there's a `
` element (#844, #853) @@ -161,22 +214,28 @@ This project adheres to [Semantic Versioning](https://semver.org/). ## 3.1.0 ### Added + - Add support for PHP 7.4 (#821, #829) ### Changed + - Upgrade to Symfony 5.0 (#820) ## 3.0.0 ### Added -- Test and document excluding entire subtree with `addExcludedSelector()` (#347, #768) + +- Test and document excluding entire subtree with `addExcludedSelector()` + (#347, #768) - Test that rules with `:optional` or `:required` are copied to the ` diff --git a/lib/symfony/error-handler/Resources/views/exception_full.html.php b/lib/symfony/error-handler/Resources/views/exception_full.html.php index 9d5f6e3366..af04db1bd2 100644 --- a/lib/symfony/error-handler/Resources/views/exception_full.html.php +++ b/lib/symfony/error-handler/Resources/views/exception_full.html.php @@ -2,11 +2,11 @@ - - - + + + <?= $_message; ?> - + diff --git a/lib/symfony/filesystem/Exception/FileNotFoundException.php b/lib/symfony/filesystem/Exception/FileNotFoundException.php index 48b6408095..d0d27977d0 100644 --- a/lib/symfony/filesystem/Exception/FileNotFoundException.php +++ b/lib/symfony/filesystem/Exception/FileNotFoundException.php @@ -19,13 +19,13 @@ */ class FileNotFoundException extends IOException { - public function __construct(string $message = null, int $code = 0, \Throwable $previous = null, string $path = null) + public function __construct(?string $message = null, int $code = 0, ?\Throwable $previous = null, ?string $path = null) { if (null === $message) { if (null === $path) { $message = 'File could not be found.'; } else { - $message = sprintf('File "%s" could not be found.', $path); + $message = \sprintf('File "%s" could not be found.', $path); } } diff --git a/lib/symfony/filesystem/Exception/IOException.php b/lib/symfony/filesystem/Exception/IOException.php index a3c5445534..df3a0850a0 100644 --- a/lib/symfony/filesystem/Exception/IOException.php +++ b/lib/symfony/filesystem/Exception/IOException.php @@ -22,7 +22,7 @@ class IOException extends \RuntimeException implements IOExceptionInterface { private ?string $path; - public function __construct(string $message, int $code = 0, \Throwable $previous = null, string $path = null) + public function __construct(string $message, int $code = 0, ?\Throwable $previous = null, ?string $path = null) { $this->path = $path; diff --git a/lib/symfony/filesystem/Filesystem.php b/lib/symfony/filesystem/Filesystem.php index 78458d5b91..71628ceed9 100644 --- a/lib/symfony/filesystem/Filesystem.php +++ b/lib/symfony/filesystem/Filesystem.php @@ -40,25 +40,25 @@ public function copy(string $originFile, string $targetFile, bool $overwriteNewe { $originIsLocal = stream_is_local($originFile) || 0 === stripos($originFile, 'file://'); if ($originIsLocal && !is_file($originFile)) { - throw new FileNotFoundException(sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile); + throw new FileNotFoundException(\sprintf('Failed to copy "%s" because file does not exist.', $originFile), 0, null, $originFile); } $this->mkdir(\dirname($targetFile)); $doCopy = true; - if (!$overwriteNewerFiles && null === parse_url($originFile, \PHP_URL_HOST) && is_file($targetFile)) { + if (!$overwriteNewerFiles && !parse_url($originFile, \PHP_URL_HOST) && is_file($targetFile)) { $doCopy = filemtime($originFile) > filemtime($targetFile); } if ($doCopy) { // https://bugs.php.net/64634 if (!$source = self::box('fopen', $originFile, 'r')) { - throw new IOException(sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile); + throw new IOException(\sprintf('Failed to copy "%s" to "%s" because source file could not be opened for reading: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile); } // Stream context created to allow files overwrite when using FTP stream wrapper - disabled by default if (!$target = self::box('fopen', $targetFile, 'w', false, stream_context_create(['ftp' => ['overwrite' => true]]))) { - throw new IOException(sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile); + throw new IOException(\sprintf('Failed to copy "%s" to "%s" because target file could not be opened for writing: ', $originFile, $targetFile).self::$lastError, 0, null, $originFile); } $bytesCopied = stream_copy_to_stream($source, $target); @@ -67,15 +67,18 @@ public function copy(string $originFile, string $targetFile, bool $overwriteNewe unset($source, $target); if (!is_file($targetFile)) { - throw new IOException(sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile); + throw new IOException(\sprintf('Failed to copy "%s" to "%s".', $originFile, $targetFile), 0, null, $originFile); } if ($originIsLocal) { // Like `cp`, preserve executable permission bits self::box('chmod', $targetFile, fileperms($targetFile) | (fileperms($originFile) & 0111)); + // Like `cp`, preserve the file modification time + self::box('touch', $targetFile, filemtime($originFile)); + if ($bytesCopied !== $bytesOrigin = filesize($originFile)) { - throw new IOException(sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile); + throw new IOException(\sprintf('Failed to copy the whole content of "%s" to "%s" (%g of %g bytes copied).', $originFile, $targetFile, $bytesCopied, $bytesOrigin), 0, null, $originFile); } } } @@ -96,7 +99,7 @@ public function mkdir(string|iterable $dirs, int $mode = 0777) } if (!self::box('mkdir', $dir, $mode, true) && !is_dir($dir)) { - throw new IOException(sprintf('Failed to create "%s": ', $dir).self::$lastError, 0, null, $dir); + throw new IOException(\sprintf('Failed to create "%s": ', $dir).self::$lastError, 0, null, $dir); } } } @@ -110,7 +113,7 @@ public function exists(string|iterable $files): bool foreach ($this->toIterable($files) as $file) { if (\strlen($file) > $maxPathLength) { - throw new IOException(sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file); + throw new IOException(\sprintf('Could not check if file exist because path length exceeds %d characters.', $maxPathLength), 0, null, $file); } if (!file_exists($file)) { @@ -131,11 +134,11 @@ public function exists(string|iterable $files): bool * * @throws IOException When touch fails */ - public function touch(string|iterable $files, int $time = null, int $atime = null) + public function touch(string|iterable $files, ?int $time = null, ?int $atime = null) { foreach ($this->toIterable($files) as $file) { if (!($time ? self::box('touch', $file, $time, $atime) : self::box('touch', $file))) { - throw new IOException(sprintf('Failed to touch "%s": ', $file).self::$lastError, 0, null, $file); + throw new IOException(\sprintf('Failed to touch "%s": ', $file).self::$lastError, 0, null, $file); } } } @@ -165,11 +168,11 @@ private static function doRemove(array $files, bool $isRecursive): void if (is_link($file)) { // See https://bugs.php.net/52176 if (!(self::box('unlink', $file) || '\\' !== \DIRECTORY_SEPARATOR || self::box('rmdir', $file)) && file_exists($file)) { - throw new IOException(sprintf('Failed to remove symlink "%s": ', $file).self::$lastError); + throw new IOException(\sprintf('Failed to remove symlink "%s": ', $file).self::$lastError); } } elseif (is_dir($file)) { if (!$isRecursive) { - $tmpName = \dirname(realpath($file)).'/.'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-_')); + $tmpName = \dirname(realpath($file)).'/.!'.strrev(strtr(base64_encode(random_bytes(2)), '/=', '-!')); if (file_exists($tmpName)) { try { @@ -196,10 +199,10 @@ private static function doRemove(array $files, bool $isRecursive): void $file = $origFile; } - throw new IOException(sprintf('Failed to remove directory "%s": ', $file).$lastError); + throw new IOException(\sprintf('Failed to remove directory "%s": ', $file).$lastError); } - } elseif (!self::box('unlink', $file) && (str_contains(self::$lastError, 'Permission denied') || file_exists($file))) { - throw new IOException(sprintf('Failed to remove file "%s": ', $file).self::$lastError); + } elseif (!self::box('unlink', $file) && ((self::$lastError && str_contains(self::$lastError, 'Permission denied')) || file_exists($file))) { + throw new IOException(\sprintf('Failed to remove file "%s": ', $file).self::$lastError); } } } @@ -219,7 +222,7 @@ public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool { foreach ($this->toIterable($files) as $file) { if (!self::box('chmod', $file, $mode & ~$umask)) { - throw new IOException(sprintf('Failed to chmod file "%s": ', $file).self::$lastError, 0, null, $file); + throw new IOException(\sprintf('Failed to chmod file "%s": ', $file).self::$lastError, 0, null, $file); } if ($recursive && is_dir($file) && !is_link($file)) { $this->chmod(new \FilesystemIterator($file), $mode, $umask, true); @@ -230,6 +233,10 @@ public function chmod(string|iterable $files, int $mode, int $umask = 0000, bool /** * Change the owner of an array of files or directories. * + * This method always throws on Windows, as the underlying PHP function is not supported. + * + * @see https://php.net/chown + * * @param string|int $user A user name or number * @param bool $recursive Whether change the owner recursively or not * @@ -245,11 +252,11 @@ public function chown(string|iterable $files, string|int $user, bool $recursive } if (is_link($file) && \function_exists('lchown')) { if (!self::box('lchown', $file, $user)) { - throw new IOException(sprintf('Failed to chown file "%s": ', $file).self::$lastError, 0, null, $file); + throw new IOException(\sprintf('Failed to chown file "%s": ', $file).self::$lastError, 0, null, $file); } } else { if (!self::box('chown', $file, $user)) { - throw new IOException(sprintf('Failed to chown file "%s": ', $file).self::$lastError, 0, null, $file); + throw new IOException(\sprintf('Failed to chown file "%s": ', $file).self::$lastError, 0, null, $file); } } } @@ -258,6 +265,10 @@ public function chown(string|iterable $files, string|int $user, bool $recursive /** * Change the group of an array of files or directories. * + * This method always throws on Windows, as the underlying PHP function is not supported. + * + * @see https://php.net/chgrp + * * @param string|int $group A group name or number * @param bool $recursive Whether change the group recursively or not * @@ -273,11 +284,11 @@ public function chgrp(string|iterable $files, string|int $group, bool $recursive } if (is_link($file) && \function_exists('lchgrp')) { if (!self::box('lchgrp', $file, $group)) { - throw new IOException(sprintf('Failed to chgrp file "%s": ', $file).self::$lastError, 0, null, $file); + throw new IOException(\sprintf('Failed to chgrp file "%s": ', $file).self::$lastError, 0, null, $file); } } else { if (!self::box('chgrp', $file, $group)) { - throw new IOException(sprintf('Failed to chgrp file "%s": ', $file).self::$lastError, 0, null, $file); + throw new IOException(\sprintf('Failed to chgrp file "%s": ', $file).self::$lastError, 0, null, $file); } } } @@ -295,7 +306,7 @@ public function rename(string $origin, string $target, bool $overwrite = false) { // we check that target does not exist if (!$overwrite && $this->isReadable($target)) { - throw new IOException(sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target); + throw new IOException(\sprintf('Cannot rename because the target "%s" already exists.', $target), 0, null, $target); } if (!self::box('rename', $origin, $target)) { @@ -306,7 +317,7 @@ public function rename(string $origin, string $target, bool $overwrite = false) return; } - throw new IOException(sprintf('Cannot rename "%s" to "%s": ', $origin, $target).self::$lastError, 0, null, $target); + throw new IOException(\sprintf('Cannot rename "%s" to "%s": ', $origin, $target).self::$lastError, 0, null, $target); } } @@ -320,7 +331,7 @@ private function isReadable(string $filename): bool $maxPathLength = \PHP_MAXPATHLEN - 2; if (\strlen($filename) > $maxPathLength) { - throw new IOException(sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename); + throw new IOException(\sprintf('Could not check if file is readable because path length exceeds %d characters.', $maxPathLength), 0, null, $filename); } return is_readable($filename); @@ -381,7 +392,7 @@ public function hardlink(string $originFile, string|iterable $targetFiles) } if (!is_file($originFile)) { - throw new FileNotFoundException(sprintf('Origin file "%s" is not a file.', $originFile)); + throw new FileNotFoundException(\sprintf('Origin file "%s" is not a file.', $originFile)); } foreach ($this->toIterable($targetFiles) as $targetFile) { @@ -405,10 +416,10 @@ private function linkException(string $origin, string $target, string $linkType) { if (self::$lastError) { if ('\\' === \DIRECTORY_SEPARATOR && str_contains(self::$lastError, 'error code(1314)')) { - throw new IOException(sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target); + throw new IOException(\sprintf('Unable to create "%s" link due to error code 1314: \'A required privilege is not held by the client\'. Do you have the required Administrator-rights?', $linkType), 0, null, $target); } } - throw new IOException(sprintf('Failed to create "%s" link from "%s" to "%s": ', $linkType, $origin, $target).self::$lastError, 0, null, $target); + throw new IOException(\sprintf('Failed to create "%s" link from "%s" to "%s": ', $linkType, $origin, $target).self::$lastError, 0, null, $target); } /** @@ -445,11 +456,11 @@ public function readlink(string $path, bool $canonicalize = false): ?string public function makePathRelative(string $endPath, string $startPath): string { if (!$this->isAbsolutePath($startPath)) { - throw new InvalidArgumentException(sprintf('The start path "%s" is not absolute.', $startPath)); + throw new InvalidArgumentException(\sprintf('The start path "%s" is not absolute.', $startPath)); } if (!$this->isAbsolutePath($endPath)) { - throw new InvalidArgumentException(sprintf('The end path "%s" is not absolute.', $endPath)); + throw new InvalidArgumentException(\sprintf('The end path "%s" is not absolute.', $endPath)); } // Normalize separators on Windows @@ -530,14 +541,14 @@ public function makePathRelative(string $endPath, string $startPath): string * * @throws IOException When file type is unknown */ - public function mirror(string $originDir, string $targetDir, \Traversable $iterator = null, array $options = []) + public function mirror(string $originDir, string $targetDir, ?\Traversable $iterator = null, array $options = []) { $targetDir = rtrim($targetDir, '/\\'); $originDir = rtrim($originDir, '/\\'); $originDirLen = \strlen($originDir); if (!$this->exists($originDir)) { - throw new IOException(sprintf('The origin directory specified "%s" was not found.', $originDir), 0, null, $originDir); + throw new IOException(\sprintf('The origin directory specified "%s" was not found.', $originDir), 0, null, $originDir); } // Iterate in destination folder to remove obsolete entries @@ -581,7 +592,7 @@ public function mirror(string $originDir, string $targetDir, \Traversable $itera } elseif (is_file($file)) { $this->copy($file, $target, $options['override'] ?? false); } else { - throw new IOException(sprintf('Unable to guess "%s" file type.', $file), 0, null, $file); + throw new IOException(\sprintf('Unable to guess "%s" file type.', $file), 0, null, $file); } } } @@ -659,7 +670,7 @@ public function tempnam(string $dir, string $prefix, string $suffix = ''): strin public function dumpFile(string $filename, $content) { if (\is_array($content)) { - throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); + throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); } $dir = \dirname($filename); @@ -680,14 +691,18 @@ public function dumpFile(string $filename, $content) try { if (false === self::box('file_put_contents', $tmpFile, $content)) { - throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename); + throw new IOException(\sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename); } - self::box('chmod', $tmpFile, file_exists($filename) ? fileperms($filename) : 0666 & ~umask()); + self::box('chmod', $tmpFile, self::box('fileperms', $filename) ?: 0666 & ~umask()); $this->rename($tmpFile, $filename, true); } finally { if (file_exists($tmpFile)) { + if ('\\' === \DIRECTORY_SEPARATOR && !is_writable($tmpFile)) { + self::box('chmod', $tmpFile, self::box('fileperms', $tmpFile) | 0200); + } + self::box('unlink', $tmpFile); } } @@ -706,7 +721,7 @@ public function dumpFile(string $filename, $content) public function appendToFile(string $filename, $content/* , bool $lock = false */) { if (\is_array($content)) { - throw new \TypeError(sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); + throw new \TypeError(\sprintf('Argument 2 passed to "%s()" must be string or resource, array given.', __METHOD__)); } $dir = \dirname($filename); @@ -718,7 +733,7 @@ public function appendToFile(string $filename, $content/* , bool $lock = false * $lock = \func_num_args() > 2 && func_get_arg(2); if (false === self::box('file_put_contents', $filename, $content, \FILE_APPEND | ($lock ? \LOCK_EX : 0))) { - throw new IOException(sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename); + throw new IOException(\sprintf('Failed to write file "%s": ', $filename).self::$lastError, 0, null, $filename); } } @@ -740,7 +755,7 @@ private function getSchemeAndHierarchy(string $filename): array private static function assertFunctionExists(string $func): void { if (!\function_exists($func)) { - throw new IOException(sprintf('Unable to perform filesystem operation because the "%s()" function has been disabled.', $func)); + throw new IOException(\sprintf('Unable to perform filesystem operation because the "%s()" function has been disabled.', $func)); } } diff --git a/lib/symfony/filesystem/Path.php b/lib/symfony/filesystem/Path.php index 6643962351..093d19f5e9 100644 --- a/lib/symfony/filesystem/Path.php +++ b/lib/symfony/filesystem/Path.php @@ -254,7 +254,7 @@ public static function getRoot(string $path): string * @param string|null $extension if specified, only that extension is cut * off (may contain leading dot) */ - public static function getFilenameWithoutExtension(string $path, string $extension = null): string + public static function getFilenameWithoutExtension(string $path, ?string $extension = null): string { if ('' === $path) { return ''; @@ -365,7 +365,7 @@ public static function isAbsolute(string $path): bool } // Strip scheme - if (false !== $schemeSeparatorPosition = strpos($path, '://')) { + if (false !== ($schemeSeparatorPosition = strpos($path, '://')) && 1 !== $schemeSeparatorPosition) { $path = substr($path, $schemeSeparatorPosition + 3); } @@ -437,11 +437,11 @@ public static function isRelative(string $path): bool public static function makeAbsolute(string $path, string $basePath): string { if ('' === $basePath) { - throw new InvalidArgumentException(sprintf('The base path must be a non-empty string. Got: "%s".', $basePath)); + throw new InvalidArgumentException(\sprintf('The base path must be a non-empty string. Got: "%s".', $basePath)); } if (!self::isAbsolute($basePath)) { - throw new InvalidArgumentException(sprintf('The base path "%s" is not an absolute path.', $basePath)); + throw new InvalidArgumentException(\sprintf('The base path "%s" is not an absolute path.', $basePath)); } if (self::isAbsolute($path)) { @@ -531,12 +531,12 @@ public static function makeRelative(string $path, string $basePath): string // If the passed path is absolute, but the base path is not, we // cannot generate a relative path if ('' !== $root && '' === $baseRoot) { - throw new InvalidArgumentException(sprintf('The absolute path "%s" cannot be made relative to the relative path "%s". You should provide an absolute base path instead.', $path, $basePath)); + throw new InvalidArgumentException(\sprintf('The absolute path "%s" cannot be made relative to the relative path "%s". You should provide an absolute base path instead.', $path, $basePath)); } // Fail if the roots of the two paths are different if ($baseRoot && $root !== $baseRoot) { - throw new InvalidArgumentException(sprintf('The path "%s" cannot be made relative to "%s", because they have different roots ("%s" and "%s").', $path, $basePath, $root, $baseRoot)); + throw new InvalidArgumentException(\sprintf('The path "%s" cannot be made relative to "%s", because they have different roots ("%s" and "%s").', $path, $basePath, $root, $baseRoot)); } if ('' === $relativeBasePath) { diff --git a/lib/symfony/filesystem/composer.json b/lib/symfony/filesystem/composer.json index 10a7a531c0..fd75755b2b 100644 --- a/lib/symfony/filesystem/composer.json +++ b/lib/symfony/filesystem/composer.json @@ -20,6 +20,9 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" }, "exclude-from-classmap": [ diff --git a/lib/symfony/finder/Comparator/Comparator.php b/lib/symfony/finder/Comparator/Comparator.php index bd68583473..23e42f719f 100644 --- a/lib/symfony/finder/Comparator/Comparator.php +++ b/lib/symfony/finder/Comparator/Comparator.php @@ -22,7 +22,7 @@ class Comparator public function __construct(string $target, string $operator = '==') { if (!\in_array($operator, ['>', '<', '>=', '<=', '==', '!='])) { - throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator)); + throw new \InvalidArgumentException(\sprintf('Invalid operator "%s".', $operator)); } $this->target = $target; diff --git a/lib/symfony/finder/Comparator/DateComparator.php b/lib/symfony/finder/Comparator/DateComparator.php index e0c523d055..bcf93cfb6a 100644 --- a/lib/symfony/finder/Comparator/DateComparator.php +++ b/lib/symfony/finder/Comparator/DateComparator.php @@ -26,17 +26,17 @@ class DateComparator extends Comparator public function __construct(string $test) { if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) { - throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test)); + throw new \InvalidArgumentException(\sprintf('Don\'t understand "%s" as a date test.', $test)); } try { $date = new \DateTimeImmutable($matches[2]); $target = $date->format('U'); } catch (\Exception) { - throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2])); + throw new \InvalidArgumentException(\sprintf('"%s" is not a valid date.', $matches[2])); } - $operator = $matches[1] ?? '=='; + $operator = $matches[1] ?: '=='; if ('since' === $operator || 'after' === $operator) { $operator = '>'; } diff --git a/lib/symfony/finder/Comparator/NumberComparator.php b/lib/symfony/finder/Comparator/NumberComparator.php index dd3082077a..49cfcc4bca 100644 --- a/lib/symfony/finder/Comparator/NumberComparator.php +++ b/lib/symfony/finder/Comparator/NumberComparator.php @@ -42,12 +42,12 @@ class NumberComparator extends Comparator public function __construct(?string $test) { if (null === $test || !preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) { - throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test ?? 'null')); + throw new \InvalidArgumentException(\sprintf('Don\'t understand "%s" as a number test.', $test ?? 'null')); } $target = $matches[2]; if (!is_numeric($target)) { - throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target)); + throw new \InvalidArgumentException(\sprintf('Invalid number "%s".', $target)); } if (isset($matches[3])) { // magnitude diff --git a/lib/symfony/finder/Finder.php b/lib/symfony/finder/Finder.php index 0fd283c123..83e5d2a8b6 100644 --- a/lib/symfony/finder/Finder.php +++ b/lib/symfony/finder/Finder.php @@ -57,8 +57,10 @@ class Finder implements \IteratorAggregate, \Countable private bool $reverseSorting = false; private \Closure|int|false $sort = false; private int $ignore = 0; + /** @var list */ private array $dirs = []; private array $dates = []; + /** @var list> */ private array $iterators = []; private array $contains = []; private array $notContains = []; @@ -124,7 +126,7 @@ public function files(): static public function depth(string|int|array $levels): static { foreach ((array) $levels as $level) { - $this->depths[] = new Comparator\NumberComparator($level); + $this->depths[] = new NumberComparator($level); } return $this; @@ -152,7 +154,7 @@ public function depth(string|int|array $levels): static public function date(string|array $dates): static { foreach ((array) $dates as $date) { - $this->dates[] = new Comparator\DateComparator($date); + $this->dates[] = new DateComparator($date); } return $this; @@ -307,7 +309,7 @@ public function notPath(string|array $patterns): static public function size(string|int|array $sizes): static { foreach ((array) $sizes as $size) { - $this->sizes[] = new Comparator\NumberComparator($size); + $this->sizes[] = new NumberComparator($size); } return $this; @@ -438,7 +440,7 @@ public function sort(\Closure $closure): static */ public function sortByExtension(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_EXTENSION; + $this->sort = SortableIterator::SORT_BY_EXTENSION; return $this; } @@ -454,7 +456,7 @@ public function sortByExtension(): static */ public function sortByName(bool $useNaturalSort = false): static { - $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL : Iterator\SortableIterator::SORT_BY_NAME; + $this->sort = $useNaturalSort ? SortableIterator::SORT_BY_NAME_NATURAL : SortableIterator::SORT_BY_NAME; return $this; } @@ -470,7 +472,7 @@ public function sortByName(bool $useNaturalSort = false): static */ public function sortByCaseInsensitiveName(bool $useNaturalSort = false): static { - $this->sort = $useNaturalSort ? Iterator\SortableIterator::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE : Iterator\SortableIterator::SORT_BY_NAME_CASE_INSENSITIVE; + $this->sort = $useNaturalSort ? SortableIterator::SORT_BY_NAME_NATURAL_CASE_INSENSITIVE : SortableIterator::SORT_BY_NAME_CASE_INSENSITIVE; return $this; } @@ -486,7 +488,7 @@ public function sortByCaseInsensitiveName(bool $useNaturalSort = false): static */ public function sortBySize(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_SIZE; + $this->sort = SortableIterator::SORT_BY_SIZE; return $this; } @@ -502,7 +504,7 @@ public function sortBySize(): static */ public function sortByType(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_TYPE; + $this->sort = SortableIterator::SORT_BY_TYPE; return $this; } @@ -520,7 +522,7 @@ public function sortByType(): static */ public function sortByAccessedTime(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME; + $this->sort = SortableIterator::SORT_BY_ACCESSED_TIME; return $this; } @@ -552,7 +554,7 @@ public function reverseSorting(): static */ public function sortByChangedTime(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME; + $this->sort = SortableIterator::SORT_BY_CHANGED_TIME; return $this; } @@ -570,7 +572,7 @@ public function sortByChangedTime(): static */ public function sortByModifiedTime(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME; + $this->sort = SortableIterator::SORT_BY_MODIFIED_TIME; return $this; } @@ -646,7 +648,7 @@ public function in(string|array $dirs): static sort($glob); $resolvedDirs[] = array_map($this->normalizeDir(...), $glob); } else { - throw new DirectoryNotFoundException(sprintf('The "%s" directory does not exist.', $dir)); + throw new DirectoryNotFoundException(\sprintf('The "%s" directory does not exist.', $dir)); } } @@ -666,31 +668,37 @@ public function in(string|array $dirs): static */ public function getIterator(): \Iterator { - if (0 === \count($this->dirs) && 0 === \count($this->iterators)) { + if (!$this->dirs && !$this->iterators) { throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.'); } - if (1 === \count($this->dirs) && 0 === \count($this->iterators)) { + if (1 === \count($this->dirs) && !$this->iterators) { $iterator = $this->searchInDirectory($this->dirs[0]); - - if ($this->sort || $this->reverseSorting) { - $iterator = (new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); + } else { + $iterator = new \AppendIterator(); + foreach ($this->dirs as $dir) { + $iterator->append(new \IteratorIterator(new LazyIterator(fn () => $this->searchInDirectory($dir)))); } - return $iterator; - } - - $iterator = new \AppendIterator(); - foreach ($this->dirs as $dir) { - $iterator->append(new \IteratorIterator(new LazyIterator(fn () => $this->searchInDirectory($dir)))); - } - - foreach ($this->iterators as $it) { - $iterator->append($it); + foreach ($this->iterators as $it) { + $iterator->append(new \IteratorIterator(new LazyIterator(static function () use ($it) { + foreach ($it as $file) { + if (!$file instanceof \SplFileInfo) { + $file = new \SplFileInfo($file); + } + $key = $file->getPathname(); + if (!$file instanceof SplFileInfo) { + $file = new SplFileInfo($key, $file->getPath(), $key); + } + + yield $key => $file; + } + }))); + } } if ($this->sort || $this->reverseSorting) { - $iterator = (new Iterator\SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); + $iterator = (new SortableIterator($iterator, $this->sort, $this->reverseSorting))->getIterator(); } return $iterator; @@ -701,26 +709,13 @@ public function getIterator(): \Iterator * * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array. * - * @return $this + * @param iterable $iterator * - * @throws \InvalidArgumentException when the given argument is not iterable + * @return $this */ public function append(iterable $iterator): static { - if ($iterator instanceof \IteratorAggregate) { - $this->iterators[] = $iterator->getIterator(); - } elseif ($iterator instanceof \Iterator) { - $this->iterators[] = $iterator; - } elseif (is_iterable($iterator)) { - $it = new \ArrayIterator(); - foreach ($iterator as $file) { - $file = $file instanceof \SplFileInfo ? $file : new \SplFileInfo($file); - $it[$file->getPathname()] = $file; - } - $this->iterators[] = $it; - } else { - throw new \InvalidArgumentException('Finder::append() method wrong argument type.'); - } + $this->iterators[] = $iterator; return $this; } @@ -793,13 +788,13 @@ private function searchInDirectory(string $dir): \Iterator $iterator = new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs); if ($exclude) { - $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $exclude); + $iterator = new ExcludeDirectoryFilterIterator($iterator, $exclude); } $iterator = new \RecursiveIteratorIterator($iterator, \RecursiveIteratorIterator::SELF_FIRST); if ($minDepth > 0 || $maxDepth < \PHP_INT_MAX) { - $iterator = new Iterator\DepthRangeFilterIterator($iterator, $minDepth, $maxDepth); + $iterator = new DepthRangeFilterIterator($iterator, $minDepth, $maxDepth); } if ($this->mode) { @@ -807,23 +802,23 @@ private function searchInDirectory(string $dir): \Iterator } if ($this->names || $this->notNames) { - $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames); + $iterator = new FilenameFilterIterator($iterator, $this->names, $this->notNames); } if ($this->contains || $this->notContains) { - $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains); + $iterator = new FilecontentFilterIterator($iterator, $this->contains, $this->notContains); } if ($this->sizes) { - $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes); + $iterator = new SizeRangeFilterIterator($iterator, $this->sizes); } if ($this->dates) { - $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates); + $iterator = new DateRangeFilterIterator($iterator, $this->dates); } if ($this->filters) { - $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters); + $iterator = new CustomFilterIterator($iterator, $this->filters); } if ($this->paths || $notPaths) { diff --git a/lib/symfony/finder/Glob.php b/lib/symfony/finder/Glob.php index 7fe8b1a86c..d950e48fc7 100644 --- a/lib/symfony/finder/Glob.php +++ b/lib/symfony/finder/Glob.php @@ -44,6 +44,9 @@ public static function toRegex(string $glob, bool $strictLeadingDot = true, bool $escaping = false; $inCurlies = 0; $regex = ''; + if ($unanchored = str_starts_with($glob, '**/')) { + $glob = '/'.$glob; + } $sizeGlob = \strlen($glob); for ($i = 0; $i < $sizeGlob; ++$i) { $car = $glob[$i]; @@ -104,6 +107,10 @@ public static function toRegex(string $glob, bool $strictLeadingDot = true, bool $escaping = false; } + if ($unanchored) { + $regex = substr_replace($regex, '?', 1 + ('/' === $delimiter) + ($strictLeadingDot ? \strlen('(?=[^\.])') : 0), 0); + } + return $delimiter.'^'.$regex.'$'.$delimiter; } } diff --git a/lib/symfony/finder/Iterator/RecursiveDirectoryIterator.php b/lib/symfony/finder/Iterator/RecursiveDirectoryIterator.php index 34cced6889..f5fd2d4dc5 100644 --- a/lib/symfony/finder/Iterator/RecursiveDirectoryIterator.php +++ b/lib/symfony/finder/Iterator/RecursiveDirectoryIterator.php @@ -63,8 +63,9 @@ public function current(): SplFileInfo $subPathname .= $this->directorySeparator; } $subPathname .= $this->getFilename(); + $basePath = $this->rootPath; - if ('/' !== $basePath = $this->rootPath) { + if ('/' !== $basePath && !str_ends_with($basePath, $this->directorySeparator) && !str_ends_with($basePath, '/')) { $basePath .= $this->directorySeparator; } diff --git a/lib/symfony/finder/Iterator/VcsIgnoredFilterIterator.php b/lib/symfony/finder/Iterator/VcsIgnoredFilterIterator.php index ddd7007728..b278706e9f 100644 --- a/lib/symfony/finder/Iterator/VcsIgnoredFilterIterator.php +++ b/lib/symfony/finder/Iterator/VcsIgnoredFilterIterator.php @@ -37,9 +37,9 @@ public function __construct(\Iterator $iterator, string $baseDir) { $this->baseDir = $this->normalizePath($baseDir); - foreach ($this->parentDirectoriesUpwards($this->baseDir) as $parentDirectory) { - if (@is_dir("{$parentDirectory}/.git")) { - $this->baseDir = $parentDirectory; + foreach ([$this->baseDir, ...$this->parentDirectoriesUpwards($this->baseDir)] as $directory) { + if (@is_dir("{$directory}/.git")) { + $this->baseDir = $directory; break; } } diff --git a/lib/symfony/framework-bundle/CHANGELOG.md b/lib/symfony/framework-bundle/CHANGELOG.md index 949aad31c3..639fe721d2 100644 --- a/lib/symfony/framework-bundle/CHANGELOG.md +++ b/lib/symfony/framework-bundle/CHANGELOG.md @@ -6,6 +6,7 @@ CHANGELOG * Add `HttpClientAssertionsTrait` * Add `AbstractController::renderBlock()` and `renderBlockView()` + * Remove call to `renderView()` in `AbstractController::render()` * Add native return type to `Translator` and to `Application::reset()` * Deprecate the integration of Doctrine annotations, either uninstall the `doctrine/annotations` package or disable the integration by setting `framework.annotations` to `false` * Enable `json_decode_detailed_errors` context for Serializer by default if `kernel.debug` is true and the `seld/jsonlint` package is installed diff --git a/lib/symfony/framework-bundle/CacheWarmer/CachePoolClearerCacheWarmer.php b/lib/symfony/framework-bundle/CacheWarmer/CachePoolClearerCacheWarmer.php index 7498a82d1f..ae27502cfb 100644 --- a/lib/symfony/framework-bundle/CacheWarmer/CachePoolClearerCacheWarmer.php +++ b/lib/symfony/framework-bundle/CacheWarmer/CachePoolClearerCacheWarmer.php @@ -37,7 +37,7 @@ public function __construct(Psr6CacheClearer $poolClearer, array $pools = []) $this->pools = $pools; } - public function warmUp(string $cacheDir, string $buildDir = null): array + public function warmUp(string $cacheDir, ?string $buildDir = null): array { foreach ($this->pools as $pool) { if ($this->poolClearer->hasPool($pool)) { diff --git a/lib/symfony/framework-bundle/CacheWarmer/ConfigBuilderCacheWarmer.php b/lib/symfony/framework-bundle/CacheWarmer/ConfigBuilderCacheWarmer.php index 7e039ae2f4..c43fc8af13 100644 --- a/lib/symfony/framework-bundle/CacheWarmer/ConfigBuilderCacheWarmer.php +++ b/lib/symfony/framework-bundle/CacheWarmer/ConfigBuilderCacheWarmer.php @@ -15,10 +15,14 @@ use Symfony\Component\Config\Builder\ConfigBuilderGenerator; use Symfony\Component\Config\Builder\ConfigBuilderGeneratorInterface; use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; +use Symfony\Component\DependencyInjection\ParameterBag\ContainerBag; +use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface; +use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelInterface; /** @@ -31,7 +35,7 @@ class ConfigBuilderCacheWarmer implements CacheWarmerInterface private KernelInterface $kernel; private ?LoggerInterface $logger; - public function __construct(KernelInterface $kernel, LoggerInterface $logger = null) + public function __construct(KernelInterface $kernel, ?LoggerInterface $logger = null) { $this->kernel = $kernel; $this->logger = $logger; @@ -50,12 +54,27 @@ public function warmUp(string $cacheDir /* , string $buildDir = null */): array $generator = new ConfigBuilderGenerator($buildDir); - foreach ($this->kernel->getBundles() as $bundle) { - $extension = $bundle->getContainerExtension(); - if (null === $extension) { - continue; + if ($this->kernel instanceof Kernel) { + /** @var ContainerBuilder $container */ + $container = \Closure::bind(function (Kernel $kernel) { + $containerBuilder = $kernel->getContainerBuilder(); + $kernel->prepareContainer($containerBuilder); + + return $containerBuilder; + }, null, $this->kernel)($this->kernel); + + $extensions = $container->getExtensions(); + } else { + $extensions = []; + foreach ($this->kernel->getBundles() as $bundle) { + $extension = $bundle->getContainerExtension(); + if (null !== $extension) { + $extensions[] = $extension; + } } + } + foreach ($extensions as $extension) { try { $this->dumpExtension($extension, $generator); } catch (\Exception $e) { @@ -73,7 +92,8 @@ private function dumpExtension(ExtensionInterface $extension, ConfigBuilderGener if ($extension instanceof ConfigurationInterface) { $configuration = $extension; } elseif ($extension instanceof ConfigurationExtensionInterface) { - $configuration = $extension->getConfiguration([], new ContainerBuilder($this->kernel->getContainer()->getParameterBag())); + $container = $this->kernel->getContainer(); + $configuration = $extension->getConfiguration([], new ContainerBuilder($container instanceof Container ? new ContainerBag($container) : new ParameterBag())); } if (!$configuration) { @@ -85,6 +105,6 @@ private function dumpExtension(ExtensionInterface $extension, ConfigBuilderGener public function isOptional(): bool { - return true; + return false; } } diff --git a/lib/symfony/framework-bundle/CacheWarmer/RouterCacheWarmer.php b/lib/symfony/framework-bundle/CacheWarmer/RouterCacheWarmer.php index 2af9a2fe80..b14bb74f19 100644 --- a/lib/symfony/framework-bundle/CacheWarmer/RouterCacheWarmer.php +++ b/lib/symfony/framework-bundle/CacheWarmer/RouterCacheWarmer.php @@ -34,7 +34,7 @@ public function __construct(ContainerInterface $container) $this->container = $container; } - public function warmUp(string $cacheDir, string $buildDir = null): array + public function warmUp(string $cacheDir, ?string $buildDir = null): array { $router = $this->container->get('router'); @@ -42,7 +42,7 @@ public function warmUp(string $cacheDir, string $buildDir = null): array return (array) $router->warmUp($cacheDir, $buildDir); } - throw new \LogicException(sprintf('The router "%s" cannot be warmed up because it does not implement "%s".', get_debug_type($router), WarmableInterface::class)); + throw new \LogicException(\sprintf('The router "%s" cannot be warmed up because it does not implement "%s".', get_debug_type($router), WarmableInterface::class)); } public function isOptional(): bool diff --git a/lib/symfony/framework-bundle/Command/AbstractConfigCommand.php b/lib/symfony/framework-bundle/Command/AbstractConfigCommand.php index 94b95e5029..ac2c5c9e6c 100644 --- a/lib/symfony/framework-bundle/Command/AbstractConfigCommand.php +++ b/lib/symfony/framework-bundle/Command/AbstractConfigCommand.php @@ -117,7 +117,7 @@ protected function findExtension(string $name): ExtensionInterface foreach ($bundles as $bundle) { if ($name === $bundle->getName()) { if (!$bundle->getContainerExtension()) { - throw new \LogicException(sprintf('Bundle "%s" does not have a container extension.', $name)); + throw new \LogicException(\sprintf('Bundle "%s" does not have a container extension.', $name)); } return $bundle->getContainerExtension(); @@ -147,13 +147,13 @@ protected function findExtension(string $name): ExtensionInterface } if (!str_ends_with($name, 'Bundle')) { - $message = sprintf('No extensions with configuration available for "%s".', $name); + $message = \sprintf('No extensions with configuration available for "%s".', $name); } else { - $message = sprintf('No extension with alias "%s" is enabled.', $name); + $message = \sprintf('No extension with alias "%s" is enabled.', $name); } if (isset($guess) && $minScore < 3) { - $message .= sprintf("\n\nDid you mean \"%s\"?", $guess); + $message .= \sprintf("\n\nDid you mean \"%s\"?", $guess); } throw new LogicException($message); @@ -165,11 +165,11 @@ protected function findExtension(string $name): ExtensionInterface public function validateConfiguration(ExtensionInterface $extension, mixed $configuration) { if (!$configuration) { - throw new \LogicException(sprintf('The extension with alias "%s" does not have its getConfiguration() method setup.', $extension->getAlias())); + throw new \LogicException(\sprintf('The extension with alias "%s" does not have its getConfiguration() method setup.', $extension->getAlias())); } if (!$configuration instanceof ConfigurationInterface) { - throw new \LogicException(sprintf('Configuration class "%s" should implement ConfigurationInterface in order to be dumpable.', get_debug_type($configuration))); + throw new \LogicException(\sprintf('Configuration class "%s" should implement ConfigurationInterface in order to be dumpable.', get_debug_type($configuration))); } } diff --git a/lib/symfony/framework-bundle/Command/AssetsInstallCommand.php b/lib/symfony/framework-bundle/Command/AssetsInstallCommand.php index 264955d795..936912876a 100644 --- a/lib/symfony/framework-bundle/Command/AssetsInstallCommand.php +++ b/lib/symfony/framework-bundle/Command/AssetsInstallCommand.php @@ -97,7 +97,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $targetArg = $kernel->getProjectDir().'/'.$targetArg; if (!is_dir($targetArg)) { - throw new InvalidArgumentException(sprintf('The target directory "%s" does not exist.', $targetArg)); + throw new InvalidArgumentException(\sprintf('The target directory "%s" does not exist.', $targetArg)); } } @@ -134,7 +134,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $validAssetDirs[] = $assetDir; if (OutputInterface::VERBOSITY_VERBOSE <= $output->getVerbosity()) { - $message = sprintf("%s\n-> %s", $bundle->getName(), $targetDir); + $message = \sprintf("%s\n-> %s", $bundle->getName(), $targetDir); } else { $message = $bundle->getName(); } @@ -155,13 +155,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int } if ($method === $expectedMethod) { - $rows[] = [sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */), $message, $method]; + $rows[] = [\sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'OK' : "\xE2\x9C\x94" /* HEAVY CHECK MARK (U+2714) */), $message, $method]; } else { - $rows[] = [sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'WARNING' : '!'), $message, $method]; + $rows[] = [\sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'WARNING' : '!'), $message, $method]; } } catch (\Exception $e) { $exitCode = 1; - $rows[] = [sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */), $message, $e->getMessage()]; + $rows[] = [\sprintf('%s', '\\' === \DIRECTORY_SEPARATOR ? 'ERROR' : "\xE2\x9C\x98" /* HEAVY BALLOT X (U+2718) */), $message, $e->getMessage()]; } } // remove the assets of the bundles that no longer exist @@ -234,7 +234,7 @@ private function symlink(string $originDir, string $targetDir, bool $relative = } $this->filesystem->symlink($originDir, $targetDir); if (!file_exists($targetDir)) { - throw new IOException(sprintf('Symbolic link "%s" was created but appears to be broken.', $targetDir), 0, null, $targetDir); + throw new IOException(\sprintf('Symbolic link "%s" was created but appears to be broken.', $targetDir), 0, null, $targetDir); } } diff --git a/lib/symfony/framework-bundle/Command/CacheClearCommand.php b/lib/symfony/framework-bundle/Command/CacheClearCommand.php index 878157e872..df9f38a265 100644 --- a/lib/symfony/framework-bundle/Command/CacheClearCommand.php +++ b/lib/symfony/framework-bundle/Command/CacheClearCommand.php @@ -40,7 +40,7 @@ class CacheClearCommand extends Command private CacheClearerInterface $cacheClearer; private Filesystem $filesystem; - public function __construct(CacheClearerInterface $cacheClearer, Filesystem $filesystem = null) + public function __construct(CacheClearerInterface $cacheClearer, ?Filesystem $filesystem = null) { parent::__construct(); @@ -80,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $fs->remove($oldCacheDir); if (!is_writable($realCacheDir)) { - throw new RuntimeException(sprintf('Unable to write in the "%s" directory.', $realCacheDir)); + throw new RuntimeException(\sprintf('Unable to write in the "%s" directory.', $realCacheDir)); } $useBuildDir = $realBuildDir !== $realCacheDir; @@ -89,7 +89,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $fs->remove($oldBuildDir); if (!is_writable($realBuildDir)) { - throw new RuntimeException(sprintf('Unable to write in the "%s" directory.', $realBuildDir)); + throw new RuntimeException(\sprintf('Unable to write in the "%s" directory.', $realBuildDir)); } if ($this->isNfs($realCacheDir)) { @@ -100,7 +100,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $fs->mkdir($realCacheDir); } - $io->comment(sprintf('Clearing the cache for the %s environment with debug %s', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); + $io->comment(\sprintf('Clearing the cache for the %s environment with debug %s', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); if ($useBuildDir) { $this->cacheClearer->clear($realBuildDir); } @@ -146,6 +146,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int } $this->warmupOptionals($useBuildDir ? $realCacheDir : $warmupDir, $warmupDir, $io); } + + // fix references to cached files with the real cache directory name + $search = [$warmupDir, str_replace('/', '\\/', $warmupDir), str_replace('\\', '\\\\', $warmupDir)]; + $replace = str_replace('\\', '/', $realBuildDir); + foreach (Finder::create()->files()->in($warmupDir) as $file) { + $content = str_replace($search, $replace, file_get_contents($file), $count); + if ($count) { + file_put_contents($file, $content); + } + } } if (!$fs->exists($warmupDir.'/'.$containerDir)) { @@ -154,7 +164,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } if ($this->isNfs($realBuildDir)) { - $io->note('For better performances, you should move the cache and log directories to a non-shared folder of the VM.'); + $io->note('For better performance, you should move the cache and log directories to a non-shared folder of the VM.'); $fs->remove($realBuildDir); } else { $fs->rename($realBuildDir, $oldBuildDir); @@ -189,7 +199,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io->comment('Finished'); } - $io->success(sprintf('Cache for the "%s" environment (debug=%s) was successfully cleared.', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); + $io->success(\sprintf('Cache for the "%s" environment (debug=%s) was successfully cleared.', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); return 0; } @@ -200,7 +210,7 @@ private function isNfs(string $dir): bool if (null === $mounts) { $mounts = []; - if ('/' === \DIRECTORY_SEPARATOR && $files = @file('/proc/mounts')) { + if ('/' === \DIRECTORY_SEPARATOR && @is_readable('/proc/mounts') && $files = @file('/proc/mounts')) { foreach ($files as $mount) { $mount = \array_slice(explode(' ', $mount), 1, -3); if (!\in_array(array_pop($mount), ['vboxsf', 'nfs'])) { @@ -227,16 +237,6 @@ private function warmup(string $warmupDir, string $realBuildDir): void throw new \LogicException('Calling "cache:clear" with a kernel that does not implement "Symfony\Component\HttpKernel\RebootableInterface" is not supported.'); } $kernel->reboot($warmupDir); - - // fix references to cached files with the real cache directory name - $search = [$warmupDir, str_replace('\\', '\\\\', $warmupDir)]; - $replace = str_replace('\\', '/', $realBuildDir); - foreach (Finder::create()->files()->in($warmupDir) as $file) { - $content = str_replace($search, $replace, file_get_contents($file), $count); - if ($count) { - file_put_contents($file, $content); - } - } } private function warmupOptionals(string $cacheDir, string $warmupDir, SymfonyStyle $io): void diff --git a/lib/symfony/framework-bundle/Command/CachePoolClearCommand.php b/lib/symfony/framework-bundle/Command/CachePoolClearCommand.php index fcd70ca0e9..9d1662e655 100644 --- a/lib/symfony/framework-bundle/Command/CachePoolClearCommand.php +++ b/lib/symfony/framework-bundle/Command/CachePoolClearCommand.php @@ -38,7 +38,7 @@ final class CachePoolClearCommand extends Command /** * @param string[]|null $poolNames */ - public function __construct(Psr6CacheClearer $poolClearer, array $poolNames = null) + public function __construct(Psr6CacheClearer $poolClearer, ?array $poolNames = null) { parent::__construct(); @@ -72,7 +72,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $poolNames = $input->getArgument('pools'); $excludedPoolNames = $input->getOption('exclude'); - if ($input->getOption('all')) { + if ($clearAll = $input->getOption('all')) { if (!$this->poolNames) { throw new InvalidArgumentException('Could not clear all cache pools, try specifying a specific pool or cache clearer.'); } @@ -91,7 +91,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int foreach ($poolNames as $id) { if ($this->poolClearer->hasPool($id)) { $pools[$id] = $id; - } else { + } elseif (!$clearAll || $kernel->getContainer()->has($id)) { $pool = $kernel->getContainer()->get($id); if ($pool instanceof CacheItemPoolInterface) { @@ -99,28 +99,28 @@ protected function execute(InputInterface $input, OutputInterface $output): int } elseif ($pool instanceof Psr6CacheClearer) { $clearers[$id] = $pool; } else { - throw new InvalidArgumentException(sprintf('"%s" is not a cache pool nor a cache clearer.', $id)); + throw new InvalidArgumentException(\sprintf('"%s" is not a cache pool nor a cache clearer.', $id)); } } } foreach ($clearers as $id => $clearer) { - $io->comment(sprintf('Calling cache clearer: %s', $id)); + $io->comment(\sprintf('Calling cache clearer: %s', $id)); $clearer->clear($kernel->getContainer()->getParameter('kernel.cache_dir')); } $failure = false; foreach ($pools as $id => $pool) { - $io->comment(sprintf('Clearing cache pool: %s', $id)); + $io->comment(\sprintf('Clearing cache pool: %s', $id)); if ($pool instanceof CacheItemPoolInterface) { if (!$pool->clear()) { - $io->warning(sprintf('Cache pool "%s" could not be cleared.', $pool)); + $io->warning(\sprintf('Cache pool "%s" could not be cleared.', $pool)); $failure = true; } } else { if (false === $this->poolClearer->clearPool($id)) { - $io->warning(sprintf('Cache pool "%s" could not be cleared.', $pool)); + $io->warning(\sprintf('Cache pool "%s" could not be cleared.', $pool)); $failure = true; } } diff --git a/lib/symfony/framework-bundle/Command/CachePoolDeleteCommand.php b/lib/symfony/framework-bundle/Command/CachePoolDeleteCommand.php index 7b53ceb8ba..3c5e49dbfc 100644 --- a/lib/symfony/framework-bundle/Command/CachePoolDeleteCommand.php +++ b/lib/symfony/framework-bundle/Command/CachePoolDeleteCommand.php @@ -35,7 +35,7 @@ final class CachePoolDeleteCommand extends Command /** * @param string[]|null $poolNames */ - public function __construct(Psr6CacheClearer $poolClearer, array $poolNames = null) + public function __construct(Psr6CacheClearer $poolClearer, ?array $poolNames = null) { parent::__construct(); @@ -67,16 +67,16 @@ protected function execute(InputInterface $input, OutputInterface $output): int $cachePool = $this->poolClearer->getPool($pool); if (!$cachePool->hasItem($key)) { - $io->note(sprintf('Cache item "%s" does not exist in cache pool "%s".', $key, $pool)); + $io->note(\sprintf('Cache item "%s" does not exist in cache pool "%s".', $key, $pool)); return 0; } if (!$cachePool->deleteItem($key)) { - throw new \Exception(sprintf('Cache item "%s" could not be deleted.', $key)); + throw new \Exception(\sprintf('Cache item "%s" could not be deleted.', $key)); } - $io->success(sprintf('Cache item "%s" was successfully deleted.', $key)); + $io->success(\sprintf('Cache item "%s" was successfully deleted.', $key)); return 0; } diff --git a/lib/symfony/framework-bundle/Command/CachePoolInvalidateTagsCommand.php b/lib/symfony/framework-bundle/Command/CachePoolInvalidateTagsCommand.php index 9e6ef9330e..8c56847e9b 100644 --- a/lib/symfony/framework-bundle/Command/CachePoolInvalidateTagsCommand.php +++ b/lib/symfony/framework-bundle/Command/CachePoolInvalidateTagsCommand.php @@ -65,26 +65,26 @@ protected function execute(InputInterface $input, OutputInterface $output): int $errors = false; foreach ($pools as $name) { - $io->comment(sprintf('Invalidating tag(s): %s from pool %s.', $tagList, $name)); + $io->comment(\sprintf('Invalidating tag(s): %s from pool %s.', $tagList, $name)); try { $pool = $this->pools->get($name); } catch (ServiceNotFoundException) { - $io->error(sprintf('Pool "%s" not found.', $name)); + $io->error(\sprintf('Pool "%s" not found.', $name)); $errors = true; continue; } if (!$pool instanceof TagAwareCacheInterface) { - $io->error(sprintf('Pool "%s" is not taggable.', $name)); + $io->error(\sprintf('Pool "%s" is not taggable.', $name)); $errors = true; continue; } if (!$pool->invalidateTags($tags)) { - $io->error(sprintf('Cache tag(s) "%s" could not be invalidated for pool "%s".', $tagList, $name)); + $io->error(\sprintf('Cache tag(s) "%s" could not be invalidated for pool "%s".', $tagList, $name)); $errors = true; } } diff --git a/lib/symfony/framework-bundle/Command/CachePoolPruneCommand.php b/lib/symfony/framework-bundle/Command/CachePoolPruneCommand.php index fc0dc6d795..ff90a9dbad 100644 --- a/lib/symfony/framework-bundle/Command/CachePoolPruneCommand.php +++ b/lib/symfony/framework-bundle/Command/CachePoolPruneCommand.php @@ -53,14 +53,21 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); + $exitCode = Command::SUCCESS; foreach ($this->pools as $name => $pool) { - $io->comment(sprintf('Pruning cache pool: %s', $name)); - $pool->prune(); + $io->comment(\sprintf('Pruning cache pool: %s', $name)); + + if (!$pool->prune()) { + $io->error(\sprintf('Cache pool "%s" could not be pruned.', $name)); + $exitCode = Command::FAILURE; + } } - $io->success('Successfully pruned cache pool(s).'); + if (Command::SUCCESS === $exitCode) { + $io->success('Successfully pruned cache pool(s).'); + } - return 0; + return $exitCode; } } diff --git a/lib/symfony/framework-bundle/Command/CacheWarmupCommand.php b/lib/symfony/framework-bundle/Command/CacheWarmupCommand.php index 6f1073de4e..08e6ebc4d3 100644 --- a/lib/symfony/framework-bundle/Command/CacheWarmupCommand.php +++ b/lib/symfony/framework-bundle/Command/CacheWarmupCommand.php @@ -61,7 +61,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io = new SymfonyStyle($input, $output); $kernel = $this->getApplication()->getKernel(); - $io->comment(sprintf('Warming up the cache for the %s environment with debug %s', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); + $io->comment(\sprintf('Warming up the cache for the %s environment with debug %s', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); if (!$input->getOption('no-optional-warmers')) { $this->cacheWarmer->enableOptionalWarmers(); @@ -72,14 +72,15 @@ protected function execute(InputInterface $input, OutputInterface $output): int $kernel->warmUp($cacheDir); } - $preload = $this->cacheWarmer->warmUp($cacheDir); - $buildDir = $kernel->getContainer()->getParameter('kernel.build_dir'); + + $preload = $this->cacheWarmer->warmUp($cacheDir, $buildDir); + if ($preload && $cacheDir === $buildDir && file_exists($preloadFile = $buildDir.'/'.$kernel->getContainer()->getParameter('kernel.container_class').'.preload.php')) { Preloader::append($preloadFile, $preload); } - $io->success(sprintf('Cache for the "%s" environment (debug=%s) was successfully warmed.', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); + $io->success(\sprintf('Cache for the "%s" environment (debug=%s) was successfully warmed.', $kernel->getEnvironment(), var_export($kernel->isDebug(), true))); return 0; } diff --git a/lib/symfony/framework-bundle/Command/ConfigDebugCommand.php b/lib/symfony/framework-bundle/Command/ConfigDebugCommand.php index cc116fc689..fcef7c1d6c 100644 --- a/lib/symfony/framework-bundle/Command/ConfigDebugCommand.php +++ b/lib/symfony/framework-bundle/Command/ConfigDebugCommand.php @@ -41,7 +41,7 @@ class ConfigDebugCommand extends AbstractConfigCommand { protected function configure(): void { - $commentedHelpFormats = array_map(fn ($format) => sprintf('%s', $format), $this->getAvailableFormatOptions()); + $commentedHelpFormats = array_map(fn ($format) => \sprintf('%s', $format), $this->getAvailableFormatOptions()); $helpFormats = implode('", "', $commentedHelpFormats); $this @@ -49,7 +49,7 @@ protected function configure(): void new InputArgument('name', InputArgument::OPTIONAL, 'The bundle name or the extension alias'), new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'), new InputOption('resolve-env', null, InputOption::VALUE_NONE, 'Display resolved environment variable values instead of placeholders'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), class_exists(Yaml::class) ? 'txt' : 'json'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), class_exists(Yaml::class) ? 'txt' : 'json'), ]) ->setHelp(<<%command.name% command dumps the current configuration for an @@ -106,7 +106,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if (null === $path = $input->getArgument('path')) { if ('txt' === $input->getOption('format')) { $io->title( - sprintf('Current configuration for %s', $name === $extensionAlias ? sprintf('extension with alias "%s"', $extensionAlias) : sprintf('"%s"', $name)) + \sprintf('Current configuration for %s', $name === $extensionAlias ? \sprintf('extension with alias "%s"', $extensionAlias) : \sprintf('"%s"', $name)) ); } @@ -123,7 +123,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int return 1; } - $io->title(sprintf('Current configuration for "%s.%s"', $extensionAlias, $path)); + $io->title(\sprintf('Current configuration for "%s.%s"', $extensionAlias, $path)); $io->writeln($this->convertToFormat($config, $format)); @@ -135,7 +135,7 @@ private function convertToFormat(mixed $config, string $format): string return match ($format) { 'txt', 'yaml' => Yaml::dump($config, 10), 'json' => json_encode($config, \JSON_PRETTY_PRINT | \JSON_UNESCAPED_SLASHES | \JSON_UNESCAPED_UNICODE), - default => throw new InvalidArgumentException(sprintf('Supported formats are "%s".', implode('", "', $this->getAvailableFormatOptions()))), + default => throw new InvalidArgumentException(\sprintf('Supported formats are "%s".', implode('", "', $this->getAvailableFormatOptions()))), }; } @@ -161,8 +161,8 @@ private function getConfigForPath(array $config, string $path, string $alias): m $steps = explode('.', $path); foreach ($steps as $step) { - if (!\array_key_exists($step, $config)) { - throw new LogicException(sprintf('Unable to find configuration for "%s.%s".', $alias, $path)); + if (!\is_array($config) || !\array_key_exists($step, $config)) { + throw new LogicException(\sprintf('Unable to find configuration for "%s.%s".', $alias, $path)); } $config = $config[$step]; @@ -190,7 +190,7 @@ private function getConfigForExtension(ExtensionInterface $extension, ContainerB // Fall back to default config if the extension has one if (!$extension instanceof ConfigurationExtensionInterface && !$extension instanceof ConfigurationInterface) { - throw new \LogicException(sprintf('The extension with alias "%s" does not have configuration.', $extensionAlias)); + throw new \LogicException(\sprintf('The extension with alias "%s" does not have configuration.', $extensionAlias)); } $configs = $container->getExtensionConfig($extensionAlias); diff --git a/lib/symfony/framework-bundle/Command/ConfigDumpReferenceCommand.php b/lib/symfony/framework-bundle/Command/ConfigDumpReferenceCommand.php index 3231e5a476..27dc01b112 100644 --- a/lib/symfony/framework-bundle/Command/ConfigDumpReferenceCommand.php +++ b/lib/symfony/framework-bundle/Command/ConfigDumpReferenceCommand.php @@ -39,14 +39,14 @@ class ConfigDumpReferenceCommand extends AbstractConfigCommand { protected function configure(): void { - $commentedHelpFormats = array_map(fn ($format) => sprintf('%s', $format), $this->getAvailableFormatOptions()); + $commentedHelpFormats = array_map(fn ($format) => \sprintf('%s', $format), $this->getAvailableFormatOptions()); $helpFormats = implode('", "', $commentedHelpFormats); $this ->setDefinition([ new InputArgument('name', InputArgument::OPTIONAL, 'The Bundle name or the extension alias'), new InputArgument('path', InputArgument::OPTIONAL, 'The configuration option path'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'yaml'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'yaml'), ]) ->setHelp(<<%command.name% command dumps the default configuration for an @@ -118,27 +118,27 @@ protected function execute(InputInterface $input, OutputInterface $output): int } if ($name === $extension->getAlias()) { - $message = sprintf('Default configuration for extension with alias: "%s"', $name); + $message = \sprintf('Default configuration for extension with alias: "%s"', $name); } else { - $message = sprintf('Default configuration for "%s"', $name); + $message = \sprintf('Default configuration for "%s"', $name); } if (null !== $path) { - $message .= sprintf(' at path "%s"', $path); + $message .= \sprintf(' at path "%s"', $path); } switch ($format) { case 'yaml': - $io->writeln(sprintf('# %s', $message)); + $io->writeln(\sprintf('# %s', $message)); $dumper = new YamlReferenceDumper(); break; case 'xml': - $io->writeln(sprintf('', $message)); + $io->writeln(\sprintf('', $message)); $dumper = new XmlReferenceDumper(); break; default: $io->writeln($message); - throw new InvalidArgumentException(sprintf('Supported formats are "%s".', implode('", "', $this->getAvailableFormatOptions()))); + throw new InvalidArgumentException(\sprintf('Supported formats are "%s".', implode('", "', $this->getAvailableFormatOptions()))); } $io->writeln(null === $path ? $dumper->dump($configuration, $extension->getNamespace()) : $dumper->dumpAtPath($configuration, $path)); diff --git a/lib/symfony/framework-bundle/Command/ContainerDebugCommand.php b/lib/symfony/framework-bundle/Command/ContainerDebugCommand.php index df6aef5dd6..6847926ff9 100644 --- a/lib/symfony/framework-bundle/Command/ContainerDebugCommand.php +++ b/lib/symfony/framework-bundle/Command/ContainerDebugCommand.php @@ -52,7 +52,7 @@ protected function configure(): void new InputOption('types', null, InputOption::VALUE_NONE, 'Display types (classes/interfaces) available in the container'), new InputOption('env-var', null, InputOption::VALUE_REQUIRED, 'Display a specific environment variable used in the container'), new InputOption('env-vars', null, InputOption::VALUE_NONE, 'Display environment variables used in the container'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'), new InputOption('deprecations', null, InputOption::VALUE_NONE, 'Display deprecations generated when compiling and warming up the container'), ]) @@ -171,19 +171,19 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($object->hasDefinition($options['id'])) { $definition = $object->getDefinition($options['id']); if ($definition->isDeprecated()) { - $errorIo->warning($definition->getDeprecation($options['id'])['message'] ?? sprintf('The "%s" service is deprecated.', $options['id'])); + $errorIo->warning($definition->getDeprecation($options['id'])['message'] ?? \sprintf('The "%s" service is deprecated.', $options['id'])); } } if ($object->hasAlias($options['id'])) { $alias = $object->getAlias($options['id']); if ($alias->isDeprecated()) { - $errorIo->warning($alias->getDeprecation($options['id'])['message'] ?? sprintf('The "%s" alias is deprecated.', $options['id'])); + $errorIo->warning($alias->getDeprecation($options['id'])['message'] ?? \sprintf('The "%s" alias is deprecated.', $options['id'])); } } } if (isset($options['id']) && isset($kernel->getContainer()->getRemovedIds()[$options['id']])) { - $errorIo->note(sprintf('The "%s" service or alias has been removed or inlined when the container was compiled.', $options['id'])); + $errorIo->note(\sprintf('The "%s" service or alias has been removed or inlined when the container was compiled.', $options['id'])); } } catch (ServiceNotFoundException $e) { if ('' !== $e->getId() && '@' === $e->getId()[0]) { @@ -277,14 +277,16 @@ private function findProperServiceName(InputInterface $input, SymfonyStyle $io, $matchingServices = $this->findServiceIdsContaining($container, $name, $showHidden); if (!$matchingServices) { - throw new InvalidArgumentException(sprintf('No services found that match "%s".', $name)); + throw new InvalidArgumentException(\sprintf('No services found that match "%s".', $name)); } if (1 === \count($matchingServices)) { return $matchingServices[0]; } - return $io->choice('Select one of the following services to display its information', $matchingServices); + natsort($matchingServices); + + return $io->choice('Select one of the following services to display its information', array_values($matchingServices)); } private function findProperTagName(InputInterface $input, SymfonyStyle $io, ContainerBuilder $container, string $tagName): string @@ -295,14 +297,16 @@ private function findProperTagName(InputInterface $input, SymfonyStyle $io, Cont $matchingTags = $this->findTagsContaining($container, $tagName); if (!$matchingTags) { - throw new InvalidArgumentException(sprintf('No tags found that match "%s".', $tagName)); + throw new InvalidArgumentException(\sprintf('No tags found that match "%s".', $tagName)); } if (1 === \count($matchingTags)) { return $matchingTags[0]; } - return $io->choice('Select one of the following tags to display its information', $matchingTags); + natsort($matchingTags); + + return $io->choice('Select one of the following tags to display its information', array_values($matchingTags)); } private function findServiceIdsContaining(ContainerBuilder $container, string $name, bool $showHidden): array diff --git a/lib/symfony/framework-bundle/Command/ContainerLintCommand.php b/lib/symfony/framework-bundle/Command/ContainerLintCommand.php index b63ebe4317..2cad0f3497 100644 --- a/lib/symfony/framework-bundle/Command/ContainerLintCommand.php +++ b/lib/symfony/framework-bundle/Command/ContainerLintCommand.php @@ -80,7 +80,7 @@ private function getContainerBuilder(): ContainerBuilder if (!$kernel->isDebug() || !$kernelContainer->getParameter('debug.container.dump') || !(new ConfigCache($kernelContainer->getParameter('debug.container.dump'), true))->isFresh()) { if (!$kernel instanceof Kernel) { - throw new RuntimeException(sprintf('This command does not support the application kernel: "%s" does not extend "%s".', get_debug_type($kernel), Kernel::class)); + throw new RuntimeException(\sprintf('This command does not support the application kernel: "%s" does not extend "%s".', get_debug_type($kernel), Kernel::class)); } $buildContainer = \Closure::bind(function (): ContainerBuilder { @@ -91,7 +91,7 @@ private function getContainerBuilder(): ContainerBuilder $container = $buildContainer(); } else { if (!$kernelContainer instanceof Container) { - throw new RuntimeException(sprintf('This command does not support the application container: "%s" does not extend "%s".', get_debug_type($kernelContainer), Container::class)); + throw new RuntimeException(\sprintf('This command does not support the application container: "%s" does not extend "%s".', get_debug_type($kernelContainer), Container::class)); } (new XmlFileLoader($container = new ContainerBuilder($parameterBag = new EnvPlaceholderParameterBag()), new FileLocator()))->load($kernelContainer->getParameter('debug.container.dump')); diff --git a/lib/symfony/framework-bundle/Command/DebugAutowiringCommand.php b/lib/symfony/framework-bundle/Command/DebugAutowiringCommand.php index ab4793b685..3fde1407b6 100644 --- a/lib/symfony/framework-bundle/Command/DebugAutowiringCommand.php +++ b/lib/symfony/framework-bundle/Command/DebugAutowiringCommand.php @@ -35,7 +35,7 @@ class DebugAutowiringCommand extends ContainerDebugCommand { private ?FileLinkFormatter $fileLinkFormatter; - public function __construct(string $name = null, FileLinkFormatter $fileLinkFormatter = null) + public function __construct(?string $name = null, ?FileLinkFormatter $fileLinkFormatter = null) { $this->fileLinkFormatter = $fileLinkFormatter; parent::__construct($name); @@ -78,7 +78,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $serviceIds = array_filter($serviceIds, fn ($serviceId) => false !== stripos(str_replace('\\', '', $serviceId), $searchNormalized) && !str_starts_with($serviceId, '.')); if (!$serviceIds) { - $errorIo->error(sprintf('No autowirable classes or interfaces found matching "%s"', $search)); + $errorIo->error(\sprintf('No autowirable classes or interfaces found matching "%s"', $search)); return 1; } @@ -97,7 +97,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io->title('Autowirable Types'); $io->text('The following classes & interfaces can be used as type-hints when autowiring:'); if ($search) { - $io->text(sprintf('(only showing classes/interfaces matching %s)', $search)); + $io->text(\sprintf('(only showing classes/interfaces matching %s)', $search)); } $hasAlias = []; $all = $input->getOption('all'); @@ -120,10 +120,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int } } - $serviceLine = sprintf('%s', $serviceId); + $serviceLine = \sprintf('%s', $serviceId); if ('' !== $fileLink = $this->getFileLink($previousId)) { $serviceLine = substr($serviceId, \strlen($previousId)); - $serviceLine = sprintf('%s', $fileLink, $previousId).('' !== $serviceLine ? sprintf('%s', $serviceLine) : ''); + $serviceLine = \sprintf('%s', $fileLink, $previousId).('' !== $serviceLine ? \sprintf('%s', $serviceLine) : ''); } if ($container->hasAlias($serviceId)) { @@ -168,7 +168,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io->newLine(); if (0 < $serviceIdsNb) { - $io->text(sprintf('%s more concrete service%s would be displayed when adding the "--all" option.', $serviceIdsNb, $serviceIdsNb > 1 ? 's' : '')); + $io->text(\sprintf('%s more concrete service%s would be displayed when adding the "--all" option.', $serviceIdsNb, $serviceIdsNb > 1 ? 's' : '')); } if ($all) { $io->text('Pro-tip: use interfaces in your type-hints instead of classes to benefit from the dependency inversion principle.'); diff --git a/lib/symfony/framework-bundle/Command/EventDispatcherDebugCommand.php b/lib/symfony/framework-bundle/Command/EventDispatcherDebugCommand.php index 1a74e86824..b6c644499c 100644 --- a/lib/symfony/framework-bundle/Command/EventDispatcherDebugCommand.php +++ b/lib/symfony/framework-bundle/Command/EventDispatcherDebugCommand.php @@ -52,7 +52,7 @@ protected function configure(): void ->setDefinition([ new InputArgument('event', InputArgument::OPTIONAL, 'An event name or a part of the event name'), new InputOption('dispatcher', null, InputOption::VALUE_REQUIRED, 'To view events of a specific event dispatcher', self::DEFAULT_DISPATCHER), - new InputOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw description'), ]) ->setHelp(<<<'EOF' @@ -78,7 +78,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $options = []; $dispatcherServiceName = $input->getOption('dispatcher'); if (!$this->dispatchers->has($dispatcherServiceName)) { - $io->getErrorStyle()->error(sprintf('Event dispatcher "%s" is not available.', $dispatcherServiceName)); + $io->getErrorStyle()->error(\sprintf('Event dispatcher "%s" is not available.', $dispatcherServiceName)); return 1; } @@ -92,7 +92,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int // if there is no direct match, try find partial matches $events = $this->searchForEvent($dispatcher, $event); if (0 === \count($events)) { - $io->getErrorStyle()->warning(sprintf('The event "%s" does not have any registered listeners.', $event)); + $io->getErrorStyle()->warning(\sprintf('The event "%s" does not have any registered listeners.', $event)); return 0; } elseif (1 === \count($events)) { diff --git a/lib/symfony/framework-bundle/Command/RouterDebugCommand.php b/lib/symfony/framework-bundle/Command/RouterDebugCommand.php index 8d4e38a294..9f689a1423 100644 --- a/lib/symfony/framework-bundle/Command/RouterDebugCommand.php +++ b/lib/symfony/framework-bundle/Command/RouterDebugCommand.php @@ -42,7 +42,7 @@ class RouterDebugCommand extends Command private RouterInterface $router; private ?FileLinkFormatter $fileLinkFormatter; - public function __construct(RouterInterface $router, FileLinkFormatter $fileLinkFormatter = null) + public function __construct(RouterInterface $router, ?FileLinkFormatter $fileLinkFormatter = null) { parent::__construct(); @@ -57,7 +57,7 @@ protected function configure(): void new InputArgument('name', InputArgument::OPTIONAL, 'A route name'), new InputOption('show-controllers', null, InputOption::VALUE_NONE, 'Show assigned controllers in overview'), new InputOption('show-aliases', null, InputOption::VALUE_NONE, 'Show aliases in overview'), - new InputOption('format', null, InputOption::VALUE_REQUIRED, sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, \sprintf('The output format ("%s")', implode('", "', $this->getAvailableFormatOptions())), 'txt'), new InputOption('raw', null, InputOption::VALUE_NONE, 'To output raw route(s)'), ]) ->setHelp(<<<'EOF' @@ -107,7 +107,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } if (!$route) { - throw new InvalidArgumentException(sprintf('The route "%s" does not exist.', $name)); + throw new InvalidArgumentException(\sprintf('The route "%s" does not exist.', $name)); } $helper->describe($io, $route, [ diff --git a/lib/symfony/framework-bundle/Command/RouterMatchCommand.php b/lib/symfony/framework-bundle/Command/RouterMatchCommand.php index 7efd1f3ed3..73e5c5d0db 100644 --- a/lib/symfony/framework-bundle/Command/RouterMatchCommand.php +++ b/lib/symfony/framework-bundle/Command/RouterMatchCommand.php @@ -97,21 +97,21 @@ protected function execute(InputInterface $input, OutputInterface $output): int $matches = false; foreach ($traces as $trace) { if (TraceableUrlMatcher::ROUTE_ALMOST_MATCHES == $trace['level']) { - $io->text(sprintf('Route "%s" almost matches but %s', $trace['name'], lcfirst($trace['log']))); + $io->text(\sprintf('Route "%s" almost matches but %s', $trace['name'], lcfirst($trace['log']))); } elseif (TraceableUrlMatcher::ROUTE_MATCHES == $trace['level']) { - $io->success(sprintf('Route "%s" matches', $trace['name'])); + $io->success(\sprintf('Route "%s" matches', $trace['name'])); $routerDebugCommand = $this->getApplication()->find('debug:router'); $routerDebugCommand->run(new ArrayInput(['name' => $trace['name']]), $output); $matches = true; } elseif ($input->getOption('verbose')) { - $io->text(sprintf('Route "%s" does not match: %s', $trace['name'], $trace['log'])); + $io->text(\sprintf('Route "%s" does not match: %s', $trace['name'], $trace['log'])); } } if (!$matches) { - $io->error(sprintf('None of the routes match the path "%s"', $input->getArgument('path_info'))); + $io->error(\sprintf('None of the routes match the path "%s"', $input->getArgument('path_info'))); return 1; } diff --git a/lib/symfony/framework-bundle/Command/SecretsDecryptToLocalCommand.php b/lib/symfony/framework-bundle/Command/SecretsDecryptToLocalCommand.php index 22be895024..665c5c454a 100644 --- a/lib/symfony/framework-bundle/Command/SecretsDecryptToLocalCommand.php +++ b/lib/symfony/framework-bundle/Command/SecretsDecryptToLocalCommand.php @@ -31,7 +31,7 @@ final class SecretsDecryptToLocalCommand extends Command private AbstractVault $vault; private ?AbstractVault $localVault; - public function __construct(AbstractVault $vault, AbstractVault $localVault = null) + public function __construct(AbstractVault $vault, ?AbstractVault $localVault = null) { $this->vault = $vault; $this->localVault = $localVault; @@ -48,7 +48,7 @@ protected function configure(): void %command.full_name% -When the option --force is provided, secrets that already exist in the local vault are overriden. +When the --force option is provided, secrets that already exist in the local vault are overridden. %command.full_name% --force EOF @@ -68,7 +68,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $secrets = $this->vault->list(true); - $io->comment(sprintf('%d secret%s found in the vault.', \count($secrets), 1 !== \count($secrets) ? 's' : '')); + $io->comment(\sprintf('%d secret%s found in the vault.', \count($secrets), 1 !== \count($secrets) ? 's' : '')); $skipped = 0; if (!$input->getOption('force')) { @@ -82,14 +82,14 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($skipped > 0) { $io->warning([ - sprintf('%d secret%s already overridden in the local vault and will be skipped.', $skipped, 1 !== $skipped ? 's are' : ' is'), + \sprintf('%d secret%s already overridden in the local vault and will be skipped.', $skipped, 1 !== $skipped ? 's are' : ' is'), 'Use the --force flag to override these.', ]); } foreach ($secrets as $k => $v) { if (null === $v) { - $io->error($this->vault->getLastMessage() ?? sprintf('Secret "%s" has been skipped as there was an error reading it.', $k)); + $io->error($this->vault->getLastMessage() ?? \sprintf('Secret "%s" has been skipped as there was an error reading it.', $k)); continue; } diff --git a/lib/symfony/framework-bundle/Command/SecretsEncryptFromLocalCommand.php b/lib/symfony/framework-bundle/Command/SecretsEncryptFromLocalCommand.php index 4c613ef7b2..0eba8956c0 100644 --- a/lib/symfony/framework-bundle/Command/SecretsEncryptFromLocalCommand.php +++ b/lib/symfony/framework-bundle/Command/SecretsEncryptFromLocalCommand.php @@ -30,7 +30,7 @@ final class SecretsEncryptFromLocalCommand extends Command private AbstractVault $vault; private ?AbstractVault $localVault; - public function __construct(AbstractVault $vault, AbstractVault $localVault = null) + public function __construct(AbstractVault $vault, ?AbstractVault $localVault = null) { $this->vault = $vault; $this->localVault = $localVault; @@ -61,14 +61,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int } foreach ($this->vault->list(true) as $name => $value) { - $localValue = $this->localVault->reveal($name); + if (null === $localValue = $this->localVault->reveal($name)) { + continue; + } - if (null !== $localValue && $value !== $localValue) { + if ($value !== $localValue) { $this->vault->seal($name, $localValue); - } elseif (null !== $message = $this->localVault->getLastMessage()) { - $io->error($message); - - return 1; + $io->note($this->vault->getLastMessage()); } } diff --git a/lib/symfony/framework-bundle/Command/SecretsGenerateKeysCommand.php b/lib/symfony/framework-bundle/Command/SecretsGenerateKeysCommand.php index 761f6c260c..c250258c1e 100644 --- a/lib/symfony/framework-bundle/Command/SecretsGenerateKeysCommand.php +++ b/lib/symfony/framework-bundle/Command/SecretsGenerateKeysCommand.php @@ -33,7 +33,7 @@ final class SecretsGenerateKeysCommand extends Command private AbstractVault $vault; private ?AbstractVault $localVault; - public function __construct(AbstractVault $vault, AbstractVault $localVault = null) + public function __construct(AbstractVault $vault, ?AbstractVault $localVault = null) { $this->vault = $vault; $this->localVault = $localVault; @@ -67,7 +67,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $vault = $input->getOption('local') ? $this->localVault : $this->vault; if (null === $vault) { - $io->success('The local vault is disabled.'); + $io->error('The local vault is disabled.'); return 1; } diff --git a/lib/symfony/framework-bundle/Command/SecretsListCommand.php b/lib/symfony/framework-bundle/Command/SecretsListCommand.php index de8a7e7722..4ba335e622 100644 --- a/lib/symfony/framework-bundle/Command/SecretsListCommand.php +++ b/lib/symfony/framework-bundle/Command/SecretsListCommand.php @@ -34,7 +34,7 @@ final class SecretsListCommand extends Command private AbstractVault $vault; private ?AbstractVault $localVault; - public function __construct(AbstractVault $vault, AbstractVault $localVault = null) + public function __construct(AbstractVault $vault, ?AbstractVault $localVault = null) { $this->vault = $vault; $this->localVault = $localVault; @@ -66,7 +66,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $io->comment('Use "%env()%" to reference a secret in a config file.'); if (!$reveal = $input->getOption('reveal')) { - $io->comment(sprintf('To reveal the secrets run php %s %s --reveal', $_SERVER['PHP_SELF'], $this->getName())); + $io->comment(\sprintf('To reveal the secrets run php %s %s --reveal', $_SERVER['PHP_SELF'], $this->getName())); } $secrets = $this->vault->list($reveal); diff --git a/lib/symfony/framework-bundle/Command/SecretsRemoveCommand.php b/lib/symfony/framework-bundle/Command/SecretsRemoveCommand.php index e03afcd0cf..3e75ba0c41 100644 --- a/lib/symfony/framework-bundle/Command/SecretsRemoveCommand.php +++ b/lib/symfony/framework-bundle/Command/SecretsRemoveCommand.php @@ -35,7 +35,7 @@ final class SecretsRemoveCommand extends Command private AbstractVault $vault; private ?AbstractVault $localVault; - public function __construct(AbstractVault $vault, AbstractVault $localVault = null) + public function __construct(AbstractVault $vault, ?AbstractVault $localVault = null) { $this->vault = $vault; $this->localVault = $localVault; @@ -63,7 +63,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $vault = $input->getOption('local') ? $this->localVault : $this->vault; if (null === $vault) { - $io->success('The local vault is disabled.'); + $io->error('The local vault is disabled.'); return 1; } diff --git a/lib/symfony/framework-bundle/Command/SecretsSetCommand.php b/lib/symfony/framework-bundle/Command/SecretsSetCommand.php index 0e831a343d..e2fc39e04c 100644 --- a/lib/symfony/framework-bundle/Command/SecretsSetCommand.php +++ b/lib/symfony/framework-bundle/Command/SecretsSetCommand.php @@ -36,7 +36,7 @@ final class SecretsSetCommand extends Command private AbstractVault $vault; private ?AbstractVault $localVault; - public function __construct(AbstractVault $vault, AbstractVault $localVault = null) + public function __construct(AbstractVault $vault, ?AbstractVault $localVault = null) { $this->vault = $vault; $this->localVault = $localVault; @@ -88,7 +88,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } if ($this->localVault === $vault && !\array_key_exists($name, $this->vault->list())) { - $io->error(sprintf('Secret "%s" does not exist in the vault, you cannot override it locally.', $name)); + $io->error(\sprintf('Secret "%s" does not exist in the vault, you cannot override it locally.', $name)); return 1; } @@ -107,9 +107,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int } elseif (is_file($file) && is_readable($file)) { $value = file_get_contents($file); } elseif (!is_file($file)) { - throw new \InvalidArgumentException(sprintf('File not found: "%s".', $file)); + throw new \InvalidArgumentException(\sprintf('File not found: "%s".', $file)); } elseif (!is_readable($file)) { - throw new \InvalidArgumentException(sprintf('File is not readable: "%s".', $file)); + throw new \InvalidArgumentException(\sprintf('File is not readable: "%s".', $file)); } if ($vault->generateKeys()) { diff --git a/lib/symfony/framework-bundle/Command/TranslationDebugCommand.php b/lib/symfony/framework-bundle/Command/TranslationDebugCommand.php index 79a67847a2..46e90ed402 100644 --- a/lib/symfony/framework-bundle/Command/TranslationDebugCommand.php +++ b/lib/symfony/framework-bundle/Command/TranslationDebugCommand.php @@ -59,7 +59,7 @@ class TranslationDebugCommand extends Command private array $codePaths; private array $enabledLocales; - public function __construct(TranslatorInterface $translator, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultTransPath = null, string $defaultViewsPath = null, array $transPaths = [], array $codePaths = [], array $enabledLocales = []) + public function __construct(TranslatorInterface $translator, TranslationReaderInterface $reader, ExtractorInterface $extractor, ?string $defaultTransPath = null, ?string $defaultViewsPath = null, array $transPaths = [], array $codePaths = [], array $enabledLocales = []) { parent::__construct(); @@ -79,7 +79,7 @@ protected function configure(): void ->setDefinition([ new InputArgument('locale', InputArgument::REQUIRED, 'The locale'), new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'), - new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'The messages domain'), + new InputOption('domain', null, InputOption::VALUE_REQUIRED, 'The messages domain'), new InputOption('only-missing', null, InputOption::VALUE_NONE, 'Display only missing messages'), new InputOption('only-unused', null, InputOption::VALUE_NONE, 'Display only unused messages'), new InputOption('all', null, InputOption::VALUE_NONE, 'Load messages from all registered bundles'), @@ -155,7 +155,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $codePaths = [$path.'/templates']; if (!is_dir($transPaths[0])) { - throw new InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0])); + throw new InvalidArgumentException(\sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0])); } } } elseif ($input->getOption('all')) { @@ -181,10 +181,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int // No defined or extracted messages if (!$allMessages || null !== $domain && empty($allMessages[$domain])) { - $outputMessage = sprintf('No defined or extracted messages for locale "%s"', $locale); + $outputMessage = \sprintf('No defined or extracted messages for locale "%s"', $locale); if (null !== $domain) { - $outputMessage .= sprintf(' and domain "%s"', $domain); + $outputMessage .= \sprintf(' and domain "%s"', $domain); } $io->getErrorStyle()->warning($outputMessage); @@ -196,9 +196,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int $fallbackCatalogues = $this->loadFallbackCatalogues($locale, $transPaths); // Display header line - $headers = ['State', 'Domain', 'Id', sprintf('Message Preview (%s)', $locale)]; + $headers = ['State', 'Domain', 'Id', \sprintf('Message Preview (%s)', $locale)]; foreach ($fallbackCatalogues as $fallbackCatalogue) { - $headers[] = sprintf('Fallback Message Preview (%s)', $fallbackCatalogue->getLocale()); + $headers[] = \sprintf('Fallback Message Preview (%s)', $fallbackCatalogue->getLocale()); } $rows = []; // Iterate all message ids and determine their state @@ -320,7 +320,7 @@ private function formatStates(array $states): string private function formatId(string $id): string { - return sprintf('%s', $id); + return \sprintf('%s', $id); } private function sanitizeString(string $string, int $length = 40): string diff --git a/lib/symfony/framework-bundle/Command/TranslationUpdateCommand.php b/lib/symfony/framework-bundle/Command/TranslationUpdateCommand.php index 4563779bad..b8759bc92c 100644 --- a/lib/symfony/framework-bundle/Command/TranslationUpdateCommand.php +++ b/lib/symfony/framework-bundle/Command/TranslationUpdateCommand.php @@ -19,7 +19,6 @@ use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; -use Symfony\Component\Console\Output\ConsoleOutputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\HttpKernel\KernelInterface; @@ -60,10 +59,14 @@ class TranslationUpdateCommand extends Command private array $codePaths; private array $enabledLocales; - public function __construct(TranslationWriterInterface $writer, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultLocale, string $defaultTransPath = null, string $defaultViewsPath = null, array $transPaths = [], array $codePaths = [], array $enabledLocales = []) + public function __construct(TranslationWriterInterface $writer, TranslationReaderInterface $reader, ExtractorInterface $extractor, string $defaultLocale, ?string $defaultTransPath = null, ?string $defaultViewsPath = null, array $transPaths = [], array $codePaths = [], array $enabledLocales = []) { parent::__construct(); + if (!method_exists($writer, 'getFormats')) { + throw new \InvalidArgumentException(\sprintf('The writer class "%s" does not implement the "getFormats()" method.', $writer::class)); + } + $this->writer = $writer; $this->reader = $reader; $this->extractor = $extractor; @@ -81,14 +84,14 @@ protected function configure(): void ->setDefinition([ new InputArgument('locale', InputArgument::REQUIRED, 'The locale'), new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'), - new InputOption('prefix', null, InputOption::VALUE_OPTIONAL, 'Override the default prefix', '__'), - new InputOption('format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf12'), + new InputOption('prefix', null, InputOption::VALUE_REQUIRED, 'Override the default prefix', '__'), + new InputOption('format', null, InputOption::VALUE_REQUIRED, 'Override the default output format', 'xlf12'), new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'), new InputOption('force', null, InputOption::VALUE_NONE, 'Should the extract be done'), new InputOption('clean', null, InputOption::VALUE_NONE, 'Should clean not found messages'), - new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'Specify the domain to extract'), + new InputOption('domain', null, InputOption::VALUE_REQUIRED, 'Specify the domain to extract'), new InputOption('sort', null, InputOption::VALUE_OPTIONAL, 'Return list of messages sorted alphabetically (only works with --dump-messages)', 'asc'), - new InputOption('as-tree', null, InputOption::VALUE_OPTIONAL, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'), + new InputOption('as-tree', null, InputOption::VALUE_REQUIRED, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'), ]) ->setHelp(<<<'EOF' The %command.name% command extracts translation strings from templates @@ -124,13 +127,6 @@ protected function configure(): void protected function execute(InputInterface $input, OutputInterface $output): int { - $io = new SymfonyStyle($input, $output); - $errorIo = $output instanceof ConsoleOutputInterface ? new SymfonyStyle($input, $output->getErrorOutput()) : $io; - - if ('translation:update' === $input->getFirstArgument()) { - $errorIo->caution('Command "translation:update" is deprecated since version 5.4 and will be removed in Symfony 6.0. Use "translation:extract" instead.'); - } - $io = new SymfonyStyle($input, $output); $errorIo = $io->getErrorStyle(); @@ -187,13 +183,13 @@ protected function execute(InputInterface $input, OutputInterface $output): int $codePaths = [$path.'/templates']; if (!is_dir($transPaths[0])) { - throw new InvalidArgumentException(sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0])); + throw new InvalidArgumentException(\sprintf('"%s" is neither an enabled bundle nor a directory.', $transPaths[0])); } } } $io->title('Translation Messages Extractor and Dumper'); - $io->comment(sprintf('Generating "%s" translation files for "%s"', $input->getArgument('locale'), $currentName)); + $io->comment(\sprintf('Generating "%s" translation files for "%s"', $input->getArgument('locale'), $currentName)); $io->comment('Parsing templates...'); $extractedCatalogue = $this->extractMessages($input->getArgument('locale'), $codePaths, $input->getOption('prefix')); @@ -232,8 +228,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $list = array_merge( array_diff($allKeys, $newKeys), - array_map(fn ($id) => sprintf('%s', $id), $newKeys), - array_map(fn ($id) => sprintf('%s', $id), array_keys($operation->getObsoleteMessages($domain))) + array_map(fn ($id) => \sprintf('%s', $id), $newKeys), + array_map(fn ($id) => \sprintf('%s', $id), array_keys($operation->getObsoleteMessages($domain))) ); $domainMessagesCount = \count($list); @@ -253,17 +249,17 @@ protected function execute(InputInterface $input, OutputInterface $output): int } } - $io->section(sprintf('Messages extracted for domain "%s" (%d message%s)', $domain, $domainMessagesCount, $domainMessagesCount > 1 ? 's' : '')); + $io->section(\sprintf('Messages extracted for domain "%s" (%d message%s)', $domain, $domainMessagesCount, $domainMessagesCount > 1 ? 's' : '')); $io->listing($list); $extractedMessagesCount += $domainMessagesCount; } if ('xlf' === $format) { - $io->comment(sprintf('Xliff output version is %s', $xliffVersion)); + $io->comment(\sprintf('Xliff output version is %s', $xliffVersion)); } - $resultMessage = sprintf('%d message%s successfully extracted', $extractedMessagesCount, $extractedMessagesCount > 1 ? 's were' : ' was'); + $resultMessage = \sprintf('%d message%s successfully extracted', $extractedMessagesCount, $extractedMessagesCount > 1 ? 's were' : ' was'); } // save the files diff --git a/lib/symfony/framework-bundle/Command/WorkflowDumpCommand.php b/lib/symfony/framework-bundle/Command/WorkflowDumpCommand.php index f84a560c6d..5abd982976 100644 --- a/lib/symfony/framework-bundle/Command/WorkflowDumpCommand.php +++ b/lib/symfony/framework-bundle/Command/WorkflowDumpCommand.php @@ -62,7 +62,7 @@ public function __construct($workflows) $this->definitions = $workflows; trigger_deprecation('symfony/framework-bundle', '6.2', 'Passing an array of definitions in "%s()" is deprecated. Inject a ServiceLocator filled with all workflows instead.', __METHOD__); } else { - throw new \TypeError(sprintf('Argument 1 passed to "%s()" must be an array or a ServiceLocator, "%s" given.', __METHOD__, \gettype($workflows))); + throw new \TypeError(\sprintf('Argument 1 passed to "%s()" must be an array or a ServiceLocator, "%s" given.', __METHOD__, \gettype($workflows))); } } @@ -94,7 +94,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if (isset($this->workflows)) { if (!$this->workflows->has($workflowName)) { - throw new InvalidArgumentException(sprintf('The workflow named "%s" cannot be found.', $workflowName)); + throw new InvalidArgumentException(\sprintf('The workflow named "%s" cannot be found.', $workflowName)); } $workflow = $this->workflows->get($workflowName); $type = $workflow instanceof StateMachine ? 'state_machine' : 'workflow'; @@ -108,7 +108,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } if (null === $definition) { - throw new InvalidArgumentException(sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $workflowName)); + throw new InvalidArgumentException(\sprintf('No service found for "workflow.%1$s" nor "state_machine.%1$s".', $workflowName)); } switch ($input->getOption('dump-format')) { diff --git a/lib/symfony/framework-bundle/Console/Application.php b/lib/symfony/framework-bundle/Console/Application.php index 38dd8405ad..a963361166 100644 --- a/lib/symfony/framework-bundle/Console/Application.php +++ b/lib/symfony/framework-bundle/Console/Application.php @@ -157,7 +157,7 @@ public function get(string $name): Command return $command; } - public function all(string $namespace = null): array + public function all(?string $namespace = null): array { $this->registerCommands(); @@ -166,7 +166,7 @@ public function all(string $namespace = null): array public function getLongVersion(): string { - return parent::getLongVersion().sprintf(' (env: %s, debug: %s)', $this->kernel->getEnvironment(), $this->kernel->isDebug() ? 'true' : 'false'); + return parent::getLongVersion().\sprintf(' (env: %s, debug: %s)', $this->kernel->getEnvironment(), $this->kernel->isDebug() ? 'true' : 'false'); } public function add(Command $command): ?Command diff --git a/lib/symfony/framework-bundle/Console/Descriptor/Descriptor.php b/lib/symfony/framework-bundle/Console/Descriptor/Descriptor.php index ba500adb2b..af5c3b10ac 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/Descriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/Descriptor.php @@ -62,7 +62,7 @@ public function describe(OutputInterface $output, mixed $object, array $options $object instanceof Alias => $this->describeContainerAlias($object, $options), $object instanceof EventDispatcherInterface => $this->describeEventDispatcherListeners($object, $options), \is_callable($object) => $this->describeCallable($object, $options), - default => throw new \InvalidArgumentException(sprintf('Object of type "%s" is not describable.', get_debug_type($object))), + default => throw new \InvalidArgumentException(\sprintf('Object of type "%s" is not describable.', get_debug_type($object))), }; if ($object instanceof ContainerBuilder) { @@ -96,7 +96,7 @@ abstract protected function describeContainerTags(ContainerBuilder $container, a * * @param Definition|Alias|object $service */ - abstract protected function describeContainerService(object $service, array $options = [], ContainerBuilder $container = null): void; + abstract protected function describeContainerService(object $service, array $options = [], ?ContainerBuilder $container = null): void; /** * Describes container services. @@ -108,9 +108,9 @@ abstract protected function describeContainerServices(ContainerBuilder $containe abstract protected function describeContainerDeprecations(ContainerBuilder $container, array $options = []): void; - abstract protected function describeContainerDefinition(Definition $definition, array $options = [], ContainerBuilder $container = null): void; + abstract protected function describeContainerDefinition(Definition $definition, array $options = [], ?ContainerBuilder $container = null): void; - abstract protected function describeContainerAlias(Alias $alias, array $options = [], ContainerBuilder $container = null): void; + abstract protected function describeContainerAlias(Alias $alias, array $options = [], ?ContainerBuilder $container = null): void; abstract protected function describeContainerParameter(mixed $parameter, ?array $deprecation, array $options = []): void; @@ -133,7 +133,7 @@ protected function formatValue(mixed $value): string } if (\is_object($value)) { - return sprintf('object(%s)', $value::class); + return \sprintf('object(%s)', $value::class); } if (\is_string($value)) { @@ -278,7 +278,7 @@ protected function getReverseAliases(RouteCollection $routes): array return $reverseAliases; } - public static function getClassDescription(string $class, string &$resolvedClass = null): string + public static function getClassDescription(string $class, ?string &$resolvedClass = null): string { $resolvedClass = $class; try { diff --git a/lib/symfony/framework-bundle/Console/Descriptor/JsonDescriptor.php b/lib/symfony/framework-bundle/Console/Descriptor/JsonDescriptor.php index 1dc567a3fd..344db992f2 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/JsonDescriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/JsonDescriptor.php @@ -70,7 +70,7 @@ protected function describeContainerTags(ContainerBuilder $container, array $opt $this->writeData($data, $options); } - protected function describeContainerService(object $service, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerService(object $service, array $options = [], ?ContainerBuilder $container = null): void { if (!isset($options['id'])) { throw new \InvalidArgumentException('An "id" option must be provided.'); @@ -121,12 +121,12 @@ protected function describeContainerServices(ContainerBuilder $container, array $this->writeData($data, $options); } - protected function describeContainerDefinition(Definition $definition, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerDefinition(Definition $definition, array $options = [], ?ContainerBuilder $container = null): void { $this->writeData($this->getContainerDefinitionData($definition, isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container, $options['id'] ?? null), $options); } - protected function describeContainerAlias(Alias $alias, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerAlias(Alias $alias, array $options = [], ?ContainerBuilder $container = null): void { if (!$container) { $this->writeData($this->getContainerAliasData($alias), $options); @@ -156,7 +156,7 @@ protected function describeContainerParameter(mixed $parameter, ?array $deprecat $data = [$key => $parameter]; if ($deprecation) { - $data['_deprecation'] = sprintf('Since %s %s: %s', $deprecation[0], $deprecation[1], sprintf(...\array_slice($deprecation, 2))); + $data['_deprecation'] = \sprintf('Since %s %s: %s', $deprecation[0], $deprecation[1], \sprintf(...\array_slice($deprecation, 2))); } $this->writeData($data, $options); @@ -169,7 +169,7 @@ protected function describeContainerEnvVars(array $envs, array $options = []): v protected function describeContainerDeprecations(ContainerBuilder $container, array $options = []): void { - $containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $container->getParameter('kernel.build_dir'), $container->getParameter('kernel.container_class')); + $containerDeprecationFilePath = \sprintf('%s/%sDeprecations.log', $container->getParameter('kernel.build_dir'), $container->getParameter('kernel.container_class')); if (!file_exists($containerDeprecationFilePath)) { throw new RuntimeException('The deprecation file does not exist, please try warming the cache first.'); } @@ -236,7 +236,7 @@ protected function sortParameters(ParameterBag $parameters): array $deprecations = []; foreach ($deprecated as $parameter => $deprecation) { - $deprecations[$parameter] = sprintf('Since %s %s: %s', $deprecation[0], $deprecation[1], sprintf(...\array_slice($deprecation, 2))); + $deprecations[$parameter] = \sprintf('Since %s %s: %s', $deprecation[0], $deprecation[1], \sprintf(...\array_slice($deprecation, 2))); } $sortedParameters['_deprecations'] = $deprecations; @@ -245,7 +245,7 @@ protected function sortParameters(ParameterBag $parameters): array return $sortedParameters; } - private function getContainerDefinitionData(Definition $definition, bool $omitTags = false, bool $showArguments = false, ContainerBuilder $container = null, string $id = null): array + private function getContainerDefinitionData(Definition $definition, bool $omitTags = false, bool $showArguments = false, ?ContainerBuilder $container = null, ?string $id = null): array { $data = [ 'class' => (string) $definition->getClass(), @@ -280,7 +280,7 @@ private function getContainerDefinitionData(Definition $definition, bool $omitTa if ($factory[0] instanceof Reference) { $data['factory_service'] = (string) $factory[0]; } elseif ($factory[0] instanceof Definition) { - $data['factory_service'] = sprintf('inline factory service (%s)', $factory[0]->getClass() ?? 'class not configured'); + $data['factory_service'] = \sprintf('inline factory service (%s)', $factory[0]->getClass() ?? 'class not configured'); } else { $data['factory_class'] = $factory[0]; } @@ -393,7 +393,7 @@ private function getCallableData(mixed $callable): array $data['type'] = 'closure'; $r = new \ReflectionFunction($callable); - if (str_contains($r->name, '{closure}')) { + if (str_contains($r->name, '{closure')) { return $data; } $data['name'] = $r->name; @@ -418,7 +418,7 @@ private function getCallableData(mixed $callable): array throw new \InvalidArgumentException('Callable is not describable.'); } - private function describeValue($value, bool $omitTags, bool $showArguments, ContainerBuilder $container = null, string $id = null): mixed + private function describeValue($value, bool $omitTags, bool $showArguments, ?ContainerBuilder $container = null, ?string $id = null): mixed { if (\is_array($value)) { $data = []; diff --git a/lib/symfony/framework-bundle/Console/Descriptor/MarkdownDescriptor.php b/lib/symfony/framework-bundle/Console/Descriptor/MarkdownDescriptor.php index 275294d7e2..c84fd5b1cc 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/MarkdownDescriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/MarkdownDescriptor.php @@ -40,7 +40,7 @@ protected function describeRouteCollection(RouteCollection $routes, array $optio } $this->describeRoute($route, ['name' => $name]); if (($showAliases ??= $options['show_aliases'] ?? false) && $aliases = ($reverseAliases ??= $this->getReverseAliases($routes))[$name] ?? []) { - $this->write(sprintf("- Aliases: \n%s", implode("\n", array_map(static fn (string $alias): string => sprintf(' - %s', $alias), $aliases)))); + $this->write(\sprintf("- Aliases: \n%s", implode("\n", array_map(static fn (string $alias): string => \sprintf(' - %s', $alias), $aliases)))); } } $this->write("\n"); @@ -75,11 +75,11 @@ protected function describeContainerParameters(ParameterBag $parameters, array $ $this->write("Container parameters\n====================\n"); foreach ($this->sortParameters($parameters) as $key => $value) { - $this->write(sprintf( + $this->write(\sprintf( "\n- `%s`: `%s`%s", $key, $this->formatParameter($value), - isset($deprecatedParameters[$key]) ? sprintf(' *Since %s %s: %s*', $deprecatedParameters[$key][0], $deprecatedParameters[$key][1], sprintf(...\array_slice($deprecatedParameters[$key], 2))) : '' + isset($deprecatedParameters[$key]) ? \sprintf(' *Since %s %s: %s*', $deprecatedParameters[$key][0], $deprecatedParameters[$key][1], \sprintf(...\array_slice($deprecatedParameters[$key], 2))) : '' )); } } @@ -98,7 +98,7 @@ protected function describeContainerTags(ContainerBuilder $container, array $opt } } - protected function describeContainerService(object $service, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerService(object $service, array $options = [], ?ContainerBuilder $container = null): void { if (!isset($options['id'])) { throw new \InvalidArgumentException('An "id" option must be provided.'); @@ -111,13 +111,13 @@ protected function describeContainerService(object $service, array $options = [] } elseif ($service instanceof Definition) { $this->describeContainerDefinition($service, $childOptions, $container); } else { - $this->write(sprintf('**`%s`:** `%s`', $options['id'], $service::class)); + $this->write(\sprintf('**`%s`:** `%s`', $options['id'], $service::class)); } } protected function describeContainerDeprecations(ContainerBuilder $container, array $options = []): void { - $containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $container->getParameter('kernel.build_dir'), $container->getParameter('kernel.container_class')); + $containerDeprecationFilePath = \sprintf('%s/%sDeprecations.log', $container->getParameter('kernel.build_dir'), $container->getParameter('kernel.container_class')); if (!file_exists($containerDeprecationFilePath)) { throw new RuntimeException('The deprecation file does not exist, please try warming the cache first.'); } @@ -132,11 +132,11 @@ protected function describeContainerDeprecations(ContainerBuilder $container, ar $formattedLogs = []; $remainingCount = 0; foreach ($logs as $log) { - $formattedLogs[] = sprintf("- %sx: \"%s\" in %s:%s\n", $log['count'], $log['message'], $log['file'], $log['line']); + $formattedLogs[] = \sprintf("- %sx: \"%s\" in %s:%s\n", $log['count'], $log['message'], $log['file'], $log['line']); $remainingCount += $log['count']; } - $this->write(sprintf("## Remaining deprecations (%s)\n\n", $remainingCount)); + $this->write(\sprintf("## Remaining deprecations (%s)\n\n", $remainingCount)); foreach ($formattedLogs as $formattedLog) { $this->write($formattedLog); } @@ -201,12 +201,12 @@ protected function describeContainerServices(ContainerBuilder $container, array $this->write("\n\nServices\n--------\n"); foreach ($services['services'] as $id => $service) { $this->write("\n"); - $this->write(sprintf('- `%s`: `%s`', $id, $service::class)); + $this->write(\sprintf('- `%s`: `%s`', $id, $service::class)); } } } - protected function describeContainerDefinition(Definition $definition, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerDefinition(Definition $definition, array $options = [], ?ContainerBuilder $container = null): void { $output = ''; @@ -244,7 +244,7 @@ protected function describeContainerDefinition(Definition $definition, array $op if ($factory[0] instanceof Reference) { $output .= "\n".'- Factory Service: `'.$factory[0].'`'; } elseif ($factory[0] instanceof Definition) { - $output .= "\n".sprintf('- Factory Service: inline factory service (%s)', $factory[0]->getClass() ? sprintf('`%s`', $factory[0]->getClass()) : 'not configured'); + $output .= "\n".\sprintf('- Factory Service: inline factory service (%s)', $factory[0]->getClass() ? \sprintf('`%s`', $factory[0]->getClass()) : 'not configured'); } else { $output .= "\n".'- Factory Class: `'.$factory[0].'`'; } @@ -273,10 +273,10 @@ protected function describeContainerDefinition(Definition $definition, array $op $inEdges = null !== $container && isset($options['id']) ? $this->getServiceEdges($container, $options['id']) : []; $output .= "\n".'- Usages: '.($inEdges ? implode(', ', $inEdges) : 'none'); - $this->write(isset($options['id']) ? sprintf("### %s\n\n%s\n", $options['id'], $output) : $output); + $this->write(isset($options['id']) ? \sprintf("### %s\n\n%s\n", $options['id'], $output) : $output); } - protected function describeContainerAlias(Alias $alias, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerAlias(Alias $alias, array $options = [], ?ContainerBuilder $container = null): void { $output = '- Service: `'.$alias.'`' ."\n".'- Public: '.($alias->isPublic() && !$alias->isPrivate() ? 'yes' : 'no'); @@ -287,7 +287,7 @@ protected function describeContainerAlias(Alias $alias, array $options = [], Con return; } - $this->write(sprintf("### %s\n\n%s\n", $options['id'], $output)); + $this->write(\sprintf("### %s\n\n%s\n", $options['id'], $output)); if (!$container) { return; @@ -300,7 +300,7 @@ protected function describeContainerAlias(Alias $alias, array $options = [], Con protected function describeContainerParameter(mixed $parameter, ?array $deprecation, array $options = []): void { if (isset($options['parameter'])) { - $this->write(sprintf("%s\n%s\n\n%s%s", $options['parameter'], str_repeat('=', \strlen($options['parameter'])), $this->formatParameter($parameter), $deprecation ? sprintf("\n\n*Since %s %s: %s*", $deprecation[0], $deprecation[1], sprintf(...\array_slice($deprecation, 2))) : '')); + $this->write(\sprintf("%s\n%s\n\n%s%s", $options['parameter'], str_repeat('=', \strlen($options['parameter'])), $this->formatParameter($parameter), $deprecation ? \sprintf("\n\n*Since %s %s: %s*", $deprecation[0], $deprecation[1], \sprintf(...\array_slice($deprecation, 2))) : '')); } else { $this->write($parameter); } @@ -319,35 +319,35 @@ protected function describeEventDispatcherListeners(EventDispatcherInterface $ev $title = 'Registered listeners'; if (null !== $dispatcherServiceName) { - $title .= sprintf(' of event dispatcher "%s"', $dispatcherServiceName); + $title .= \sprintf(' of event dispatcher "%s"', $dispatcherServiceName); } if (null !== $event) { - $title .= sprintf(' for event `%s` ordered by descending priority', $event); + $title .= \sprintf(' for event `%s` ordered by descending priority', $event); $registeredListeners = $eventDispatcher->getListeners($event); } else { // Try to see if "events" exists $registeredListeners = \array_key_exists('events', $options) ? array_combine($options['events'], array_map(fn ($event) => $eventDispatcher->getListeners($event), $options['events'])) : $eventDispatcher->getListeners(); } - $this->write(sprintf('# %s', $title)."\n"); + $this->write(\sprintf('# %s', $title)."\n"); if (null !== $event) { foreach ($registeredListeners as $order => $listener) { - $this->write("\n".sprintf('## Listener %d', $order + 1)."\n"); + $this->write("\n".\sprintf('## Listener %d', $order + 1)."\n"); $this->describeCallable($listener); - $this->write(sprintf('- Priority: `%d`', $eventDispatcher->getListenerPriority($event, $listener))."\n"); + $this->write(\sprintf('- Priority: `%d`', $eventDispatcher->getListenerPriority($event, $listener))."\n"); } } else { ksort($registeredListeners); foreach ($registeredListeners as $eventListened => $eventListeners) { - $this->write("\n".sprintf('## %s', $eventListened)."\n"); + $this->write("\n".\sprintf('## %s', $eventListened)."\n"); foreach ($eventListeners as $order => $eventListener) { - $this->write("\n".sprintf('### Listener %d', $order + 1)."\n"); + $this->write("\n".\sprintf('### Listener %d', $order + 1)."\n"); $this->describeCallable($eventListener); - $this->write(sprintf('- Priority: `%d`', $eventDispatcher->getListenerPriority($eventListened, $eventListener))."\n"); + $this->write(\sprintf('- Priority: `%d`', $eventDispatcher->getListenerPriority($eventListened, $eventListener))."\n"); } } } @@ -361,16 +361,16 @@ protected function describeCallable(mixed $callable, array $options = []): void $string .= "\n- Type: `function`"; if (\is_object($callable[0])) { - $string .= "\n".sprintf('- Name: `%s`', $callable[1]); - $string .= "\n".sprintf('- Class: `%s`', $callable[0]::class); + $string .= "\n".\sprintf('- Name: `%s`', $callable[1]); + $string .= "\n".\sprintf('- Class: `%s`', $callable[0]::class); } else { if (!str_starts_with($callable[1], 'parent::')) { - $string .= "\n".sprintf('- Name: `%s`', $callable[1]); - $string .= "\n".sprintf('- Class: `%s`', $callable[0]); + $string .= "\n".\sprintf('- Name: `%s`', $callable[1]); + $string .= "\n".\sprintf('- Class: `%s`', $callable[0]); $string .= "\n- Static: yes"; } else { - $string .= "\n".sprintf('- Name: `%s`', substr($callable[1], 8)); - $string .= "\n".sprintf('- Class: `%s`', $callable[0]); + $string .= "\n".\sprintf('- Name: `%s`', substr($callable[1], 8)); + $string .= "\n".\sprintf('- Class: `%s`', $callable[0]); $string .= "\n- Static: yes"; $string .= "\n- Parent: yes"; } @@ -385,12 +385,12 @@ protected function describeCallable(mixed $callable, array $options = []): void $string .= "\n- Type: `function`"; if (!str_contains($callable, '::')) { - $string .= "\n".sprintf('- Name: `%s`', $callable); + $string .= "\n".\sprintf('- Name: `%s`', $callable); } else { $callableParts = explode('::', $callable); - $string .= "\n".sprintf('- Name: `%s`', $callableParts[1]); - $string .= "\n".sprintf('- Class: `%s`', $callableParts[0]); + $string .= "\n".\sprintf('- Name: `%s`', $callableParts[1]); + $string .= "\n".\sprintf('- Class: `%s`', $callableParts[0]); $string .= "\n- Static: yes"; } @@ -403,15 +403,15 @@ protected function describeCallable(mixed $callable, array $options = []): void $string .= "\n- Type: `closure`"; $r = new \ReflectionFunction($callable); - if (str_contains($r->name, '{closure}')) { + if (str_contains($r->name, '{closure')) { $this->write($string."\n"); return; } - $string .= "\n".sprintf('- Name: `%s`', $r->name); + $string .= "\n".\sprintf('- Name: `%s`', $r->name); if ($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) { - $string .= "\n".sprintf('- Class: `%s`', $class->name); + $string .= "\n".\sprintf('- Class: `%s`', $class->name); if (!$r->getClosureThis()) { $string .= "\n- Static: yes"; } @@ -424,7 +424,7 @@ protected function describeCallable(mixed $callable, array $options = []): void if (method_exists($callable, '__invoke')) { $string .= "\n- Type: `object`"; - $string .= "\n".sprintf('- Name: `%s`', $callable::class); + $string .= "\n".\sprintf('- Name: `%s`', $callable::class); $this->write($string."\n"); diff --git a/lib/symfony/framework-bundle/Console/Descriptor/TextDescriptor.php b/lib/symfony/framework-bundle/Console/Descriptor/TextDescriptor.php index b0fe7f2ac0..9e05f90e37 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/TextDescriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/TextDescriptor.php @@ -40,7 +40,7 @@ class TextDescriptor extends Descriptor { private ?FileLinkFormatter $fileLinkFormatter; - public function __construct(FileLinkFormatter $fileLinkFormatter = null) + public function __construct(?FileLinkFormatter $fileLinkFormatter = null) { $this->fileLinkFormatter = $fileLinkFormatter; } @@ -133,7 +133,7 @@ protected function describeContainerParameters(ParameterBag $parameters, array $ if (isset($deprecatedParameters[$parameter])) { $tableRows[] = [new TableCell( - sprintf('(Since %s %s: %s)', $deprecatedParameters[$parameter][0], $deprecatedParameters[$parameter][1], sprintf(...\array_slice($deprecatedParameters[$parameter], 2))), + \sprintf('(Since %s %s: %s)', $deprecatedParameters[$parameter][0], $deprecatedParameters[$parameter][1], \sprintf(...\array_slice($deprecatedParameters[$parameter], 2))), ['colspan' => 2] )]; } @@ -154,12 +154,12 @@ protected function describeContainerTags(ContainerBuilder $container, array $opt } foreach ($this->findDefinitionsByTag($container, $showHidden) as $tag => $definitions) { - $options['output']->section(sprintf('"%s" tag', $tag)); + $options['output']->section(\sprintf('"%s" tag', $tag)); $options['output']->listing(array_keys($definitions)); } } - protected function describeContainerService(object $service, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerService(object $service, array $options = [], ?ContainerBuilder $container = null): void { if (!isset($options['id'])) { throw new \InvalidArgumentException('An "id" option must be provided.'); @@ -170,7 +170,7 @@ protected function describeContainerService(object $service, array $options = [] } elseif ($service instanceof Definition) { $this->describeContainerDefinition($service, $options, $container); } else { - $options['output']->title(sprintf('Information for Service "%s"', $options['id'])); + $options['output']->title(\sprintf('Information for Service "%s"', $options['id'])); $options['output']->table( ['Service ID', 'Class'], [ @@ -192,7 +192,7 @@ protected function describeContainerServices(ContainerBuilder $container, array } if ($showTag) { - $title .= sprintf(' Tagged with "%s" Tag', $options['tag']); + $title .= \sprintf(' Tagged with "%s" Tag', $options['tag']); } $options['output']->title($title); @@ -249,7 +249,7 @@ protected function describeContainerServices(ContainerBuilder $container, array foreach ($serviceIds as $serviceId) { $definition = $this->resolveServiceDefinition($container, $serviceId); - $styledServiceId = $rawOutput ? $serviceId : sprintf('%s', OutputFormatter::escape($serviceId)); + $styledServiceId = $rawOutput ? $serviceId : \sprintf('%s', OutputFormatter::escape($serviceId)); if ($definition instanceof Definition) { if ($showTag) { foreach ($this->sortByPriority($definition->getTag($showTag)) as $key => $tag) { @@ -272,7 +272,7 @@ protected function describeContainerServices(ContainerBuilder $container, array } } elseif ($definition instanceof Alias) { $alias = $definition; - $tableRows[] = array_merge([$styledServiceId, sprintf('alias for "%s"', $alias)], $tagsCount ? array_fill(0, $tagsCount, '') : []); + $tableRows[] = array_merge([$styledServiceId, \sprintf('alias for "%s"', $alias)], $tagsCount ? array_fill(0, $tagsCount, '') : []); } else { $tableRows[] = array_merge([$styledServiceId, $definition::class], $tagsCount ? array_fill(0, $tagsCount, '') : []); } @@ -281,10 +281,10 @@ protected function describeContainerServices(ContainerBuilder $container, array $options['output']->table($tableHeaders, $tableRows); } - protected function describeContainerDefinition(Definition $definition, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerDefinition(Definition $definition, array $options = [], ?ContainerBuilder $container = null): void { if (isset($options['id'])) { - $options['output']->title(sprintf('Information for Service "%s"', $options['id'])); + $options['output']->title(\sprintf('Information for Service "%s"', $options['id'])); } if ('' !== $classDescription = $this->getClassDescription((string) $definition->getClass())) { @@ -301,13 +301,13 @@ protected function describeContainerDefinition(Definition $definition, array $op $tagInformation = []; foreach ($tags as $tagName => $tagData) { foreach ($tagData as $tagParameters) { - $parameters = array_map(fn ($key, $value) => sprintf('%s: %s', $key, \is_array($value) ? $this->formatParameter($value) : $value), array_keys($tagParameters), array_values($tagParameters)); + $parameters = array_map(fn ($key, $value) => \sprintf('%s: %s', $key, \is_array($value) ? $this->formatParameter($value) : $value), array_keys($tagParameters), array_values($tagParameters)); $parameters = implode(', ', $parameters); if ('' === $parameters) { - $tagInformation[] = sprintf('%s', $tagName); + $tagInformation[] = \sprintf('%s', $tagName); } else { - $tagInformation[] = sprintf('%s (%s)', $tagName, $parameters); + $tagInformation[] = \sprintf('%s (%s)', $tagName, $parameters); } } } @@ -343,7 +343,7 @@ protected function describeContainerDefinition(Definition $definition, array $op if ($factory[0] instanceof Reference) { $tableRows[] = ['Factory Service', $factory[0]]; } elseif ($factory[0] instanceof Definition) { - $tableRows[] = ['Factory Service', sprintf('inline factory service (%s)', $factory[0]->getClass() ?? 'class not configured')]; + $tableRows[] = ['Factory Service', \sprintf('inline factory service (%s)', $factory[0]->getClass() ?? 'class not configured')]; } else { $tableRows[] = ['Factory Class', $factory[0]]; } @@ -361,27 +361,27 @@ protected function describeContainerDefinition(Definition $definition, array $op $argument = $argument->getValues()[0]; } if ($argument instanceof Reference) { - $argumentsInformation[] = sprintf('Service(%s)', (string) $argument); + $argumentsInformation[] = \sprintf('Service(%s)', (string) $argument); } elseif ($argument instanceof IteratorArgument) { if ($argument instanceof TaggedIteratorArgument) { - $argumentsInformation[] = sprintf('Tagged Iterator for "%s"%s', $argument->getTag(), $options['is_debug'] ? '' : sprintf(' (%d element(s))', \count($argument->getValues()))); + $argumentsInformation[] = \sprintf('Tagged Iterator for "%s"%s', $argument->getTag(), $options['is_debug'] ? '' : \sprintf(' (%d element(s))', \count($argument->getValues()))); } else { - $argumentsInformation[] = sprintf('Iterator (%d element(s))', \count($argument->getValues())); + $argumentsInformation[] = \sprintf('Iterator (%d element(s))', \count($argument->getValues())); } foreach ($argument->getValues() as $ref) { - $argumentsInformation[] = sprintf('- Service(%s)', $ref); + $argumentsInformation[] = \sprintf('- Service(%s)', $ref); } } elseif ($argument instanceof ServiceLocatorArgument) { - $argumentsInformation[] = sprintf('Service locator (%d element(s))', \count($argument->getValues())); + $argumentsInformation[] = \sprintf('Service locator (%d element(s))', \count($argument->getValues())); } elseif ($argument instanceof Definition) { $argumentsInformation[] = 'Inlined Service'; } elseif ($argument instanceof \UnitEnum) { $argumentsInformation[] = ltrim(var_export($argument, true), '\\'); } elseif ($argument instanceof AbstractArgument) { - $argumentsInformation[] = sprintf('Abstract argument (%s)', $argument->getText()); + $argumentsInformation[] = \sprintf('Abstract argument (%s)', $argument->getText()); } else { - $argumentsInformation[] = \is_array($argument) ? sprintf('Array (%d element(s))', \count($argument)) : $argument; + $argumentsInformation[] = \is_array($argument) ? \sprintf('Array (%d element(s))', \count($argument)) : $argument; } } @@ -396,7 +396,7 @@ protected function describeContainerDefinition(Definition $definition, array $op protected function describeContainerDeprecations(ContainerBuilder $container, array $options = []): void { - $containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $container->getParameter('kernel.build_dir'), $container->getParameter('kernel.container_class')); + $containerDeprecationFilePath = \sprintf('%s/%sDeprecations.log', $container->getParameter('kernel.build_dir'), $container->getParameter('kernel.container_class')); if (!file_exists($containerDeprecationFilePath)) { $options['output']->warning('The deprecation file does not exist, please try warming the cache first.'); @@ -413,19 +413,19 @@ protected function describeContainerDeprecations(ContainerBuilder $container, ar $formattedLogs = []; $remainingCount = 0; foreach ($logs as $log) { - $formattedLogs[] = sprintf("%sx: %s\n in %s:%s", $log['count'], $log['message'], $log['file'], $log['line']); + $formattedLogs[] = \sprintf("%sx: %s\n in %s:%s", $log['count'], $log['message'], $log['file'], $log['line']); $remainingCount += $log['count']; } - $options['output']->title(sprintf('Remaining deprecations (%s)', $remainingCount)); + $options['output']->title(\sprintf('Remaining deprecations (%s)', $remainingCount)); $options['output']->listing($formattedLogs); } - protected function describeContainerAlias(Alias $alias, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerAlias(Alias $alias, array $options = [], ?ContainerBuilder $container = null): void { if ($alias->isPublic() && !$alias->isPrivate()) { - $options['output']->comment(sprintf('This service is a public alias for the service %s', (string) $alias)); + $options['output']->comment(\sprintf('This service is a public alias for the service %s', (string) $alias)); } else { - $options['output']->comment(sprintf('This service is a private alias for the service %s', (string) $alias)); + $options['output']->comment(\sprintf('This service is a private alias for the service %s', (string) $alias)); } if (!$container) { @@ -444,7 +444,7 @@ protected function describeContainerParameter(mixed $parameter, ?array $deprecat if ($deprecation) { $rows[] = [new TableCell( - sprintf('(Since %s %s: %s)', $deprecation[0], $deprecation[1], sprintf(...\array_slice($deprecation, 2))), + \sprintf('(Since %s %s: %s)', $deprecation[0], $deprecation[1], \sprintf(...\array_slice($deprecation, 2))), ['colspan' => 2] )]; } @@ -522,11 +522,11 @@ protected function describeEventDispatcherListeners(EventDispatcherInterface $ev $title = 'Registered Listeners'; if (null !== $dispatcherServiceName) { - $title .= sprintf(' of Event Dispatcher "%s"', $dispatcherServiceName); + $title .= \sprintf(' of Event Dispatcher "%s"', $dispatcherServiceName); } if (null !== $event) { - $title .= sprintf(' for "%s" Event', $event); + $title .= \sprintf(' for "%s" Event', $event); $registeredListeners = $eventDispatcher->getListeners($event); } else { $title .= ' Grouped by Event'; @@ -540,7 +540,7 @@ protected function describeEventDispatcherListeners(EventDispatcherInterface $ev } else { ksort($registeredListeners); foreach ($registeredListeners as $eventListened => $eventListeners) { - $options['output']->section(sprintf('"%s" event', $eventListened)); + $options['output']->section(\sprintf('"%s" event', $eventListened)); $this->renderEventListenerTable($eventDispatcher, $eventListened, $eventListeners, $options['output']); } } @@ -557,7 +557,7 @@ private function renderEventListenerTable(EventDispatcherInterface $eventDispatc $tableRows = []; foreach ($eventListeners as $order => $listener) { - $tableRows[] = [sprintf('#%d', $order + 1), $this->formatCallable($listener), $eventDispatcher->getListenerPriority($event, $listener)]; + $tableRows[] = [\sprintf('#%d', $order + 1), $this->formatCallable($listener), $eventDispatcher->getListenerPriority($event, $listener)]; } $io->table($tableHeaders, $tableRows); @@ -573,13 +573,13 @@ private function formatRouterConfig(array $config): string $configAsString = ''; foreach ($config as $key => $value) { - $configAsString .= sprintf("\n%s: %s", $key, $this->formatValue($value)); + $configAsString .= \sprintf("\n%s: %s", $key, $this->formatValue($value)); } return trim($configAsString); } - private function formatControllerLink(mixed $controller, string $anchorText, callable $getContainer = null): string + private function formatControllerLink(mixed $controller, string $anchorText, ?callable $getContainer = null): string { if (null === $this->fileLinkFormatter) { return $anchorText; @@ -597,7 +597,7 @@ private function formatControllerLink(mixed $controller, string $anchorText, cal } elseif (!\is_string($controller)) { return $anchorText; } elseif (str_contains($controller, '::')) { - $r = new \ReflectionMethod($controller); + $r = new \ReflectionMethod(...explode('::', $controller, 2)); } else { $r = new \ReflectionFunction($controller); } @@ -627,7 +627,7 @@ private function formatControllerLink(mixed $controller, string $anchorText, cal $fileLink = $this->fileLinkFormatter->format($r->getFileName(), $r->getStartLine()); if ($fileLink) { - return sprintf('%s', $fileLink, $anchorText); + return \sprintf('%s', $fileLink, $anchorText); } return $anchorText; @@ -637,30 +637,30 @@ private function formatCallable(mixed $callable): string { if (\is_array($callable)) { if (\is_object($callable[0])) { - return sprintf('%s::%s()', $callable[0]::class, $callable[1]); + return \sprintf('%s::%s()', $callable[0]::class, $callable[1]); } - return sprintf('%s::%s()', $callable[0], $callable[1]); + return \sprintf('%s::%s()', $callable[0], $callable[1]); } if (\is_string($callable)) { - return sprintf('%s()', $callable); + return \sprintf('%s()', $callable); } if ($callable instanceof \Closure) { $r = new \ReflectionFunction($callable); - if (str_contains($r->name, '{closure}')) { + if (str_contains($r->name, '{closure')) { return 'Closure()'; } if ($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) { - return sprintf('%s::%s()', $class->name, $r->name); + return \sprintf('%s::%s()', $class->name, $r->name); } return $r->name.'()'; } if (method_exists($callable, '__invoke')) { - return sprintf('%s::__invoke()', $callable::class); + return \sprintf('%s::__invoke()', $callable::class); } throw new \InvalidArgumentException('Callable is not describable.'); diff --git a/lib/symfony/framework-bundle/Console/Descriptor/XmlDescriptor.php b/lib/symfony/framework-bundle/Console/Descriptor/XmlDescriptor.php index f12e4583b2..fb4ab11a69 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/XmlDescriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/XmlDescriptor.php @@ -53,7 +53,7 @@ protected function describeContainerTags(ContainerBuilder $container, array $opt $this->writeDocument($this->getContainerTagsDocument($container, isset($options['show_hidden']) && $options['show_hidden'])); } - protected function describeContainerService(object $service, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerService(object $service, array $options = [], ?ContainerBuilder $container = null): void { if (!isset($options['id'])) { throw new \InvalidArgumentException('An "id" option must be provided.'); @@ -67,12 +67,12 @@ protected function describeContainerServices(ContainerBuilder $container, array $this->writeDocument($this->getContainerServicesDocument($container, $options['tag'] ?? null, isset($options['show_hidden']) && $options['show_hidden'], isset($options['show_arguments']) && $options['show_arguments'], $options['filter'] ?? null, $options['id'] ?? null)); } - protected function describeContainerDefinition(Definition $definition, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerDefinition(Definition $definition, array $options = [], ?ContainerBuilder $container = null): void { $this->writeDocument($this->getContainerDefinitionDocument($definition, $options['id'] ?? null, isset($options['omit_tags']) && $options['omit_tags'], isset($options['show_arguments']) && $options['show_arguments'], $container)); } - protected function describeContainerAlias(Alias $alias, array $options = [], ContainerBuilder $container = null): void + protected function describeContainerAlias(Alias $alias, array $options = [], ?ContainerBuilder $container = null): void { $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->appendChild($dom->importNode($this->getContainerAliasDocument($alias, $options['id'] ?? null)->childNodes->item(0), true)); @@ -110,7 +110,7 @@ protected function describeContainerEnvVars(array $envs, array $options = []): v protected function describeContainerDeprecations(ContainerBuilder $container, array $options = []): void { - $containerDeprecationFilePath = sprintf('%s/%sDeprecations.log', $container->getParameter('kernel.build_dir'), $container->getParameter('kernel.container_class')); + $containerDeprecationFilePath = \sprintf('%s/%sDeprecations.log', $container->getParameter('kernel.build_dir'), $container->getParameter('kernel.container_class')); if (!file_exists($containerDeprecationFilePath)) { throw new RuntimeException('The deprecation file does not exist, please try warming the cache first.'); } @@ -162,7 +162,7 @@ private function getRouteCollectionDocument(RouteCollection $routes, array $opti return $dom; } - private function getRouteDocument(Route $route, string $name = null): \DOMDocument + private function getRouteDocument(Route $route, ?string $name = null): \DOMDocument { $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->appendChild($routeXML = $dom->createElement('route')); @@ -243,7 +243,7 @@ private function getContainerParametersDocument(ParameterBag $parameters): \DOMD $parameterXML->appendChild(new \DOMText($this->formatParameter($value))); if (isset($deprecatedParameters[$key])) { - $parameterXML->setAttribute('deprecated', sprintf('Since %s %s: %s', $deprecatedParameters[$key][0], $deprecatedParameters[$key][1], sprintf(...\array_slice($deprecatedParameters[$key], 2)))); + $parameterXML->setAttribute('deprecated', \sprintf('Since %s %s: %s', $deprecatedParameters[$key][0], $deprecatedParameters[$key][1], \sprintf(...\array_slice($deprecatedParameters[$key], 2)))); } } @@ -268,7 +268,7 @@ private function getContainerTagsDocument(ContainerBuilder $container, bool $sho return $dom; } - private function getContainerServiceDocument(object $service, string $id, ContainerBuilder $container = null, bool $showArguments = false): \DOMDocument + private function getContainerServiceDocument(object $service, string $id, ?ContainerBuilder $container = null, bool $showArguments = false): \DOMDocument { $dom = new \DOMDocument('1.0', 'UTF-8'); @@ -288,7 +288,7 @@ private function getContainerServiceDocument(object $service, string $id, Contai return $dom; } - private function getContainerServicesDocument(ContainerBuilder $container, string $tag = null, bool $showHidden = false, bool $showArguments = false, callable $filter = null, string $id = null): \DOMDocument + private function getContainerServicesDocument(ContainerBuilder $container, ?string $tag = null, bool $showHidden = false, bool $showArguments = false, ?callable $filter = null, ?string $id = null): \DOMDocument { $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->appendChild($containerXML = $dom->createElement('container')); @@ -318,7 +318,7 @@ private function getContainerServicesDocument(ContainerBuilder $container, strin return $dom; } - private function getContainerDefinitionDocument(Definition $definition, string $id = null, bool $omitTags = false, bool $showArguments = false, ContainerBuilder $container = null): \DOMDocument + private function getContainerDefinitionDocument(Definition $definition, ?string $id = null, bool $omitTags = false, bool $showArguments = false, ?ContainerBuilder $container = null): \DOMDocument { $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->appendChild($serviceXML = $dom->createElement('definition')); @@ -341,7 +341,7 @@ private function getContainerDefinitionDocument(Definition $definition, string $ if ($factory[0] instanceof Reference) { $factoryXML->setAttribute('service', (string) $factory[0]); } elseif ($factory[0] instanceof Definition) { - $factoryXML->setAttribute('service', sprintf('inline factory service (%s)', $factory[0]->getClass() ?? 'not configured')); + $factoryXML->setAttribute('service', \sprintf('inline factory service (%s)', $factory[0]->getClass() ?? 'not configured')); } else { $factoryXML->setAttribute('class', $factory[0]); } @@ -418,7 +418,7 @@ private function getContainerDefinitionDocument(Definition $definition, string $ /** * @return \DOMNode[] */ - private function getArgumentNodes(array $arguments, \DOMDocument $dom, ContainerBuilder $container = null): array + private function getArgumentNodes(array $arguments, \DOMDocument $dom, ?ContainerBuilder $container = null): array { $nodes = []; @@ -466,7 +466,7 @@ private function getArgumentNodes(array $arguments, \DOMDocument $dom, Container return $nodes; } - private function getContainerAliasDocument(Alias $alias, string $id = null): \DOMDocument + private function getContainerAliasDocument(Alias $alias, ?string $id = null): \DOMDocument { $dom = new \DOMDocument('1.0', 'UTF-8'); $dom->appendChild($aliasXML = $dom->createElement('alias')); @@ -490,7 +490,7 @@ private function getContainerParameterDocument(mixed $parameter, ?array $depreca $parameterXML->setAttribute('key', $options['parameter']); if ($deprecation) { - $parameterXML->setAttribute('deprecated', sprintf('Since %s %s: %s', $deprecation[0], $deprecation[1], sprintf(...\array_slice($deprecation, 2)))); + $parameterXML->setAttribute('deprecated', \sprintf('Since %s %s: %s', $deprecation[0], $deprecation[1], \sprintf(...\array_slice($deprecation, 2)))); } } @@ -581,7 +581,7 @@ private function getCallableDocument(mixed $callable): \DOMDocument $callableXML->setAttribute('type', 'closure'); $r = new \ReflectionFunction($callable); - if (str_contains($r->name, '{closure}')) { + if (str_contains($r->name, '{closure')) { return $dom; } $callableXML->setAttribute('name', $r->name); diff --git a/lib/symfony/framework-bundle/Console/Helper/DescriptorHelper.php b/lib/symfony/framework-bundle/Console/Helper/DescriptorHelper.php index 47d69fef46..b12a8d8621 100644 --- a/lib/symfony/framework-bundle/Console/Helper/DescriptorHelper.php +++ b/lib/symfony/framework-bundle/Console/Helper/DescriptorHelper.php @@ -25,7 +25,7 @@ */ class DescriptorHelper extends BaseDescriptorHelper { - public function __construct(FileLinkFormatter $fileLinkFormatter = null) + public function __construct(?FileLinkFormatter $fileLinkFormatter = null) { $this ->register('txt', new TextDescriptor($fileLinkFormatter)) diff --git a/lib/symfony/framework-bundle/Controller/AbstractController.php b/lib/symfony/framework-bundle/Controller/AbstractController.php index 4ede883f7e..b474498168 100644 --- a/lib/symfony/framework-bundle/Controller/AbstractController.php +++ b/lib/symfony/framework-bundle/Controller/AbstractController.php @@ -75,7 +75,7 @@ public function setContainer(ContainerInterface $container): ?ContainerInterface protected function getParameter(string $name): array|bool|string|int|float|\UnitEnum|null { if (!$this->container->has('parameter_bag')) { - throw new ServiceNotFoundException('parameter_bag.', null, null, [], sprintf('The "%s::getParameter()" method is missing a parameter bag to work properly. Did you forget to register your controller as a service subscriber? This can be fixed either by using autoconfiguration or by manually wiring a "parameter_bag" in the service locator passed to the controller.', static::class)); + throw new ServiceNotFoundException('parameter_bag.', null, null, [], \sprintf('The "%s::getParameter()" method is missing a parameter bag to work properly. Did you forget to register your controller as a service subscriber? This can be fixed either by using autoconfiguration or by manually wiring a "parameter_bag" in the service locator passed to the controller.', static::class)); } return $this->container->get('parameter_bag')->get($name); @@ -157,13 +157,17 @@ protected function json(mixed $data, int $status = 200, array $headers = [], arr return new JsonResponse($json, $status, $headers, true); } + if (null === $data) { + return new JsonResponse('null', $status, $headers, true); + } + return new JsonResponse($data, $status, $headers); } /** * Returns a BinaryFileResponse object with original or customized file name and disposition header. */ - protected function file(\SplFileInfo|string $file, string $fileName = null, string $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT): BinaryFileResponse + protected function file(\SplFileInfo|string $file, ?string $fileName = null, string $disposition = ResponseHeaderBag::DISPOSITION_ATTACHMENT): BinaryFileResponse { $response = new BinaryFileResponse($file); $response->setContentDisposition($disposition, $fileName ?? $response->getFile()->getFilename()); @@ -248,7 +252,7 @@ protected function renderBlockView(string $view, string $block, array $parameter * If an invalid form is found in the list of parameters, a 422 status code is returned. * Forms found in parameters are auto-cast to form views. */ - protected function render(string $view, array $parameters = [], Response $response = null): Response + protected function render(string $view, array $parameters = [], ?Response $response = null): Response { return $this->doRender($view, null, $parameters, $response, __FUNCTION__); } @@ -259,7 +263,7 @@ protected function render(string $view, array $parameters = [], Response $respon * If an invalid form is found in the list of parameters, a 422 status code is returned. * Forms found in parameters are auto-cast to form views. */ - protected function renderBlock(string $view, string $block, array $parameters = [], Response $response = null): Response + protected function renderBlock(string $view, string $block, array $parameters = [], ?Response $response = null): Response { return $this->doRender($view, $block, $parameters, $response, __FUNCTION__); } @@ -271,7 +275,7 @@ protected function renderBlock(string $view, string $block, array $parameters = * * @deprecated since Symfony 6.2, use render() instead */ - protected function renderForm(string $view, array $parameters = [], Response $response = null): Response + protected function renderForm(string $view, array $parameters = [], ?Response $response = null): Response { trigger_deprecation('symfony/framework-bundle', '6.2', 'The "%s::renderForm()" method is deprecated, use "render()" instead.', get_debug_type($this)); @@ -281,7 +285,7 @@ protected function renderForm(string $view, array $parameters = [], Response $re /** * Streams a view. */ - protected function stream(string $view, array $parameters = [], StreamedResponse $response = null): StreamedResponse + protected function stream(string $view, array $parameters = [], ?StreamedResponse $response = null): StreamedResponse { if (!$this->container->has('twig')) { throw new \LogicException('You cannot use the "stream" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".'); @@ -309,7 +313,7 @@ protected function stream(string $view, array $parameters = [], StreamedResponse * * throw $this->createNotFoundException('Page not found!'); */ - protected function createNotFoundException(string $message = 'Not Found', \Throwable $previous = null): NotFoundHttpException + protected function createNotFoundException(string $message = 'Not Found', ?\Throwable $previous = null): NotFoundHttpException { return new NotFoundHttpException($message, $previous); } @@ -323,7 +327,7 @@ protected function createNotFoundException(string $message = 'Not Found', \Throw * * @throws \LogicException If the Security component is not available */ - protected function createAccessDeniedException(string $message = 'Access Denied.', \Throwable $previous = null): AccessDeniedException + protected function createAccessDeniedException(string $message = 'Access Denied.', ?\Throwable $previous = null): AccessDeniedException { if (!class_exists(AccessDeniedException::class)) { throw new \LogicException('You cannot use the "createAccessDeniedException" method if the Security component is not available. Try running "composer require symfony/security-bundle".'); @@ -406,7 +410,7 @@ protected function addLink(Request $request, LinkInterface $link): void /** * @param LinkInterface[] $links */ - protected function sendEarlyHints(iterable $links = [], Response $response = null): Response + protected function sendEarlyHints(iterable $links = [], ?Response $response = null): Response { if (!$this->container->has('web_link.http_header_serializer')) { throw new \LogicException('You cannot use the "sendEarlyHints" method if the WebLink component is not available. Try running "composer require symfony/web-link".'); @@ -432,7 +436,7 @@ protected function sendEarlyHints(iterable $links = [], Response $response = nul private function doRenderView(string $view, ?string $block, array $parameters, string $method): string { if (!$this->container->has('twig')) { - throw new \LogicException(sprintf('You cannot use the "%s" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".', $method)); + throw new \LogicException(\sprintf('You cannot use the "%s" method if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".', $method)); } foreach ($parameters as $k => $v) { diff --git a/lib/symfony/framework-bundle/Controller/ControllerResolver.php b/lib/symfony/framework-bundle/Controller/ControllerResolver.php index 3449740bf3..8d7613d41f 100644 --- a/lib/symfony/framework-bundle/Controller/ControllerResolver.php +++ b/lib/symfony/framework-bundle/Controller/ControllerResolver.php @@ -31,7 +31,7 @@ protected function instantiateController(string $class): object } if ($controller instanceof AbstractController) { if (null === $previousContainer = $controller->setContainer($this->container)) { - throw new \LogicException(sprintf('"%s" has no container set, did you forget to define it as a service subscriber?', $class)); + throw new \LogicException(\sprintf('"%s" has no container set, did you forget to define it as a service subscriber?', $class)); } else { $controller->setContainer($previousContainer); } diff --git a/lib/symfony/framework-bundle/Controller/RedirectController.php b/lib/symfony/framework-bundle/Controller/RedirectController.php index f5f42a7f77..91d1e67dd0 100644 --- a/lib/symfony/framework-bundle/Controller/RedirectController.php +++ b/lib/symfony/framework-bundle/Controller/RedirectController.php @@ -31,7 +31,7 @@ class RedirectController private ?int $httpPort; private ?int $httpsPort; - public function __construct(UrlGeneratorInterface $router = null, int $httpPort = null, int $httpsPort = null) + public function __construct(?UrlGeneratorInterface $router = null, ?int $httpPort = null, ?int $httpsPort = null) { $this->router = $router; $this->httpPort = $httpPort; @@ -107,9 +107,9 @@ public function redirectAction(Request $request, string $route, bool $permanent * * @throws HttpException In case the path is empty */ - public function urlRedirectAction(Request $request, string $path, bool $permanent = false, string $scheme = null, int $httpPort = null, int $httpsPort = null, bool $keepRequestMethod = false): Response + public function urlRedirectAction(Request $request, string $path, bool $permanent = false, ?string $scheme = null, ?int $httpPort = null, ?int $httpsPort = null, bool $keepRequestMethod = false): Response { - if ('' == $path) { + if ('' === $path) { throw new HttpException($permanent ? 410 : 404); } @@ -119,13 +119,17 @@ public function urlRedirectAction(Request $request, string $path, bool $permanen $statusCode = $permanent ? 301 : 302; } + $scheme ??= $request->getScheme(); + + if (str_starts_with($path, '//')) { + $path = $scheme.':'.$path; + } + // redirect if the path is a full URL if (parse_url($path, \PHP_URL_SCHEME)) { return new RedirectResponse($path, $statusCode); } - $scheme ??= $request->getScheme(); - if ($qs = $request->server->get('QUERY_STRING') ?: $request->getQueryString()) { if (!str_contains($path, '?')) { $qs = '?'.$qs; @@ -172,7 +176,7 @@ public function __invoke(Request $request): Response if (\array_key_exists('route', $p)) { if (\array_key_exists('path', $p)) { - throw new \RuntimeException(sprintf('Ambiguous redirection settings, use the "path" or "route" parameter, not both: "%s" and "%s" found respectively in "%s" routing configuration.', $p['path'], $p['route'], $request->attributes->get('_route'))); + throw new \RuntimeException(\sprintf('Ambiguous redirection settings, use the "path" or "route" parameter, not both: "%s" and "%s" found respectively in "%s" routing configuration.', $p['path'], $p['route'], $request->attributes->get('_route'))); } return $this->redirectAction($request, $p['route'], $p['permanent'] ?? false, $p['ignoreAttributes'] ?? false, $p['keepRequestMethod'] ?? false, $p['keepQueryParams'] ?? false); @@ -182,6 +186,6 @@ public function __invoke(Request $request): Response return $this->urlRedirectAction($request, $p['path'], $p['permanent'] ?? false, $p['scheme'] ?? null, $p['httpPort'] ?? null, $p['httpsPort'] ?? null, $p['keepRequestMethod'] ?? false); } - throw new \RuntimeException(sprintf('The parameter "path" or "route" is required to configure the redirect action in "%s" routing configuration.', $request->attributes->get('_route'))); + throw new \RuntimeException(\sprintf('The parameter "path" or "route" is required to configure the redirect action in "%s" routing configuration.', $request->attributes->get('_route'))); } } diff --git a/lib/symfony/framework-bundle/Controller/TemplateController.php b/lib/symfony/framework-bundle/Controller/TemplateController.php index 437458a499..97631572c9 100644 --- a/lib/symfony/framework-bundle/Controller/TemplateController.php +++ b/lib/symfony/framework-bundle/Controller/TemplateController.php @@ -25,7 +25,7 @@ class TemplateController { private ?Environment $twig; - public function __construct(Environment $twig = null) + public function __construct(?Environment $twig = null) { $this->twig = $twig; } @@ -40,7 +40,7 @@ public function __construct(Environment $twig = null) * @param array $context The context (arguments) of the template * @param int $statusCode The HTTP status code to return with the response (200 "OK" by default) */ - public function templateAction(string $template, int $maxAge = null, int $sharedAge = null, bool $private = null, array $context = [], int $statusCode = 200): Response + public function templateAction(string $template, ?int $maxAge = null, ?int $sharedAge = null, ?bool $private = null, array $context = [], int $statusCode = 200): Response { if (null === $this->twig) { throw new \LogicException('You cannot use the TemplateController if the Twig Bundle is not available. Try running "composer require symfony/twig-bundle".'); @@ -68,7 +68,7 @@ public function templateAction(string $template, int $maxAge = null, int $shared /** * @param int $statusCode The HTTP status code (200 "OK" by default) */ - public function __invoke(string $template, int $maxAge = null, int $sharedAge = null, bool $private = null, array $context = [], int $statusCode = 200): Response + public function __invoke(string $template, ?int $maxAge = null, ?int $sharedAge = null, ?bool $private = null, array $context = [], int $statusCode = 200): Response { return $this->templateAction($template, $maxAge, $sharedAge, $private, $context, $statusCode); } diff --git a/lib/symfony/framework-bundle/DataCollector/RouterDataCollector.php b/lib/symfony/framework-bundle/DataCollector/RouterDataCollector.php index 700d0f22d4..e383d48aef 100644 --- a/lib/symfony/framework-bundle/DataCollector/RouterDataCollector.php +++ b/lib/symfony/framework-bundle/DataCollector/RouterDataCollector.php @@ -28,7 +28,7 @@ public function guessRoute(Request $request, mixed $controller): string $controller = $controller[0]; } - if ($controller instanceof RedirectController) { + if ($controller instanceof RedirectController && $request->attributes->has('_route')) { return $request->attributes->get('_route'); } diff --git a/lib/symfony/framework-bundle/DependencyInjection/Compiler/LoggingTranslatorPass.php b/lib/symfony/framework-bundle/DependencyInjection/Compiler/LoggingTranslatorPass.php index 5b31f2884e..b76b1f3cae 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/LoggingTranslatorPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/LoggingTranslatorPass.php @@ -41,7 +41,7 @@ public function process(ContainerBuilder $container) $class = $container->getParameterBag()->resolveValue($definition->getClass()); if (!$r = $container->getReflectionClass($class)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $translatorAlias)); + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $translatorAlias)); } if ($r->isSubclassOf(TranslatorInterface::class) && $r->isSubclassOf(TranslatorBagInterface::class)) { $container->getDefinition('translator.logging')->setDecoratedService('translator'); diff --git a/lib/symfony/framework-bundle/DependencyInjection/Compiler/ProfilerPass.php b/lib/symfony/framework-bundle/DependencyInjection/Compiler/ProfilerPass.php index 8f3f9b220d..f904e8b199 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/ProfilerPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/ProfilerPass.php @@ -45,7 +45,7 @@ public function process(ContainerBuilder $container) if (isset($attributes[0]['template']) || is_subclass_of($collectorClass, TemplateAwareDataCollectorInterface::class)) { $idForTemplate = $attributes[0]['id'] ?? $collectorClass; if (!$idForTemplate) { - throw new InvalidArgumentException(sprintf('Data collector service "%s" must have an id attribute in order to specify a template.', $id)); + throw new InvalidArgumentException(\sprintf('Data collector service "%s" must have an id attribute in order to specify a template.', $id)); } $template = [$idForTemplate, $attributes[0]['template'] ?? $collectorClass::getTemplate()]; } diff --git a/lib/symfony/framework-bundle/DependencyInjection/Compiler/TestServiceContainerWeakRefPass.php b/lib/symfony/framework-bundle/DependencyInjection/Compiler/TestServiceContainerWeakRefPass.php index 6e7669a710..428137ff82 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/TestServiceContainerWeakRefPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/TestServiceContainerWeakRefPass.php @@ -34,7 +34,10 @@ public function process(ContainerBuilder $container) $definitions = $container->getDefinitions(); foreach ($definitions as $id => $definition) { - if ($id && '.' !== $id[0] && (!$definition->isPublic() || $definition->isPrivate() || $definition->hasTag('container.private')) && !$definition->hasErrors() && !$definition->isAbstract()) { + if ($inner = $definition->getTag('container.decorator')[0]['inner'] ?? null) { + $privateServices[$inner] = new Reference($inner, ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE); + } + if ($id && '.' !== $id[0] && ($definition->isPrivate() || $definition->hasTag('container.private')) && !$definition->hasErrors() && !$definition->isAbstract()) { $privateServices[$id] = new Reference($id, ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE); } } diff --git a/lib/symfony/framework-bundle/DependencyInjection/Compiler/UnusedTagsPass.php b/lib/symfony/framework-bundle/DependencyInjection/Compiler/UnusedTagsPass.php index 5f975f8681..1d151fb618 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/UnusedTagsPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/UnusedTagsPass.php @@ -132,9 +132,9 @@ public function process(ContainerBuilder $container) } $services = array_keys($container->findTaggedServiceIds($tag)); - $message = sprintf('Tag "%s" was defined on service(s) "%s", but was never used.', $tag, implode('", "', $services)); + $message = \sprintf('Tag "%s" was defined on service(s) "%s", but was never used.', $tag, implode('", "', $services)); if ($candidates) { - $message .= sprintf(' Did you mean "%s"?', implode('", "', $candidates)); + $message .= \sprintf(' Did you mean "%s"?', implode('", "', $candidates)); } $container->log($this, $message); diff --git a/lib/symfony/framework-bundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php b/lib/symfony/framework-bundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php index c072083112..6f40cc6a62 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php @@ -45,7 +45,7 @@ public function process(ContainerBuilder $container) foreach ($servicesNeeded as $service) { if (!$container->has($service)) { - throw new LogicException(sprintf('The "%s" service is needed to be able to use the workflow guard listener.', $service)); + throw new LogicException(\sprintf('The "%s" service is needed to be able to use the workflow guard listener.', $service)); } } } diff --git a/lib/symfony/framework-bundle/DependencyInjection/Configuration.php b/lib/symfony/framework-bundle/DependencyInjection/Configuration.php index 46177a09e5..7fe754e3df 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Configuration.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Configuration.php @@ -146,7 +146,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ; - $willBeAvailable = static function (string $package, string $class, string $parentPackage = null) { + $willBeAvailable = static function (string $package, string $class, ?string $parentPackage = null) { $parentPackages = (array) $parentPackage; $parentPackages[] = 'symfony/framework-bundle'; @@ -358,7 +358,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void ->arrayNode('workflows') ->canBeEnabled() ->beforeNormalization() - ->always(function ($v) { + ->always(static function ($v) { if (\is_array($v) && true === $v['enabled']) { $workflows = $v; unset($workflows['enabled']); @@ -367,13 +367,13 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void $workflows = []; } - if (1 === \count($workflows) && isset($workflows['workflows']) && !array_is_list($workflows['workflows']) && array_diff(array_keys($workflows['workflows']), ['audit_trail', 'type', 'marking_store', 'supports', 'support_strategy', 'initial_marking', 'places', 'transitions'])) { + if (1 === \count($workflows) && isset($workflows['workflows']) && !array_is_list($workflows['workflows']) && array_diff_key($workflows['workflows'], ['audit_trail' => 1, 'type' => 1, 'marking_store' => 1, 'supports' => 1, 'support_strategy' => 1, 'initial_marking' => 1, 'places' => 1, 'transitions' => 1])) { $workflows = $workflows['workflows']; } foreach ($workflows as $key => $workflow) { if (isset($workflow['enabled']) && false === $workflow['enabled']) { - throw new LogicException(sprintf('Cannot disable a single workflow. Remove the configuration for the workflow "%s" instead.', $key)); + throw new LogicException(\sprintf('Cannot disable a single workflow. Remove the configuration for the workflow "%s" instead.', $key)); } unset($workflows[$key]['enabled']); @@ -473,27 +473,16 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void throw new InvalidConfigurationException('The "places" option must be an array in workflow configuration.'); } - // It's an indexed array of shape ['place1', 'place2'] - if (isset($places[0]) && \is_string($places[0])) { - return array_map(function (string $place) { - return ['name' => $place]; - }, $places); - } - - // It's an indexed array, we let the validation occur - if (isset($places[0]) && \is_array($places[0])) { - return $places; - } - - foreach ($places as $name => $place) { - if (\is_array($place) && \array_key_exists('name', $place)) { - continue; + $normalizedPlaces = []; + foreach ($places as $key => $value) { + if (!\is_array($value)) { + $value = ['name' => $value]; } - $place['name'] = $name; - $places[$name] = $place; + $value['name'] ??= $key; + $normalizedPlaces[] = $value; } - return array_values($places); + return $normalizedPlaces; }) ->end() ->isRequired() @@ -516,26 +505,26 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void ->end() ->arrayNode('transitions') ->beforeNormalization() - ->always() - ->then(function ($transitions) { + ->always(static function ($transitions) { if (!\is_array($transitions)) { throw new InvalidConfigurationException('The "transitions" option must be an array in workflow configuration.'); } - // It's an indexed array, we let the validation occur - if (isset($transitions[0]) && \is_array($transitions[0])) { - return $transitions; - } - - foreach ($transitions as $name => $transition) { - if (\is_array($transition) && \array_key_exists('name', $transition)) { - continue; + $normalizedTransitions = []; + foreach ($transitions as $key => $transition) { + if (\is_array($transition)) { + if (\is_string($key = $transition['key'] ?? $key)) { + $transition['name'] ??= $key; + } + if (!($transition['name'] ?? false)) { + throw new InvalidConfigurationException('The "name" option is required for each transition in workflow configuration.'); + } + unset($transition['key']); } - $transition['name'] = $name; - $transitions[$name] = $transition; + $normalizedTransitions[$key] = $transition; } - return $transitions; + return $normalizedTransitions; }) ->end() ->isRequired() @@ -552,6 +541,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void ->example('is_fully_authenticated() and is_granted(\'ROLE_JOURNALIST\') and subject.getTitle() == \'My first article\'') ->end() ->arrayNode('from') + ->performNoDeepMerging() ->beforeNormalization() ->ifString() ->then(fn ($v) => [$v]) @@ -562,6 +552,7 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode): void ->end() ->end() ->arrayNode('to') + ->performNoDeepMerging() ->beforeNormalization() ->ifString() ->then(fn ($v) => [$v]) @@ -930,6 +921,10 @@ private function addAssetMapperSection(ArrayNodeDefinition $rootNode, callable $ ->end() ->scalarNode('importmap_polyfill') ->info('The importmap name that will be used to load the polyfill. Set to false to disable.') + ->validate() + ->ifTrue() + ->thenInvalid('Invalid "importmap_polyfill" value. Must be either an importmap name or false.') + ->end() ->defaultValue('es-module-shims') ->end() ->arrayNode('importmap_script_attributes') @@ -1062,7 +1057,7 @@ private function addValidationSection(ArrayNodeDefinition $rootNode, callable $e ->validate()->castToArray()->end() ->end() ->scalarNode('translation_domain')->defaultValue('validators')->end() - ->enumNode('email_validation_mode')->values(['html5', 'loose', 'strict'])->end() + ->enumNode('email_validation_mode')->values(['html5', 'html5-allow-no-tld', 'strict', 'loose'])->end() ->arrayNode('mapping') ->addDefaultsIfNotSet() ->fixXmlConfig('path') @@ -1192,8 +1187,7 @@ private function addSerializerSection(ArrayNodeDefinition $rootNode, callable $e ->end() ->arrayNode('default_context') ->normalizeKeys(false) - ->useAttributeAsKey('name') - ->beforeNormalization() + ->validate() ->ifTrue(fn () => $this->debug && class_exists(JsonParser::class)) ->then(fn (array $v) => $v + [JsonDecode::DETAILED_ERROR_MESSAGES => true]) ->end() @@ -1422,7 +1416,7 @@ private function addExceptionsSection(ArrayNodeDefinition $rootNode): void ->info('The level of log message. Null to let Symfony decide.') ->validate() ->ifTrue(fn ($v) => null !== $v && !\in_array($v, $logLevels, true)) - ->thenInvalid(sprintf('The log level is not valid. Pick one among "%s".', implode('", "', $logLevels))) + ->thenInvalid(\sprintf('The log level is not valid. Pick one among "%s".', implode('", "', $logLevels))) ->end() ->defaultNull() ->end() @@ -1590,7 +1584,7 @@ private function addMessengerSection(ArrayNodeDefinition $rootNode, callable $en ->end() ->validate() ->ifTrue(fn ($v) => isset($v['buses']) && null !== $v['default_bus'] && !isset($v['buses'][$v['default_bus']])) - ->then(fn ($v) => throw new InvalidConfigurationException(sprintf('The specified default bus "%s" is not configured. Available buses are "%s".', $v['default_bus'], implode('", "', array_keys($v['buses']))))) + ->then(fn ($v) => throw new InvalidConfigurationException(\sprintf('The specified default bus "%s" is not configured. Available buses are "%s".', $v['default_bus'], implode('", "', array_keys($v['buses']))))) ->end() ->children() ->arrayNode('routing') @@ -1863,6 +1857,7 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode, callable $e ->end() ->arrayNode('vars') ->info('Associative array: the default vars used to expand the templated URI.') + ->useAttributeAsKey('name') ->normalizeKeys(false) ->variablePrototype()->end() ->end() @@ -1943,6 +1938,7 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode, callable $e ->end() ->arrayNode('extra') ->info('Extra options for specific HTTP client') + ->useAttributeAsKey('name') ->normalizeKeys(false) ->variablePrototype()->end() ->end() @@ -2089,8 +2085,12 @@ private function addHttpClientSection(ArrayNodeDefinition $rootNode, callable $e ->variableNode('md5')->end() ->end() ->end() + ->scalarNode('crypto_method') + ->info('The minimum version of TLS to accept; must be one of STREAM_CRYPTO_METHOD_TLSv*_CLIENT constants.') + ->end() ->arrayNode('extra') ->info('Extra options for specific HTTP client') + ->useAttributeAsKey('name') ->normalizeKeys(false) ->variablePrototype()->end() ->end() @@ -2195,6 +2195,7 @@ private function addMailerSection(ArrayNodeDefinition $rootNode, callable $enabl ->end() ->arrayNode('envelope') ->info('Mailer Envelope configuration') + ->fixXmlConfig('recipient') ->children() ->scalarNode('sender')->end() ->arrayNode('recipients') diff --git a/lib/symfony/framework-bundle/DependencyInjection/FrameworkExtension.php b/lib/symfony/framework-bundle/DependencyInjection/FrameworkExtension.php index 32026a84df..a8ef96b659 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/FrameworkExtension.php +++ b/lib/symfony/framework-bundle/DependencyInjection/FrameworkExtension.php @@ -122,6 +122,8 @@ use Symfony\Component\Mime\MimeTypeGuesserInterface; use Symfony\Component\Mime\MimeTypes; use Symfony\Component\Notifier\Bridge as NotifierBridge; +use Symfony\Component\Notifier\Bridge\FakeChat\FakeChatTransportFactory; +use Symfony\Component\Notifier\Bridge\FakeSms\FakeSmsTransportFactory; use Symfony\Component\Notifier\ChatterInterface; use Symfony\Component\Notifier\Notifier; use Symfony\Component\Notifier\Recipient\Recipient; @@ -161,6 +163,7 @@ use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader; use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader; use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader; +use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface; use Symfony\Component\Serializer\Normalizer\DenormalizerInterface; use Symfony\Component\Serializer\Normalizer\NormalizerInterface; use Symfony\Component\Serializer\Serializer; @@ -349,7 +352,7 @@ public function load(array $configs, ContainerBuilder $container) throw new LogicException('AssetMapper support cannot be enabled as the AssetMapper component is not installed. Try running "composer require symfony/asset-mapper".'); } - $this->registerAssetMapperConfiguration($config['asset_mapper'], $container, $loader, $this->readConfigEnabled('assets', $container, $config['assets'])); + $this->registerAssetMapperConfiguration($config['asset_mapper'], $container, $loader, $this->readConfigEnabled('assets', $container, $config['assets']), $this->readConfigEnabled('http_client', $container, $config['http_client'])); } else { $container->removeDefinition('cache.asset_mapper'); } @@ -677,7 +680,7 @@ public function load(array $configs, ContainerBuilder $container) $tagAttributes = get_object_vars($attribute); if ($reflector instanceof \ReflectionMethod) { if (isset($tagAttributes['method'])) { - throw new LogicException(sprintf('AsEventListener attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name)); + throw new LogicException(\sprintf('AsEventListener attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name)); } $tagAttributes['method'] = $reflector->getName(); } @@ -695,7 +698,7 @@ public function load(array $configs, ContainerBuilder $container) unset($tagAttributes['fromTransport']); if ($reflector instanceof \ReflectionMethod) { if (isset($tagAttributes['method'])) { - throw new LogicException(sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name)); + throw new LogicException(\sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name)); } $tagAttributes['method'] = $reflector->getName(); } @@ -719,7 +722,7 @@ static function (ChildDefinition $definition, AsPeriodicTask|AsCronTask $attribu ]; if ($reflector instanceof \ReflectionMethod) { if (isset($tagAttributes['method'])) { - throw new LogicException(sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name)); + throw new LogicException(\sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name)); } $tagAttributes['method'] = $reflector->getName(); } @@ -733,7 +736,7 @@ static function (ChildDefinition $definition, AsPeriodicTask|AsCronTask $attribu $container->getDefinition('config_cache_factory')->setArguments([]); } - if (!$config['disallow_search_engine_index'] ?? false) { + if (!$config['disallow_search_engine_index']) { $container->removeDefinition('disallow_search_engine_index_response_listener'); } @@ -906,7 +909,7 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $ // Choose storage class based on the DSN [$class] = explode(':', $config['dsn'], 2); if ('file' !== $class) { - throw new \LogicException(sprintf('Driver "%s" is not supported for the profiler.', $class)); + throw new \LogicException(\sprintf('Driver "%s" is not supported for the profiler.', $class)); } $container->setParameter('profiler.storage.dsn', $config['dsn']); @@ -918,11 +921,11 @@ private function registerProfilerConfiguration(array $config, ContainerBuilder $ $container->getDefinition('profiler_listener') ->addArgument($config['collect_parameter']); - if (!$container->getParameter('kernel.debug') || !class_exists(CliRequest::class) || !$container->has('debug.stopwatch')) { + if (!$container->getParameter('kernel.debug') || !$this->hasConsole() || !$container->has('debug.stopwatch') || !class_exists(CliRequest::class)) { $container->removeDefinition('console_profiler_listener'); } - if (!class_exists(CommandDataCollector::class)) { + if (!$this->hasConsole() || !class_exists(CommandDataCollector::class)) { $container->removeDefinition('.data_collector.command'); } } @@ -945,7 +948,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ foreach ($config['workflows'] as $name => $workflow) { $type = $workflow['type']; - $workflowId = sprintf('%s.%s', $type, $name); + $workflowId = \sprintf('%s.%s', $type, $name); // Process Metadata (workflow + places (transition is done in the "create transition" block)) $metadataStoreDefinition = new Definition(Workflow\Metadata\InMemoryMetadataStore::class, [[], [], null]); @@ -970,19 +973,19 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ $transitionCounter = 0; foreach ($workflow['transitions'] as $transition) { if ('workflow' === $type) { - $transitionDefinition = new Definition(Workflow\Transition::class, [$transition['name'], $transition['from'], $transition['to']]); - $transitionId = sprintf('.%s.transition.%s', $workflowId, $transitionCounter++); - $container->setDefinition($transitionId, $transitionDefinition); + $transitionId = \sprintf('.%s.transition.%s', $workflowId, $transitionCounter++); + $container->register($transitionId, Workflow\Transition::class) + ->setArguments([$transition['name'], $transition['from'], $transition['to']]); $transitions[] = new Reference($transitionId); if (isset($transition['guard'])) { - $configuration = new Definition(Workflow\EventListener\GuardExpression::class); - $configuration->addArgument(new Reference($transitionId)); - $configuration->addArgument($transition['guard']); - $eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']); - $guardsConfiguration[$eventName][] = $configuration; + $eventName = \sprintf('workflow.%s.guard.%s', $name, $transition['name']); + $guardsConfiguration[$eventName][] = new Definition( + Workflow\EventListener\GuardExpression::class, + [new Reference($transitionId), $transition['guard']] + ); } if ($transition['metadata']) { - $transitionsMetadataDefinition->addMethodCall('attach', [ + $transitionsMetadataDefinition->addMethodCall('offsetSet', [ new Reference($transitionId), $transition['metadata'], ]); @@ -990,19 +993,19 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ } elseif ('state_machine' === $type) { foreach ($transition['from'] as $from) { foreach ($transition['to'] as $to) { - $transitionDefinition = new Definition(Workflow\Transition::class, [$transition['name'], $from, $to]); - $transitionId = sprintf('.%s.transition.%s', $workflowId, $transitionCounter++); - $container->setDefinition($transitionId, $transitionDefinition); + $transitionId = \sprintf('.%s.transition.%s', $workflowId, $transitionCounter++); + $container->register($transitionId, Workflow\Transition::class) + ->setArguments([$transition['name'], $from, $to]); $transitions[] = new Reference($transitionId); if (isset($transition['guard'])) { - $configuration = new Definition(Workflow\EventListener\GuardExpression::class); - $configuration->addArgument(new Reference($transitionId)); - $configuration->addArgument($transition['guard']); - $eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']); - $guardsConfiguration[$eventName][] = $configuration; + $eventName = \sprintf('workflow.%s.guard.%s', $name, $transition['name']); + $guardsConfiguration[$eventName][] = new Definition( + Workflow\EventListener\GuardExpression::class, + [new Reference($transitionId), $transition['guard']] + ); } if ($transition['metadata']) { - $transitionsMetadataDefinition->addMethodCall('attach', [ + $transitionsMetadataDefinition->addMethodCall('offsetSet', [ new Reference($transitionId), $transition['metadata'], ]); @@ -1012,7 +1015,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ } } $metadataStoreDefinition->replaceArgument(2, $transitionsMetadataDefinition); - $container->setDefinition(sprintf('%s.metadata_store', $workflowId), $metadataStoreDefinition); + $container->setDefinition(\sprintf('%s.metadata_store', $workflowId), $metadataStoreDefinition); // Create places $places = array_column($workflow['places'], 'name'); @@ -1023,7 +1026,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ $definitionDefinition->addArgument($places); $definitionDefinition->addArgument($transitions); $definitionDefinition->addArgument($initialMarking); - $definitionDefinition->addArgument(new Reference(sprintf('%s.metadata_store', $workflowId))); + $definitionDefinition->addArgument(new Reference(\sprintf('%s.metadata_store', $workflowId))); // Create MarkingStore $markingStoreDefinition = null; @@ -1038,8 +1041,8 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ } // Create Workflow - $workflowDefinition = new ChildDefinition(sprintf('%s.abstract', $type)); - $workflowDefinition->replaceArgument(0, new Reference(sprintf('%s.definition', $workflowId))); + $workflowDefinition = new ChildDefinition(\sprintf('%s.abstract', $type)); + $workflowDefinition->replaceArgument(0, new Reference(\sprintf('%s.definition', $workflowId))); $workflowDefinition->replaceArgument(1, $markingStoreDefinition); $workflowDefinition->replaceArgument(3, $name); $workflowDefinition->replaceArgument(4, $workflow['events_to_dispatch']); @@ -1053,7 +1056,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ // Store to container $container->setDefinition($workflowId, $workflowDefinition); - $container->setDefinition(sprintf('%s.definition', $workflowId), $definitionDefinition); + $container->setDefinition(\sprintf('%s.definition', $workflowId), $definitionDefinition); $container->registerAliasForArgument($workflowId, WorkflowInterface::class, $name.'.'.$type); $container->registerAliasForArgument($workflowId, WorkflowInterface::class, $name); @@ -1082,11 +1085,11 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ if ($workflow['audit_trail']['enabled']) { $listener = new Definition(Workflow\EventListener\AuditTrailListener::class); $listener->addTag('monolog.logger', ['channel' => 'workflow']); - $listener->addTag('kernel.event_listener', ['event' => sprintf('workflow.%s.leave', $name), 'method' => 'onLeave']); - $listener->addTag('kernel.event_listener', ['event' => sprintf('workflow.%s.transition', $name), 'method' => 'onTransition']); - $listener->addTag('kernel.event_listener', ['event' => sprintf('workflow.%s.enter', $name), 'method' => 'onEnter']); + $listener->addTag('kernel.event_listener', ['event' => \sprintf('workflow.%s.leave', $name), 'method' => 'onLeave']); + $listener->addTag('kernel.event_listener', ['event' => \sprintf('workflow.%s.transition', $name), 'method' => 'onTransition']); + $listener->addTag('kernel.event_listener', ['event' => \sprintf('workflow.%s.enter', $name), 'method' => 'onEnter']); $listener->addArgument(new Reference('logger')); - $container->setDefinition(sprintf('.%s.listener.audit_trail', $workflowId), $listener); + $container->setDefinition(\sprintf('.%s.listener.audit_trail', $workflowId), $listener); } // Add Guard Listener @@ -1114,7 +1117,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ $guard->addTag('kernel.event_listener', ['event' => $eventName, 'method' => 'onTransition']); } - $container->setDefinition(sprintf('.%s.listener.guard', $workflowId), $guard); + $container->setDefinition(\sprintf('.%s.listener.guard', $workflowId), $guard); $container->setParameter('workflow.has_guard_listeners', true); } } @@ -1134,7 +1137,7 @@ private function registerWorkflowConfiguration(array $config, ContainerBuilder $ $tagAttributes = get_object_vars($attribute); if ($reflector instanceof \ReflectionMethod) { if (isset($tagAttributes['method'])) { - throw new LogicException(sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name)); + throw new LogicException(\sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name)); } $tagAttributes['method'] = $reflector->getName(); } @@ -1330,7 +1333,7 @@ private function registerAssetsConfiguration(array $config, ContainerBuilder $co } } - private function registerAssetMapperConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $assetEnabled): void + private function registerAssetMapperConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $assetEnabled, bool $httpClientEnabled): void { $loader->load('asset_mapper.php'); @@ -1338,10 +1341,16 @@ private function registerAssetMapperConfiguration(array $config, ContainerBuilde $container->removeDefinition('asset_mapper.asset_package'); } + if (!$httpClientEnabled) { + $container->register('asset_mapper.http_client', HttpClientInterface::class) + ->addTag('container.error') + ->addError('You cannot use the AssetMapper integration since the HttpClient component is not enabled. Try enabling the "framework.http_client" config option.'); + } + $paths = $config['paths']; foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) { if ($container->fileExists($dir = $bundle['path'].'/Resources/public') || $container->fileExists($dir = $bundle['path'].'/public')) { - $paths[$dir] = sprintf('bundles/%s', preg_replace('/bundle$/', '', strtolower($name))); + $paths[$dir] = \sprintf('bundles/%s', preg_replace('/bundle$/', '', strtolower($name))); } } $excludedPathPatterns = []; @@ -1507,7 +1516,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder $defaultDir = $container->getParameterBag()->resolveValue($config['default_path']); foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) { if ($container->fileExists($dir = $bundle['path'].'/Resources/translations') || $container->fileExists($dir = $bundle['path'].'/translations')) { - $dirs[] = $dir; + $dirs[] = $transPaths[] = $dir; } else { $nonExistingDirs[] = $dir; } @@ -1517,7 +1526,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder if ($container->fileExists($dir)) { $dirs[] = $transPaths[] = $dir; } else { - throw new \UnexpectedValueException(sprintf('"%s" defined in translator.paths does not exist or is not a directory.', $dir)); + throw new \UnexpectedValueException(\sprintf('"%s" defined in translator.paths does not exist or is not a directory.', $dir)); } } @@ -1601,7 +1610,7 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder foreach ($classToServices as $class => $service) { $package = substr($service, \strlen('translation.provider_factory.')); - if (!$container->hasDefinition('http_client') || !ContainerBuilder::willBeAvailable(sprintf('symfony/%s-translation-provider', $package), $class, $parentPackages)) { + if (!$container->hasDefinition('http_client') || !ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-translation-provider', $package), $class, $parentPackages)) { $container->removeDefinition($service); } } @@ -1614,11 +1623,11 @@ private function registerTranslatorConfiguration(array $config, ContainerBuilder foreach ($config['providers'] as $provider) { if ($provider['locales']) { - $locales += $provider['locales']; + $locales = array_merge($locales, $provider['locales']); } } - $locales = array_unique($locales); + $locales = array_values(array_unique($locales)); $container->getDefinition('console.command.translation_pull') ->replaceArgument(4, array_merge($transPaths, [$config['default_path']])) @@ -1762,11 +1771,11 @@ private function registerMappingFilesFromConfig(ContainerBuilder $container, arr $container->addResource(new DirectoryResource($path, '/^$/')); } elseif ($container->fileExists($path, false)) { if (!preg_match('/\.(xml|ya?ml)$/', $path, $matches)) { - throw new \RuntimeException(sprintf('Unsupported mapping type in "%s", supported types are XML & Yaml.', $path)); + throw new \RuntimeException(\sprintf('Unsupported mapping type in "%s", supported types are XML & Yaml.', $path)); } $fileRecorder($matches[1], $path); } else { - throw new \RuntimeException(sprintf('Could not open file or directory "%s".', $path)); + throw new \RuntimeException(\sprintf('Could not open file or directory "%s".', $path)); } } } @@ -1802,7 +1811,7 @@ private function registerAnnotationsConfiguration(array $config, ContainerBuilde $cacheDir = $container->getParameterBag()->resolveValue($config['file_cache_dir']); if (!is_dir($cacheDir) && false === @mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) { - throw new \RuntimeException(sprintf('Could not create cache directory "%s".', $cacheDir)); + throw new \RuntimeException(\sprintf('Could not create cache directory "%s".', $cacheDir)); } $container @@ -1874,7 +1883,7 @@ private function registerSecretsConfiguration(array $config, ContainerBuilder $c if ($config['decryption_env_var']) { if (!preg_match('/^(?:[-.\w\\\\]*+:)*+\w++$/', $config['decryption_env_var'])) { - throw new InvalidArgumentException(sprintf('Invalid value "%s" set as "decryption_env_var": only "word" characters are allowed.', $config['decryption_env_var'])); + throw new InvalidArgumentException(\sprintf('Invalid value "%s" set as "decryption_env_var": only "word" characters are allowed.', $config['decryption_env_var'])); } if (ContainerBuilder::willBeAvailable('symfony/string', LazyString::class, ['symfony/framework-bundle'])) { @@ -1946,7 +1955,7 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder if (isset($config['enable_attributes']) && $config['enable_attributes']) { $annotationLoader = new Definition( AttributeLoader::class, - [new Reference('annotation_reader', ContainerInterface::NULL_ON_INVALID_REFERENCE)] + interface_exists(CacheableSupportsMethodInterface::class) ? [new Reference('annotation_reader', ContainerInterface::NULL_ON_INVALID_REFERENCE)] : [], ); $serializerLoaders[] = $annotationLoader; @@ -1996,18 +2005,23 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder $container->setParameter('serializer.default_context', $defaultContext); } - if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) { + if ($container->hasDefinition('serializer.normalizer.object')) { $arguments = $container->getDefinition('serializer.normalizer.object')->getArguments(); - $context = ($arguments[6] ?? $defaultContext) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])]; - $container->getDefinition('serializer.normalizer.object')->setArgument(5, null); - $container->getDefinition('serializer.normalizer.object')->setArgument(6, $context); - } + $context = $arguments[6] ?? $defaultContext; + + if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) { + $context += ['circular_reference_handler' => new Reference($config['circular_reference_handler'])]; + $container->getDefinition('serializer.normalizer.object')->setArgument(5, null); + } + + if ($config['max_depth_handler'] ?? false) { + $context += ['max_depth_handler' => new Reference($config['max_depth_handler'])]; + } - if ($config['max_depth_handler'] ?? false) { - $arguments = $container->getDefinition('serializer.normalizer.object')->getArguments(); - $context = ($arguments[6] ?? $defaultContext) + ['max_depth_handler' => new Reference($config['max_depth_handler'])]; $container->getDefinition('serializer.normalizer.object')->setArgument(6, $context); } + + $container->getDefinition('serializer.normalizer.property')->setArgument(5, $defaultContext); } private function registerPropertyInfoConfiguration(ContainerBuilder $container, PhpFileLoader $loader): void @@ -2201,16 +2215,18 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder $defaultMiddleware['after'][0]['arguments'] = [$bus['default_middleware']['allow_no_senders']]; $defaultMiddleware['after'][1]['arguments'] = [$bus['default_middleware']['allow_no_handlers']]; - // argument to add_bus_name_stamp_middleware - $defaultMiddleware['before'][0]['arguments'] = [$busId]; - $middleware = array_merge($defaultMiddleware['before'], $middleware, $defaultMiddleware['after']); } - foreach ($middleware as $middlewareItem) { + foreach ($middleware as $key => $middlewareItem) { if (!$validationEnabled && \in_array($middlewareItem['id'], ['validation', 'messenger.middleware.validation'], true)) { throw new LogicException('The Validation middleware is only available when the Validator component is installed and enabled. Try running "composer require symfony/validator".'); } + + // argument to add_bus_name_stamp_middleware + if ('add_bus_name_stamp_middleware' === $middlewareItem['id']) { + $middleware[$key]['arguments'] = [$busId]; + } } if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class)) { @@ -2245,7 +2261,7 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder $failureTransports = []; if ($config['failure_transport']) { if (!isset($config['transports'][$config['failure_transport']])) { - throw new LogicException(sprintf('Invalid Messenger configuration: the failure transport "%s" is not a valid transport or service id.', $config['failure_transport'])); + throw new LogicException(\sprintf('Invalid Messenger configuration: the failure transport "%s" is not a valid transport or service id.', $config['failure_transport'])); } $container->setAlias('messenger.failure_transports.default', 'messenger.transport.'.$config['failure_transport']); @@ -2267,14 +2283,17 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder $transportRateLimiterReferences = []; foreach ($config['transports'] as $name => $transport) { $serializerId = $transport['serializer'] ?? 'messenger.default_serializer'; + $tags = [ + 'alias' => $name, + 'is_failure_transport' => \in_array($name, $failureTransports), + ]; + if (str_starts_with($transport['dsn'], 'sync://')) { + $tags['is_consumable'] = false; + } $transportDefinition = (new Definition(TransportInterface::class)) ->setFactory([new Reference('messenger.transport_factory'), 'createTransport']) ->setArguments([$transport['dsn'], $transport['options'] + ['transport_name' => $name], new Reference($serializerId)]) - ->addTag('messenger.receiver', [ - 'alias' => $name, - 'is_failure_transport' => \in_array($name, $failureTransports), - ] - ) + ->addTag('messenger.receiver', $tags) ; $container->setDefinition($transportId = 'messenger.transport.'.$name, $transportDefinition); $senderAliases[$name] = $transportId; @@ -2282,7 +2301,7 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder if (null !== $transport['retry_strategy']['service']) { $transportRetryReferences[$name] = new Reference($transport['retry_strategy']['service']); } else { - $retryServiceId = sprintf('messenger.retry.multiplier_retry_strategy.%s', $name); + $retryServiceId = \sprintf('messenger.retry.multiplier_retry_strategy.%s', $name); $retryDefinition = new ChildDefinition('messenger.retry.abstract_multiplier_retry_strategy'); $retryDefinition ->replaceArgument(0, $transport['retry_strategy']['max_retries']) @@ -2316,7 +2335,7 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder foreach ($config['transports'] as $name => $transport) { if ($transport['failure_transport']) { if (!isset($senderReferences[$transport['failure_transport']])) { - throw new LogicException(sprintf('Invalid Messenger configuration: the failure transport "%s" is not a valid transport or service id.', $transport['failure_transport'])); + throw new LogicException(\sprintf('Invalid Messenger configuration: the failure transport "%s" is not a valid transport or service id.', $transport['failure_transport'])); } } } @@ -2327,16 +2346,16 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder foreach ($config['routing'] as $message => $messageConfiguration) { if ('*' !== $message && !class_exists($message) && !interface_exists($message, false) && !preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\\)++\*$/', $message)) { if (str_contains($message, '*')) { - throw new LogicException(sprintf('Invalid Messenger routing configuration: invalid namespace "%s" wildcard.', $message)); + throw new LogicException(\sprintf('Invalid Messenger routing configuration: invalid namespace "%s" wildcard.', $message)); } - throw new LogicException(sprintf('Invalid Messenger routing configuration: class or interface "%s" not found.', $message)); + throw new LogicException(\sprintf('Invalid Messenger routing configuration: class or interface "%s" not found.', $message)); } // make sure senderAliases contains all senders foreach ($messageConfiguration['senders'] as $sender) { if (!isset($senderReferences[$sender])) { - throw new LogicException(sprintf('Invalid Messenger routing configuration: the "%s" class is being routed to a sender called "%s". This is not a valid transport or service id.', $message, $sender)); + throw new LogicException(\sprintf('Invalid Messenger routing configuration: the "%s" class is being routed to a sender called "%s". This is not a valid transport or service id.', $message, $sender)); } } @@ -2537,7 +2556,7 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder foreach ($config['scoped_clients'] as $name => $scopeConfig) { if ($container->has($name)) { - throw new InvalidArgumentException(sprintf('Invalid scope name: "%s" is reserved.', $name)); + throw new InvalidArgumentException(\sprintf('Invalid scope name: "%s" is reserved.', $name)); } $scope = $scopeConfig['scope'] ?? null; @@ -2553,11 +2572,13 @@ private function registerHttpClientConfiguration(array $config, ContainerBuilder ->setFactory([ScopingHttpClient::class, 'forBaseUri']) ->setArguments([new Reference('http_client.transport'), $baseUri, $scopeConfig]) ->addTag('http_client.client') + ->addTag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore']) ; } else { $container->register($name, ScopingHttpClient::class) ->setArguments([new Reference('http_client.transport'), [$scope => $scopeConfig], $scope]) ->addTag('http_client.client') + ->addTag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore']) ; } @@ -2644,7 +2665,6 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co } $transports = $config['dsn'] ? ['main' => $config['dsn']] : $config['transports']; $container->getDefinition('mailer.transports')->setArgument(0, $transports); - $container->getDefinition('mailer.default_transport')->setArgument(0, current($transports)); $mailer = $container->getDefinition('mailer.mailer'); if (false === $messageBus = $config['message_bus']) { @@ -2673,7 +2693,7 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co foreach ($classToServices as $class => $service) { $package = substr($service, \strlen('mailer.transport_factory.')); - if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) { + if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) { $container->removeDefinition($service); } } @@ -2690,7 +2710,7 @@ private function registerMailerConfiguration(array $config, ContainerBuilder $co foreach ($webhookRequestParsers as $class => $service) { $package = substr($service, \strlen('mailer.webhook.request_parser.')); - if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) { + if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) { $container->removeDefinition($service); } } @@ -2753,7 +2773,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ $container->removeDefinition('notifier.channel.email'); } - foreach (['texter', 'chatter', 'notifier.channel.chat', 'notifier.channel.email', 'notifier.channel.sms'] as $serviceId) { + foreach (['texter', 'chatter', 'notifier.channel.chat', 'notifier.channel.email', 'notifier.channel.sms', 'notifier.channel.push'] as $serviceId) { if (!$container->hasDefinition($serviceId)) { continue; } @@ -2800,8 +2820,6 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ NotifierBridge\Engagespot\EngagespotTransportFactory::class => 'notifier.transport_factory.engagespot', NotifierBridge\Esendex\EsendexTransportFactory::class => 'notifier.transport_factory.esendex', NotifierBridge\Expo\ExpoTransportFactory::class => 'notifier.transport_factory.expo', - NotifierBridge\FakeChat\FakeChatTransportFactory::class => 'notifier.transport_factory.fake-chat', - NotifierBridge\FakeSms\FakeSmsTransportFactory::class => 'notifier.transport_factory.fake-sms', NotifierBridge\Firebase\FirebaseTransportFactory::class => 'notifier.transport_factory.firebase', NotifierBridge\FortySixElks\FortySixElksTransportFactory::class => 'notifier.transport_factory.forty-six-elks', NotifierBridge\FreeMobile\FreeMobileTransportFactory::class => 'notifier.transport_factory.free-mobile', @@ -2820,7 +2838,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ NotifierBridge\Mastodon\MastodonTransportFactory::class => 'notifier.transport_factory.mastodon', NotifierBridge\Mattermost\MattermostTransportFactory::class => 'notifier.transport_factory.mattermost', NotifierBridge\Mercure\MercureTransportFactory::class => 'notifier.transport_factory.mercure', - NotifierBridge\MessageBird\MessageBirdTransport::class => 'notifier.transport_factory.message-bird', + NotifierBridge\MessageBird\MessageBirdTransportFactory::class => 'notifier.transport_factory.message-bird', NotifierBridge\MessageMedia\MessageMediaTransportFactory::class => 'notifier.transport_factory.message-media', NotifierBridge\MicrosoftTeams\MicrosoftTeamsTransportFactory::class => 'notifier.transport_factory.microsoft-teams', NotifierBridge\Mobyt\MobytTransportFactory::class => 'notifier.transport_factory.mobyt', @@ -2851,7 +2869,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ NotifierBridge\Telegram\TelegramTransportFactory::class => 'notifier.transport_factory.telegram', NotifierBridge\Telnyx\TelnyxTransportFactory::class => 'notifier.transport_factory.telnyx', NotifierBridge\Termii\TermiiTransportFactory::class => 'notifier.transport_factory.termii', - NotifierBridge\TurboSms\TurboSmsTransport::class => 'notifier.transport_factory.turbo-sms', + NotifierBridge\TurboSms\TurboSmsTransportFactory::class => 'notifier.transport_factory.turbo-sms', NotifierBridge\Twilio\TwilioTransportFactory::class => 'notifier.transport_factory.twilio', NotifierBridge\Twitter\TwitterTransportFactory::class => 'notifier.transport_factory.twitter', NotifierBridge\Vonage\VonageTransportFactory::class => 'notifier.transport_factory.vonage', @@ -2865,34 +2883,40 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ foreach ($classToServices as $class => $service) { $package = substr($service, \strlen('notifier.transport_factory.')); - if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-notifier', $package), $class, $parentPackages)) { + if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-notifier', $package), $class, $parentPackages)) { $container->removeDefinition($service); } } if (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', NotifierBridge\Mercure\MercureTransportFactory::class, $parentPackages) && ContainerBuilder::willBeAvailable('symfony/mercure-bundle', MercureBundle::class, $parentPackages) && \in_array(MercureBundle::class, $container->getParameter('kernel.bundles'), true)) { $container->getDefinition($classToServices[NotifierBridge\Mercure\MercureTransportFactory::class]) - ->replaceArgument('$registry', new Reference(HubRegistry::class)) - ->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) - ->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); + ->replaceArgument(0, new Reference(HubRegistry::class)) + ->replaceArgument(1, new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); } elseif (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', NotifierBridge\Mercure\MercureTransportFactory::class, $parentPackages)) { $container->removeDefinition($classToServices[NotifierBridge\Mercure\MercureTransportFactory::class]); } - if (ContainerBuilder::willBeAvailable('symfony/fake-chat-notifier', NotifierBridge\FakeChat\FakeChatTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) { - $container->getDefinition($classToServices[NotifierBridge\FakeChat\FakeChatTransportFactory::class]) - ->replaceArgument('$mailer', new Reference('mailer')) - ->replaceArgument('$logger', new Reference('logger')) - ->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) - ->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); + // don't use ContainerBuilder::willBeAvailable() as these are not needed in production + if (class_exists(FakeChatTransportFactory::class)) { + $container->getDefinition('notifier.transport_factory.fake-chat') + ->replaceArgument(0, new Reference('mailer', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->replaceArgument(1, new Reference('logger', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->addArgument(new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); + } else { + $container->removeDefinition('notifier.transport_factory.fake-chat'); } - if (ContainerBuilder::willBeAvailable('symfony/fake-sms-notifier', NotifierBridge\FakeSms\FakeSmsTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) { - $container->getDefinition($classToServices[NotifierBridge\FakeSms\FakeSmsTransportFactory::class]) - ->replaceArgument('$mailer', new Reference('mailer')) - ->replaceArgument('$logger', new Reference('logger')) - ->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) - ->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); + // don't use ContainerBuilder::willBeAvailable() as these are not needed in production + if (class_exists(FakeSmsTransportFactory::class)) { + $container->getDefinition('notifier.transport_factory.fake-sms') + ->replaceArgument(0, new Reference('mailer', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->replaceArgument(1, new Reference('logger', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->addArgument(new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE)) + ->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE)); + } else { + $container->removeDefinition('notifier.transport_factory.fake-sms'); } if (isset($config['admin_recipients'])) { @@ -2915,7 +2939,7 @@ private function registerNotifierConfiguration(array $config, ContainerBuilder $ foreach ($webhookRequestParsers as $class => $service) { $package = substr($service, \strlen('notifier.webhook.request_parser.')); - if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-notifier', $package), $class, ['symfony/framework-bundle', 'symfony/notifier'])) { + if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-notifier', $package), $class, ['symfony/framework-bundle', 'symfony/notifier'])) { $container->removeDefinition($service); } } @@ -2964,11 +2988,11 @@ private function registerRateLimiterConfiguration(array $config, ContainerBuilde if (null !== $limiterConfig['lock_factory']) { if (!interface_exists(LockInterface::class)) { - throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name)); + throw new LogicException(\sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name)); } if (!$this->isInitializedConfigEnabled('lock')) { - throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name)); + throw new LogicException(\sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name)); } $limiter->replaceArgument(2, new Reference($limiterConfig['lock_factory'])); @@ -3005,10 +3029,10 @@ public static function registerRateLimiter(ContainerBuilder $container, string $ if (null !== $limiterConfig['lock_factory']) { if (!interface_exists(LockInterface::class)) { - throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name)); + throw new LogicException(\sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name)); } if (!$container->hasDefinition('lock.factory.abstract')) { - throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name)); + throw new LogicException(\sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name)); } $limiter->replaceArgument(2, new Reference($limiterConfig['lock_factory'])); @@ -3173,7 +3197,7 @@ private function isInitializedConfigEnabled(string $path): bool return $this->configsEnabled[$path]; } - throw new LogicException(sprintf('Can not read config enabled at "%s" because it has not been initialized.', $path)); + throw new LogicException(\sprintf('Can not read config enabled at "%s" because it has not been initialized.', $path)); } private function readConfigEnabled(string $path, ContainerBuilder $container, array $config): bool diff --git a/lib/symfony/framework-bundle/EventListener/ConsoleProfilerListener.php b/lib/symfony/framework-bundle/EventListener/ConsoleProfilerListener.php index c2a71d0a7c..15318d9796 100644 --- a/lib/symfony/framework-bundle/EventListener/ConsoleProfilerListener.php +++ b/lib/symfony/framework-bundle/EventListener/ConsoleProfilerListener.php @@ -38,6 +38,8 @@ final class ConsoleProfilerListener implements EventSubscriberInterface /** @var \SplObjectStorage */ private \SplObjectStorage $parents; + private bool $disabled = false; + public function __construct( private readonly Profiler $profiler, private readonly RequestStack $requestStack, @@ -66,7 +68,7 @@ public function initialize(ConsoleCommandEvent $event): void $input = $event->getInput(); if (!$input->hasOption('profile') || !$input->getOption('profile')) { - $this->profiler->disable(); + $this->disabled = true; return; } @@ -92,7 +94,12 @@ public function catch(ConsoleErrorEvent $event): void public function profile(ConsoleTerminateEvent $event): void { - if (!$this->cliMode || !$this->profiler->isEnabled()) { + $error = $this->error; + $this->error = null; + + if (!$this->cliMode || $this->disabled) { + $this->disabled = false; + return; } @@ -102,6 +109,10 @@ public function profile(ConsoleTerminateEvent $event): void return; } + if (!$this->profiler->isEnabled()) { + return; + } + if (null !== $sectionId = $request->attributes->get('_stopwatch_token')) { // we must close the section before saving the profile to allow late collect try { @@ -114,8 +125,7 @@ public function profile(ConsoleTerminateEvent $event): void $request->command->exitCode = $event->getExitCode(); $request->command->interruptedBySignal = $event->getInterruptingSignal(); - $profile = $this->profiler->collect($request, $request->getResponse(), $this->error); - $this->error = null; + $profile = $this->profiler->collect($request, $request->getResponse(), $error); $this->profiles[$request] = $profile; if ($this->parents[$request] = $this->requestStack->getParentRequest()) { @@ -142,7 +152,7 @@ public function profile(ConsoleTerminateEvent $event): void if ($this->urlGenerator && $output) { $token = $p->getToken(); - $output->writeln(sprintf( + $output->writeln(\sprintf( 'See profile %s', $this->urlGenerator->generate('_profiler', ['token' => $token], UrlGeneratorInterface::ABSOLUTE_URL), $token diff --git a/lib/symfony/framework-bundle/EventListener/SuggestMissingPackageSubscriber.php b/lib/symfony/framework-bundle/EventListener/SuggestMissingPackageSubscriber.php index d7bdc8e668..a5a0d5d631 100644 --- a/lib/symfony/framework-bundle/EventListener/SuggestMissingPackageSubscriber.php +++ b/lib/symfony/framework-bundle/EventListener/SuggestMissingPackageSubscriber.php @@ -66,7 +66,7 @@ public function onConsoleError(ConsoleErrorEvent $event): void return; } - $message = sprintf("%s\n\nYou may be looking for a command provided by the \"%s\" which is currently not installed. Try running \"composer require %s\".", $error->getMessage(), $suggestion[0], $suggestion[1]); + $message = \sprintf("%s\n\nYou may be looking for a command provided by the \"%s\" which is currently not installed. Try running \"composer require %s\".", $error->getMessage(), $suggestion[0], $suggestion[1]); $event->setError(new CommandNotFoundException($message)); } diff --git a/lib/symfony/framework-bundle/FrameworkBundle.php b/lib/symfony/framework-bundle/FrameworkBundle.php index 4ba30a5c8e..c371d10dbc 100644 --- a/lib/symfony/framework-bundle/FrameworkBundle.php +++ b/lib/symfony/framework-bundle/FrameworkBundle.php @@ -20,6 +20,7 @@ use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\RemoveUnusedSessionMarshallingHandlerPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerRealRefPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TestServiceContainerWeakRefPass; +use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\TranslationUpdateCommandPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler\UnusedTagsPass; use Symfony\Bundle\FrameworkBundle\DependencyInjection\VirtualRequestStackPass; use Symfony\Component\Cache\Adapter\ApcuAdapter; @@ -58,6 +59,7 @@ use Symfony\Component\PropertyInfo\DependencyInjection\PropertyInfoPass; use Symfony\Component\Routing\DependencyInjection\AddExpressionLanguageProvidersPass; use Symfony\Component\Routing\DependencyInjection\RoutingResolverPass; +use Symfony\Component\Runtime\SymfonyRuntime; use Symfony\Component\Scheduler\DependencyInjection\AddScheduleMessengerPass; use Symfony\Component\Serializer\DependencyInjection\SerializerPass; use Symfony\Component\Translation\DependencyInjection\DataCollectorTranslatorPass; @@ -99,13 +101,19 @@ public function boot() { $_ENV['DOCTRINE_DEPRECATIONS'] = $_SERVER['DOCTRINE_DEPRECATIONS'] ??= 'trigger'; - $handler = ErrorHandler::register(null, false); + if (class_exists(SymfonyRuntime::class)) { + $handler = set_error_handler('var_dump'); + restore_error_handler(); + } else { + $handler = [ErrorHandler::register(null, false)]; + } - // When upgrading an existing Symfony application from 6.2 to 6.3, and - // the cache is warmed up, the service is not available yet, so we need - // to check if it exists. - if ($this->container->has('debug.error_handler_configurator')) { - $this->container->get('debug.error_handler_configurator')->configure($handler); + if (!$this->container->has('debug.error_handler_configurator')) { + // When upgrading an existing Symfony application from 6.2 to 6.3, and + // the cache is warmed up, the service is not available yet, so we need + // to check if it exists. + } elseif (\is_array($handler) && $handler[0] instanceof ErrorHandler) { + $this->container->get('debug.error_handler_configurator')->configure($handler[0]); } if ($this->container->getParameter('kernel.http_method_override')) { @@ -186,6 +194,7 @@ public function build(ContainerBuilder $container) // must be registered after MonologBundle's LoggerChannelPass $container->addCompilerPass(new ErrorLoggerCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -32); $container->addCompilerPass(new VirtualRequestStackPass()); + $container->addCompilerPass(new TranslationUpdateCommandPass(), PassConfig::TYPE_BEFORE_REMOVING); if ($container->getParameter('kernel.debug')) { $container->addCompilerPass(new AddDebugLogProcessorPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 2); diff --git a/lib/symfony/framework-bundle/HttpCache/HttpCache.php b/lib/symfony/framework-bundle/HttpCache/HttpCache.php index f312a7afe4..481e8cf3ce 100644 --- a/lib/symfony/framework-bundle/HttpCache/HttpCache.php +++ b/lib/symfony/framework-bundle/HttpCache/HttpCache.php @@ -37,7 +37,7 @@ class HttpCache extends BaseHttpCache /** * @param $cache The cache directory (default used if null) or the storage instance */ - public function __construct(KernelInterface $kernel, string|StoreInterface $cache = null, SurrogateInterface $surrogate = null, array $options = null) + public function __construct(KernelInterface $kernel, string|StoreInterface|null $cache = null, ?SurrogateInterface $surrogate = null, ?array $options = null) { $this->kernel = $kernel; $this->surrogate = $surrogate; @@ -60,7 +60,7 @@ public function __construct(KernelInterface $kernel, string|StoreInterface $cach parent::__construct($kernel, $this->createStore(), $this->createSurrogate(), array_merge($this->options, $this->getOptions())); } - protected function forward(Request $request, bool $catch = false, Response $entry = null): Response + protected function forward(Request $request, bool $catch = false, ?Response $entry = null): Response { $this->getKernel()->boot(); $this->getKernel()->getContainer()->set('cache', $this); diff --git a/lib/symfony/framework-bundle/Kernel/MicroKernelTrait.php b/lib/symfony/framework-bundle/Kernel/MicroKernelTrait.php index bbbfd5426e..dd6f4eeff3 100644 --- a/lib/symfony/framework-bundle/Kernel/MicroKernelTrait.php +++ b/lib/symfony/framework-bundle/Kernel/MicroKernelTrait.php @@ -178,7 +178,7 @@ public function registerContainerConfiguration(LoaderInterface $loader) } $file = (new \ReflectionObject($this))->getFileName(); - /* @var ContainerPhpFileLoader $kernelLoader */ + /** @var ContainerPhpFileLoader $kernelLoader */ $kernelLoader = $loader->getResolver()->resolve($file); $kernelLoader->setCurrentDir(\dirname($file)); $instanceof = &\Closure::bind(fn &() => $this->instanceof, $kernelLoader, $kernelLoader)(); @@ -204,7 +204,7 @@ public function registerContainerConfiguration(LoaderInterface $loader) public function loadRoutes(LoaderInterface $loader): RouteCollection { $file = (new \ReflectionObject($this))->getFileName(); - /* @var RoutingPhpFileLoader $kernelLoader */ + /** @var RoutingPhpFileLoader $kernelLoader */ $kernelLoader = $loader->getResolver()->resolve($file, 'php'); $kernelLoader->setCurrentDir(\dirname($file)); $collection = new RouteCollection(); @@ -217,7 +217,7 @@ public function loadRoutes(LoaderInterface $loader): RouteCollection if (\is_array($controller) && [0, 1] === array_keys($controller) && $this === $controller[0]) { $route->setDefault('_controller', ['kernel', $controller[1]]); - } elseif ($controller instanceof \Closure && $this === ($r = new \ReflectionFunction($controller))->getClosureThis() && !str_contains($r->name, '{closure}')) { + } elseif ($controller instanceof \Closure && $this === ($r = new \ReflectionFunction($controller))->getClosureThis() && !str_contains($r->name, '{closure')) { $route->setDefault('_controller', ['kernel', $r->name]); } } diff --git a/lib/symfony/framework-bundle/KernelBrowser.php b/lib/symfony/framework-bundle/KernelBrowser.php index 45120e42b5..cf1d1652fe 100644 --- a/lib/symfony/framework-bundle/KernelBrowser.php +++ b/lib/symfony/framework-bundle/KernelBrowser.php @@ -34,7 +34,7 @@ class KernelBrowser extends HttpKernelBrowser private bool $profiler = false; private bool $reboot = true; - public function __construct(KernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null) + public function __construct(KernelInterface $kernel, array $server = [], ?History $history = null, ?CookieJar $cookieJar = null) { parent::__construct($kernel, $server, $history, $cookieJar); } @@ -117,11 +117,11 @@ public function loginUser(object $user, string $firewallContext = 'main'/* , arr $tokenAttributes = 2 < \func_num_args() ? func_get_arg(2) : []; if (!interface_exists(UserInterface::class)) { - throw new \LogicException(sprintf('"%s" requires symfony/security-core to be installed. Try running "composer require symfony/security-core".', __METHOD__)); + throw new \LogicException(\sprintf('"%s" requires symfony/security-core to be installed. Try running "composer require symfony/security-core".', __METHOD__)); } if (!$user instanceof UserInterface) { - throw new \LogicException(sprintf('The first argument of "%s" must be instance of "%s", "%s" provided.', __METHOD__, UserInterface::class, get_debug_type($user))); + throw new \LogicException(\sprintf('The first argument of "%s" must be instance of "%s", "%s" provided.', __METHOD__, UserInterface::class, get_debug_type($user))); } $token = new TestBrowserToken($user->getRoles(), $user, $firewallContext); diff --git a/lib/symfony/framework-bundle/README.md b/lib/symfony/framework-bundle/README.md index 14c600facf..220d72a8a1 100644 --- a/lib/symfony/framework-bundle/README.md +++ b/lib/symfony/framework-bundle/README.md @@ -17,4 +17,4 @@ Resources [send Pull Requests](https://github.com/symfony/symfony/pulls) in the [main Symfony repository](https://github.com/symfony/symfony) -[3]: https://symfony.com/sponsor +[1]: https://symfony.com/sponsor diff --git a/lib/symfony/framework-bundle/Resources/config/asset_mapper.php b/lib/symfony/framework-bundle/Resources/config/asset_mapper.php index f41574d3b5..404e7af18d 100644 --- a/lib/symfony/framework-bundle/Resources/config/asset_mapper.php +++ b/lib/symfony/framework-bundle/Resources/config/asset_mapper.php @@ -54,6 +54,8 @@ ]) ->alias(AssetMapperInterface::class, 'asset_mapper') + ->alias('asset_mapper.http_client', 'http_client') + ->set('asset_mapper.mapped_asset_factory', MappedAssetFactory::class) ->args([ service('asset_mapper.public_assets_path_resolver'), @@ -75,6 +77,7 @@ param('kernel.project_dir'), abstract_arg('array of excluded path patterns'), abstract_arg('exclude dot files'), + param('kernel.debug'), ]) ->set('asset_mapper.public_assets_path_resolver', PublicAssetsPathResolver::class) @@ -196,7 +199,7 @@ ]) ->set('asset_mapper.importmap.resolver', JsDelivrEsmResolver::class) - ->args([service('http_client')]) + ->args([service('asset_mapper.http_client')]) ->set('asset_mapper.importmap.renderer', ImportMapRenderer::class) ->args([ @@ -211,12 +214,12 @@ ->set('asset_mapper.importmap.auditor', ImportMapAuditor::class) ->args([ service('asset_mapper.importmap.config_reader'), - service('http_client'), + service('asset_mapper.http_client'), ]) ->set('asset_mapper.importmap.update_checker', ImportMapUpdateChecker::class) ->args([ service('asset_mapper.importmap.config_reader'), - service('http_client'), + service('asset_mapper.http_client'), ]) ->set('asset_mapper.importmap.command.require', ImportMapRequireCommand::class) diff --git a/lib/symfony/framework-bundle/Resources/config/cache.php b/lib/symfony/framework-bundle/Resources/config/cache.php index 87207cf95c..8cb1a95f62 100644 --- a/lib/symfony/framework-bundle/Resources/config/cache.php +++ b/lib/symfony/framework-bundle/Resources/config/cache.php @@ -88,7 +88,7 @@ '', // namespace 0, // default lifetime abstract_arg('version'), - sprintf('%s/pools/system', param('kernel.cache_dir')), + \sprintf('%s/pools/system', param('kernel.cache_dir')), service('logger')->ignoreOnInvalid(), ]) ->tag('cache.pool', ['clearer' => 'cache.system_clearer', 'reset' => 'reset']) @@ -110,7 +110,7 @@ ->args([ '', // namespace 0, // default lifetime - sprintf('%s/pools/app', param('kernel.cache_dir')), + \sprintf('%s/pools/app', param('kernel.cache_dir')), service('cache.default_marshaller')->ignoreOnInvalid(), ]) ->call('setLogger', [service('logger')->ignoreOnInvalid()]) diff --git a/lib/symfony/framework-bundle/Resources/config/collectors.php b/lib/symfony/framework-bundle/Resources/config/collectors.php index aa6d4e33c3..954ddeffa8 100644 --- a/lib/symfony/framework-bundle/Resources/config/collectors.php +++ b/lib/symfony/framework-bundle/Resources/config/collectors.php @@ -56,7 +56,7 @@ ->set('data_collector.logger', LoggerDataCollector::class) ->args([ service('logger')->ignoreOnInvalid(), - sprintf('%s/%s', param('kernel.build_dir'), param('kernel.container_class')), + \sprintf('%s/%s', param('kernel.build_dir'), param('kernel.container_class')), service('.virtual_request_stack')->ignoreOnInvalid(), ]) ->tag('monolog.logger', ['channel' => 'profiler']) diff --git a/lib/symfony/framework-bundle/Resources/config/http_client.php b/lib/symfony/framework-bundle/Resources/config/http_client.php index a4c78d0ec2..593b78fdd5 100644 --- a/lib/symfony/framework-bundle/Resources/config/http_client.php +++ b/lib/symfony/framework-bundle/Resources/config/http_client.php @@ -39,6 +39,7 @@ ->factory('current') ->args([[service('http_client.transport')]]) ->tag('http_client.client') + ->tag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore']) ->alias(HttpClientInterface::class, 'http_client') diff --git a/lib/symfony/framework-bundle/Resources/config/mailer.php b/lib/symfony/framework-bundle/Resources/config/mailer.php index 9eb545ca26..f1dc560ab7 100644 --- a/lib/symfony/framework-bundle/Resources/config/mailer.php +++ b/lib/symfony/framework-bundle/Resources/config/mailer.php @@ -45,11 +45,7 @@ tagged_iterator('mailer.transport_factory'), ]) - ->set('mailer.default_transport', TransportInterface::class) - ->factory([service('mailer.transport_factory'), 'fromString']) - ->args([ - abstract_arg('env(MAILER_DSN)'), - ]) + ->alias('mailer.default_transport', 'mailer.transports') ->alias(TransportInterface::class, 'mailer.default_transport') ->set('mailer.messenger.message_handler', MessageHandler::class) diff --git a/lib/symfony/framework-bundle/Resources/config/notifier.php b/lib/symfony/framework-bundle/Resources/config/notifier.php index 6ce674148a..bcc1248208 100644 --- a/lib/symfony/framework-bundle/Resources/config/notifier.php +++ b/lib/symfony/framework-bundle/Resources/config/notifier.php @@ -73,7 +73,10 @@ ->tag('notifier.channel', ['channel' => 'email']) ->set('notifier.channel.push', PushChannel::class) - ->args([service('texter.transports'), service('messenger.default_bus')->ignoreOnInvalid()]) + ->args([ + service('texter.transports'), + abstract_arg('message bus'), + ]) ->tag('notifier.channel', ['channel' => 'push']) ->set('notifier.monolog_handler', NotifierHandler::class) diff --git a/lib/symfony/framework-bundle/Resources/config/profiling.php b/lib/symfony/framework-bundle/Resources/config/profiling.php index eaef795977..4ae34649b4 100644 --- a/lib/symfony/framework-bundle/Resources/config/profiling.php +++ b/lib/symfony/framework-bundle/Resources/config/profiling.php @@ -40,7 +40,7 @@ ->set('console_profiler_listener', ConsoleProfilerListener::class) ->args([ - service('profiler'), + service('.lazy_profiler'), service('.virtual_request_stack'), service('debug.stopwatch'), param('kernel.runtime_mode.cli'), @@ -48,6 +48,11 @@ ]) ->tag('kernel.event_subscriber') + ->set('.lazy_profiler', Profiler::class) + ->factory('current') + ->args([[service('profiler')]]) + ->lazy() + ->set('.virtual_request_stack', VirtualRequestStack::class) ->args([service('request_stack')]) ->public() diff --git a/lib/symfony/framework-bundle/Resources/config/schema/symfony-1.0.xsd b/lib/symfony/framework-bundle/Resources/config/schema/symfony-1.0.xsd index ffa47c3845..4a650af6bc 100644 --- a/lib/symfony/framework-bundle/Resources/config/schema/symfony-1.0.xsd +++ b/lib/symfony/framework-bundle/Resources/config/schema/symfony-1.0.xsd @@ -266,6 +266,7 @@ + @@ -294,11 +295,17 @@ + + + + + + @@ -464,7 +471,8 @@ - + + @@ -551,7 +559,7 @@ - + @@ -781,7 +789,7 @@ - + diff --git a/lib/symfony/framework-bundle/Resources/config/serializer.php b/lib/symfony/framework-bundle/Resources/config/serializer.php index 2311df0fcf..c29258d527 100644 --- a/lib/symfony/framework-bundle/Resources/config/serializer.php +++ b/lib/symfony/framework-bundle/Resources/config/serializer.php @@ -60,7 +60,7 @@ $container->services() ->set('serializer', Serializer::class) - ->args([[], []]) + ->args([[], [], []]) ->alias(SerializerInterface::class, 'serializer') ->alias(NormalizerInterface::class, 'serializer') @@ -116,7 +116,7 @@ ->set('serializer.normalizer.translatable', TranslatableNormalizer::class) ->args(['$translator' => service('translator')]) - ->tag('serializer.normalizer', ['priority' => -890]) + ->tag('serializer.normalizer', ['priority' => -920]) ->set('serializer.normalizer.form_error', FormErrorNormalizer::class) ->tag('serializer.normalizer', ['priority' => -915]) @@ -129,6 +129,8 @@ service('property_info')->ignoreOnInvalid(), service('serializer.mapping.class_discriminator_resolver')->ignoreOnInvalid(), null, + null, + service('property_info')->ignoreOnInvalid(), ]) ->tag('serializer.normalizer', ['priority' => -1000]) diff --git a/lib/symfony/framework-bundle/Resources/config/services.php b/lib/symfony/framework-bundle/Resources/config/services.php index 905e16f9b9..78daa3b875 100644 --- a/lib/symfony/framework-bundle/Resources/config/services.php +++ b/lib/symfony/framework-bundle/Resources/config/services.php @@ -100,6 +100,7 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : [] ->alias(HttpKernelInterface::class, 'http_kernel') ->set('request_stack', RequestStack::class) + ->tag('kernel.reset', ['method' => 'resetRequestFormats', 'on_invalid' => 'ignore']) ->public() ->alias(RequestStack::class, 'request_stack') @@ -130,7 +131,7 @@ class_exists(WorkflowEvents::class) ? WorkflowEvents::ALIASES : [] ->args([ tagged_iterator('kernel.cache_warmer'), param('kernel.debug'), - sprintf('%s/%sDeprecations.log', param('kernel.build_dir'), param('kernel.container_class')), + \sprintf('%s/%sDeprecations.log', param('kernel.build_dir'), param('kernel.container_class')), ]) ->tag('container.no_preload') diff --git a/lib/symfony/framework-bundle/Resources/config/session.php b/lib/symfony/framework-bundle/Resources/config/session.php index 907b1b5844..2e481359aa 100644 --- a/lib/symfony/framework-bundle/Resources/config/session.php +++ b/lib/symfony/framework-bundle/Resources/config/session.php @@ -90,6 +90,7 @@ 'session_factory' => service('session.factory')->ignoreOnInvalid(), 'logger' => service('logger')->ignoreOnInvalid(), 'session_collector' => service('data_collector.request.session_collector')->ignoreOnInvalid(), + 'request_stack' => service('request_stack')->ignoreOnInvalid(), ]), param('kernel.debug'), param('session.storage.options'), diff --git a/lib/symfony/framework-bundle/Routing/Attribute/AsRoutingConditionService.php b/lib/symfony/framework-bundle/Routing/Attribute/AsRoutingConditionService.php index d1f1a5f34a..13f8ff26a2 100644 --- a/lib/symfony/framework-bundle/Routing/Attribute/AsRoutingConditionService.php +++ b/lib/symfony/framework-bundle/Routing/Attribute/AsRoutingConditionService.php @@ -42,7 +42,7 @@ class AsRoutingConditionService extends AutoconfigureTag { public function __construct( - string $alias = null, + ?string $alias = null, int $priority = 0, ) { parent::__construct('routing.condition_service', ['alias' => $alias, 'priority' => $priority]); diff --git a/lib/symfony/framework-bundle/Routing/DelegatingLoader.php b/lib/symfony/framework-bundle/Routing/DelegatingLoader.php index df7e9348c3..3239d1094b 100644 --- a/lib/symfony/framework-bundle/Routing/DelegatingLoader.php +++ b/lib/symfony/framework-bundle/Routing/DelegatingLoader.php @@ -40,7 +40,7 @@ public function __construct(LoaderResolverInterface $resolver, array $defaultOpt parent::__construct($resolver); } - public function load(mixed $resource, string $type = null): RouteCollection + public function load(mixed $resource, ?string $type = null): RouteCollection { if ($this->loading) { // This can happen if a fatal error occurs in parent::load(). diff --git a/lib/symfony/framework-bundle/Routing/RedirectableCompiledUrlMatcher.php b/lib/symfony/framework-bundle/Routing/RedirectableCompiledUrlMatcher.php index 538427aae6..609502bcaf 100644 --- a/lib/symfony/framework-bundle/Routing/RedirectableCompiledUrlMatcher.php +++ b/lib/symfony/framework-bundle/Routing/RedirectableCompiledUrlMatcher.php @@ -21,7 +21,7 @@ */ class RedirectableCompiledUrlMatcher extends CompiledUrlMatcher implements RedirectableUrlMatcherInterface { - public function redirect(string $path, string $route, string $scheme = null): array + public function redirect(string $path, string $route, ?string $scheme = null): array { return [ '_controller' => 'Symfony\\Bundle\\FrameworkBundle\\Controller\\RedirectController::urlRedirectAction', diff --git a/lib/symfony/framework-bundle/Routing/Router.php b/lib/symfony/framework-bundle/Routing/Router.php index 3367ecec2b..ac6cb03a39 100644 --- a/lib/symfony/framework-bundle/Routing/Router.php +++ b/lib/symfony/framework-bundle/Routing/Router.php @@ -40,7 +40,7 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI /** * @param mixed $resource The main resource to load */ - public function __construct(ContainerInterface $container, mixed $resource, array $options = [], RequestContext $context = null, ContainerInterface $parameters = null, LoggerInterface $logger = null, string $defaultLocale = null) + public function __construct(ContainerInterface $container, mixed $resource, array $options = [], ?RequestContext $context = null, ?ContainerInterface $parameters = null, ?LoggerInterface $logger = null, ?string $defaultLocale = null) { $this->container = $container; $this->resource = $resource; @@ -53,7 +53,7 @@ public function __construct(ContainerInterface $container, mixed $resource, arra } elseif ($container instanceof SymfonyContainerInterface) { $this->paramFetcher = $container->getParameter(...); } else { - throw new \LogicException(sprintf('You should either pass a "%s" instance or provide the $parameters argument of the "%s" method.', SymfonyContainerInterface::class, __METHOD__)); + throw new \LogicException(\sprintf('You should either pass a "%s" instance or provide the $parameters argument of the "%s" method.', SymfonyContainerInterface::class, __METHOD__)); } $this->defaultLocale = $defaultLocale; @@ -165,7 +165,7 @@ private function resolve(mixed $value): mixed } if (preg_match('/^env\((?:\w++:)*+\w++\)$/', $match[1])) { - throw new RuntimeException(sprintf('Using "%%%s%%" is not allowed in routing configuration.', $match[1])); + throw new RuntimeException(\sprintf('Using "%%%s%%" is not allowed in routing configuration.', $match[1])); } $resolved = ($this->paramFetcher)($match[1]); @@ -182,7 +182,7 @@ private function resolve(mixed $value): mixed } } - throw new RuntimeException(sprintf('The container parameter "%s", used in the route configuration value "%s", must be a string or numeric, but it is of type "%s".', $match[1], $value, get_debug_type($resolved))); + throw new RuntimeException(\sprintf('The container parameter "%s", used in the route configuration value "%s", must be a string or numeric, but it is of type "%s".', $match[1], $value, get_debug_type($resolved))); }, $value); return str_replace('%%', '%', $escapedValue); diff --git a/lib/symfony/framework-bundle/Secrets/AbstractVault.php b/lib/symfony/framework-bundle/Secrets/AbstractVault.php index b3eb0c6bc3..1324b14095 100644 --- a/lib/symfony/framework-bundle/Secrets/AbstractVault.php +++ b/lib/symfony/framework-bundle/Secrets/AbstractVault.php @@ -36,7 +36,7 @@ abstract public function list(bool $reveal = false): array; protected function validateName(string $name): void { if (!preg_match('/^\w++$/D', $name)) { - throw new \LogicException(sprintf('Invalid secret name "%s": only "word" characters are allowed.', $name)); + throw new \LogicException(\sprintf('Invalid secret name "%s": only "word" characters are allowed.', $name)); } } diff --git a/lib/symfony/framework-bundle/Secrets/DotenvVault.php b/lib/symfony/framework-bundle/Secrets/DotenvVault.php index 994b31d18b..c1f08e9774 100644 --- a/lib/symfony/framework-bundle/Secrets/DotenvVault.php +++ b/lib/symfony/framework-bundle/Secrets/DotenvVault.php @@ -45,7 +45,7 @@ public function seal(string $name, string $value): void file_put_contents($this->dotenvFile, $content); - $this->lastMessage = sprintf('Secret "%s" %s in "%s".', $name, $count ? 'added' : 'updated', $this->getPrettyPath($this->dotenvFile)); + $this->lastMessage = \sprintf('Secret "%s" %s in "%s".', $name, $count ? 'added' : 'updated', $this->getPrettyPath($this->dotenvFile)); } public function reveal(string $name): ?string @@ -55,7 +55,7 @@ public function reveal(string $name): ?string $v = $_ENV[$name] ?? (str_starts_with($name, 'HTTP_') ? null : ($_SERVER[$name] ?? null)); if ('' === ($v ?? '')) { - $this->lastMessage = sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath($this->dotenvFile)); + $this->lastMessage = \sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath($this->dotenvFile)); return null; } @@ -73,12 +73,12 @@ public function remove(string $name): bool if ($count) { file_put_contents($this->dotenvFile, $content); - $this->lastMessage = sprintf('Secret "%s" removed from file "%s".', $name, $this->getPrettyPath($this->dotenvFile)); + $this->lastMessage = \sprintf('Secret "%s" removed from file "%s".', $name, $this->getPrettyPath($this->dotenvFile)); return true; } - $this->lastMessage = sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath($this->dotenvFile)); + $this->lastMessage = \sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath($this->dotenvFile)); return false; } diff --git a/lib/symfony/framework-bundle/Secrets/SodiumVault.php b/lib/symfony/framework-bundle/Secrets/SodiumVault.php index b6bb058b3f..1aa03ac519 100644 --- a/lib/symfony/framework-bundle/Secrets/SodiumVault.php +++ b/lib/symfony/framework-bundle/Secrets/SodiumVault.php @@ -12,6 +12,7 @@ namespace Symfony\Bundle\FrameworkBundle\Secrets; use Symfony\Component\DependencyInjection\EnvVarLoaderInterface; +use Symfony\Component\String\LazyString; use Symfony\Component\VarExporter\VarExporter; /** @@ -30,7 +31,7 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface * @param $decryptionKey A string or a stringable object that defines the private key to use to decrypt the vault * or null to store generated keys in the provided $secretsDir */ - public function __construct(string $secretsDir, #[\SensitiveParameter] string|\Stringable $decryptionKey = null) + public function __construct(string $secretsDir, #[\SensitiveParameter] string|\Stringable|null $decryptionKey = null) { $this->pathPrefix = rtrim(strtr($secretsDir, '/', \DIRECTORY_SEPARATOR), \DIRECTORY_SEPARATOR).\DIRECTORY_SEPARATOR.basename($secretsDir).'.'; $this->decryptionKey = $decryptionKey; @@ -58,7 +59,7 @@ public function generateKeys(bool $override = false): bool } if (!$override && null !== $this->encryptionKey) { - $this->lastMessage = sprintf('Sodium keys already exist at "%s*.{public,private}" and won\'t be overridden.', $this->getPrettyPath($this->pathPrefix)); + $this->lastMessage = \sprintf('Sodium keys already exist at "%s*.{public,private}" and won\'t be overridden.', $this->getPrettyPath($this->pathPrefix)); return false; } @@ -69,7 +70,7 @@ public function generateKeys(bool $override = false): bool $this->export('encrypt.public', $this->encryptionKey); $this->export('decrypt.private', $this->decryptionKey); - $this->lastMessage = sprintf('Sodium keys have been generated at "%s*.public/private.php".', $this->getPrettyPath($this->pathPrefix)); + $this->lastMessage = \sprintf('Sodium keys have been generated at "%s*.public/private.php".', $this->getPrettyPath($this->pathPrefix)); return true; } @@ -85,9 +86,9 @@ public function seal(string $name, string $value): void $list = $this->list(); $list[$name] = null; uksort($list, 'strnatcmp'); - file_put_contents($this->pathPrefix.'list.php', sprintf("pathPrefix.'list.php', \sprintf("lastMessage = sprintf('Secret "%s" encrypted in "%s"; you can commit it.', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); + $this->lastMessage = \sprintf('Secret "%s" encrypted in "%s"; you can commit it.', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); } public function reveal(string $name): ?string @@ -97,13 +98,13 @@ public function reveal(string $name): ?string $filename = $this->getFilename($name); if (!is_file($file = $this->pathPrefix.$filename.'.php')) { - $this->lastMessage = sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); + $this->lastMessage = \sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); return null; } if (!\function_exists('sodium_crypto_box_seal')) { - $this->lastMessage = sprintf('Secret "%s" cannot be revealed as the "sodium" PHP extension missing. Try running "composer require paragonie/sodium_compat" if you cannot enable the extension."', $name); + $this->lastMessage = \sprintf('Secret "%s" cannot be revealed as the "sodium" PHP extension missing. Try running "composer require paragonie/sodium_compat" if you cannot enable the extension."', $name); return null; } @@ -111,13 +112,13 @@ public function reveal(string $name): ?string $this->loadKeys(); if ('' === $this->decryptionKey) { - $this->lastMessage = sprintf('Secret "%s" cannot be revealed as no decryption key was found in "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); + $this->lastMessage = \sprintf('Secret "%s" cannot be revealed as no decryption key was found in "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); return null; } if (false === $value = sodium_crypto_box_seal_open(include $file, $this->decryptionKey)) { - $this->lastMessage = sprintf('Secret "%s" cannot be revealed as the wrong decryption key was provided for "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); + $this->lastMessage = \sprintf('Secret "%s" cannot be revealed as the wrong decryption key was provided for "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); return null; } @@ -132,16 +133,16 @@ public function remove(string $name): bool $filename = $this->getFilename($name); if (!is_file($file = $this->pathPrefix.$filename.'.php')) { - $this->lastMessage = sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); + $this->lastMessage = \sprintf('Secret "%s" not found in "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); return false; } $list = $this->list(); unset($list[$name]); - file_put_contents($this->pathPrefix.'list.php', sprintf("pathPrefix.'list.php', \sprintf("lastMessage = sprintf('Secret "%s" removed from "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); + $this->lastMessage = \sprintf('Secret "%s" removed from "%s".', $name, $this->getPrettyPath(\dirname($this->pathPrefix).\DIRECTORY_SEPARATOR)); return @unlink($file) || !file_exists($file); } @@ -169,7 +170,14 @@ public function list(bool $reveal = false): array public function loadEnvVars(): array { - return $this->list(true); + $envs = []; + $reveal = $this->reveal(...); + + foreach ($this->list() as $name => $value) { + $envs[$name] = LazyString::fromCallable($reveal, $name); + } + + return $envs; } private function loadKeys(): void @@ -191,7 +199,7 @@ private function loadKeys(): void } elseif ('' !== $this->decryptionKey) { $this->encryptionKey = sodium_crypto_box_publickey($this->decryptionKey); } else { - throw new \RuntimeException(sprintf('Encryption key not found in "%s".', \dirname($this->pathPrefix))); + throw new \RuntimeException(\sprintf('Encryption key not found in "%s".', \dirname($this->pathPrefix))); } } @@ -200,7 +208,7 @@ private function export(string $filename, string $data): void $b64 = 'decrypt.private' === $filename ? '// SYMFONY_DECRYPTION_SECRET='.base64_encode($data)."\n" : ''; $name = basename($this->pathPrefix.$filename); $data = str_replace('%', '\x', rawurlencode($data)); - $data = sprintf("createSecretsDir(); @@ -213,7 +221,7 @@ private function export(string $filename, string $data): void private function createSecretsDir(): void { if ($this->secretsDir && !is_dir($this->secretsDir) && !@mkdir($this->secretsDir, 0777, true) && !is_dir($this->secretsDir)) { - throw new \RuntimeException(sprintf('Unable to create the secrets directory (%s).', $this->secretsDir)); + throw new \RuntimeException(\sprintf('Unable to create the secrets directory (%s).', $this->secretsDir)); } $this->secretsDir = null; diff --git a/lib/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php b/lib/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php index a6d4fed337..b09045b4f8 100644 --- a/lib/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php +++ b/lib/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php @@ -43,7 +43,7 @@ public static function assertResponseFormatSame(?string $expectedFormat, string self::assertThatForResponse(new ResponseConstraint\ResponseFormatSame(self::getRequest(), $expectedFormat), $message); } - public static function assertResponseRedirects(string $expectedLocation = null, int $expectedCode = null, string $message = ''): void + public static function assertResponseRedirects(?string $expectedLocation = null, ?int $expectedCode = null, string $message = ''): void { $constraint = new ResponseConstraint\ResponseIsRedirected(); if ($expectedLocation) { @@ -82,17 +82,17 @@ public static function assertResponseHeaderNotSame(string $headerName, string $e self::assertThatForResponse(new LogicalNot(new ResponseConstraint\ResponseHeaderSame($headerName, $expectedValue)), $message); } - public static function assertResponseHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void + public static function assertResponseHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void { self::assertThatForResponse(new ResponseConstraint\ResponseHasCookie($name, $path, $domain), $message); } - public static function assertResponseNotHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void + public static function assertResponseNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void { self::assertThatForResponse(new LogicalNot(new ResponseConstraint\ResponseHasCookie($name, $path, $domain)), $message); } - public static function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', string $domain = null, string $message = ''): void + public static function assertResponseCookieValueSame(string $name, string $expectedValue, string $path = '/', ?string $domain = null, string $message = ''): void { self::assertThatForResponse(LogicalAnd::fromConstraints( new ResponseConstraint\ResponseHasCookie($name, $path, $domain), @@ -105,17 +105,17 @@ public static function assertResponseIsUnprocessable(string $message = ''): void self::assertThatForResponse(new ResponseConstraint\ResponseIsUnprocessable(), $message); } - public static function assertBrowserHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void + public static function assertBrowserHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void { self::assertThatForClient(new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), $message); } - public static function assertBrowserNotHasCookie(string $name, string $path = '/', string $domain = null, string $message = ''): void + public static function assertBrowserNotHasCookie(string $name, string $path = '/', ?string $domain = null, string $message = ''): void { self::assertThatForClient(new LogicalNot(new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain)), $message); } - public static function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', string $domain = null, string $message = ''): void + public static function assertBrowserCookieValueSame(string $name, string $expectedValue, bool $raw = false, string $path = '/', ?string $domain = null, string $message = ''): void { self::assertThatForClient(LogicalAnd::fromConstraints( new BrowserKitConstraint\BrowserHasCookie($name, $path, $domain), @@ -162,7 +162,7 @@ public static function assertThatForClient(Constraint $constraint, string $messa self::assertThat(self::getClient(), $constraint, $message); } - protected static function getClient(AbstractBrowser $newClient = null): ?AbstractBrowser + protected static function getClient(?AbstractBrowser $newClient = null): ?AbstractBrowser { static $client; @@ -171,7 +171,7 @@ protected static function getClient(AbstractBrowser $newClient = null): ?Abstrac } if (!$client instanceof AbstractBrowser) { - static::fail(sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient()"?', __CLASS__)); + static::fail(\sprintf('A client must be set to make assertions on it. Did you forget to call "%s::createClient()"?', __CLASS__)); } return $client; diff --git a/lib/symfony/framework-bundle/Test/DomCrawlerAssertionsTrait.php b/lib/symfony/framework-bundle/Test/DomCrawlerAssertionsTrait.php index a167094614..ede359bcc2 100644 --- a/lib/symfony/framework-bundle/Test/DomCrawlerAssertionsTrait.php +++ b/lib/symfony/framework-bundle/Test/DomCrawlerAssertionsTrait.php @@ -26,12 +26,12 @@ trait DomCrawlerAssertionsTrait { public static function assertSelectorExists(string $selector, string $message = ''): void { - self::assertThat(self::getCrawler(), new DomCrawlerConstraint\CrawlerSelectorExists($selector), $message); + self::assertThat(self::getCrawler(), new CrawlerSelectorExists($selector), $message); } public static function assertSelectorNotExists(string $selector, string $message = ''): void { - self::assertThat(self::getCrawler(), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorExists($selector)), $message); + self::assertThat(self::getCrawler(), new LogicalNot(new CrawlerSelectorExists($selector)), $message); } public static function assertSelectorCount(int $expectedCount, string $selector, string $message = ''): void @@ -42,7 +42,7 @@ public static function assertSelectorCount(int $expectedCount, string $selector, public static function assertSelectorTextContains(string $selector, string $text, string $message = ''): void { self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new CrawlerSelectorExists($selector), new DomCrawlerConstraint\CrawlerSelectorTextContains($selector, $text) ), $message); } @@ -50,7 +50,7 @@ public static function assertSelectorTextContains(string $selector, string $text public static function assertAnySelectorTextContains(string $selector, string $text, string $message = ''): void { self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new CrawlerSelectorExists($selector), new DomCrawlerConstraint\CrawlerAnySelectorTextContains($selector, $text) ), $message); } @@ -58,7 +58,7 @@ public static function assertAnySelectorTextContains(string $selector, string $t public static function assertSelectorTextSame(string $selector, string $text, string $message = ''): void { self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new CrawlerSelectorExists($selector), new DomCrawlerConstraint\CrawlerSelectorTextSame($selector, $text) ), $message); } @@ -66,7 +66,7 @@ public static function assertSelectorTextSame(string $selector, string $text, st public static function assertAnySelectorTextSame(string $selector, string $text, string $message = ''): void { self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new CrawlerSelectorExists($selector), new DomCrawlerConstraint\CrawlerAnySelectorTextSame($selector, $text) ), $message); } @@ -74,7 +74,7 @@ public static function assertAnySelectorTextSame(string $selector, string $text, public static function assertSelectorTextNotContains(string $selector, string $text, string $message = ''): void { self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new CrawlerSelectorExists($selector), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorTextContains($selector, $text)) ), $message); } @@ -82,7 +82,7 @@ public static function assertSelectorTextNotContains(string $selector, string $t public static function assertAnySelectorTextNotContains(string $selector, string $text, string $message = ''): void { self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists($selector), + new CrawlerSelectorExists($selector), new LogicalNot(new DomCrawlerConstraint\CrawlerAnySelectorTextContains($selector, $text)) ), $message); } @@ -100,7 +100,7 @@ public static function assertPageTitleContains(string $expectedTitle, string $me public static function assertInputValueSame(string $fieldName, string $expectedValue, string $message = ''): void { self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists("input[name=\"$fieldName\"]"), + new CrawlerSelectorExists("input[name=\"$fieldName\"]"), new DomCrawlerConstraint\CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue) ), $message); } @@ -108,7 +108,7 @@ public static function assertInputValueSame(string $fieldName, string $expectedV public static function assertInputValueNotSame(string $fieldName, string $expectedValue, string $message = ''): void { self::assertThat(self::getCrawler(), LogicalAnd::fromConstraints( - new DomCrawlerConstraint\CrawlerSelectorExists("input[name=\"$fieldName\"]"), + new CrawlerSelectorExists("input[name=\"$fieldName\"]"), new LogicalNot(new DomCrawlerConstraint\CrawlerSelectorAttributeValueSame("input[name=\"$fieldName\"]", 'value', $expectedValue)) ), $message); } @@ -126,18 +126,18 @@ public static function assertCheckboxNotChecked(string $fieldName, string $messa public static function assertFormValue(string $formSelector, string $fieldName, string $value, string $message = ''): void { $node = self::getCrawler()->filter($formSelector); - self::assertNotEmpty($node, sprintf('Form "%s" not found.', $formSelector)); + self::assertNotEmpty($node, \sprintf('Form "%s" not found.', $formSelector)); $values = $node->form()->getValues(); - self::assertArrayHasKey($fieldName, $values, $message ?: sprintf('Field "%s" not found in form "%s".', $fieldName, $formSelector)); + self::assertArrayHasKey($fieldName, $values, $message ?: \sprintf('Field "%s" not found in form "%s".', $fieldName, $formSelector)); self::assertSame($value, $values[$fieldName]); } public static function assertNoFormValue(string $formSelector, string $fieldName, string $message = ''): void { $node = self::getCrawler()->filter($formSelector); - self::assertNotEmpty($node, sprintf('Form "%s" not found.', $formSelector)); + self::assertNotEmpty($node, \sprintf('Form "%s" not found.', $formSelector)); $values = $node->form()->getValues(); - self::assertArrayNotHasKey($fieldName, $values, $message ?: sprintf('Field "%s" has a value in form "%s".', $fieldName, $formSelector)); + self::assertArrayNotHasKey($fieldName, $values, $message ?: \sprintf('Field "%s" has a value in form "%s".', $fieldName, $formSelector)); } private static function getCrawler(): Crawler diff --git a/lib/symfony/framework-bundle/Test/HttpClientAssertionsTrait.php b/lib/symfony/framework-bundle/Test/HttpClientAssertionsTrait.php index bed835fa1e..4a8afbab4a 100644 --- a/lib/symfony/framework-bundle/Test/HttpClientAssertionsTrait.php +++ b/lib/symfony/framework-bundle/Test/HttpClientAssertionsTrait.php @@ -14,13 +14,12 @@ use Symfony\Bundle\FrameworkBundle\KernelBrowser; use Symfony\Component\HttpClient\DataCollector\HttpClientDataCollector; -/* +/** * @author Mathieu Santostefano */ - trait HttpClientAssertionsTrait { - public static function assertHttpClientRequest(string $expectedUrl, string $expectedMethod = 'GET', string|array $expectedBody = null, array $expectedHeaders = [], string $httpClientId = 'http_client'): void + public static function assertHttpClientRequest(string $expectedUrl, string $expectedMethod = 'GET', string|array|null $expectedBody = null, array $expectedHeaders = [], string $httpClientId = 'http_client'): void { /** @var KernelBrowser $client */ $client = static::getClient(); @@ -34,7 +33,7 @@ public static function assertHttpClientRequest(string $expectedUrl, string $expe $expectedRequestHasBeenFound = false; if (!\array_key_exists($httpClientId, $httpClientDataCollector->getClients())) { - static::fail(sprintf('HttpClient "%s" is not registered.', $httpClientId)); + static::fail(\sprintf('HttpClient "%s" is not registered.', $httpClientId)); } foreach ($httpClientDataCollector->getClients()[$httpClientId]['traces'] as $trace) { @@ -102,7 +101,7 @@ public function assertNotHttpClientRequest(string $unexpectedUrl, string $expect $unexpectedUrlHasBeenFound = false; if (!\array_key_exists($httpClientId, $httpClientDataCollector->getClients())) { - static::fail(sprintf('HttpClient "%s" is not registered.', $httpClientId)); + static::fail(\sprintf('HttpClient "%s" is not registered.', $httpClientId)); } foreach ($httpClientDataCollector->getClients()[$httpClientId]['traces'] as $trace) { @@ -114,7 +113,7 @@ public function assertNotHttpClientRequest(string $unexpectedUrl, string $expect } } - self::assertFalse($unexpectedUrlHasBeenFound, sprintf('Unexpected URL called: "%s" - "%s"', $expectedMethod, $unexpectedUrl)); + self::assertFalse($unexpectedUrlHasBeenFound, \sprintf('Unexpected URL called: "%s" - "%s"', $expectedMethod, $unexpectedUrl)); } public static function assertHttpClientRequestCount(int $count, string $httpClientId = 'http_client'): void diff --git a/lib/symfony/framework-bundle/Test/KernelTestCase.php b/lib/symfony/framework-bundle/Test/KernelTestCase.php index 8d27b757f1..5c337b7300 100644 --- a/lib/symfony/framework-bundle/Test/KernelTestCase.php +++ b/lib/symfony/framework-bundle/Test/KernelTestCase.php @@ -15,6 +15,7 @@ use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\ContainerInterface; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; +use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Contracts\Service\ResetInterface; @@ -45,6 +46,14 @@ protected function tearDown(): void static::$booted = false; } + public static function tearDownAfterClass(): void + { + static::ensureKernelShutdown(); + static::$class = null; + static::$kernel = null; + static::$booted = false; + } + /** * @throws \RuntimeException * @throws \LogicException @@ -52,11 +61,11 @@ protected function tearDown(): void protected static function getKernelClass(): string { if (!isset($_SERVER['KERNEL_CLASS']) && !isset($_ENV['KERNEL_CLASS'])) { - throw new \LogicException(sprintf('You must set the KERNEL_CLASS environment variable to the fully-qualified class name of your Kernel in phpunit.xml / phpunit.xml.dist or override the "%1$s::createKernel()" or "%1$s::getKernelClass()" method.', static::class)); + throw new \LogicException(\sprintf('You must set the KERNEL_CLASS environment variable to the fully-qualified class name of your Kernel in phpunit.xml / phpunit.xml.dist or override the "%1$s::createKernel()" or "%1$s::getKernelClass()" method.', static::class)); } if (!class_exists($class = $_ENV['KERNEL_CLASS'] ?? $_SERVER['KERNEL_CLASS'])) { - throw new \RuntimeException(sprintf('Class "%s" doesn\'t exist or cannot be autoloaded. Check that the KERNEL_CLASS value in phpunit.xml matches the fully-qualified class name of your Kernel or override the "%s::createKernel()" method.', $class, static::class)); + throw new \RuntimeException(\sprintf('Class "%s" doesn\'t exist or cannot be autoloaded. Check that the KERNEL_CLASS value in phpunit.xml matches the fully-qualified class name of your Kernel or override the "%s::createKernel()" method.', $class, static::class)); } return $class; @@ -74,6 +83,18 @@ protected static function bootKernel(array $options = []): KernelInterface static::$kernel = $kernel; static::$booted = true; + // If the cache warmer is registered, it means that the cache has been + // warmed up, so the current container is not fresh anymore. Let's + // reboot a fresh one. + if (self::getContainer()->initialized('cache_warmer')) { + static::ensureKernelShutdown(); + + $kernel = static::createKernel($options); + $kernel->boot(); + static::$kernel = $kernel; + static::$booted = true; + } + return static::$kernel; } @@ -126,12 +147,27 @@ protected static function ensureKernelShutdown() if (null !== static::$kernel) { static::$kernel->boot(); $container = static::$kernel->getContainer(); + + $httpCacheDir = null; + if ($container->has('http_cache')) { + $httpCacheDir = static::$kernel->getCacheDir().'/http_cache'; + } + + if ($container->has('services_resetter')) { + // Instantiate the service because Container::reset() only resets services that have been used + $container->get('services_resetter'); + } + static::$kernel->shutdown(); static::$booted = false; if ($container instanceof ResetInterface) { $container->reset(); } + + if (null !== $httpCacheDir && is_dir($httpCacheDir)) { + (new Filesystem())->remove($httpCacheDir); + } } } } diff --git a/lib/symfony/framework-bundle/Test/MailerAssertionsTrait.php b/lib/symfony/framework-bundle/Test/MailerAssertionsTrait.php index 83643421ef..2308c3e2fd 100644 --- a/lib/symfony/framework-bundle/Test/MailerAssertionsTrait.php +++ b/lib/symfony/framework-bundle/Test/MailerAssertionsTrait.php @@ -20,12 +20,12 @@ trait MailerAssertionsTrait { - public static function assertEmailCount(int $count, string $transport = null, string $message = ''): void + public static function assertEmailCount(int $count, ?string $transport = null, string $message = ''): void { self::assertThat(self::getMessageMailerEvents(), new MailerConstraint\EmailCount($count, $transport), $message); } - public static function assertQueuedEmailCount(int $count, string $transport = null, string $message = ''): void + public static function assertQueuedEmailCount(int $count, ?string $transport = null, string $message = ''): void { self::assertThat(self::getMessageMailerEvents(), new MailerConstraint\EmailCount($count, $transport, true), $message); } @@ -103,12 +103,12 @@ public static function assertEmailSubjectNotContains(RawMessage $email, string $ /** * @return MessageEvent[] */ - public static function getMailerEvents(string $transport = null): array + public static function getMailerEvents(?string $transport = null): array { return self::getMessageMailerEvents()->getEvents($transport); } - public static function getMailerEvent(int $index = 0, string $transport = null): ?MessageEvent + public static function getMailerEvent(int $index = 0, ?string $transport = null): ?MessageEvent { return self::getMailerEvents($transport)[$index] ?? null; } @@ -116,12 +116,12 @@ public static function getMailerEvent(int $index = 0, string $transport = null): /** * @return RawMessage[] */ - public static function getMailerMessages(string $transport = null): array + public static function getMailerMessages(?string $transport = null): array { return self::getMessageMailerEvents()->getMessages($transport); } - public static function getMailerMessage(int $index = 0, string $transport = null): ?RawMessage + public static function getMailerMessage(int $index = 0, ?string $transport = null): ?RawMessage { return self::getMailerMessages($transport)[$index] ?? null; } diff --git a/lib/symfony/framework-bundle/Test/NotificationAssertionsTrait.php b/lib/symfony/framework-bundle/Test/NotificationAssertionsTrait.php index 53d24cb128..2c4c5467d4 100644 --- a/lib/symfony/framework-bundle/Test/NotificationAssertionsTrait.php +++ b/lib/symfony/framework-bundle/Test/NotificationAssertionsTrait.php @@ -17,17 +17,17 @@ use Symfony\Component\Notifier\Message\MessageInterface; use Symfony\Component\Notifier\Test\Constraint as NotifierConstraint; -/* +/** * @author Smaïne Milianni */ trait NotificationAssertionsTrait { - public static function assertNotificationCount(int $count, string $transportName = null, string $message = ''): void + public static function assertNotificationCount(int $count, ?string $transportName = null, string $message = ''): void { self::assertThat(self::getNotificationEvents(), new NotifierConstraint\NotificationCount($count, $transportName), $message); } - public static function assertQueuedNotificationCount(int $count, string $transportName = null, string $message = ''): void + public static function assertQueuedNotificationCount(int $count, ?string $transportName = null, string $message = ''): void { self::assertThat(self::getNotificationEvents(), new NotifierConstraint\NotificationCount($count, $transportName, true), $message); } @@ -52,12 +52,12 @@ public static function assertNotificationSubjectNotContains(MessageInterface $no self::assertThat($notification, new LogicalNot(new NotifierConstraint\NotificationSubjectContains($text)), $message); } - public static function assertNotificationTransportIsEqual(MessageInterface $notification, string $transportName = null, string $message = ''): void + public static function assertNotificationTransportIsEqual(MessageInterface $notification, ?string $transportName = null, string $message = ''): void { self::assertThat($notification, new NotifierConstraint\NotificationTransportIsEqual($transportName), $message); } - public static function assertNotificationTransportIsNotEqual(MessageInterface $notification, string $transportName = null, string $message = ''): void + public static function assertNotificationTransportIsNotEqual(MessageInterface $notification, ?string $transportName = null, string $message = ''): void { self::assertThat($notification, new LogicalNot(new NotifierConstraint\NotificationTransportIsEqual($transportName)), $message); } @@ -65,12 +65,12 @@ public static function assertNotificationTransportIsNotEqual(MessageInterface $n /** * @return MessageEvent[] */ - public static function getNotifierEvents(string $transportName = null): array + public static function getNotifierEvents(?string $transportName = null): array { return self::getNotificationEvents()->getEvents($transportName); } - public static function getNotifierEvent(int $index = 0, string $transportName = null): ?MessageEvent + public static function getNotifierEvent(int $index = 0, ?string $transportName = null): ?MessageEvent { return self::getNotifierEvents($transportName)[$index] ?? null; } @@ -78,12 +78,12 @@ public static function getNotifierEvent(int $index = 0, string $transportName = /** * @return MessageInterface[] */ - public static function getNotifierMessages(string $transportName = null): array + public static function getNotifierMessages(?string $transportName = null): array { return self::getNotificationEvents()->getMessages($transportName); } - public static function getNotifierMessage(int $index = 0, string $transportName = null): ?MessageInterface + public static function getNotifierMessage(int $index = 0, ?string $transportName = null): ?MessageInterface { return self::getNotifierMessages($transportName)[$index] ?? null; } diff --git a/lib/symfony/framework-bundle/Test/TestBrowserToken.php b/lib/symfony/framework-bundle/Test/TestBrowserToken.php index 8bf365eb06..25d71d084a 100644 --- a/lib/symfony/framework-bundle/Test/TestBrowserToken.php +++ b/lib/symfony/framework-bundle/Test/TestBrowserToken.php @@ -23,7 +23,7 @@ class TestBrowserToken extends AbstractToken { private string $firewallName; - public function __construct(array $roles = [], UserInterface $user = null, string $firewallName = 'main') + public function __construct(array $roles = [], ?UserInterface $user = null, string $firewallName = 'main') { parent::__construct($roles); diff --git a/lib/symfony/framework-bundle/Test/TestContainer.php b/lib/symfony/framework-bundle/Test/TestContainer.php index e1e7a85926..288fd76e8a 100644 --- a/lib/symfony/framework-bundle/Test/TestContainer.php +++ b/lib/symfony/framework-bundle/Test/TestContainer.php @@ -71,15 +71,11 @@ public function set(string $id, mixed $service): void $container = $this->getPublicContainer(); $renamedId = $this->renamedIds[$id] ?? $id; - try { + if (!$this->getPrivateContainer()->has($renamedId)) { $container->set($renamedId, $service); - } catch (InvalidArgumentException $e) { - if (!str_starts_with($e->getMessage(), "The \"$renamedId\" service is private")) { - throw $e; - } - if (isset($container->privates[$renamedId])) { - throw new InvalidArgumentException(sprintf('The "%s" service is already initialized, you cannot replace it.', $id)); - } + } elseif (isset($container->privates[$renamedId])) { + throw new InvalidArgumentException(\sprintf('The "%s" service is already initialized, you cannot replace it.', $id)); + } else { $container->privates[$renamedId] = $service; } } diff --git a/lib/symfony/framework-bundle/Test/WebTestCase.php b/lib/symfony/framework-bundle/Test/WebTestCase.php index de31d4ba92..9c6ee9c986 100644 --- a/lib/symfony/framework-bundle/Test/WebTestCase.php +++ b/lib/symfony/framework-bundle/Test/WebTestCase.php @@ -38,7 +38,7 @@ protected function tearDown(): void protected static function createClient(array $options = [], array $server = []): KernelBrowser { if (static::$booted) { - throw new \LogicException(sprintf('Booting the kernel before calling "%s()" is not supported, the kernel should only be booted once.', __METHOD__)); + throw new \LogicException(\sprintf('Booting the kernel before calling "%s()" is not supported, the kernel should only be booted once.', __METHOD__)); } $kernel = static::bootKernel($options); diff --git a/lib/symfony/framework-bundle/Translation/Translator.php b/lib/symfony/framework-bundle/Translation/Translator.php index 04b56308f3..d53296ee68 100644 --- a/lib/symfony/framework-bundle/Translation/Translator.php +++ b/lib/symfony/framework-bundle/Translation/Translator.php @@ -83,7 +83,7 @@ public function __construct(ContainerInterface $container, MessageFormatterInter // check option names if ($diff = array_diff(array_keys($options), array_keys($this->options))) { - throw new InvalidArgumentException(sprintf('The Translator does not support the following options: \'%s\'.', implode('\', \'', $diff))); + throw new InvalidArgumentException(\sprintf('The Translator does not support the following options: \'%s\'.', implode('\', \'', $diff))); } $this->options = array_merge($this->options, $options); @@ -118,7 +118,7 @@ public function warmUp(string $cacheDir /* , string $buildDir = null */): array return []; } - public function addResource(string $format, mixed $resource, string $locale, string $domain = null): void + public function addResource(string $format, mixed $resource, string $locale, ?string $domain = null): void { if ($this->resourceFiles) { $this->addResourceFiles(); diff --git a/lib/symfony/framework-bundle/composer.json b/lib/symfony/framework-bundle/composer.json index 3aedebd742..c3aab8455b 100644 --- a/lib/symfony/framework-bundle/composer.json +++ b/lib/symfony/framework-bundle/composer.json @@ -21,7 +21,7 @@ "ext-xml": "*", "symfony/cache": "^5.4|^6.0|^7.0", "symfony/config": "^6.1|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4.12|^7.0", "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.1|^7.0", "symfony/event-dispatcher": "^5.4|^6.0|^7.0", @@ -57,7 +57,7 @@ "symfony/notifier": "^5.4|^6.0|^7.0", "symfony/process": "^5.4|^6.0|^7.0", "symfony/rate-limiter": "^5.4|^6.0|^7.0", - "symfony/scheduler": "^6.4|^7.0", + "symfony/scheduler": "^6.4.4|^7.0.4", "symfony/security-bundle": "^5.4|^6.0|^7.0", "symfony/semaphore": "^5.4|^6.0|^7.0", "symfony/serializer": "^6.4|^7.0", @@ -72,7 +72,7 @@ "symfony/uid": "^5.4|^6.0|^7.0", "symfony/web-link": "^5.4|^6.0|^7.0", "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "twig/twig": "^2.10|^3.0" + "twig/twig": "^2.10|^3.0.4" }, "conflict": { "doctrine/annotations": "<1.13.1", @@ -93,7 +93,8 @@ "symfony/mime": "<6.4", "symfony/property-info": "<5.4", "symfony/property-access": "<5.4", - "symfony/scheduler": "<6.4", + "symfony/runtime": "<5.4.45|>=6.0,<6.4.13|>=7.0,<7.1.6", + "symfony/scheduler": "<6.4.4|>=7.0.0,<7.0.4", "symfony/serializer": "<6.4", "symfony/security-csrf": "<5.4", "symfony/security-core": "<5.4", diff --git a/lib/symfony/http-foundation/AcceptHeader.php b/lib/symfony/http-foundation/AcceptHeader.php index 853c000e00..e735c75647 100644 --- a/lib/symfony/http-foundation/AcceptHeader.php +++ b/lib/symfony/http-foundation/AcceptHeader.php @@ -25,7 +25,7 @@ class_exists(AcceptHeaderItem::class); class AcceptHeader { /** - * @var AcceptHeaderItem[] + * @var array */ private array $items = []; @@ -46,18 +46,15 @@ public function __construct(array $items) */ public static function fromString(?string $headerValue): self { - $parts = HeaderUtils::split($headerValue ?? '', ',;='); + $items = []; + foreach (HeaderUtils::split($headerValue ?? '', ',;=') as $i => $parts) { + $part = array_shift($parts); + $item = new AcceptHeaderItem($part[0], HeaderUtils::combine($parts)); - return new self(array_map(function ($subParts) { - static $index = 0; - $part = array_shift($subParts); - $attributes = HeaderUtils::combine($subParts); - - $item = new AcceptHeaderItem($part[0], $attributes); - $item->setIndex($index++); + $items[] = $item->setIndex($i); + } - return $item; - }, $parts)); + return new self($items); } /** @@ -73,7 +70,9 @@ public function __toString(): string */ public function has(string $value): bool { - return isset($this->items[$value]); + $canonicalKey = $this->getCanonicalKey(AcceptHeaderItem::fromString($value)); + + return isset($this->items[$canonicalKey]); } /** @@ -81,7 +80,26 @@ public function has(string $value): bool */ public function get(string $value): ?AcceptHeaderItem { - return $this->items[$value] ?? $this->items[explode('/', $value)[0].'/*'] ?? $this->items['*/*'] ?? $this->items['*'] ?? null; + $queryItem = AcceptHeaderItem::fromString($value.';q=1'); + $canonicalKey = $this->getCanonicalKey($queryItem); + + if (isset($this->items[$canonicalKey])) { + return $this->items[$canonicalKey]; + } + + // Collect and filter matching candidates + if (!$candidates = array_filter($this->items, fn (AcceptHeaderItem $item) => $this->matches($item, $queryItem))) { + return null; + } + + usort( + $candidates, + fn ($a, $b) => $this->getSpecificity($b, $queryItem) <=> $this->getSpecificity($a, $queryItem) // Descending specificity + ?: $b->getQuality() <=> $a->getQuality() // Descending quality + ?: $a->getIndex() <=> $b->getIndex() // Ascending index (stability) + ); + + return reset($candidates); } /** @@ -91,7 +109,7 @@ public function get(string $value): ?AcceptHeaderItem */ public function add(AcceptHeaderItem $item): static { - $this->items[$item->getValue()] = $item; + $this->items[$this->getCanonicalKey($item)] = $item; $this->sorted = false; return $this; @@ -114,7 +132,7 @@ public function all(): array */ public function filter(string $pattern): self { - return new self(array_filter($this->items, fn (AcceptHeaderItem $item) => preg_match($pattern, $item->getValue()))); + return new self(array_filter($this->items, static fn ($item) => preg_match($pattern, $item->getValue()))); } /** @@ -133,18 +151,154 @@ public function first(): ?AcceptHeaderItem private function sort(): void { if (!$this->sorted) { - uasort($this->items, function (AcceptHeaderItem $a, AcceptHeaderItem $b) { - $qA = $a->getQuality(); - $qB = $b->getQuality(); + uasort($this->items, static fn ($a, $b) => $b->getQuality() <=> $a->getQuality() ?: $a->getIndex() <=> $b->getIndex()); - if ($qA === $qB) { - return $a->getIndex() > $b->getIndex() ? 1 : -1; - } + $this->sorted = true; + } + } - return $qA > $qB ? -1 : 1; - }); + /** + * Generates the canonical key for storing/retrieving an item. + */ + private function getCanonicalKey(AcceptHeaderItem $item): string + { + $parts = []; - $this->sorted = true; + // Normalize and sort attributes for consistent key generation + $attributes = $this->getMediaParams($item); + ksort($attributes); + + foreach ($attributes as $name => $value) { + if (null === $value) { + $parts[] = $name; // Flag parameter (e.g., "flowed") + continue; + } + + // Quote values containing spaces, commas, semicolons, or equals per RFC 9110 + // This handles cases like 'format="value with space"' or similar. + $quotedValue = \is_string($value) && preg_match('/[\s;,=]/', $value) ? '"'.addcslashes($value, '"\\').'"' : $value; + + $parts[] = $name.'='.$quotedValue; + } + + return $item->getValue().($parts ? ';'.implode(';', $parts) : ''); + } + + /** + * Checks if a given header item (range) matches a queried item (value). + * + * @param AcceptHeaderItem $rangeItem The item from the Accept header (e.g., text/*;format=flowed) + * @param AcceptHeaderItem $queryItem The item being queried (e.g., text/plain;format=flowed;charset=utf-8) + */ + private function matches(AcceptHeaderItem $rangeItem, AcceptHeaderItem $queryItem): bool + { + $rangeValue = strtolower($rangeItem->getValue()); + $queryValue = strtolower($queryItem->getValue()); + + // Handle universal wildcard ranges + if ('*' === $rangeValue || '*/*' === $rangeValue) { + return $this->rangeParametersMatch($rangeItem, $queryItem); + } + + // Queries for '*' only match wildcard ranges (handled above) + if ('*' === $queryValue) { + return false; } + + // Ensure media vs. non-media consistency + $isQueryMedia = str_contains($queryValue, '/'); + $isRangeMedia = str_contains($rangeValue, '/'); + + if ($isQueryMedia !== $isRangeMedia) { + return false; + } + + // Non-media: exact match only (wildcards handled above) + if (!$isQueryMedia) { + return $rangeValue === $queryValue && $this->rangeParametersMatch($rangeItem, $queryItem); + } + + // Media type: type/subtype with wildcards + [$queryType, $querySubtype] = explode('/', $queryValue, 2); + [$rangeType, $rangeSubtype] = explode('/', $rangeValue, 2) + [1 => '*']; + + if ('*' !== $rangeType && $rangeType !== $queryType) { + return false; + } + + if ('*' !== $rangeSubtype && $rangeSubtype !== $querySubtype) { + return false; + } + + // Parameters must match + return $this->rangeParametersMatch($rangeItem, $queryItem); + } + + /** + * Checks if the parameters of a range item are satisfied by the query item. + * + * Parameters are case-insensitive; range params must be a subset of query params. + */ + private function rangeParametersMatch(AcceptHeaderItem $rangeItem, AcceptHeaderItem $queryItem): bool + { + $queryAttributes = $this->getMediaParams($queryItem); + $rangeAttributes = $this->getMediaParams($rangeItem); + + foreach ($rangeAttributes as $name => $rangeValue) { + if (!\array_key_exists($name, $queryAttributes)) { + return false; // Missing required param + } + + $queryValue = $queryAttributes[$name]; + + if (null === $rangeValue) { + return null === $queryValue; // Both flags or neither + } + + if (null === $queryValue || strtolower($queryValue) !== strtolower($rangeValue)) { + return false; + } + } + + return true; + } + + /** + * Calculates a specificity score for sorting: media precision + param count. + */ + private function getSpecificity(AcceptHeaderItem $item, AcceptHeaderItem $queryItem): int + { + $rangeValue = strtolower($item->getValue()); + $queryValue = strtolower($queryItem->getValue()); + + $paramCount = \count($this->getMediaParams($item)); + + $isQueryMedia = str_contains($queryValue, '/'); + $isRangeMedia = str_contains($rangeValue, '/'); + + if (!$isQueryMedia && !$isRangeMedia) { + return ('*' !== $rangeValue ? 2000 : 1000) + $paramCount; + } + + [$rangeType, $rangeSubtype] = explode('/', $rangeValue, 2) + [1 => '*']; + + $specificity = match (true) { + '*' !== $rangeSubtype => 3000, // Exact subtype (text/plain) + '*' !== $rangeType => 2000, // Type wildcard (text/*) + default => 1000, // Full wildcard (*/* or *) + }; + + return $specificity + $paramCount; + } + + /** + * Returns normalized attributes: keys lowercased, excluding 'q'. + */ + private function getMediaParams(AcceptHeaderItem $item): array + { + $attributes = array_change_key_case($item->getAttributes(), \CASE_LOWER); + unset($attributes['q']); + + return $attributes; } } diff --git a/lib/symfony/http-foundation/Request.php b/lib/symfony/http-foundation/Request.php index a66312c8ed..8a497a77c3 100644 --- a/lib/symfony/http-foundation/Request.php +++ b/lib/symfony/http-foundation/Request.php @@ -857,7 +857,7 @@ public function getScriptName(): string * * Suppose this request is instantiated from /mysite on localhost: * - * * http://localhost/mysite returns an empty string + * * http://localhost/mysite returns '/' * * http://localhost/mysite/about returns '/about' * * http://localhost/mysite/enco%20ded returns '/enco%20ded' * * http://localhost/mysite/about?var=1 returns '/about' diff --git a/lib/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php b/lib/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php index 48c219a7aa..8d757f03f1 100644 --- a/lib/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php +++ b/lib/symfony/http-foundation/Session/Storage/Handler/PdoSessionHandler.php @@ -194,7 +194,6 @@ public function configureSchema(Schema $schema, ?\Closure $isSameDatabase = null $table->addColumn($this->dataCol, Types::BLOB)->setNotnull(true); $table->addColumn($this->lifetimeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true); $table->addColumn($this->timeCol, Types::INTEGER)->setUnsigned(true)->setNotnull(true); - $table->addOption('collate', 'utf8mb4_bin'); $table->addOption('engine', 'InnoDB'); break; case 'sqlite': @@ -252,7 +251,7 @@ public function createTable() // - trailing space removal // - case-insensitivity // - language processing like é == e - 'mysql' => "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL) COLLATE utf8mb4_bin, ENGINE = InnoDB", + 'mysql' => "CREATE TABLE $this->table ($this->idCol VARBINARY(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER UNSIGNED NOT NULL, $this->timeCol INTEGER UNSIGNED NOT NULL), ENGINE = InnoDB", 'sqlite' => "CREATE TABLE $this->table ($this->idCol TEXT NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)", 'pgsql' => "CREATE TABLE $this->table ($this->idCol VARCHAR(128) NOT NULL PRIMARY KEY, $this->dataCol BYTEA NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)", 'oci' => "CREATE TABLE $this->table ($this->idCol VARCHAR2(128) NOT NULL PRIMARY KEY, $this->dataCol BLOB NOT NULL, $this->lifetimeCol INTEGER NOT NULL, $this->timeCol INTEGER NOT NULL)", @@ -795,6 +794,12 @@ private function getInsertStatement(#[\SensitiveParameter] string $sessionId, st rewind($data); $sql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, EMPTY_BLOB(), :expiry, :time) RETURNING $this->dataCol into :data"; break; + case 'sqlsrv': + $data = fopen('php://memory', 'r+'); + fwrite($data, $sessionData); + rewind($data); + $sql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :expiry, :time)"; + break; default: $data = $sessionData; $sql = "INSERT INTO $this->table ($this->idCol, $this->dataCol, $this->lifetimeCol, $this->timeCol) VALUES (:id, :data, :expiry, :time)"; @@ -822,6 +827,12 @@ private function getUpdateStatement(#[\SensitiveParameter] string $sessionId, st rewind($data); $sql = "UPDATE $this->table SET $this->dataCol = EMPTY_BLOB(), $this->lifetimeCol = :expiry, $this->timeCol = :time WHERE $this->idCol = :id RETURNING $this->dataCol into :data"; break; + case 'sqlsrv': + $data = fopen('php://memory', 'r+'); + fwrite($data, $sessionData); + rewind($data); + $sql = "UPDATE $this->table SET $this->dataCol = :data, $this->lifetimeCol = :expiry, $this->timeCol = :time WHERE $this->idCol = :id"; + break; default: $data = $sessionData; $sql = "UPDATE $this->table SET $this->dataCol = :data, $this->lifetimeCol = :expiry, $this->timeCol = :time WHERE $this->idCol = :id"; @@ -869,12 +880,16 @@ private function getMergeStatement(#[\SensitiveParameter] string $sessionId, str $mergeStmt = $this->pdo->prepare($mergeSql); if ('sqlsrv' === $this->driver) { + $dataStream = fopen('php://memory', 'r+'); + fwrite($dataStream, $data); + rewind($dataStream); + $mergeStmt->bindParam(1, $sessionId, \PDO::PARAM_STR); $mergeStmt->bindParam(2, $sessionId, \PDO::PARAM_STR); - $mergeStmt->bindParam(3, $data, \PDO::PARAM_LOB); + $mergeStmt->bindParam(3, $dataStream, \PDO::PARAM_LOB); $mergeStmt->bindValue(4, time() + $maxlifetime, \PDO::PARAM_INT); $mergeStmt->bindValue(5, time(), \PDO::PARAM_INT); - $mergeStmt->bindParam(6, $data, \PDO::PARAM_LOB); + $mergeStmt->bindParam(6, $dataStream, \PDO::PARAM_LOB); $mergeStmt->bindValue(7, time() + $maxlifetime, \PDO::PARAM_INT); $mergeStmt->bindValue(8, time(), \PDO::PARAM_INT); } else { diff --git a/lib/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php b/lib/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php index 43a9eb84e2..e41d035392 100644 --- a/lib/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php +++ b/lib/symfony/http-foundation/Session/Storage/Handler/SessionHandlerFactory.php @@ -62,6 +62,7 @@ public static function createHandler(object|string $connection, array $options = throw new \InvalidArgumentException('Unsupported Redis or Memcached DSN. Try running "composer require symfony/cache".'); } $handlerClass = str_starts_with($connection, 'memcached:') ? MemcachedSessionHandler::class : RedisSessionHandler::class; + $connection = preg_replace('/([?&])prefix=[^&]*+&?/', '\1', $connection); $connection = AbstractAdapter::createConnection($connection, ['lazy' => true]); return new $handlerClass($connection, array_intersect_key($options, ['prefix' => 1, 'ttl' => 1])); diff --git a/lib/symfony/http-kernel/Attribute/MapQueryParameter.php b/lib/symfony/http-kernel/Attribute/MapQueryParameter.php index f83e331e41..bbc1fff273 100644 --- a/lib/symfony/http-kernel/Attribute/MapQueryParameter.php +++ b/lib/symfony/http-kernel/Attribute/MapQueryParameter.php @@ -22,7 +22,7 @@ final class MapQueryParameter extends ValueResolver { /** - * @see https://php.net/filter.filters.validate for filter, flags and options + * @see https://php.net/manual/filter.constants for filter, flags and options * * @param string|null $name The name of the query parameter. If null, the name of the argument in the controller will be used. */ diff --git a/lib/symfony/http-kernel/Attribute/WithLogLevel.php b/lib/symfony/http-kernel/Attribute/WithLogLevel.php index 762b077043..10ed3b8eaa 100644 --- a/lib/symfony/http-kernel/Attribute/WithLogLevel.php +++ b/lib/symfony/http-kernel/Attribute/WithLogLevel.php @@ -25,7 +25,7 @@ final class WithLogLevel public function __construct(public readonly string $level) { if (!\defined('Psr\Log\LogLevel::'.strtoupper($this->level))) { - throw new \InvalidArgumentException(sprintf('Invalid log level "%s".', $this->level)); + throw new \InvalidArgumentException(\sprintf('Invalid log level "%s".', $this->level)); } } } diff --git a/lib/symfony/http-kernel/Bundle/Bundle.php b/lib/symfony/http-kernel/Bundle/Bundle.php index 09a19c480c..0efc21a5e0 100644 --- a/lib/symfony/http-kernel/Bundle/Bundle.php +++ b/lib/symfony/http-kernel/Bundle/Bundle.php @@ -70,7 +70,7 @@ public function getContainerExtension(): ?ExtensionInterface if (null !== $extension) { if (!$extension instanceof ExtensionInterface) { - throw new \LogicException(sprintf('Extension "%s" must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', get_debug_type($extension))); + throw new \LogicException(\sprintf('Extension "%s" must implement Symfony\Component\DependencyInjection\Extension\ExtensionInterface.', get_debug_type($extension))); } // check naming convention @@ -78,7 +78,7 @@ public function getContainerExtension(): ?ExtensionInterface $expectedAlias = Container::underscore($basename); if ($expectedAlias != $extension->getAlias()) { - throw new \LogicException(sprintf('Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.', $expectedAlias, $extension->getAlias())); + throw new \LogicException(\sprintf('Users will expect the alias of the default extension of a bundle to be the underscored version of the bundle name ("%s"). You can override "Bundle::getContainerExtension()" if you want to use "%s" or another alias.', $expectedAlias, $extension->getAlias())); } $this->extension = $extension; diff --git a/lib/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php b/lib/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php index 3c99b74af3..87614e9417 100644 --- a/lib/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php +++ b/lib/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php @@ -39,7 +39,7 @@ public function hasPool(string $name): bool public function getPool(string $name): CacheItemPoolInterface { if (!$this->hasPool($name)) { - throw new \InvalidArgumentException(sprintf('Cache pool not found: "%s".', $name)); + throw new \InvalidArgumentException(\sprintf('Cache pool not found: "%s".', $name)); } return $this->pools[$name]; @@ -51,7 +51,7 @@ public function getPool(string $name): CacheItemPoolInterface public function clearPool(string $name): bool { if (!isset($this->pools[$name])) { - throw new \InvalidArgumentException(sprintf('Cache pool not found: "%s".', $name)); + throw new \InvalidArgumentException(\sprintf('Cache pool not found: "%s".', $name)); } return $this->pools[$name]->clear(); diff --git a/lib/symfony/http-kernel/CacheWarmer/CacheWarmer.php b/lib/symfony/http-kernel/CacheWarmer/CacheWarmer.php index f940ba4a72..664110a222 100644 --- a/lib/symfony/http-kernel/CacheWarmer/CacheWarmer.php +++ b/lib/symfony/http-kernel/CacheWarmer/CacheWarmer.php @@ -30,6 +30,6 @@ protected function writeCacheFile(string $file, $content) return; } - throw new \RuntimeException(sprintf('Failed to write cache file "%s".', $file)); + throw new \RuntimeException(\sprintf('Failed to write cache file "%s".', $file)); } } diff --git a/lib/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php b/lib/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php index a672956e0f..9f1c53456c 100644 --- a/lib/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php +++ b/lib/symfony/http-kernel/CacheWarmer/CacheWarmerAggregate.php @@ -31,7 +31,7 @@ class CacheWarmerAggregate implements CacheWarmerInterface /** * @param iterable $warmers */ - public function __construct(iterable $warmers = [], bool $debug = false, string $deprecationLogsFilepath = null) + public function __construct(iterable $warmers = [], bool $debug = false, ?string $deprecationLogsFilepath = null) { $this->warmers = $warmers; $this->debug = $debug; @@ -51,7 +51,7 @@ public function enableOnlyOptionalWarmers(): void /** * @param string|null $buildDir */ - public function warmUp(string $cacheDir, string|SymfonyStyle $buildDir = null, SymfonyStyle $io = null): array + public function warmUp(string $cacheDir, string|SymfonyStyle|null $buildDir = null, ?SymfonyStyle $io = null): array { if ($buildDir instanceof SymfonyStyle) { trigger_deprecation('symfony/http-kernel', '6.4', 'Passing a "%s" as second argument of "%s()" is deprecated, pass it as third argument instead, after the build directory.', SymfonyStyle::class, __METHOD__); @@ -107,13 +107,13 @@ public function warmUp(string $cacheDir, string|SymfonyStyle $buildDir = null, S $start = microtime(true); foreach ((array) $warmer->warmUp($cacheDir, $buildDir) as $item) { if (is_dir($item) || (str_starts_with($item, \dirname($cacheDir)) && !is_file($item)) || ($buildDir && str_starts_with($item, \dirname($buildDir)) && !is_file($item))) { - throw new \LogicException(sprintf('"%s::warmUp()" should return a list of files or classes but "%s" is none of them.', $warmer::class, $item)); + throw new \LogicException(\sprintf('"%s::warmUp()" should return a list of files or classes but "%s" is none of them.', $warmer::class, $item)); } $preload[] = $item; } if ($io?->isDebug()) { - $io->info(sprintf('"%s" completed in %0.2fms.', $warmer::class, 1000 * (microtime(true) - $start))); + $io->info(\sprintf('"%s" completed in %0.2fms.', $warmer::class, 1000 * (microtime(true) - $start))); } } } finally { diff --git a/lib/symfony/http-kernel/Config/FileLocator.php b/lib/symfony/http-kernel/Config/FileLocator.php index f81f91925b..fb6bb10f1f 100644 --- a/lib/symfony/http-kernel/Config/FileLocator.php +++ b/lib/symfony/http-kernel/Config/FileLocator.php @@ -30,7 +30,7 @@ public function __construct(KernelInterface $kernel) parent::__construct(); } - public function locate(string $file, string $currentPath = null, bool $first = true): string|array + public function locate(string $file, ?string $currentPath = null, bool $first = true): string|array { if (isset($file[0]) && '@' === $file[0]) { $resource = $this->kernel->locateResource($file); diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver.php index 6643cc58ee..991e99bdc6 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver.php @@ -39,14 +39,14 @@ final class ArgumentResolver implements ArgumentResolverInterface /** * @param iterable $argumentValueResolvers */ - public function __construct(ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, iterable $argumentValueResolvers = [], ContainerInterface $namedResolvers = null) + public function __construct(?ArgumentMetadataFactoryInterface $argumentMetadataFactory = null, iterable $argumentValueResolvers = [], ?ContainerInterface $namedResolvers = null) { $this->argumentMetadataFactory = $argumentMetadataFactory ?? new ArgumentMetadataFactory(); $this->argumentValueResolvers = $argumentValueResolvers ?: self::getDefaultArgumentValueResolvers(); $this->namedResolvers = $namedResolvers; } - public function getArguments(Request $request, callable $controller, \ReflectionFunctionAbstract $reflector = null): array + public function getArguments(Request $request, callable $controller, ?\ReflectionFunctionAbstract $reflector = null): array { $arguments = []; @@ -60,7 +60,7 @@ public function getArguments(Request $request, callable $controller, \Reflection if ($attribute->disabled) { $disabledResolvers[$attribute->resolver] = true; } elseif ($resolverName) { - throw new \LogicException(sprintf('You can only pin one resolver per argument, but argument "$%s" of "%s()" has more.', $metadata->getName(), $this->getPrettyName($controller))); + throw new \LogicException(\sprintf('You can only pin one resolver per argument, but argument "$%s" of "%s()" has more.', $metadata->getName(), $this->getPrettyName($controller))); } else { $resolverName = $attribute->resolver; } @@ -94,7 +94,7 @@ public function getArguments(Request $request, callable $controller, \Reflection } if (1 < $count && !$metadata->isVariadic()) { - throw new \InvalidArgumentException(sprintf('"%s::resolve()" must yield at most one value for non-variadic arguments.', get_debug_type($resolver))); + throw new \InvalidArgumentException(\sprintf('"%s::resolve()" must yield at most one value for non-variadic arguments.', get_debug_type($resolver))); } if ($count) { @@ -103,11 +103,11 @@ public function getArguments(Request $request, callable $controller, \Reflection } if (!$resolver instanceof ValueResolverInterface) { - throw new \InvalidArgumentException(sprintf('"%s::resolve()" must yield at least one value.', get_debug_type($resolver))); + throw new \InvalidArgumentException(\sprintf('"%s::resolve()" must yield at least one value.', get_debug_type($resolver))); } } - throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or there is a non-optional argument after this one.', $this->getPrettyName($controller), $metadata->getName())); + throw new \RuntimeException(\sprintf('Controller "%s" requires that you provide a value for the "$%s" argument. Either the argument is nullable and no null value has been provided, no default value has been provided or there is a non-optional argument after this one.', $this->getPrettyName($controller), $metadata->getName())); } return $arguments; diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver/BackedEnumValueResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver/BackedEnumValueResolver.php index 620e2de080..c29725dd22 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/BackedEnumValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/BackedEnumValueResolver.php @@ -78,7 +78,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable } if (!\is_int($value) && !\is_string($value)) { - throw new \LogicException(sprintf('Could not resolve the "%s $%s" controller argument: expecting an int or string, got "%s".', $argument->getType(), $argument->getName(), get_debug_type($value))); + throw new \LogicException(\sprintf('Could not resolve the "%s $%s" controller argument: expecting an int or string, got "%s".', $argument->getType(), $argument->getName(), get_debug_type($value))); } /** @var class-string<\BackedEnum> $enumType */ @@ -87,7 +87,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable try { return [$enumType::from($value)]; } catch (\ValueError|\TypeError $e) { - throw new NotFoundHttpException(sprintf('Could not resolve the "%s $%s" controller argument: ', $argument->getType(), $argument->getName()).$e->getMessage(), $e); + throw new NotFoundHttpException(\sprintf('Could not resolve the "%s $%s" controller argument: ', $argument->getType(), $argument->getName()).$e->getMessage(), $e); } } } diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php index 0cfd42badc..388f02b317 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php @@ -90,7 +90,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array } if (!$date) { - throw new NotFoundHttpException(sprintf('Invalid date given for parameter "%s".', $argument->getName())); + throw new NotFoundHttpException(\sprintf('Invalid date given for parameter "%s".', $argument->getName())); } return [$date]; diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver/NotTaggedControllerValueResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver/NotTaggedControllerValueResolver.php index 2640361288..594f1b8a6f 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/NotTaggedControllerValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/NotTaggedControllerValueResolver.php @@ -82,8 +82,8 @@ public function resolve(Request $request, ArgumentMetadata $argument): array return []; } - $what = sprintf('argument $%s of "%s()"', $argument->getName(), $controller); - $message = sprintf('Could not resolve %s, maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?', $what); + $what = \sprintf('argument $%s of "%s()"', $argument->getName(), $controller); + $message = \sprintf('Could not resolve %s, maybe you forgot to register the controller as a service or missed tagging it with the "controller.service_arguments"?', $what); throw new RuntimeException($message); } diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php index b186a39c59..0b64a444b9 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php @@ -38,7 +38,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array return []; } - throw new NotFoundHttpException(sprintf('Missing query parameter "%s".', $name)); + throw new NotFoundHttpException(\sprintf('Missing query parameter "%s".', $name)); } $value = $request->query->all()[$name]; @@ -52,7 +52,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array $filtered = array_values(array_filter((array) $value, \is_array(...))); if ($filtered !== $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) { - throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name)); + throw new NotFoundHttpException(\sprintf('Invalid query parameter "%s".', $name)); } return $filtered; @@ -80,8 +80,8 @@ public function resolve(Request $request, ArgumentMetadata $argument): array default => match ($enumType = is_subclass_of($type, \BackedEnum::class) ? (new \ReflectionEnum($type))->getBackingType()->getName() : null) { 'int' => \FILTER_VALIDATE_INT, 'string' => \FILTER_DEFAULT, - default => throw new \LogicException(sprintf('#[MapQueryParameter] cannot be used on controller argument "%s$%s" of type "%s"; one of array, string, int, float, bool or \BackedEnum should be used.', $argument->isVariadic() ? '...' : '', $argument->getName(), $type ?? 'mixed')), - } + default => throw new \LogicException(\sprintf('#[MapQueryParameter] cannot be used on controller argument "%s$%s" of type "%s"; one of array, string, int, float, bool or \BackedEnum should be used.', $argument->isVariadic() ? '...' : '', $argument->getName(), $type ?? 'mixed')), + }, }; $value = filter_var($value, $attribute->filter ?? $filter, $options); @@ -103,7 +103,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array } if (null === $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) { - throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name)); + throw new NotFoundHttpException(\sprintf('Invalid query parameter "%s".', $name)); } if (!\is_array($value)) { @@ -117,7 +117,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array } if ($filtered !== $value && !($attribute->flags & \FILTER_NULL_ON_FAILURE)) { - throw new NotFoundHttpException(sprintf('Invalid query parameter "%s".', $name)); + throw new NotFoundHttpException(\sprintf('Invalid query parameter "%s".', $name)); } return $argument->isVariadic() ? $filtered : [$filtered]; diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php index 444be1b3fe..0fb42944f9 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php @@ -40,11 +40,9 @@ class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscriberInterface { /** - * @see \Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer::DISABLE_TYPE_ENFORCEMENT * @see DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS */ private const CONTEXT_DENORMALIZE = [ - 'disable_type_enforcement' => true, 'collect_denormalization_errors' => true, ]; @@ -73,7 +71,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): iterable } if ($argument->isVariadic()) { - throw new \LogicException(sprintf('Mapping variadic argument "$%s" is not supported.', $argument->getName())); + throw new \LogicException(\sprintf('Mapping variadic argument "$%s" is not supported.', $argument->getName())); } $attribute->metadata = $argument; @@ -98,7 +96,7 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo $request = $event->getRequest(); if (!$type = $argument->metadata->getType()) { - throw new \LogicException(sprintf('Could not resolve the "$%s" controller argument: argument should be typed.', $argument->metadata->getName())); + throw new \LogicException(\sprintf('Could not resolve the "$%s" controller argument: argument should be typed.', $argument->metadata->getName())); } if ($this->validator) { @@ -108,11 +106,15 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo } catch (PartialDenormalizationException $e) { $trans = $this->translator ? $this->translator->trans(...) : fn ($m, $p) => strtr($m, $p); foreach ($e->getErrors() as $error) { - $parameters = ['{{ type }}' => implode('|', $error->getExpectedTypes())]; + $parameters = []; + $template = 'This value was of an unexpected type.'; + if ($expectedTypes = $error->getExpectedTypes()) { + $template = 'This value should be of type {{ type }}.'; + $parameters['{{ type }}'] = implode('|', $expectedTypes); + } if ($error->canUseMessageForUser()) { $parameters['hint'] = $error->getMessage(); } - $template = 'This value should be of type {{ type }}.'; $message = $trans($template, $parameters, 'validators'); $violations->add(new ConstraintViolation($message, $template, $parameters, null, $error->getPath(), null)); } @@ -138,7 +140,7 @@ public function onKernelControllerArguments(ControllerArgumentsEvent $event): vo $payload = match (true) { $argument->metadata->hasDefaultValue() => $argument->metadata->getDefaultValue(), $argument->metadata->isNullable() => null, - default => throw new HttpException($validationFailedCode) + default => throw new HttpException($validationFailedCode), }; } @@ -161,25 +163,25 @@ private function mapQueryString(Request $request, string $type, MapQueryString $ return null; } - return $this->serializer->denormalize($data, $type, null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE); + return $this->serializer->denormalize($data, $type, 'csv', $attribute->serializationContext + self::CONTEXT_DENORMALIZE); } private function mapRequestPayload(Request $request, string $type, MapRequestPayload $attribute): ?object { + if ('' === $data = $request->request->all() ?: $request->getContent()) { + return null; + } + if (null === $format = $request->getContentTypeFormat()) { throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, 'Unsupported format.'); } if ($attribute->acceptFormat && !\in_array($format, (array) $attribute->acceptFormat, true)) { - throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, sprintf('Unsupported format, expects "%s", but "%s" given.', implode('", "', (array) $attribute->acceptFormat), $format)); + throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, \sprintf('Unsupported format, expects "%s", but "%s" given.', implode('", "', (array) $attribute->acceptFormat), $format)); } - if ($data = $request->request->all()) { - return $this->serializer->denormalize($data, $type, null, $attribute->serializationContext + self::CONTEXT_DENORMALIZE); - } - - if ('' === $data = $request->getContent()) { - return null; + if (\is_array($data)) { + return $this->serializer->denormalize($data, $type, 'csv', $attribute->serializationContext + self::CONTEXT_DENORMALIZE); } if ('form' === $format) { @@ -189,9 +191,9 @@ private function mapRequestPayload(Request $request, string $type, MapRequestPay try { return $this->serializer->deserialize($data, $type, $format, self::CONTEXT_DESERIALIZE + $attribute->serializationContext); } catch (UnsupportedFormatException $e) { - throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, sprintf('Unsupported format: "%s".', $format), $e); + throw new HttpException(Response::HTTP_UNSUPPORTED_MEDIA_TYPE, \sprintf('Unsupported format: "%s".', $format), $e); } catch (NotEncodableValueException $e) { - throw new HttpException(Response::HTTP_BAD_REQUEST, sprintf('Request payload contains invalid "%s" data.', $format), $e); + throw new HttpException(Response::HTTP_BAD_REQUEST, \sprintf('Request payload contains invalid "%s" data.', $format), $e); } } } diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver/ServiceValueResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver/ServiceValueResolver.php index 96e0337d6a..fecf59cafe 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/ServiceValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/ServiceValueResolver.php @@ -83,11 +83,11 @@ public function resolve(Request $request, ArgumentMetadata $argument): array try { return [$this->container->get($controller)->get($argument->getName())]; } catch (RuntimeException $e) { - $what = sprintf('argument $%s of "%s()"', $argument->getName(), $controller); + $what = \sprintf('argument $%s of "%s()"', $argument->getName(), $controller); $message = preg_replace('/service "\.service_locator\.[^"]++"/', $what, $e->getMessage()); if ($e->getMessage() === $message) { - $message = sprintf('Cannot resolve %s: %s', $what, $message); + $message = \sprintf('Cannot resolve %s: %s', $what, $message); } $r = new \ReflectionProperty($e, 'message'); diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver/UidValueResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver/UidValueResolver.php index 7a12e21ead..afe702300e 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/UidValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/UidValueResolver.php @@ -46,7 +46,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array try { return [$uidClass::fromString($value)]; } catch (\InvalidArgumentException $e) { - throw new NotFoundHttpException(sprintf('The uid for the "%s" parameter is invalid.', $argument->getName()), $e); + throw new NotFoundHttpException(\sprintf('The uid for the "%s" parameter is invalid.', $argument->getName()), $e); } } } diff --git a/lib/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php b/lib/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php index 4f6cba729e..b4946698d1 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php @@ -42,7 +42,7 @@ public function resolve(Request $request, ArgumentMetadata $argument): array $values = $request->attributes->get($argument->getName()); if (!\is_array($values)) { - throw new \InvalidArgumentException(sprintf('The action argument "...$%1$s" is required to be an array, the request attribute "%1$s" contains a type of "%2$s" instead.', $argument->getName(), get_debug_type($values))); + throw new \InvalidArgumentException(\sprintf('The action argument "...$%1$s" is required to be an array, the request attribute "%1$s" contains a type of "%2$s" instead.', $argument->getName(), get_debug_type($values))); } return $values; diff --git a/lib/symfony/http-kernel/Controller/ContainerControllerResolver.php b/lib/symfony/http-kernel/Controller/ContainerControllerResolver.php index 1c9254e732..5cd9edb31c 100644 --- a/lib/symfony/http-kernel/Controller/ContainerControllerResolver.php +++ b/lib/symfony/http-kernel/Controller/ContainerControllerResolver.php @@ -25,7 +25,7 @@ class ContainerControllerResolver extends ControllerResolver { protected $container; - public function __construct(ContainerInterface $container, LoggerInterface $logger = null) + public function __construct(ContainerInterface $container, ?LoggerInterface $logger = null) { $this->container = $container; @@ -48,16 +48,16 @@ protected function instantiateController(string $class): object $this->throwExceptionIfControllerWasRemoved($class, $e); if ($e instanceof \ArgumentCountError) { - throw new \InvalidArgumentException(sprintf('Controller "%s" has required constructor arguments and does not exist in the container. Did you forget to define the controller as a service?', $class), 0, $e); + throw new \InvalidArgumentException(\sprintf('Controller "%s" has required constructor arguments and does not exist in the container. Did you forget to define the controller as a service?', $class), 0, $e); } - throw new \InvalidArgumentException(sprintf('Controller "%s" does neither exist as service nor as class.', $class), 0, $e); + throw new \InvalidArgumentException(\sprintf('Controller "%s" does neither exist as service nor as class.', $class), 0, $e); } private function throwExceptionIfControllerWasRemoved(string $controller, \Throwable $previous): void { if ($this->container instanceof Container && isset($this->container->getRemovedIds()[$controller])) { - throw new \InvalidArgumentException(sprintf('Controller "%s" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?', $controller), 0, $previous); + throw new \InvalidArgumentException(\sprintf('Controller "%s" cannot be fetched from the container because it is private. Did you forget to tag the service with "controller.service_arguments"?', $controller), 0, $previous); } } } diff --git a/lib/symfony/http-kernel/Controller/ControllerResolver.php b/lib/symfony/http-kernel/Controller/ControllerResolver.php index d395089492..72ece351bf 100644 --- a/lib/symfony/http-kernel/Controller/ControllerResolver.php +++ b/lib/symfony/http-kernel/Controller/ControllerResolver.php @@ -29,7 +29,7 @@ class ControllerResolver implements ControllerResolverInterface private array $allowedControllerTypes = []; private array $allowedControllerAttributes = [AsController::class => AsController::class]; - public function __construct(LoggerInterface $logger = null) + public function __construct(?LoggerInterface $logger = null) { $this->logger = $logger; } @@ -74,7 +74,7 @@ public function getController(Request $request): callable|false } if (!\is_callable($controller)) { - throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($controller)); + throw new \InvalidArgumentException(\sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($controller)); } return $this->checkController($request, $controller); @@ -82,7 +82,7 @@ public function getController(Request $request): callable|false if (\is_object($controller)) { if (!\is_callable($controller)) { - throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($controller)); + throw new \InvalidArgumentException(\sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($controller)); } return $this->checkController($request, $controller); @@ -95,11 +95,11 @@ public function getController(Request $request): callable|false try { $callable = $this->createController($controller); } catch (\InvalidArgumentException $e) { - throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$e->getMessage(), 0, $e); + throw new \InvalidArgumentException(\sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$e->getMessage(), 0, $e); } if (!\is_callable($callable)) { - throw new \InvalidArgumentException(sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($callable)); + throw new \InvalidArgumentException(\sprintf('The controller for URI "%s" is not callable: ', $request->getPathInfo()).$this->getControllerError($callable)); } return $this->checkController($request, $callable); @@ -159,19 +159,19 @@ private function getControllerError(mixed $callable): string if (str_contains($callable, '::')) { $callable = explode('::', $callable, 2); } else { - return sprintf('Function "%s" does not exist.', $callable); + return \sprintf('Function "%s" does not exist.', $callable); } } if (\is_object($callable)) { $availableMethods = $this->getClassMethodsWithoutMagicMethods($callable); - $alternativeMsg = $availableMethods ? sprintf(' or use one of the available methods: "%s"', implode('", "', $availableMethods)) : ''; + $alternativeMsg = $availableMethods ? \sprintf(' or use one of the available methods: "%s"', implode('", "', $availableMethods)) : ''; - return sprintf('Controller class "%s" cannot be called without a method name. You need to implement "__invoke"%s.', get_debug_type($callable), $alternativeMsg); + return \sprintf('Controller class "%s" cannot be called without a method name. You need to implement "__invoke"%s.', get_debug_type($callable), $alternativeMsg); } if (!\is_array($callable)) { - return sprintf('Invalid type for controller given, expected string, array or object, got "%s".', get_debug_type($callable)); + return \sprintf('Invalid type for controller given, expected string, array or object, got "%s".', get_debug_type($callable)); } if (!isset($callable[0]) || !isset($callable[1]) || 2 !== \count($callable)) { @@ -181,13 +181,13 @@ private function getControllerError(mixed $callable): string [$controller, $method] = $callable; if (\is_string($controller) && !class_exists($controller)) { - return sprintf('Class "%s" does not exist.', $controller); + return \sprintf('Class "%s" does not exist.', $controller); } $className = \is_object($controller) ? get_debug_type($controller) : $controller; if (method_exists($controller, $method)) { - return sprintf('Method "%s" on class "%s" should be public and non-abstract.', $method, $className); + return \sprintf('Method "%s" on class "%s" should be public and non-abstract.', $method, $className); } $collection = $this->getClassMethodsWithoutMagicMethods($controller); @@ -204,12 +204,12 @@ private function getControllerError(mixed $callable): string asort($alternatives); - $message = sprintf('Expected method "%s" on class "%s"', $method, $className); + $message = \sprintf('Expected method "%s" on class "%s"', $method, $className); if (\count($alternatives) > 0) { - $message .= sprintf(', did you mean "%s"?', implode('", "', $alternatives)); + $message .= \sprintf(', did you mean "%s"?', implode('", "', $alternatives)); } else { - $message .= sprintf('. Available methods: "%s".', implode('", "', $collection)); + $message .= \sprintf('. Available methods: "%s".', implode('", "', $collection)); } return $message; @@ -240,7 +240,7 @@ private function checkController(Request $request, callable $controller): callab $r = new \ReflectionFunction($controller); $name = $r->name; - if (str_contains($name, '{closure}')) { + if (str_contains($name, '{closure')) { $name = $class = \Closure::class; } elseif ($class = \PHP_VERSION_ID >= 80111 ? $r->getClosureCalledClass() : $r->getClosureScopeClass()) { $class = $class->name; @@ -265,7 +265,7 @@ private function checkController(Request $request, callable $controller): callab } if (str_contains($name, '@anonymous')) { - $name = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)[0-9a-fA-F]++/', fn ($m) => class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0], $name); + $name = preg_replace_callback('/[a-zA-Z_\x7f-\xff][\\\\a-zA-Z0-9_\x7f-\xff]*+@anonymous\x00.*?\.php(?:0x?|:[0-9]++\$)?[0-9a-fA-F]++/', fn ($m) => class_exists($m[0], false) ? (get_parent_class($m[0]) ?: key(class_implements($m[0])) ?: 'class').'@anonymous' : $m[0], $name); } if (-1 === $request->attributes->get('_check_controller_is_allowed')) { @@ -274,6 +274,6 @@ private function checkController(Request $request, callable $controller): callab return $controller; } - throw new BadRequestException(sprintf('Callable "%s()" is not allowed as a controller. Did you miss tagging it with "#[AsController]" or registering its type with "%s::allowControllers()"?', $name, self::class)); + throw new BadRequestException(\sprintf('Callable "%s()" is not allowed as a controller. Did you miss tagging it with "#[AsController]" or registering its type with "%s::allowControllers()"?', $name, self::class)); } } diff --git a/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php b/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php index a352090eac..d3ca53fa63 100644 --- a/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php +++ b/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php @@ -94,7 +94,7 @@ public function isNullable(): bool public function getDefaultValue(): mixed { if (!$this->hasDefaultValue) { - throw new \LogicException(sprintf('Argument $%s does not have a default value. Use "%s::hasDefaultValue()" to avoid this exception.', $this->name, __CLASS__)); + throw new \LogicException(\sprintf('Argument $%s does not have a default value. Use "%s::hasDefaultValue()" to avoid this exception.', $this->name, __CLASS__)); } return $this->defaultValue; @@ -106,7 +106,7 @@ public function getDefaultValue(): mixed * * @return array */ - public function getAttributes(string $name = null, int $flags = 0): array + public function getAttributes(?string $name = null, int $flags = 0): array { if (!$name) { return $this->attributes; diff --git a/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php b/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php index cb7f0a78c4..7eafdc94b0 100644 --- a/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php +++ b/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -18,7 +18,7 @@ */ final class ArgumentMetadataFactory implements ArgumentMetadataFactoryInterface { - public function createArgumentMetadata(string|object|array $controller, \ReflectionFunctionAbstract $reflector = null): array + public function createArgumentMetadata(string|object|array $controller, ?\ReflectionFunctionAbstract $reflector = null): array { $arguments = []; $reflector ??= new \ReflectionFunction($controller(...)); diff --git a/lib/symfony/http-kernel/DataCollector/AjaxDataCollector.php b/lib/symfony/http-kernel/DataCollector/AjaxDataCollector.php index 016ef2eceb..3c8d2f0f60 100644 --- a/lib/symfony/http-kernel/DataCollector/AjaxDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/AjaxDataCollector.php @@ -21,7 +21,7 @@ */ class AjaxDataCollector extends DataCollector { - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { // all collecting is done client side } diff --git a/lib/symfony/http-kernel/DataCollector/ConfigDataCollector.php b/lib/symfony/http-kernel/DataCollector/ConfigDataCollector.php index 8a75227d46..ba8fc0c317 100644 --- a/lib/symfony/http-kernel/DataCollector/ConfigDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/ConfigDataCollector.php @@ -30,7 +30,7 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte /** * Sets the Kernel associated with this Request. */ - public function setKernel(KernelInterface $kernel = null): void + public function setKernel(?KernelInterface $kernel = null): void { if (1 > \func_num_args()) { trigger_deprecation('symfony/http-kernel', '6.2', 'Calling "%s()" without any arguments is deprecated, pass null explicitly instead.', __METHOD__); @@ -39,7 +39,7 @@ public function setKernel(KernelInterface $kernel = null): void $this->kernel = $kernel; } - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { $eom = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_MAINTENANCE); $eol = \DateTimeImmutable::createFromFormat('d/m/Y', '01/'.Kernel::END_OF_LIFE); @@ -47,7 +47,7 @@ public function collect(Request $request, Response $response, \Throwable $except $this->data = [ 'token' => $response->headers->get('X-Debug-Token'), 'symfony_version' => Kernel::VERSION, - 'symfony_minor_version' => sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION), + 'symfony_minor_version' => \sprintf('%s.%s', Kernel::MAJOR_VERSION, Kernel::MINOR_VERSION), 'symfony_lts' => 4 === Kernel::MINOR_VERSION, 'symfony_state' => $this->determineSymfonyState(), 'symfony_eom' => $eom->format('F Y'), diff --git a/lib/symfony/http-kernel/DataCollector/DataCollector.php b/lib/symfony/http-kernel/DataCollector/DataCollector.php index d8b795d422..fdc73de06f 100644 --- a/lib/symfony/http-kernel/DataCollector/DataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/DataCollector.php @@ -63,9 +63,21 @@ protected function getCasters() $casters = [ '*' => function ($v, array $a, Stub $s, $isNested) { if (!$v instanceof Stub) { + $b = $a; foreach ($a as $k => $v) { - if (\is_object($v) && !$v instanceof \DateTimeInterface && !$v instanceof Stub) { - $a[$k] = new CutStub($v); + if (!\is_object($v) || $v instanceof \DateTimeInterface || $v instanceof Stub) { + continue; + } + + try { + $a[$k] = $s = new CutStub($v); + + if ($b[$k] === $s) { + // we've hit a non-typed reference + $a[$k] = $v; + } + } catch (\TypeError $e) { + // we've hit a typed reference } } } diff --git a/lib/symfony/http-kernel/DataCollector/DataCollectorInterface.php b/lib/symfony/http-kernel/DataCollector/DataCollectorInterface.php index 8df94ccb8f..5e8593d07c 100644 --- a/lib/symfony/http-kernel/DataCollector/DataCollectorInterface.php +++ b/lib/symfony/http-kernel/DataCollector/DataCollectorInterface.php @@ -27,7 +27,7 @@ interface DataCollectorInterface extends ResetInterface * * @return void */ - public function collect(Request $request, Response $response, \Throwable $exception = null); + public function collect(Request $request, Response $response, ?\Throwable $exception = null); /** * Returns the name of the collector. diff --git a/lib/symfony/http-kernel/DataCollector/DumpDataCollector.php b/lib/symfony/http-kernel/DataCollector/DumpDataCollector.php index ce02b545bf..8c45b42792 100644 --- a/lib/symfony/http-kernel/DataCollector/DumpDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/DumpDataCollector.php @@ -44,7 +44,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface private mixed $sourceContextProvider; private bool $webMode; - public function __construct(Stopwatch $stopwatch = null, string|FileLinkFormatter $fileLinkFormat = null, string $charset = null, RequestStack $requestStack = null, DataDumperInterface|Connection $dumper = null, bool $webMode = null) + public function __construct(?Stopwatch $stopwatch = null, string|FileLinkFormatter|null $fileLinkFormat = null, ?string $charset = null, ?RequestStack $requestStack = null, DataDumperInterface|Connection|null $dumper = null, ?bool $webMode = null) { $fileLinkFormat = $fileLinkFormat ?: \ini_get('xdebug.file_link_format') ?: get_cfg_var('xdebug.file_link_format'); $this->stopwatch = $stopwatch; @@ -100,7 +100,7 @@ public function dump(Data $data): ?string return null; } - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { if (!$this->dataCount) { $this->data = []; @@ -143,10 +143,7 @@ public function reset(): void $this->clonesIndex = 0; } - /** - * @internal - */ - public function __sleep(): array + public function __serialize(): array { if (!$this->dataCount) { $this->data = []; @@ -161,16 +158,12 @@ public function __sleep(): array $this->dataCount = 0; $this->isCollected = true; - return parent::__sleep(); + return ['data' => $this->data]; } - /** - * @internal - */ - public function __wakeup(): void + public function __unserialize(array $data): void { - parent::__wakeup(); - + $this->data = array_pop($data) ?? []; $charset = array_pop($this->data); $fileLinkFormat = array_pop($this->data); $this->dataCount = \count($this->data); @@ -180,7 +173,7 @@ public function __wakeup(): void } } - self::__construct($this->stopwatch, \is_string($fileLinkFormat) || $fileLinkFormat instanceof FileLinkFormatter ? $fileLinkFormat : null, \is_string($charset) ? $charset : null); + self::__construct($this->stopwatch ?? null, \is_string($fileLinkFormat) || $fileLinkFormat instanceof FileLinkFormatter ? $fileLinkFormat : null, \is_string($charset) ? $charset : null); } public function getDumpsCount(): int @@ -196,7 +189,7 @@ public function getDumps(string $format, int $maxDepthLimit = -1, int $maxItemsP $dumper = new HtmlDumper($data, $this->charset); $dumper->setDisplayOptions(['fileLinkFormat' => $this->fileLinkFormat]); } else { - throw new \InvalidArgumentException(sprintf('Invalid dump format: "%s".', $format)); + throw new \InvalidArgumentException(\sprintf('Invalid dump format: "%s".', $format)); } $dumps = []; @@ -263,9 +256,9 @@ private function doDump(DataDumperInterface $dumper, Data $data, string $name, s $f = strip_tags($this->style('', $file)); $name = strip_tags($this->style('', $name)); if ($fmt && $link = \is_string($fmt) ? strtr($fmt, ['%f' => $file, '%l' => $line]) : $fmt->format($file, $line)) { - $name = sprintf(''.$s.'', strip_tags($this->style('', $link)), $f, $name); + $name = \sprintf(''.$s.'', strip_tags($this->style('', $link)), $f, $name); } else { - $name = sprintf(''.$s.'', $f, $name); + $name = \sprintf(''.$s.'', $f, $name); } } else { $name = $this->style('meta', $name); diff --git a/lib/symfony/http-kernel/DataCollector/EventDataCollector.php b/lib/symfony/http-kernel/DataCollector/EventDataCollector.php index a6524ea045..3a94dbc323 100644 --- a/lib/symfony/http-kernel/DataCollector/EventDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/EventDataCollector.php @@ -36,7 +36,7 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter * @param iterable|EventDispatcherInterface|null $dispatchers */ public function __construct( - iterable|EventDispatcherInterface $dispatchers = null, + iterable|EventDispatcherInterface|null $dispatchers = null, private ?RequestStack $requestStack = null, private string $defaultDispatcher = 'event_dispatcher', ) { @@ -46,7 +46,7 @@ public function __construct( $this->dispatchers = $dispatchers ?? []; } - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { $this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null; $this->data = []; @@ -86,7 +86,7 @@ public function getData(): array|Data /** * @see TraceableEventDispatcher */ - public function setCalledListeners(array $listeners, string $dispatcher = null): void + public function setCalledListeners(array $listeners, ?string $dispatcher = null): void { $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] = $listeners; } @@ -94,7 +94,7 @@ public function setCalledListeners(array $listeners, string $dispatcher = null): /** * @see TraceableEventDispatcher */ - public function getCalledListeners(string $dispatcher = null): array|Data + public function getCalledListeners(?string $dispatcher = null): array|Data { return $this->data[$dispatcher ?? $this->defaultDispatcher]['called_listeners'] ?? []; } @@ -102,7 +102,7 @@ public function getCalledListeners(string $dispatcher = null): array|Data /** * @see TraceableEventDispatcher */ - public function setNotCalledListeners(array $listeners, string $dispatcher = null): void + public function setNotCalledListeners(array $listeners, ?string $dispatcher = null): void { $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] = $listeners; } @@ -110,7 +110,7 @@ public function setNotCalledListeners(array $listeners, string $dispatcher = nul /** * @see TraceableEventDispatcher */ - public function getNotCalledListeners(string $dispatcher = null): array|Data + public function getNotCalledListeners(?string $dispatcher = null): array|Data { return $this->data[$dispatcher ?? $this->defaultDispatcher]['not_called_listeners'] ?? []; } @@ -120,7 +120,7 @@ public function getNotCalledListeners(string $dispatcher = null): array|Data * * @see TraceableEventDispatcher */ - public function setOrphanedEvents(array $events, string $dispatcher = null): void + public function setOrphanedEvents(array $events, ?string $dispatcher = null): void { $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] = $events; } @@ -128,7 +128,7 @@ public function setOrphanedEvents(array $events, string $dispatcher = null): voi /** * @see TraceableEventDispatcher */ - public function getOrphanedEvents(string $dispatcher = null): array|Data + public function getOrphanedEvents(?string $dispatcher = null): array|Data { return $this->data[$dispatcher ?? $this->defaultDispatcher]['orphaned_events'] ?? []; } diff --git a/lib/symfony/http-kernel/DataCollector/ExceptionDataCollector.php b/lib/symfony/http-kernel/DataCollector/ExceptionDataCollector.php index 16a29adc18..80156bc8d5 100644 --- a/lib/symfony/http-kernel/DataCollector/ExceptionDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/ExceptionDataCollector.php @@ -22,7 +22,7 @@ */ class ExceptionDataCollector extends DataCollector { - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { if (null !== $exception) { $this->data = [ diff --git a/lib/symfony/http-kernel/DataCollector/LoggerDataCollector.php b/lib/symfony/http-kernel/DataCollector/LoggerDataCollector.php index eb2b9c85ca..cf17e7a739 100644 --- a/lib/symfony/http-kernel/DataCollector/LoggerDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/LoggerDataCollector.php @@ -32,14 +32,14 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte private ?RequestStack $requestStack; private ?array $processedLogs = null; - public function __construct(object $logger = null, string $containerPathPrefix = null, RequestStack $requestStack = null) + public function __construct(?object $logger = null, ?string $containerPathPrefix = null, ?RequestStack $requestStack = null) { $this->logger = DebugLoggerConfigurator::getDebugLogger($logger); $this->containerPathPrefix = $containerPathPrefix; $this->requestStack = $requestStack; } - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { $this->currentRequest = $this->requestStack && $this->requestStack->getMainRequest() !== $request ? $request : null; } @@ -199,7 +199,7 @@ private function getContainerDeprecationLogs(): array return $logs; } - private function getContainerCompilerLogs(string $compilerLogsFilepath = null): array + private function getContainerCompilerLogs(?string $compilerLogsFilepath = null): array { if (!$compilerLogsFilepath || !is_file($compilerLogsFilepath)) { return []; diff --git a/lib/symfony/http-kernel/DataCollector/MemoryDataCollector.php b/lib/symfony/http-kernel/DataCollector/MemoryDataCollector.php index 8b88943675..9715f94eef 100644 --- a/lib/symfony/http-kernel/DataCollector/MemoryDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/MemoryDataCollector.php @@ -26,7 +26,7 @@ public function __construct() $this->reset(); } - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { $this->updateMemoryUsage(); } diff --git a/lib/symfony/http-kernel/DataCollector/RequestDataCollector.php b/lib/symfony/http-kernel/DataCollector/RequestDataCollector.php index eae5f24b7c..4792f160c0 100644 --- a/lib/symfony/http-kernel/DataCollector/RequestDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/RequestDataCollector.php @@ -38,13 +38,13 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter private array $sessionUsages = []; private ?RequestStack $requestStack; - public function __construct(RequestStack $requestStack = null) + public function __construct(?RequestStack $requestStack = null) { $this->controllers = new \SplObjectStorage(); $this->requestStack = $requestStack; } - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { // attributes are serialized and as they can be anything, they need to be converted to strings. $attributes = []; @@ -63,7 +63,7 @@ public function collect(Request $request, Response $response, \Throwable $except $sessionMetadata = []; $sessionAttributes = []; $flashes = []; - if ($request->hasSession()) { + if (!$request->attributes->getBoolean('_stateless') && $request->hasSession()) { $session = $request->getSession(); if ($session->isStarted()) { $sessionMetadata['Created'] = date(\DATE_RFC822, $session->getMetadataBag()->getCreated()); @@ -452,7 +452,7 @@ public function collectSessionUsage(): void array_splice($trace, 0, $traceEndIndex); // Merge identical backtraces generated by internal call reports - $name = sprintf('%s:%s', $trace[1]['class'] ?? $trace[0]['file'], $trace[0]['line']); + $name = \sprintf('%s:%s', $trace[1]['class'] ?? $trace[0]['file'], $trace[0]['line']); if (!\array_key_exists($name, $this->sessionUsages)) { $this->sessionUsages[$name] = [ 'name' => $name, @@ -505,7 +505,7 @@ private function parseController(array|object|string|null $controller): array|st 'line' => $r->getStartLine(), ]; - if (str_contains($r->name, '{closure}')) { + if (str_contains($r->name, '{closure')) { return $controller; } $controller['method'] = $r->name; diff --git a/lib/symfony/http-kernel/DataCollector/RouterDataCollector.php b/lib/symfony/http-kernel/DataCollector/RouterDataCollector.php index 444138da70..75c21e4c59 100644 --- a/lib/symfony/http-kernel/DataCollector/RouterDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/RouterDataCollector.php @@ -34,13 +34,13 @@ public function __construct() /** * @final */ - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { if ($response instanceof RedirectResponse) { $this->data['redirect'] = true; $this->data['url'] = $response->getTargetUrl(); - if ($this->controllers->contains($request)) { + if ($this->controllers->offsetExists($request)) { $this->data['route'] = $this->guessRoute($request, $this->controllers[$request]); } } diff --git a/lib/symfony/http-kernel/DataCollector/TimeDataCollector.php b/lib/symfony/http-kernel/DataCollector/TimeDataCollector.php index a8b7ead940..9799a1333d 100644 --- a/lib/symfony/http-kernel/DataCollector/TimeDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/TimeDataCollector.php @@ -27,14 +27,14 @@ class TimeDataCollector extends DataCollector implements LateDataCollectorInterf private ?KernelInterface $kernel; private ?Stopwatch $stopwatch; - public function __construct(KernelInterface $kernel = null, Stopwatch $stopwatch = null) + public function __construct(?KernelInterface $kernel = null, ?Stopwatch $stopwatch = null) { $this->kernel = $kernel; $this->stopwatch = $stopwatch; $this->data = ['events' => [], 'stopwatch_installed' => false, 'start_time' => 0]; } - public function collect(Request $request, Response $response, \Throwable $exception = null): void + public function collect(Request $request, Response $response, ?\Throwable $exception = null): void { if (null !== $this->kernel) { $startTime = $this->kernel->getStartTime(); diff --git a/lib/symfony/http-kernel/Debug/ErrorHandlerConfigurator.php b/lib/symfony/http-kernel/Debug/ErrorHandlerConfigurator.php index 49f188c22d..5b3e1cdddf 100644 --- a/lib/symfony/http-kernel/Debug/ErrorHandlerConfigurator.php +++ b/lib/symfony/http-kernel/Debug/ErrorHandlerConfigurator.php @@ -36,7 +36,7 @@ class ErrorHandlerConfigurator * @param bool $scream Enables/disables screaming mode, where even silenced errors are logged * @param bool $scope Enables/disables scoping mode */ - public function __construct(LoggerInterface $logger = null, array|int|null $levels = \E_ALL, ?int $throwAt = \E_ALL, bool $scream = true, bool $scope = true, LoggerInterface $deprecationLogger = null) + public function __construct(?LoggerInterface $logger = null, array|int|null $levels = \E_ALL, ?int $throwAt = \E_ALL, bool $scream = true, bool $scope = true, ?LoggerInterface $deprecationLogger = null) { $this->logger = $logger; $this->levels = $levels ?? \E_ALL; diff --git a/lib/symfony/http-kernel/Debug/TraceableEventDispatcher.php b/lib/symfony/http-kernel/Debug/TraceableEventDispatcher.php index d31ce75816..f3101d5b14 100644 --- a/lib/symfony/http-kernel/Debug/TraceableEventDispatcher.php +++ b/lib/symfony/http-kernel/Debug/TraceableEventDispatcher.php @@ -66,7 +66,11 @@ protected function afterDispatch(string $eventName, object $event): void if (null === $sectionId) { break; } - $this->stopwatch->stopSection($sectionId); + try { + $this->stopwatch->stopSection($sectionId); + } catch (\LogicException) { + // The stop watch service might have been reset in the meantime + } break; case KernelEvents::TERMINATE: // In the special case described in the `preDispatch` method above, the `$token` section diff --git a/lib/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php b/lib/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php index f41d58b81b..9a32b8a4eb 100644 --- a/lib/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php +++ b/lib/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php @@ -41,10 +41,10 @@ public function process(ContainerBuilder $container) $class = $container->getParameterBag()->resolveValue($def->getClass()); if (!$r = $container->getReflectionClass($class)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); } if (!$r->isSubclassOf(FragmentRendererInterface::class)) { - throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, FragmentRendererInterface::class)); + throw new InvalidArgumentException(\sprintf('Service "%s" must implement interface "%s".', $id, FragmentRendererInterface::class)); } foreach ($tags as $tag) { diff --git a/lib/symfony/http-kernel/DependencyInjection/LoggerPass.php b/lib/symfony/http-kernel/DependencyInjection/LoggerPass.php index 6270875bec..0061a577c7 100644 --- a/lib/symfony/http-kernel/DependencyInjection/LoggerPass.php +++ b/lib/symfony/http-kernel/DependencyInjection/LoggerPass.php @@ -30,7 +30,9 @@ class LoggerPass implements CompilerPassInterface */ public function process(ContainerBuilder $container) { - $container->setAlias(LoggerInterface::class, 'logger'); + if (!$container->has(LoggerInterface::class)) { + $container->setAlias(LoggerInterface::class, 'logger'); + } if ($container->has('logger')) { return; diff --git a/lib/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php b/lib/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php index f2cf2422b0..e2f50dcba1 100644 --- a/lib/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php +++ b/lib/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php @@ -45,6 +45,7 @@ public function process(ContainerBuilder $container) $parameterBag = $container->getParameterBag(); $controllers = []; + $controllerClasses = []; $publicAliases = []; foreach ($container->getAliases() as $id => $alias) { @@ -58,6 +59,7 @@ public function process(ContainerBuilder $container) foreach ($container->findTaggedServiceIds('controller.service_arguments', true) as $id => $tags) { $def = $container->getDefinition($id); $def->setPublic(true); + $def->setLazy(false); $class = $def->getClass(); $autowire = $def->isAutowired(); $bindings = $def->getBindings(); @@ -71,9 +73,11 @@ public function process(ContainerBuilder $container) $class = $parameterBag->resolveValue($class); if (!$r = $container->getReflectionClass($class)) { - throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); + throw new InvalidArgumentException(\sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id)); } + $controllerClasses[] = $class; + // get regular public methods $methods = []; $arguments = []; @@ -94,11 +98,11 @@ public function process(ContainerBuilder $container) } foreach (['action', 'argument', 'id'] as $k) { if (!isset($attributes[$k][0])) { - throw new InvalidArgumentException(sprintf('Missing "%s" attribute on tag "controller.service_arguments" %s for service "%s".', $k, json_encode($attributes, \JSON_UNESCAPED_UNICODE), $id)); + throw new InvalidArgumentException(\sprintf('Missing "%s" attribute on tag "controller.service_arguments" %s for service "%s".', $k, json_encode($attributes, \JSON_UNESCAPED_UNICODE), $id)); } } if (!isset($methods[$action = strtolower($attributes['action'])])) { - throw new InvalidArgumentException(sprintf('Invalid "action" attribute on tag "controller.service_arguments" for service "%s": no public "%s()" method found on class "%s".', $id, $attributes['action'], $class)); + throw new InvalidArgumentException(\sprintf('Invalid "action" attribute on tag "controller.service_arguments" for service "%s": no public "%s()" method found on class "%s".', $id, $attributes['action'], $class)); } [$r, $parameters] = $methods[$action]; $found = false; @@ -114,7 +118,7 @@ public function process(ContainerBuilder $container) } if (!$found) { - throw new InvalidArgumentException(sprintf('Invalid "controller.service_arguments" tag for service "%s": method "%s()" has no "%s" argument on class "%s".', $id, $r->name, $attributes['argument'], $class)); + throw new InvalidArgumentException(\sprintf('Invalid "controller.service_arguments" tag for service "%s": method "%s()" has no "%s" argument on class "%s".', $id, $r->name, $attributes['argument'], $class)); } } @@ -136,7 +140,7 @@ public function process(ContainerBuilder $container) if ('?' !== $target[0]) { $invalidBehavior = ContainerInterface::RUNTIME_EXCEPTION_ON_INVALID_REFERENCE; } elseif ('' === $target = (string) substr($target, 1)) { - throw new InvalidArgumentException(sprintf('A "controller.service_arguments" tag must have non-empty "id" attributes for service "%s".', $id)); + throw new InvalidArgumentException(\sprintf('A "controller.service_arguments" tag must have non-empty "id" attributes for service "%s".', $id)); } elseif ($p->allowsNull() && !$p->isOptional()) { $invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE; } @@ -155,7 +159,7 @@ public function process(ContainerBuilder $container) continue; } elseif (!$autowire || (!($autowireAttributes ??= $p->getAttributes(Autowire::class, \ReflectionAttribute::IS_INSTANCEOF)) && (!$type || '\\' !== $target[0]))) { continue; - } elseif (is_subclass_of($type, \UnitEnum::class)) { + } elseif (!$autowireAttributes && is_subclass_of($type, \UnitEnum::class)) { // do not attempt to register enum typed arguments if not already present in bindings continue; } elseif (!$p->allowsNull()) { @@ -187,7 +191,7 @@ public function process(ContainerBuilder $container) } if ($type && !$p->isOptional() && !$p->allowsNull() && !class_exists($type) && !interface_exists($type, false)) { - $message = sprintf('Cannot determine controller argument for "%s::%s()": the $%s argument is type-hinted with the non-existent class or interface: "%s".', $class, $r->name, $p->name, $type); + $message = \sprintf('Cannot determine controller argument for "%s::%s()": the $%s argument is type-hinted with the non-existent class or interface: "%s".', $class, $r->name, $p->name, $type); // see if the type-hint lives in the same namespace as the controller if (0 === strncmp($type, $class, strrpos($class, '\\'))) { @@ -227,5 +231,10 @@ public function process(ContainerBuilder $container) } $container->setAlias('argument_resolver.controller_locator', (string) $controllerLocatorRef); + + if ($container->hasDefinition('controller_resolver')) { + $container->getDefinition('controller_resolver') + ->addMethodCall('allowControllers', [array_unique($controllerClasses)]); + } } } diff --git a/lib/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php b/lib/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php index 7a21fe0e59..ef859a611b 100644 --- a/lib/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php +++ b/lib/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php @@ -34,7 +34,7 @@ public function process(ContainerBuilder $container) if (!$argumentLocator->getArgument(0)) { // remove empty argument locators - $reason = sprintf('Removing service-argument resolver for controller "%s": no corresponding services exist for the referenced types.', $controller); + $reason = \sprintf('Removing service-argument resolver for controller "%s": no corresponding services exist for the referenced types.', $controller); } else { // any methods listed for call-at-instantiation cannot be actions $reason = false; @@ -47,7 +47,7 @@ public function process(ContainerBuilder $container) $controllerDef = $container->getDefinition($id); foreach ($controllerDef->getMethodCalls() as [$method]) { if (0 === strcasecmp($action, $method)) { - $reason = sprintf('Removing method "%s" of service "%s" from controller candidates: the method is called at instantiation, thus cannot be an action.', $action, $id); + $reason = \sprintf('Removing method "%s" of service "%s" from controller candidates: the method is called at instantiation, thus cannot be an action.', $action, $id); break; } } diff --git a/lib/symfony/http-kernel/DependencyInjection/ResettableServicePass.php b/lib/symfony/http-kernel/DependencyInjection/ResettableServicePass.php index da9f8d6320..8479c8d630 100644 --- a/lib/symfony/http-kernel/DependencyInjection/ResettableServicePass.php +++ b/lib/symfony/http-kernel/DependencyInjection/ResettableServicePass.php @@ -39,7 +39,7 @@ public function process(ContainerBuilder $container) foreach ($tags as $attributes) { if (!isset($attributes['method'])) { - throw new RuntimeException(sprintf('Tag "kernel.reset" requires the "method" attribute to be set on service "%s".', $id)); + throw new RuntimeException(\sprintf('Tag "kernel.reset" requires the "method" attribute to be set on service "%s".', $id)); } if (!isset($methods[$id])) { diff --git a/lib/symfony/http-kernel/Event/ControllerArgumentsEvent.php b/lib/symfony/http-kernel/Event/ControllerArgumentsEvent.php index c90b7706f2..4c804ccf19 100644 --- a/lib/symfony/http-kernel/Event/ControllerArgumentsEvent.php +++ b/lib/symfony/http-kernel/Event/ControllerArgumentsEvent.php @@ -52,7 +52,7 @@ public function getController(): callable /** * @param array>|null $attributes */ - public function setController(callable $controller, array $attributes = null): void + public function setController(callable $controller, ?array $attributes = null): void { $this->controllerEvent->setController($controller, $attributes); unset($this->namedArguments); @@ -102,7 +102,7 @@ public function getNamedArguments(): array * * @psalm-return (T is null ? array> : list) */ - public function getAttributes(string $className = null): array + public function getAttributes(?string $className = null): array { return $this->controllerEvent->getAttributes($className); } diff --git a/lib/symfony/http-kernel/Event/ControllerEvent.php b/lib/symfony/http-kernel/Event/ControllerEvent.php index 239b00512f..6db2c15f9e 100644 --- a/lib/symfony/http-kernel/Event/ControllerEvent.php +++ b/lib/symfony/http-kernel/Event/ControllerEvent.php @@ -51,7 +51,7 @@ public function getControllerReflector(): \ReflectionFunctionAbstract /** * @param array>|null $attributes */ - public function setController(callable $controller, array $attributes = null): void + public function setController(callable $controller, ?array $attributes = null): void { if (null !== $attributes) { $this->attributes = $attributes; @@ -70,7 +70,7 @@ public function setController(callable $controller, array $attributes = null): v if (\is_array($controller) && method_exists(...$controller)) { $this->controllerReflector = new \ReflectionMethod(...$controller); } elseif (\is_string($controller) && str_contains($controller, '::')) { - $this->controllerReflector = new \ReflectionMethod($controller); + $this->controllerReflector = new \ReflectionMethod(...explode('::', $controller, 2)); } else { $this->controllerReflector = new \ReflectionFunction($controller(...)); } @@ -87,7 +87,7 @@ public function setController(callable $controller, array $attributes = null): v * * @psalm-return (T is null ? array> : list) */ - public function getAttributes(string $className = null): array + public function getAttributes(?string $className = null): array { if (isset($this->attributes)) { return null === $className ? $this->attributes : $this->attributes[$className] ?? []; @@ -98,7 +98,7 @@ public function getAttributes(string $className = null): array } elseif (\is_string($this->controller) && false !== $i = strpos($this->controller, '::')) { $class = new \ReflectionClass(substr($this->controller, 0, $i)); } else { - $class = str_contains($this->controllerReflector->name, '{closure}') ? null : (\PHP_VERSION_ID >= 80111 ? $this->controllerReflector->getClosureCalledClass() : $this->controllerReflector->getClosureScopeClass()); + $class = str_contains($this->controllerReflector->name, '{closure') ? null : (\PHP_VERSION_ID >= 80111 ? $this->controllerReflector->getClosureCalledClass() : $this->controllerReflector->getClosureScopeClass()); } $this->attributes = []; diff --git a/lib/symfony/http-kernel/Event/KernelEvent.php b/lib/symfony/http-kernel/Event/KernelEvent.php index e64cc419b9..02426c52a1 100644 --- a/lib/symfony/http-kernel/Event/KernelEvent.php +++ b/lib/symfony/http-kernel/Event/KernelEvent.php @@ -16,7 +16,7 @@ use Symfony\Contracts\EventDispatcher\Event; /** - * Base class for events thrown in the HttpKernel component. + * Base class for events dispatched in the HttpKernel component. * * @author Bernhard Schussek */ diff --git a/lib/symfony/http-kernel/Event/ViewEvent.php b/lib/symfony/http-kernel/Event/ViewEvent.php index bf96985b29..4d963aea1f 100644 --- a/lib/symfony/http-kernel/Event/ViewEvent.php +++ b/lib/symfony/http-kernel/Event/ViewEvent.php @@ -28,7 +28,7 @@ final class ViewEvent extends RequestEvent public readonly ?ControllerArgumentsEvent $controllerArgumentsEvent; private mixed $controllerResult; - public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, mixed $controllerResult, ControllerArgumentsEvent $controllerArgumentsEvent = null) + public function __construct(HttpKernelInterface $kernel, Request $request, int $requestType, mixed $controllerResult, ?ControllerArgumentsEvent $controllerArgumentsEvent = null) { parent::__construct($kernel, $request, $requestType); diff --git a/lib/symfony/http-kernel/EventListener/AbstractSessionListener.php b/lib/symfony/http-kernel/EventListener/AbstractSessionListener.php index 2f012ab522..1ce4905376 100644 --- a/lib/symfony/http-kernel/EventListener/AbstractSessionListener.php +++ b/lib/symfony/http-kernel/EventListener/AbstractSessionListener.php @@ -55,7 +55,7 @@ abstract class AbstractSessionListener implements EventSubscriberInterface, Rese /** * @internal */ - public function __construct(ContainerInterface $container = null, bool $debug = false, array $sessionOptions = []) + public function __construct(?ContainerInterface $container = null, bool $debug = false, array $sessionOptions = []) { $this->container = $container; $this->debug = $debug; diff --git a/lib/symfony/http-kernel/EventListener/CacheAttributeListener.php b/lib/symfony/http-kernel/EventListener/CacheAttributeListener.php index 723e758cd0..310e7f25a4 100644 --- a/lib/symfony/http-kernel/EventListener/CacheAttributeListener.php +++ b/lib/symfony/http-kernel/EventListener/CacheAttributeListener.php @@ -13,6 +13,7 @@ use Symfony\Component\EventDispatcher\EventSubscriberInterface; use Symfony\Component\ExpressionLanguage\ExpressionLanguage; +use Symfony\Component\HttpFoundation\HeaderBag; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Attribute\Cache; @@ -123,10 +124,23 @@ public function onKernelResponse(ResponseEvent $event) unset($this->lastModified[$request]); unset($this->etags[$request]); - $hasVary = $response->headers->has('Vary'); + // Check if the response has a Vary header that should be considered, ignoring cases where + // it's only 'Accept-Language' and the request has the '_vary_by_language' attribute + $hasVary = ['Accept-Language'] === $response->getVary() ? !$request->attributes->get('_vary_by_language') : $response->hasVary(); + //Check if cache-control directive was set manually in cacheControl (not auto computed) + $hasCacheControlDirective = new class($response->headers) extends HeaderBag { + public function __construct(private parent $headerBag) + { + } + + public function __invoke(string $key): bool + { + return \array_key_exists($key, $this->headerBag->cacheControl); + } + }; foreach (array_reverse($attributes) as $cache) { - if (null !== $cache->smaxage && !$response->headers->hasCacheControlDirective('s-maxage')) { + if (null !== $cache->smaxage && !$hasCacheControlDirective('s-maxage')) { $response->setSharedMaxAge($this->toSeconds($cache->smaxage)); } @@ -134,19 +148,19 @@ public function onKernelResponse(ResponseEvent $event) $response->headers->addCacheControlDirective('must-revalidate'); } - if (null !== $cache->maxage && !$response->headers->hasCacheControlDirective('max-age')) { + if (null !== $cache->maxage && !$hasCacheControlDirective('max-age')) { $response->setMaxAge($this->toSeconds($cache->maxage)); } - if (null !== $cache->maxStale && !$response->headers->hasCacheControlDirective('max-stale')) { + if (null !== $cache->maxStale && !$hasCacheControlDirective('max-stale')) { $response->headers->addCacheControlDirective('max-stale', $this->toSeconds($cache->maxStale)); } - if (null !== $cache->staleWhileRevalidate && !$response->headers->hasCacheControlDirective('stale-while-revalidate')) { + if (null !== $cache->staleWhileRevalidate && !$hasCacheControlDirective('stale-while-revalidate')) { $response->headers->addCacheControlDirective('stale-while-revalidate', $this->toSeconds($cache->staleWhileRevalidate)); } - if (null !== $cache->staleIfError && !$response->headers->hasCacheControlDirective('stale-if-error')) { + if (null !== $cache->staleIfError && !$hasCacheControlDirective('stale-if-error')) { $response->headers->addCacheControlDirective('stale-if-error', $this->toSeconds($cache->staleIfError)); } @@ -159,12 +173,14 @@ public function onKernelResponse(ResponseEvent $event) } } + $hasPublicOrPrivateCacheControlDirective = $hasCacheControlDirective('public') || $hasCacheControlDirective('private'); + foreach ($attributes as $cache) { - if (true === $cache->public) { + if (true === $cache->public && !$hasPublicOrPrivateCacheControlDirective) { $response->setPublic(); } - if (false === $cache->public) { + if (false === $cache->public && !$hasPublicOrPrivateCacheControlDirective) { $response->setPrivate(); } } diff --git a/lib/symfony/http-kernel/EventListener/DebugHandlersListener.php b/lib/symfony/http-kernel/EventListener/DebugHandlersListener.php index ce746bd125..ee720b1ea6 100644 --- a/lib/symfony/http-kernel/EventListener/DebugHandlersListener.php +++ b/lib/symfony/http-kernel/EventListener/DebugHandlersListener.php @@ -41,13 +41,14 @@ class DebugHandlersListener implements EventSubscriberInterface * @param bool $webMode * @param callable|null $exceptionHandler A handler that must support \Throwable instances that will be called on Exception */ - public function __construct(callable $exceptionHandler = null, bool|LoggerInterface $webMode = null) + public function __construct(?callable $exceptionHandler = null, bool|LoggerInterface|null $webMode = null) { if ($webMode instanceof LoggerInterface) { // BC with Symfony 5 $webMode = null; } - $handler = set_exception_handler('is_int'); + + $handler = set_exception_handler('var_dump'); $this->earlyHandler = \is_array($handler) ? $handler[0] : null; restore_exception_handler(); @@ -58,7 +59,7 @@ public function __construct(callable $exceptionHandler = null, bool|LoggerInterf /** * Configures the error handler. */ - public function configure(object $event = null): void + public function configure(?object $event = null): void { if ($event instanceof ConsoleEvent && $this->webMode) { return; @@ -67,6 +68,7 @@ public function configure(object $event = null): void return; } $this->firstCall = $this->hasTerminatedWithException = false; + $hasRun = null; if (!$this->exceptionHandler) { if ($event instanceof KernelEvent) { @@ -93,7 +95,7 @@ public function configure(object $event = null): void } } if ($this->exceptionHandler) { - $handler = set_exception_handler(static fn () => null); + $handler = set_exception_handler('var_dump'); $handler = \is_array($handler) ? $handler[0] : null; restore_exception_handler(); @@ -103,6 +105,19 @@ public function configure(object $event = null): void if ($handler instanceof ErrorHandler) { $handler->setExceptionHandler($this->exceptionHandler); + if (null !== $hasRun) { + $throwAt = $handler->throwAt(0) | \E_ERROR | \E_CORE_ERROR | \E_COMPILE_ERROR | \E_USER_ERROR | \E_RECOVERABLE_ERROR | \E_PARSE; + $loggers = []; + + foreach ($handler->setLoggers([]) as $type => $log) { + if ($type & $throwAt) { + $loggers[$type] = [null, $log[1]]; + } + } + + // Assume $kernel->terminateWithException() will log uncaught exceptions appropriately + $handler->setLoggers($loggers); + } } $this->exceptionHandler = null; } diff --git a/lib/symfony/http-kernel/EventListener/DumpListener.php b/lib/symfony/http-kernel/EventListener/DumpListener.php index b10bd37f43..07a4e7e6a0 100644 --- a/lib/symfony/http-kernel/EventListener/DumpListener.php +++ b/lib/symfony/http-kernel/EventListener/DumpListener.php @@ -29,7 +29,7 @@ class DumpListener implements EventSubscriberInterface private DataDumperInterface $dumper; private ?Connection $connection; - public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper, Connection $connection = null) + public function __construct(ClonerInterface $cloner, DataDumperInterface $dumper, ?Connection $connection = null) { $this->cloner = $cloner; $this->dumper = $dumper; @@ -45,7 +45,7 @@ public function configure() $dumper = $this->dumper; $connection = $this->connection; - VarDumper::setHandler(static function ($var, string $label = null) use ($cloner, $dumper, $connection) { + VarDumper::setHandler(static function ($var, ?string $label = null) use ($cloner, $dumper, $connection) { $data = $cloner->cloneVar($var); if (null !== $label) { $data = $data->withContext(['label' => $label]); diff --git a/lib/symfony/http-kernel/EventListener/ErrorListener.php b/lib/symfony/http-kernel/EventListener/ErrorListener.php index a2f6db57a6..266d96cf8e 100644 --- a/lib/symfony/http-kernel/EventListener/ErrorListener.php +++ b/lib/symfony/http-kernel/EventListener/ErrorListener.php @@ -44,7 +44,7 @@ class ErrorListener implements EventSubscriberInterface /** * @param array|null}> $exceptionsMapping */ - public function __construct(string|object|array|null $controller, LoggerInterface $logger = null, bool $debug = false, array $exceptionsMapping = []) + public function __construct(string|object|array|null $controller, ?LoggerInterface $logger = null, bool $debug = false, array $exceptionsMapping = []) { $this->controller = $controller; $this->logger = $logger; @@ -90,7 +90,7 @@ public function logKernelException(ExceptionEvent $event) $e = FlattenException::createFromThrowable($throwable); - $this->logException($throwable, sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), basename($e->getFile()), $e->getLine()), $logLevel); + $this->logException($throwable, \sprintf('Uncaught PHP Exception %s: "%s" at %s line %s', $e->getClass(), $e->getMessage(), basename($e->getFile()), $e->getLine()), $logLevel); } /** @@ -104,11 +104,11 @@ public function onKernelException(ExceptionEvent $event) $throwable = $event->getThrowable(); - if ($exceptionHandler = set_exception_handler(var_dump(...))) { - restore_exception_handler(); - if (\is_array($exceptionHandler) && $exceptionHandler[0] instanceof ErrorHandler) { - $throwable = $exceptionHandler[0]->enhanceError($event->getThrowable()); - } + $exceptionHandler = set_exception_handler('var_dump'); + restore_exception_handler(); + + if (\is_array($exceptionHandler) && $exceptionHandler[0] instanceof ErrorHandler) { + $throwable = $exceptionHandler[0]->enhanceError($event->getThrowable()); } $request = $this->duplicateRequest($throwable, $event->getRequest()); @@ -118,7 +118,7 @@ public function onKernelException(ExceptionEvent $event) } catch (\Exception $e) { $f = FlattenException::createFromThrowable($e); - $this->logException($e, sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', $f->getClass(), $f->getMessage(), basename($e->getFile()), $e->getLine())); + $this->logException($e, \sprintf('Exception thrown when handling an exception (%s: %s at %s line %s)', $f->getClass(), $f->getMessage(), basename($e->getFile()), $e->getLine())); $prev = $e; do { @@ -183,7 +183,7 @@ public static function getSubscribedEvents(): array /** * Logs an exception. */ - protected function logException(\Throwable $exception, string $message, string $logLevel = null): void + protected function logException(\Throwable $exception, string $message, ?string $logLevel = null): void { if (null === $this->logger) { return; diff --git a/lib/symfony/http-kernel/EventListener/LocaleListener.php b/lib/symfony/http-kernel/EventListener/LocaleListener.php index 65a3bfde46..9feaa0b4f8 100644 --- a/lib/symfony/http-kernel/EventListener/LocaleListener.php +++ b/lib/symfony/http-kernel/EventListener/LocaleListener.php @@ -35,7 +35,7 @@ class LocaleListener implements EventSubscriberInterface private bool $useAcceptLanguageHeader; private array $enabledLocales; - public function __construct(RequestStack $requestStack, string $defaultLocale = 'en', RequestContextAwareInterface $router = null, bool $useAcceptLanguageHeader = false, array $enabledLocales = []) + public function __construct(RequestStack $requestStack, string $defaultLocale = 'en', ?RequestContextAwareInterface $router = null, bool $useAcceptLanguageHeader = false, array $enabledLocales = []) { $this->defaultLocale = $defaultLocale; $this->requestStack = $requestStack; diff --git a/lib/symfony/http-kernel/EventListener/ProfilerListener.php b/lib/symfony/http-kernel/EventListener/ProfilerListener.php index 716d939fd0..1f30582f4a 100644 --- a/lib/symfony/http-kernel/EventListener/ProfilerListener.php +++ b/lib/symfony/http-kernel/EventListener/ProfilerListener.php @@ -48,7 +48,7 @@ class ProfilerListener implements EventSubscriberInterface * @param bool $onlyException True if the profiler only collects data when an exception occurs, false otherwise * @param bool $onlyMainRequests True if the profiler only collects data when the request is the main request, false otherwise */ - public function __construct(Profiler $profiler, RequestStack $requestStack, RequestMatcherInterface $matcher = null, bool $onlyException = false, bool $onlyMainRequests = false, string $collectParameter = null) + public function __construct(Profiler $profiler, RequestStack $requestStack, ?RequestMatcherInterface $matcher = null, bool $onlyException = false, bool $onlyMainRequests = false, ?string $collectParameter = null) { $this->profiler = $profiler; $this->matcher = $matcher; @@ -97,7 +97,7 @@ public function onKernelResponse(ResponseEvent $event): void return; } - $session = $request->hasPreviousSession() ? $request->getSession() : null; + $session = !$request->attributes->getBoolean('_stateless') && $request->hasPreviousSession() ? $request->getSession() : null; if ($session instanceof Session) { $usageIndexValue = $usageIndexReference = &$session->getUsageIndex(); diff --git a/lib/symfony/http-kernel/EventListener/RouterListener.php b/lib/symfony/http-kernel/EventListener/RouterListener.php index bb393c7799..fd8ac1a5c6 100644 --- a/lib/symfony/http-kernel/EventListener/RouterListener.php +++ b/lib/symfony/http-kernel/EventListener/RouterListener.php @@ -53,7 +53,7 @@ class RouterListener implements EventSubscriberInterface * * @throws \InvalidArgumentException */ - public function __construct(UrlMatcherInterface|RequestMatcherInterface $matcher, RequestStack $requestStack, RequestContext $context = null, LoggerInterface $logger = null, string $projectDir = null, bool $debug = true) + public function __construct(UrlMatcherInterface|RequestMatcherInterface $matcher, RequestStack $requestStack, ?RequestContext $context = null, ?LoggerInterface $logger = null, ?string $projectDir = null, bool $debug = true) { if (null === $context && !$matcher instanceof RequestContextAwareInterface) { throw new \InvalidArgumentException('You must either pass a RequestContext or the matcher must implement RequestContextAwareInterface.'); @@ -118,15 +118,15 @@ public function onKernelRequest(RequestEvent $event): void unset($parameters['_route'], $parameters['_controller']); $request->attributes->set('_route_params', $parameters); } catch (ResourceNotFoundException $e) { - $message = sprintf('No route found for "%s %s"', $request->getMethod(), $request->getUriForPath($request->getPathInfo())); + $message = \sprintf('No route found for "%s %s"', $request->getMethod(), $request->getUriForPath($request->getPathInfo())); if ($referer = $request->headers->get('referer')) { - $message .= sprintf(' (from "%s")', $referer); + $message .= \sprintf(' (from "%s")', $referer); } throw new NotFoundHttpException($message, $e); } catch (MethodNotAllowedException $e) { - $message = sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getUriForPath($request->getPathInfo()), implode(', ', $e->getAllowedMethods())); + $message = \sprintf('No route found for "%s %s": Method Not Allowed (Allow: %s)', $request->getMethod(), $request->getUriForPath($request->getPathInfo()), implode(', ', $e->getAllowedMethods())); throw new MethodNotAllowedHttpException($e->getAllowedMethods(), $message, $e); } diff --git a/lib/symfony/http-kernel/EventListener/SurrogateListener.php b/lib/symfony/http-kernel/EventListener/SurrogateListener.php index 17bdf2b392..a702a68f84 100644 --- a/lib/symfony/http-kernel/EventListener/SurrogateListener.php +++ b/lib/symfony/http-kernel/EventListener/SurrogateListener.php @@ -28,7 +28,7 @@ class SurrogateListener implements EventSubscriberInterface { private ?SurrogateInterface $surrogate; - public function __construct(SurrogateInterface $surrogate = null) + public function __construct(?SurrogateInterface $surrogate = null) { $this->surrogate = $surrogate; } diff --git a/lib/symfony/http-kernel/Exception/AccessDeniedHttpException.php b/lib/symfony/http-kernel/Exception/AccessDeniedHttpException.php index 78e8fe37d6..0f9ea715c0 100644 --- a/lib/symfony/http-kernel/Exception/AccessDeniedHttpException.php +++ b/lib/symfony/http-kernel/Exception/AccessDeniedHttpException.php @@ -17,7 +17,7 @@ */ class AccessDeniedHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(403, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/BadRequestHttpException.php b/lib/symfony/http-kernel/Exception/BadRequestHttpException.php index c920fbd0d6..57a7a2583e 100644 --- a/lib/symfony/http-kernel/Exception/BadRequestHttpException.php +++ b/lib/symfony/http-kernel/Exception/BadRequestHttpException.php @@ -16,7 +16,7 @@ */ class BadRequestHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(400, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/ConflictHttpException.php b/lib/symfony/http-kernel/Exception/ConflictHttpException.php index a5a6f8405c..997c4a6816 100644 --- a/lib/symfony/http-kernel/Exception/ConflictHttpException.php +++ b/lib/symfony/http-kernel/Exception/ConflictHttpException.php @@ -16,7 +16,7 @@ */ class ConflictHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(409, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/GoneHttpException.php b/lib/symfony/http-kernel/Exception/GoneHttpException.php index 2893f05cbc..c40d597cc0 100644 --- a/lib/symfony/http-kernel/Exception/GoneHttpException.php +++ b/lib/symfony/http-kernel/Exception/GoneHttpException.php @@ -16,7 +16,7 @@ */ class GoneHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(410, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/HttpException.php b/lib/symfony/http-kernel/Exception/HttpException.php index e12abce004..6d2c253a33 100644 --- a/lib/symfony/http-kernel/Exception/HttpException.php +++ b/lib/symfony/http-kernel/Exception/HttpException.php @@ -21,7 +21,7 @@ class HttpException extends \RuntimeException implements HttpExceptionInterface private int $statusCode; private array $headers; - public function __construct(int $statusCode, string $message = '', \Throwable $previous = null, array $headers = [], int $code = 0) + public function __construct(int $statusCode, string $message = '', ?\Throwable $previous = null, array $headers = [], int $code = 0) { $this->statusCode = $statusCode; $this->headers = $headers; diff --git a/lib/symfony/http-kernel/Exception/LengthRequiredHttpException.php b/lib/symfony/http-kernel/Exception/LengthRequiredHttpException.php index a3dd8b3cd7..ca8741e409 100644 --- a/lib/symfony/http-kernel/Exception/LengthRequiredHttpException.php +++ b/lib/symfony/http-kernel/Exception/LengthRequiredHttpException.php @@ -16,7 +16,7 @@ */ class LengthRequiredHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(411, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/LockedHttpException.php b/lib/symfony/http-kernel/Exception/LockedHttpException.php index 069619bfc2..3f05c2277b 100644 --- a/lib/symfony/http-kernel/Exception/LockedHttpException.php +++ b/lib/symfony/http-kernel/Exception/LockedHttpException.php @@ -16,7 +16,7 @@ */ class LockedHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(423, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php b/lib/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php index cfbaf5cb02..33572e461b 100644 --- a/lib/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php +++ b/lib/symfony/http-kernel/Exception/MethodNotAllowedHttpException.php @@ -19,7 +19,7 @@ class MethodNotAllowedHttpException extends HttpException /** * @param string[] $allow An array of allowed methods */ - public function __construct(array $allow, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(array $allow, string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { $headers['Allow'] = strtoupper(implode(', ', $allow)); diff --git a/lib/symfony/http-kernel/Exception/NotAcceptableHttpException.php b/lib/symfony/http-kernel/Exception/NotAcceptableHttpException.php index ec2bb596fc..13e9c2312f 100644 --- a/lib/symfony/http-kernel/Exception/NotAcceptableHttpException.php +++ b/lib/symfony/http-kernel/Exception/NotAcceptableHttpException.php @@ -16,7 +16,7 @@ */ class NotAcceptableHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(406, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/NotFoundHttpException.php b/lib/symfony/http-kernel/Exception/NotFoundHttpException.php index 0e78fcc155..e1b489eed2 100644 --- a/lib/symfony/http-kernel/Exception/NotFoundHttpException.php +++ b/lib/symfony/http-kernel/Exception/NotFoundHttpException.php @@ -16,7 +16,7 @@ */ class NotFoundHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(404, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/PreconditionFailedHttpException.php b/lib/symfony/http-kernel/Exception/PreconditionFailedHttpException.php index 4431f89d03..8ec710e41f 100644 --- a/lib/symfony/http-kernel/Exception/PreconditionFailedHttpException.php +++ b/lib/symfony/http-kernel/Exception/PreconditionFailedHttpException.php @@ -16,7 +16,7 @@ */ class PreconditionFailedHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(412, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php b/lib/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php index f75afd3706..848876939a 100644 --- a/lib/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php +++ b/lib/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php @@ -18,7 +18,7 @@ */ class PreconditionRequiredHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(428, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/ResolverNotFoundException.php b/lib/symfony/http-kernel/Exception/ResolverNotFoundException.php index 6d9fb8a01f..aa859d5115 100644 --- a/lib/symfony/http-kernel/Exception/ResolverNotFoundException.php +++ b/lib/symfony/http-kernel/Exception/ResolverNotFoundException.php @@ -18,7 +18,7 @@ class ResolverNotFoundException extends \RuntimeException */ public function __construct(string $name, array $alternatives = []) { - $msg = sprintf('You have requested a non-existent resolver "%s".', $name); + $msg = \sprintf('You have requested a non-existent resolver "%s".', $name); if ($alternatives) { if (1 === \count($alternatives)) { $msg .= ' Did you mean this: "'; diff --git a/lib/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php b/lib/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php index d4862bd109..842271dc92 100644 --- a/lib/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php +++ b/lib/symfony/http-kernel/Exception/ServiceUnavailableHttpException.php @@ -19,7 +19,7 @@ class ServiceUnavailableHttpException extends HttpException /** * @param int|string|null $retryAfter The number of seconds or HTTP-date after which the request may be retried */ - public function __construct(int|string $retryAfter = null, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(int|string|null $retryAfter = null, string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { if ($retryAfter) { $headers['Retry-After'] = $retryAfter; diff --git a/lib/symfony/http-kernel/Exception/TooManyRequestsHttpException.php b/lib/symfony/http-kernel/Exception/TooManyRequestsHttpException.php index b71fb2508f..2f749aa262 100644 --- a/lib/symfony/http-kernel/Exception/TooManyRequestsHttpException.php +++ b/lib/symfony/http-kernel/Exception/TooManyRequestsHttpException.php @@ -21,7 +21,7 @@ class TooManyRequestsHttpException extends HttpException /** * @param int|string|null $retryAfter The number of seconds or HTTP-date after which the request may be retried */ - public function __construct(int|string $retryAfter = null, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(int|string|null $retryAfter = null, string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { if ($retryAfter) { $headers['Retry-After'] = $retryAfter; diff --git a/lib/symfony/http-kernel/Exception/UnauthorizedHttpException.php b/lib/symfony/http-kernel/Exception/UnauthorizedHttpException.php index c866861281..de8f314b4f 100644 --- a/lib/symfony/http-kernel/Exception/UnauthorizedHttpException.php +++ b/lib/symfony/http-kernel/Exception/UnauthorizedHttpException.php @@ -19,7 +19,7 @@ class UnauthorizedHttpException extends HttpException /** * @param string $challenge WWW-Authenticate challenge string */ - public function __construct(string $challenge, string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $challenge, string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { $headers['WWW-Authenticate'] = $challenge; diff --git a/lib/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php b/lib/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php index d58af6c2b6..162aa30d6b 100644 --- a/lib/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php +++ b/lib/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php @@ -16,7 +16,7 @@ */ class UnprocessableEntityHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(422, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php b/lib/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php index 3060f1f918..736337bab0 100644 --- a/lib/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php +++ b/lib/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php @@ -16,7 +16,7 @@ */ class UnsupportedMediaTypeHttpException extends HttpException { - public function __construct(string $message = '', \Throwable $previous = null, int $code = 0, array $headers = []) + public function __construct(string $message = '', ?\Throwable $previous = null, int $code = 0, array $headers = []) { parent::__construct(415, $message, $previous, $headers, $code); } diff --git a/lib/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php b/lib/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php index 55305d44e1..7eea1aed44 100644 --- a/lib/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php +++ b/lib/symfony/http-kernel/Fragment/AbstractSurrogateFragmentRenderer.php @@ -34,7 +34,7 @@ abstract class AbstractSurrogateFragmentRenderer extends RoutableFragmentRendere * * @param FragmentRendererInterface $inlineStrategy The inline strategy to use when the surrogate is not supported */ - public function __construct(?SurrogateInterface $surrogate, FragmentRendererInterface $inlineStrategy, UriSigner $signer = null) + public function __construct(?SurrogateInterface $surrogate, FragmentRendererInterface $inlineStrategy, ?UriSigner $signer = null) { $this->surrogate = $surrogate; $this->inlineStrategy = $inlineStrategy; diff --git a/lib/symfony/http-kernel/Fragment/FragmentHandler.php b/lib/symfony/http-kernel/Fragment/FragmentHandler.php index 62b21e6d4e..7452424192 100644 --- a/lib/symfony/http-kernel/Fragment/FragmentHandler.php +++ b/lib/symfony/http-kernel/Fragment/FragmentHandler.php @@ -73,7 +73,7 @@ public function render(string|ControllerReference $uri, string $renderer = 'inli } if (!isset($this->renderers[$renderer])) { - throw new \InvalidArgumentException(sprintf('The "%s" renderer does not exist.', $renderer)); + throw new \InvalidArgumentException(\sprintf('The "%s" renderer does not exist.', $renderer)); } if (!$request = $this->requestStack->getCurrentRequest()) { @@ -97,7 +97,7 @@ protected function deliver(Response $response): ?string { if (!$response->isSuccessful()) { $responseStatusCode = $response->getStatusCode(); - throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %d).', $this->requestStack->getCurrentRequest()->getUri(), $responseStatusCode), 0, new HttpException($responseStatusCode)); + throw new \RuntimeException(\sprintf('Error when rendering "%s" (Status code is %d).', $this->requestStack->getCurrentRequest()->getUri(), $responseStatusCode), 0, new HttpException($responseStatusCode)); } if (!$response instanceof StreamedResponse) { diff --git a/lib/symfony/http-kernel/Fragment/FragmentUriGenerator.php b/lib/symfony/http-kernel/Fragment/FragmentUriGenerator.php index aeef41546e..aeb1f71239 100644 --- a/lib/symfony/http-kernel/Fragment/FragmentUriGenerator.php +++ b/lib/symfony/http-kernel/Fragment/FragmentUriGenerator.php @@ -28,14 +28,14 @@ final class FragmentUriGenerator implements FragmentUriGeneratorInterface private ?UriSigner $signer; private ?RequestStack $requestStack; - public function __construct(string $fragmentPath, UriSigner $signer = null, RequestStack $requestStack = null) + public function __construct(string $fragmentPath, ?UriSigner $signer = null, ?RequestStack $requestStack = null) { $this->fragmentPath = $fragmentPath; $this->signer = $signer; $this->requestStack = $requestStack; } - public function generate(ControllerReference $controller, Request $request = null, bool $absolute = false, bool $strict = true, bool $sign = true): string + public function generate(ControllerReference $controller, ?Request $request = null, bool $absolute = false, bool $strict = true, bool $sign = true): string { if (null === $request && (null === $this->requestStack || null === $request = $this->requestStack->getCurrentRequest())) { throw new \LogicException('Generating a fragment URL can only be done when handling a Request.'); @@ -83,7 +83,7 @@ private function checkNonScalar(array $values): void if (\is_array($value)) { $this->checkNonScalar($value); } elseif (!\is_scalar($value) && null !== $value) { - throw new \LogicException(sprintf('Controller attributes cannot contain non-scalar/non-null values (value for key "%s" is not a scalar or null).', $key)); + throw new \LogicException(\sprintf('Controller attributes cannot contain non-scalar/non-null values (value for key "%s" is not a scalar or null).', $key)); } } } diff --git a/lib/symfony/http-kernel/Fragment/FragmentUriGeneratorInterface.php b/lib/symfony/http-kernel/Fragment/FragmentUriGeneratorInterface.php index 968c002b90..6b1317c3a7 100644 --- a/lib/symfony/http-kernel/Fragment/FragmentUriGeneratorInterface.php +++ b/lib/symfony/http-kernel/Fragment/FragmentUriGeneratorInterface.php @@ -28,5 +28,5 @@ interface FragmentUriGeneratorInterface * @param bool $strict Whether to allow non-scalar attributes or not * @param bool $sign Whether to sign the URL or not */ - public function generate(ControllerReference $controller, Request $request = null, bool $absolute = false, bool $strict = true, bool $sign = true): string; + public function generate(ControllerReference $controller, ?Request $request = null, bool $absolute = false, bool $strict = true, bool $sign = true): string; } diff --git a/lib/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php b/lib/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php index d5b6c4cd3c..9cb01f321e 100644 --- a/lib/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php +++ b/lib/symfony/http-kernel/Fragment/HIncludeFragmentRenderer.php @@ -32,7 +32,7 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer /** * @param string|null $globalDefaultTemplate The global default content (it can be a template name or the content) */ - public function __construct(Environment $twig = null, UriSigner $signer = null, string $globalDefaultTemplate = null, string $charset = 'utf-8') + public function __construct(?Environment $twig = null, ?UriSigner $signer = null, ?string $globalDefaultTemplate = null, string $charset = 'utf-8') { $this->twig = $twig; $this->globalDefaultTemplate = $globalDefaultTemplate; @@ -79,7 +79,7 @@ public function render(string|ControllerReference $uri, Request $request, array if (\count($attributes) > 0) { $flags = \ENT_QUOTES | \ENT_SUBSTITUTE; foreach ($attributes as $attribute => $value) { - $renderedAttributes .= sprintf( + $renderedAttributes .= \sprintf( ' %s="%s"', htmlspecialchars($attribute, $flags, $this->charset, false), htmlspecialchars($value, $flags, $this->charset, false) @@ -87,7 +87,7 @@ public function render(string|ControllerReference $uri, Request $request, array } } - return new Response(sprintf('%s', $uri, $renderedAttributes, $content)); + return new Response(\sprintf('%s', $uri, $renderedAttributes, $content)); } public function getName(): string diff --git a/lib/symfony/http-kernel/Fragment/InlineFragmentRenderer.php b/lib/symfony/http-kernel/Fragment/InlineFragmentRenderer.php index ba3f6be708..1999603a3b 100644 --- a/lib/symfony/http-kernel/Fragment/InlineFragmentRenderer.php +++ b/lib/symfony/http-kernel/Fragment/InlineFragmentRenderer.php @@ -30,7 +30,7 @@ class InlineFragmentRenderer extends RoutableFragmentRenderer private HttpKernelInterface $kernel; private ?EventDispatcherInterface $dispatcher; - public function __construct(HttpKernelInterface $kernel, EventDispatcherInterface $dispatcher = null) + public function __construct(HttpKernelInterface $kernel, ?EventDispatcherInterface $dispatcher = null) { $this->kernel = $kernel; $this->dispatcher = $dispatcher; diff --git a/lib/symfony/http-kernel/HttpCache/AbstractSurrogate.php b/lib/symfony/http-kernel/HttpCache/AbstractSurrogate.php index 95518bed2b..152aedad08 100644 --- a/lib/symfony/http-kernel/HttpCache/AbstractSurrogate.php +++ b/lib/symfony/http-kernel/HttpCache/AbstractSurrogate.php @@ -56,7 +56,7 @@ public function hasSurrogateCapability(Request $request): bool return false; } - return str_contains($value, sprintf('%s/1.0', strtoupper($this->getName()))); + return str_contains($value, \sprintf('%s/1.0', strtoupper($this->getName()))); } /** @@ -65,7 +65,7 @@ public function hasSurrogateCapability(Request $request): bool public function addSurrogateCapability(Request $request) { $current = $request->headers->get('Surrogate-Capability'); - $new = sprintf('symfony="%s/1.0"', strtoupper($this->getName())); + $new = \sprintf('symfony="%s/1.0"', strtoupper($this->getName())); $request->headers->set('Surrogate-Capability', $current ? $current.', '.$new : $new); } @@ -76,7 +76,7 @@ public function needsParsing(Response $response): bool return false; } - $pattern = sprintf('#content="[^"]*%s/1.0[^"]*"#', strtoupper($this->getName())); + $pattern = \sprintf('#content="[^"]*%s/1.0[^"]*"#', strtoupper($this->getName())); return (bool) preg_match($pattern, $control); } @@ -89,7 +89,7 @@ public function handle(HttpCache $cache, string $uri, string $alt, bool $ignoreE $response = $cache->handle($subRequest, HttpKernelInterface::SUB_REQUEST, true); if (!$response->isSuccessful() && Response::HTTP_NOT_MODIFIED !== $response->getStatusCode()) { - throw new \RuntimeException(sprintf('Error when rendering "%s" (Status code is %d).', $subRequest->getUri(), $response->getStatusCode())); + throw new \RuntimeException(\sprintf('Error when rendering "%s" (Status code is %d).', $subRequest->getUri(), $response->getStatusCode())); } return $response->getContent(); @@ -120,12 +120,12 @@ protected function removeFromControl(Response $response) $value = $response->headers->get('Surrogate-Control'); $upperName = strtoupper($this->getName()); - if (sprintf('content="%s/1.0"', $upperName) == $value) { + if (\sprintf('content="%s/1.0"', $upperName) == $value) { $response->headers->remove('Surrogate-Control'); - } elseif (preg_match(sprintf('#,\s*content="%s/1.0"#', $upperName), $value)) { - $response->headers->set('Surrogate-Control', preg_replace(sprintf('#,\s*content="%s/1.0"#', $upperName), '', $value)); - } elseif (preg_match(sprintf('#content="%s/1.0",\s*#', $upperName), $value)) { - $response->headers->set('Surrogate-Control', preg_replace(sprintf('#content="%s/1.0",\s*#', $upperName), '', $value)); + } elseif (preg_match(\sprintf('#,\s*content="%s/1.0"#', $upperName), $value)) { + $response->headers->set('Surrogate-Control', preg_replace(\sprintf('#,\s*content="%s/1.0"#', $upperName), '', $value)); + } elseif (preg_match(\sprintf('#content="%s/1.0",\s*#', $upperName), $value)) { + $response->headers->set('Surrogate-Control', preg_replace(\sprintf('#content="%s/1.0",\s*#', $upperName), '', $value)); } } diff --git a/lib/symfony/http-kernel/HttpCache/Esi.php b/lib/symfony/http-kernel/HttpCache/Esi.php index 5db840a802..92b41a5dd6 100644 --- a/lib/symfony/http-kernel/HttpCache/Esi.php +++ b/lib/symfony/http-kernel/HttpCache/Esi.php @@ -42,16 +42,16 @@ public function addSurrogateControl(Response $response) } } - public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string + public function renderIncludeTag(string $uri, ?string $alt = null, bool $ignoreErrors = true, string $comment = ''): string { - $html = sprintf('', + $html = \sprintf('', $uri, $ignoreErrors ? ' onerror="continue"' : '', - $alt ? sprintf(' alt="%s"', $alt) : '' + $alt ? \sprintf(' alt="%s"', $alt) : '' ); if (!empty($comment)) { - return sprintf("\n%s", $comment, $html); + return \sprintf("\n%s", $comment, $html); } return $html; diff --git a/lib/symfony/http-kernel/HttpCache/HttpCache.php b/lib/symfony/http-kernel/HttpCache/HttpCache.php index eabacfec62..8d1a3a5791 100644 --- a/lib/symfony/http-kernel/HttpCache/HttpCache.php +++ b/lib/symfony/http-kernel/HttpCache/HttpCache.php @@ -17,6 +17,7 @@ namespace Symfony\Component\HttpKernel\HttpCache; +use Symfony\Component\HttpFoundation\Exception\SuspiciousOperationException; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; @@ -89,7 +90,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface * Unless your application needs to process events on cache hits, it is recommended * to set this to false to avoid having to bootstrap the Symfony framework on a cache hit. */ - public function __construct(HttpKernelInterface $kernel, StoreInterface $store, SurrogateInterface $surrogate = null, array $options = []) + public function __construct(HttpKernelInterface $kernel, StoreInterface $store, ?SurrogateInterface $surrogate = null, array $options = []) { $this->store = $store; $this->kernel = $kernel; @@ -157,7 +158,7 @@ public function getLog(): string { $log = []; foreach ($this->traces as $request => $traces) { - $log[] = sprintf('%s: %s', $request, implode(', ', $traces)); + $log[] = \sprintf('%s: %s', $request, implode(', ', $traces)); } return implode('; ', $log); @@ -218,7 +219,13 @@ public function handle(Request $request, int $type = HttpKernelInterface::MAIN_R $this->record($request, 'reload'); $response = $this->fetch($request, $catch); } else { - $response = $this->lookup($request, $catch); + $response = null; + do { + try { + $response = $this->lookup($request, $catch); + } catch (CacheWasLockedException) { + } + } while (null === $response); } $this->restoreResponseBody($request, $response); @@ -237,7 +244,9 @@ public function handle(Request $request, int $type = HttpKernelInterface::MAIN_R $response->prepare($request); - $response->isNotModified($request); + if (HttpKernelInterface::MAIN_REQUEST === $type) { + $response->isNotModified($request); + } return $response; } @@ -465,7 +474,7 @@ protected function fetch(Request $request, bool $catch = false): Response * * @return Response */ - protected function forward(Request $request, bool $catch = false, Response $entry = null) + protected function forward(Request $request, bool $catch = false, ?Response $entry = null) { $this->surrogate?->addSurrogateCapability($request); @@ -573,15 +582,7 @@ protected function lock(Request $request, Response $entry): bool // wait for the lock to be released if ($this->waitForLock($request)) { - // replace the current entry with the fresh one - $new = $this->lookup($request); - $entry->headers = $new->headers; - $entry->setContent($new->getContent()); - $entry->setStatusCode($new->getStatusCode()); - $entry->setProtocolVersion($new->getProtocolVersion()); - foreach ($new->headers->getCookies() as $cookie) { - $entry->headers->setCookie($cookie); - } + throw new CacheWasLockedException(); // unwind back to handle(), try again } else { // backend is slow as hell, send a 503 response (to avoid the dog pile effect) $entry->setStatusCode(503); @@ -723,7 +724,11 @@ private function getTraceKey(Request $request): string $path .= '?'.$qs; } - return $request->getMethod().' '.$path; + try { + return $request->getMethod().' '.$path; + } catch (SuspiciousOperationException $e) { + return '_BAD_METHOD_ '.$path; + } } /** diff --git a/lib/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php b/lib/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php index 57b5d21961..05670967a5 100644 --- a/lib/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php +++ b/lib/symfony/http-kernel/HttpCache/ResponseCacheStrategy.php @@ -37,7 +37,7 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface private int $embeddedResponses = 0; private bool $isNotCacheableResponseEmbedded = false; private int $age = 0; - private \DateTimeInterface|null|false $lastModified = null; + private \DateTimeInterface|false|null $lastModified = null; private array $flagDirectives = [ 'no-cache' => null, 'no-store' => null, @@ -51,7 +51,7 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface private array $ageDirectives = [ 'max-age' => null, 's-maxage' => null, - 'expires' => null, + 'expires' => false, ]; /** @@ -82,15 +82,30 @@ public function add(Response $response) return; } - $isHeuristicallyCacheable = $response->headers->hasCacheControlDirective('public'); $maxAge = $response->headers->hasCacheControlDirective('max-age') ? (int) $response->headers->getCacheControlDirective('max-age') : null; - $this->storeRelativeAgeDirective('max-age', $maxAge, $age, $isHeuristicallyCacheable); $sharedMaxAge = $response->headers->hasCacheControlDirective('s-maxage') ? (int) $response->headers->getCacheControlDirective('s-maxage') : $maxAge; - $this->storeRelativeAgeDirective('s-maxage', $sharedMaxAge, $age, $isHeuristicallyCacheable); - $expires = $response->getExpires(); $expires = null !== $expires ? (int) $expires->format('U') - (int) $response->getDate()->format('U') : null; - $this->storeRelativeAgeDirective('expires', $expires >= 0 ? $expires : null, 0, $isHeuristicallyCacheable); + + // See https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.2 + // If a response is "public" but does not have maximum lifetime, heuristics might be applied. + // Do not store NULL values so the final response can have more limiting value from other responses. + $isHeuristicallyCacheable = $response->headers->hasCacheControlDirective('public') + && null === $maxAge + && null === $sharedMaxAge + && null === $expires; + + if (!$isHeuristicallyCacheable || null !== $maxAge || null !== $expires) { + $this->storeRelativeAgeDirective('max-age', $maxAge, $expires, $age); + } + + if (!$isHeuristicallyCacheable || null !== $sharedMaxAge || null !== $expires) { + $this->storeRelativeAgeDirective('s-maxage', $sharedMaxAge, $expires, $age); + } + + if (null !== $expires) { + $this->ageDirectives['expires'] = true; + } if (false !== $this->lastModified) { $lastModified = $response->getLastModified(); @@ -152,9 +167,9 @@ public function update(Response $response) } } - if (is_numeric($this->ageDirectives['expires'])) { + if ($this->ageDirectives['expires'] && null !== $maxAge) { $date = clone $response->getDate(); - $date = $date->modify('+'.($this->ageDirectives['expires'] + $this->age).' seconds'); + $date = $date->modify('+'.$maxAge.' seconds'); $response->setExpires($date); } } @@ -204,33 +219,16 @@ private function willMakeFinalResponseUncacheable(Response $response): bool * we have to subtract the age so that the value is normalized for an age of 0. * * If the value is lower than the currently stored value, we update the value, to keep a rolling - * minimal value of each instruction. - * - * If the value is NULL and the isHeuristicallyCacheable parameter is false, the directive will - * not be set on the final response. In this case, not all responses had the directive set and no - * value can be found that satisfies the requirements of all responses. The directive will be dropped - * from the final response. - * - * If the isHeuristicallyCacheable parameter is true, however, the current response has been marked - * as cacheable in a public (shared) cache, but did not provide an explicit lifetime that would serve - * as an upper bound. In this case, we can proceed and possibly keep the directive on the final response. + * minimal value of each instruction. If the value is NULL, the directive will not be set on the final response. */ - private function storeRelativeAgeDirective(string $directive, ?int $value, int $age, bool $isHeuristicallyCacheable): void + private function storeRelativeAgeDirective(string $directive, ?int $value, ?int $expires, int $age): void { - if (null === $value) { - if ($isHeuristicallyCacheable) { - /* - * See https://datatracker.ietf.org/doc/html/rfc7234#section-4.2.2 - * This particular response does not require maximum lifetime; heuristics might be applied. - * Other responses, however, might have more stringent requirements on maximum lifetime. - * So, return early here so that the final response can have the more limiting value set. - */ - return; - } + if (null === $value && null === $expires) { $this->ageDirectives[$directive] = false; } if (false !== $this->ageDirectives[$directive]) { + $value = min($value ?? \PHP_INT_MAX, $expires ?? \PHP_INT_MAX); $value -= $age; $this->ageDirectives[$directive] = null !== $this->ageDirectives[$directive] ? min($this->ageDirectives[$directive], $value) : $value; } diff --git a/lib/symfony/http-kernel/HttpCache/Ssi.php b/lib/symfony/http-kernel/HttpCache/Ssi.php index b17c90ac60..9e0839d63d 100644 --- a/lib/symfony/http-kernel/HttpCache/Ssi.php +++ b/lib/symfony/http-kernel/HttpCache/Ssi.php @@ -36,9 +36,9 @@ public function addSurrogateControl(Response $response) } } - public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string + public function renderIncludeTag(string $uri, ?string $alt = null, bool $ignoreErrors = true, string $comment = ''): string { - return sprintf('', $uri); + return \sprintf('', $uri); } public function process(Request $request, Response $response): Response diff --git a/lib/symfony/http-kernel/HttpCache/Store.php b/lib/symfony/http-kernel/HttpCache/Store.php index 3f21e383f4..4eba39337d 100644 --- a/lib/symfony/http-kernel/HttpCache/Store.php +++ b/lib/symfony/http-kernel/HttpCache/Store.php @@ -45,7 +45,7 @@ public function __construct(string $root, array $options = []) { $this->root = $root; if (!is_dir($this->root) && !@mkdir($this->root, 0777, true) && !is_dir($this->root)) { - throw new \RuntimeException(sprintf('Unable to create the store directory (%s).', $this->root)); + throw new \RuntimeException(\sprintf('Unable to create the store directory (%s).', $this->root)); } $this->keyCache = new \SplObjectStorage(); $this->options = array_merge([ @@ -211,13 +211,9 @@ public function write(Request $request, Response $response): string // read existing cache entries, remove non-varying, and add this one to the list $entries = []; - $vary = $response->headers->get('vary'); + $vary = implode(', ', $response->headers->all('vary')); foreach ($this->getMetadata($key) as $entry) { - if (!isset($entry[1]['vary'][0])) { - $entry[1]['vary'] = ['']; - } - - if ($entry[1]['vary'][0] != $vary || !$this->requestsMatch($vary ?? '', $entry[0], $storedEnv)) { + if (!$this->requestsMatch($vary ?? '', $entry[0], $storedEnv)) { $entries[] = $entry; } } @@ -285,7 +281,7 @@ public function invalidate(Request $request) */ private function requestsMatch(?string $vary, array $env1, array $env2): bool { - if (empty($vary)) { + if ('' === ($vary ?? '')) { return true; } @@ -474,7 +470,7 @@ private function persistResponse(Response $response): array /** * Restores a Response from the HTTP headers and body. */ - private function restoreResponse(array $headers, string $path = null): ?Response + private function restoreResponse(array $headers, ?string $path = null): ?Response { $status = $headers['X-Status'][0]; unset($headers['X-Status']); diff --git a/lib/symfony/http-kernel/HttpCache/SubRequestHandler.php b/lib/symfony/http-kernel/HttpCache/SubRequestHandler.php index 253071f07d..4caf3daf2e 100644 --- a/lib/symfony/http-kernel/HttpCache/SubRequestHandler.php +++ b/lib/symfony/http-kernel/HttpCache/SubRequestHandler.php @@ -51,16 +51,16 @@ public static function handle(HttpKernelInterface $kernel, Request $request, int $trustedValues = []; foreach (array_reverse($request->getClientIps()) as $ip) { $trustedIps[] = $ip; - $trustedValues[] = sprintf('for="%s"', $ip); + $trustedValues[] = \sprintf('for="%s"', $ip); } if ($ip !== $remoteAddr) { $trustedIps[] = $remoteAddr; - $trustedValues[] = sprintf('for="%s"', $remoteAddr); + $trustedValues[] = \sprintf('for="%s"', $remoteAddr); } // set trusted values, reusing as much as possible the global trusted settings if (Request::HEADER_FORWARDED & $trustedHeaderSet) { - $trustedValues[0] .= sprintf(';host="%s";proto=%s', $request->getHttpHost(), $request->getScheme()); + $trustedValues[0] .= \sprintf(';host="%s";proto=%s', $request->getHttpHost(), $request->getScheme()); $request->headers->set('Forwarded', $v = implode(', ', $trustedValues)); $request->server->set('HTTP_FORWARDED', $v); } diff --git a/lib/symfony/http-kernel/HttpCache/SurrogateInterface.php b/lib/symfony/http-kernel/HttpCache/SurrogateInterface.php index e444458f73..5ff10c963e 100644 --- a/lib/symfony/http-kernel/HttpCache/SurrogateInterface.php +++ b/lib/symfony/http-kernel/HttpCache/SurrogateInterface.php @@ -58,7 +58,7 @@ public function needsParsing(Response $response): bool; * @param string|null $alt An alternate URI * @param string $comment A comment to add as an esi:include tag */ - public function renderIncludeTag(string $uri, string $alt = null, bool $ignoreErrors = true, string $comment = ''): string; + public function renderIncludeTag(string $uri, ?string $alt = null, bool $ignoreErrors = true, string $comment = ''): string; /** * Replaces a Response Surrogate tags with the included resource content. diff --git a/lib/symfony/http-kernel/HttpClientKernel.php b/lib/symfony/http-kernel/HttpClientKernel.php index 1d8c302781..ebda2750da 100644 --- a/lib/symfony/http-kernel/HttpClientKernel.php +++ b/lib/symfony/http-kernel/HttpClientKernel.php @@ -33,10 +33,10 @@ final class HttpClientKernel implements HttpKernelInterface { private HttpClientInterface $client; - public function __construct(HttpClientInterface $client = null) + public function __construct(?HttpClientInterface $client = null) { if (null === $client && !class_exists(HttpClient::class)) { - throw new \LogicException(sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__)); + throw new \LogicException(\sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__)); } $this->client = $client ?? HttpClient::create(); diff --git a/lib/symfony/http-kernel/HttpKernel.php b/lib/symfony/http-kernel/HttpKernel.php index d2cf4eaee2..886fca9cf5 100644 --- a/lib/symfony/http-kernel/HttpKernel.php +++ b/lib/symfony/http-kernel/HttpKernel.php @@ -57,7 +57,7 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface private ArgumentResolverInterface $argumentResolver; private bool $handleAllThrowables; - public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, RequestStack $requestStack = null, ArgumentResolverInterface $argumentResolver = null, bool $handleAllThrowables = false) + public function __construct(EventDispatcherInterface $dispatcher, ControllerResolverInterface $resolver, ?RequestStack $requestStack = null, ?ArgumentResolverInterface $argumentResolver = null, bool $handleAllThrowables = false) { $this->dispatcher = $dispatcher; $this->resolver = $resolver; @@ -118,7 +118,7 @@ public function terminate(Request $request, Response $response) /** * @internal */ - public function terminateWithException(\Throwable $exception, Request $request = null): void + public function terminateWithException(\Throwable $exception, ?Request $request = null): void { if (!$request ??= $this->requestStack->getMainRequest()) { throw $exception; @@ -162,7 +162,7 @@ private function handleRaw(Request $request, int $type = self::MAIN_REQUEST): Re // load controller if (false === $controller = $this->resolver->getController($request)) { - throw new NotFoundHttpException(sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo())); + throw new NotFoundHttpException(\sprintf('Unable to find the controller for path "%s". The route is wrongly configured.', $request->getPathInfo())); } $event = new ControllerEvent($this, $controller, $request, $type); @@ -188,7 +188,7 @@ private function handleRaw(Request $request, int $type = self::MAIN_REQUEST): Re if ($event->hasResponse()) { $response = $event->getResponse(); } else { - $msg = sprintf('The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned %s.', $this->varToString($response)); + $msg = \sprintf('The controller must return a "Symfony\Component\HttpFoundation\Response" object but it returned %s.', $this->varToString($response)); // the user may have forgotten to return something if (null === $response) { @@ -278,20 +278,20 @@ private function handleThrowable(\Throwable $e, Request $request, int $type): Re private function varToString(mixed $var): string { if (\is_object($var)) { - return sprintf('an object of type %s', $var::class); + return \sprintf('an object of type %s', $var::class); } if (\is_array($var)) { $a = []; foreach ($var as $k => $v) { - $a[] = sprintf('%s => ...', $k); + $a[] = \sprintf('%s => ...', $k); } - return sprintf('an array ([%s])', mb_substr(implode(', ', $a), 0, 255)); + return \sprintf('an array ([%s])', mb_substr(implode(', ', $a), 0, 255)); } if (\is_resource($var)) { - return sprintf('a resource (%s)', get_resource_type($var)); + return \sprintf('a resource (%s)', get_resource_type($var)); } if (null === $var) { @@ -307,11 +307,11 @@ private function varToString(mixed $var): string } if (\is_string($var)) { - return sprintf('a string ("%s%s")', mb_substr($var, 0, 255), mb_strlen($var) > 255 ? '...' : ''); + return \sprintf('a string ("%s%s")', mb_substr($var, 0, 255), mb_strlen($var) > 255 ? '...' : ''); } if (is_numeric($var)) { - return sprintf('a number (%s)', (string) $var); + return \sprintf('a number (%s)', (string) $var); } return (string) $var; diff --git a/lib/symfony/http-kernel/HttpKernelBrowser.php b/lib/symfony/http-kernel/HttpKernelBrowser.php index 0f3630e7fe..169789dda4 100644 --- a/lib/symfony/http-kernel/HttpKernelBrowser.php +++ b/lib/symfony/http-kernel/HttpKernelBrowser.php @@ -36,7 +36,7 @@ class HttpKernelBrowser extends AbstractBrowser /** * @param array $server The server parameters (equivalent of $_SERVER) */ - public function __construct(HttpKernelInterface $kernel, array $server = [], History $history = null, CookieJar $cookieJar = null) + public function __construct(HttpKernelInterface $kernel, array $server = [], ?History $history = null, ?CookieJar $cookieJar = null) { // These class properties must be set before calling the parent constructor, as it may depend on it. $this->kernel = $kernel; diff --git a/lib/symfony/http-kernel/Kernel.php b/lib/symfony/http-kernel/Kernel.php index 6247db9016..a2bf0f8270 100644 --- a/lib/symfony/http-kernel/Kernel.php +++ b/lib/symfony/http-kernel/Kernel.php @@ -70,17 +70,18 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl private ?string $warmupDir = null; private int $requestStackSize = 0; private bool $resetServices = false; + private bool $handlingHttpCache = false; /** * @var array */ private static array $freshCache = []; - public const VERSION = '6.4.2'; - public const VERSION_ID = 60402; + public const VERSION = '6.4.33'; + public const VERSION_ID = 60433; public const MAJOR_VERSION = 6; public const MINOR_VERSION = 4; - public const RELEASE_VERSION = 2; + public const RELEASE_VERSION = 33; public const EXTRA_VERSION = ''; public const END_OF_MAINTENANCE = '11/2026'; @@ -89,7 +90,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl public function __construct(string $environment, bool $debug) { if (!$this->environment = $environment) { - throw new \InvalidArgumentException(sprintf('Invalid environment provided to "%s": the environment cannot be empty.', get_debug_type($this))); + throw new \InvalidArgumentException(\sprintf('Invalid environment provided to "%s": the environment cannot be empty.', get_debug_type($this))); } $this->debug = $debug; @@ -101,6 +102,7 @@ public function __clone() $this->container = null; $this->requestStackSize = 0; $this->resetServices = false; + $this->handlingHttpCache = false; } /** @@ -108,7 +110,7 @@ public function __clone() */ public function boot() { - if (true === $this->booted) { + if ($this->booted) { if (!$this->requestStackSize && $this->resetServices) { if ($this->container->has('services_resetter')) { $this->container->get('services_resetter')->reset(); @@ -122,7 +124,7 @@ public function boot() return; } - if (null === $this->container) { + if (!$this->container) { $this->preBoot(); } @@ -149,7 +151,7 @@ public function reboot(?string $warmupDir) */ public function terminate(Request $request, Response $response) { - if (false === $this->booted) { + if (!$this->booted) { return; } @@ -163,7 +165,7 @@ public function terminate(Request $request, Response $response) */ public function shutdown() { - if (false === $this->booted) { + if (!$this->booted) { return; } @@ -181,17 +183,26 @@ public function shutdown() public function handle(Request $request, int $type = HttpKernelInterface::MAIN_REQUEST, bool $catch = true): Response { - if (!$this->booted) { - $container = $this->container ?? $this->preBoot(); + if (!$this->container) { + $this->preBoot(); + } + + if (HttpKernelInterface::MAIN_REQUEST === $type && !$this->handlingHttpCache && $this->container->has('http_cache')) { + $this->handlingHttpCache = true; - if ($container->has('http_cache')) { - return $container->get('http_cache')->handle($request, $type, $catch); + try { + return $this->container->get('http_cache')->handle($request, $type, $catch); + } finally { + $this->handlingHttpCache = false; + $this->resetServices = true; } } $this->boot(); ++$this->requestStackSize; - $this->resetServices = true; + if (!$this->handlingHttpCache) { + $this->resetServices = true; + } try { return $this->getHttpKernel()->handle($request, $type, $catch); @@ -216,7 +227,7 @@ public function getBundles(): array public function getBundle(string $name): BundleInterface { if (!isset($this->bundles[$name])) { - throw new \InvalidArgumentException(sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, get_debug_type($this))); + throw new \InvalidArgumentException(\sprintf('Bundle "%s" does not exist or it is not enabled. Maybe you forgot to add it in the "registerBundles()" method of your "%s.php" file?', $name, get_debug_type($this))); } return $this->bundles[$name]; @@ -225,11 +236,11 @@ public function getBundle(string $name): BundleInterface public function locateResource(string $name): string { if ('@' !== $name[0]) { - throw new \InvalidArgumentException(sprintf('A resource name must start with @ ("%s" given).', $name)); + throw new \InvalidArgumentException(\sprintf('A resource name must start with @ ("%s" given).', $name)); } if (str_contains($name, '..')) { - throw new \RuntimeException(sprintf('File name "%s" contains invalid characters (..).', $name)); + throw new \RuntimeException(\sprintf('File name "%s" contains invalid characters (..).', $name)); } $bundleName = substr($name, 1); @@ -243,7 +254,7 @@ public function locateResource(string $name): string return $file; } - throw new \InvalidArgumentException(sprintf('Unable to find file "%s".', $name)); + throw new \InvalidArgumentException(\sprintf('Unable to find file "%s".', $name)); } public function getEnvironment(): string @@ -265,7 +276,7 @@ public function getProjectDir(): string $r = new \ReflectionObject($this); if (!is_file($dir = $r->getFileName())) { - throw new \LogicException(sprintf('Cannot auto-detect project dir for kernel of class "%s".', $r->name)); + throw new \LogicException(\sprintf('Cannot auto-detect project dir for kernel of class "%s".', $r->name)); } $dir = $rootDir = \dirname($dir); @@ -295,7 +306,7 @@ public function getContainer(): ContainerInterface */ public function setAnnotatedClassCache(array $annotatedClasses): void { - file_put_contents(($this->warmupDir ?: $this->getBuildDir()).'/annotations.map', sprintf('warmupDir ?: $this->getBuildDir()).'/annotations.map', \sprintf('registerBundles() as $bundle) { $name = $bundle->getName(); if (isset($this->bundles[$name])) { - throw new \LogicException(sprintf('Trying to register two bundles with the same name "%s".', $name)); + throw new \LogicException(\sprintf('Trying to register two bundles with the same name "%s".', $name)); } $this->bundles[$name] = $bundle; } @@ -375,7 +386,7 @@ protected function getContainerClass(): string $class = str_replace('\\', '_', $class).ucfirst($this->environment).($this->debug ? 'Debug' : '').'Container'; if (!preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $class)) { - throw new \InvalidArgumentException(sprintf('The environment "%s" contains invalid characters, it can only contain characters allowed in PHP class names.', $this->environment)); + throw new \InvalidArgumentException(\sprintf('The environment "%s" contains invalid characters, it can only contain characters allowed in PHP class names.', $this->environment)); } return $class; @@ -407,7 +418,8 @@ protected function initializeContainer() $cachePath = $cache->getPath(); // Silence E_WARNING to ignore "include" failures - don't use "@" to prevent silencing fatal errors - $errorLevel = error_reporting(\E_ALL ^ \E_WARNING); + $errorLevel = error_reporting(); + error_reporting($errorLevel & ~\E_WARNING); try { if (is_file($cachePath) && \is_object($this->container = include $cachePath) @@ -539,10 +551,18 @@ protected function initializeContainer() touch($oldContainerDir.'.legacy'); } - $preload = $this instanceof WarmableInterface ? (array) $this->warmUp($this->container->getParameter('kernel.cache_dir'), $buildDir) : []; + $buildDir = $this->container->getParameter('kernel.build_dir'); + $cacheDir = $this->container->getParameter('kernel.cache_dir'); + $preload = $this instanceof WarmableInterface ? (array) $this->warmUp($cacheDir, $buildDir) : []; if ($this->container->has('cache_warmer')) { - $preload = array_merge($preload, (array) $this->container->get('cache_warmer')->warmUp($this->container->getParameter('kernel.cache_dir'), $buildDir)); + $cacheWarmer = $this->container->get('cache_warmer'); + + if ($cacheDir !== $buildDir) { + $cacheWarmer->enableOptionalWarmers(); + } + + $preload = array_merge($preload, (array) $cacheWarmer->warmUp($cacheDir, $buildDir)); } if ($preload && file_exists($preloadFile = $buildDir.'/'.$class.'.preload.php')) { @@ -594,11 +614,11 @@ protected function buildContainer(): ContainerBuilder { foreach (['cache' => $this->getCacheDir(), 'build' => $this->warmupDir ?: $this->getBuildDir(), 'logs' => $this->getLogDir()] as $name => $dir) { if (!is_dir($dir)) { - if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { - throw new \RuntimeException(sprintf('Unable to create the "%s" directory (%s).', $name, $dir)); + if (!@mkdir($dir, 0o777, true) && !is_dir($dir)) { + throw new \RuntimeException(\sprintf('Unable to create the "%s" directory (%s).', $name, $dir)); } } elseif (!is_writable($dir)) { - throw new \RuntimeException(sprintf('Unable to write in the "%s" directory (%s).', $name, $dir)); + throw new \RuntimeException(\sprintf('Unable to write in the "%s" directory (%s).', $name, $dir)); } } diff --git a/lib/symfony/http-kernel/Log/DebugLoggerConfigurator.php b/lib/symfony/http-kernel/Log/DebugLoggerConfigurator.php index 537c100408..e036f398ec 100644 --- a/lib/symfony/http-kernel/Log/DebugLoggerConfigurator.php +++ b/lib/symfony/http-kernel/Log/DebugLoggerConfigurator.php @@ -20,7 +20,7 @@ class DebugLoggerConfigurator { private ?object $processor = null; - public function __construct(callable $processor, bool $enable = null) + public function __construct(callable $processor, ?bool $enable = null) { if ($enable ?? !\in_array(\PHP_SAPI, ['cli', 'phpdbg', 'embed'], true)) { $this->processor = \is_object($processor) ? $processor : $processor(...); diff --git a/lib/symfony/http-kernel/Log/DebugLoggerInterface.php b/lib/symfony/http-kernel/Log/DebugLoggerInterface.php index 1940c80a90..956abc6f36 100644 --- a/lib/symfony/http-kernel/Log/DebugLoggerInterface.php +++ b/lib/symfony/http-kernel/Log/DebugLoggerInterface.php @@ -33,14 +33,14 @@ interface DebugLoggerInterface * timestamp_rfc3339: string, * }> */ - public function getLogs(Request $request = null); + public function getLogs(?Request $request = null); /** * Returns the number of errors. * * @return int */ - public function countErrors(Request $request = null); + public function countErrors(?Request $request = null); /** * Removes all log records. diff --git a/lib/symfony/http-kernel/Log/Logger.php b/lib/symfony/http-kernel/Log/Logger.php index 11d35b7e2f..93c1dbc95b 100644 --- a/lib/symfony/http-kernel/Log/Logger.php +++ b/lib/symfony/http-kernel/Log/Logger.php @@ -57,7 +57,7 @@ class Logger extends AbstractLogger implements DebugLoggerInterface /** * @param string|resource|null $output */ - public function __construct(string $minLevel = null, $output = null, callable $formatter = null, private readonly ?RequestStack $requestStack = null, bool $debug = false) + public function __construct(?string $minLevel = null, $output = null, ?callable $formatter = null, private readonly ?RequestStack $requestStack = null, bool $debug = false) { if (null === $minLevel) { $minLevel = null === $output || 'php://stdout' === $output || 'php://stderr' === $output ? LogLevel::ERROR : LogLevel::WARNING; @@ -74,13 +74,13 @@ public function __construct(string $minLevel = null, $output = null, callable $f } if (!isset(self::LEVELS[$minLevel])) { - throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $minLevel)); + throw new InvalidArgumentException(\sprintf('The log level "%s" does not exist.', $minLevel)); } $this->minLevelIndex = self::LEVELS[$minLevel]; $this->formatter = null !== $formatter ? $formatter(...) : $this->format(...); - if ($output && false === $this->handle = \is_resource($output) ? $output : @fopen($output, 'a')) { - throw new InvalidArgumentException(sprintf('Unable to open "%s".', $output)); + if ($output && false === $this->handle = \is_string($output) ? @fopen($output, 'a') : $output) { + throw new InvalidArgumentException(\sprintf('Unable to open "%s".', $output)); } $this->debug = $debug; } @@ -93,7 +93,7 @@ public function enableDebug(): void public function log($level, $message, array $context = []): void { if (!isset(self::LEVELS[$level])) { - throw new InvalidArgumentException(sprintf('The log level "%s" does not exist.', $level)); + throw new InvalidArgumentException(\sprintf('The log level "%s" does not exist.', $level)); } if (self::LEVELS[$level] < $this->minLevelIndex) { @@ -112,7 +112,7 @@ public function log($level, $message, array $context = []): void } } - public function getLogs(Request $request = null): array + public function getLogs(?Request $request = null): array { if ($request) { return $this->logs[spl_object_id($request)] ?? []; @@ -121,7 +121,7 @@ public function getLogs(Request $request = null): array return array_merge(...array_values($this->logs)); } - public function countErrors(Request $request = null): int + public function countErrors(?Request $request = null): int { if ($request) { return $this->errorCount[spl_object_id($request)] ?? 0; @@ -155,7 +155,7 @@ private function format(string $level, string $message, array $context, bool $pr $message = strtr($message, $replacements); } - $log = sprintf('[%s] %s', $level, $message); + $log = \sprintf('[%s] %s', $level, $message); if ($prefixDate) { $log = date(\DateTimeInterface::RFC3339).' '.$log; } diff --git a/lib/symfony/http-kernel/Profiler/FileProfilerStorage.php b/lib/symfony/http-kernel/Profiler/FileProfilerStorage.php index df61f716ff..f1e28bc2b8 100644 --- a/lib/symfony/http-kernel/Profiler/FileProfilerStorage.php +++ b/lib/symfony/http-kernel/Profiler/FileProfilerStorage.php @@ -33,19 +33,19 @@ class FileProfilerStorage implements ProfilerStorageInterface public function __construct(string $dsn) { if (!str_starts_with($dsn, 'file:')) { - throw new \RuntimeException(sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $dsn)); + throw new \RuntimeException(\sprintf('Please check your configuration. You are trying to use FileStorage with an invalid dsn "%s". The expected format is "file:/path/to/the/storage/folder".', $dsn)); } $this->folder = substr($dsn, 5); if (!is_dir($this->folder) && false === @mkdir($this->folder, 0777, true) && !is_dir($this->folder)) { - throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $this->folder)); + throw new \RuntimeException(\sprintf('Unable to create the storage directory (%s).', $this->folder)); } } /** * @param \Closure|null $filter A filter to apply on the list of tokens */ - public function find(?string $ip, ?string $url, ?int $limit, ?string $method, int $start = null, int $end = null, string $statusCode = null/* , \Closure $filter = null */): array + public function find(?string $ip, ?string $url, ?int $limit, ?string $method, ?int $start = null, ?int $end = null, ?string $statusCode = null/* , \Closure $filter = null */): array { $filter = 7 < \func_num_args() ? func_get_arg(7) : null; $file = $this->getIndexFilename(); @@ -59,7 +59,7 @@ public function find(?string $ip, ?string $url, ?int $limit, ?string $method, in $result = []; while (\count($result) < $limit && $line = $this->readLineFromFile($file)) { - $values = str_getcsv($line); + $values = str_getcsv($line, ',', '"', '\\'); if (7 > \count($values)) { // skip invalid lines @@ -144,7 +144,7 @@ public function write(Profile $profile): bool // Create directory $dir = \dirname($file); if (!is_dir($dir) && false === @mkdir($dir, 0777, true) && !is_dir($dir)) { - throw new \RuntimeException(sprintf('Unable to create the storage directory (%s).', $dir)); + throw new \RuntimeException(\sprintf('Unable to create the storage directory (%s).', $dir)); } } @@ -193,7 +193,7 @@ public function write(Profile $profile): bool $profile->getParentToken(), $profile->getStatusCode(), $profile->getVirtualType() ?? 'request', - ]); + ], ',', '"', '\\'); fclose($file); if (1 === mt_rand(1, 10)) { @@ -272,7 +272,7 @@ protected function readLineFromFile($file): mixed /** * @return Profile */ - protected function createProfileFromData(string $token, array $data, Profile $parent = null) + protected function createProfileFromData(string $token, array $data, ?Profile $parent = null) { $profile = new Profile($token); $profile->setIp($data['ip']); @@ -300,7 +300,7 @@ protected function createProfileFromData(string $token, array $data, Profile $pa return $profile; } - private function doRead($token, Profile $profile = null): ?Profile + private function doRead($token, ?Profile $profile = null): ?Profile { if (!$token || !file_exists($file = $this->getFilename($token))) { return null; @@ -334,7 +334,7 @@ private function removeExpiredProfiles(): void } while ($line = fgets($handle)) { - $values = str_getcsv($line); + $values = str_getcsv($line, ',', '"', '\\'); if (7 > \count($values)) { // skip invalid lines diff --git a/lib/symfony/http-kernel/Profiler/Profile.php b/lib/symfony/http-kernel/Profiler/Profile.php index 08e7b65a21..91ae51e958 100644 --- a/lib/symfony/http-kernel/Profiler/Profile.php +++ b/lib/symfony/http-kernel/Profiler/Profile.php @@ -232,7 +232,7 @@ public function getChildByToken(string $token): ?self public function getCollector(string $name): DataCollectorInterface { if (!isset($this->collectors[$name])) { - throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name)); + throw new \InvalidArgumentException(\sprintf('Collector "%s" does not exist.', $name)); } return $this->collectors[$name]; diff --git a/lib/symfony/http-kernel/Profiler/Profiler.php b/lib/symfony/http-kernel/Profiler/Profiler.php index 04ab0670d2..65adf0f17d 100644 --- a/lib/symfony/http-kernel/Profiler/Profiler.php +++ b/lib/symfony/http-kernel/Profiler/Profiler.php @@ -37,7 +37,7 @@ class Profiler implements ResetInterface private bool $initiallyEnabled = true; private bool $enabled = true; - public function __construct(ProfilerStorageInterface $storage, LoggerInterface $logger = null, bool $enable = true) + public function __construct(ProfilerStorageInterface $storage, ?LoggerInterface $logger = null, bool $enable = true) { $this->storage = $storage; $this->logger = $logger; @@ -128,7 +128,7 @@ public function purge() * * @see https://php.net/datetime.formats for the supported date/time formats */ - public function find(?string $ip, ?string $url, ?int $limit, ?string $method, ?string $start, ?string $end, string $statusCode = null/* , \Closure $filter = null */): array + public function find(?string $ip, ?string $url, ?int $limit, ?string $method, ?string $start, ?string $end, ?string $statusCode = null/* , \Closure $filter = null */): array { $filter = 7 < \func_num_args() ? func_get_arg(7) : null; @@ -138,7 +138,7 @@ public function find(?string $ip, ?string $url, ?int $limit, ?string $method, ?s /** * Collects data for the given Response. */ - public function collect(Request $request, Response $response, \Throwable $exception = null): ?Profile + public function collect(Request $request, Response $response, ?\Throwable $exception = null): ?Profile { if (false === $this->enabled) { return null; @@ -239,7 +239,7 @@ public function has(string $name): bool public function get(string $name): DataCollectorInterface { if (!isset($this->collectors[$name])) { - throw new \InvalidArgumentException(sprintf('Collector "%s" does not exist.', $name)); + throw new \InvalidArgumentException(\sprintf('Collector "%s" does not exist.', $name)); } return $this->collectors[$name]; diff --git a/lib/symfony/http-kernel/Profiler/ProfilerStorageInterface.php b/lib/symfony/http-kernel/Profiler/ProfilerStorageInterface.php index 14b8993b68..e2a25bc993 100644 --- a/lib/symfony/http-kernel/Profiler/ProfilerStorageInterface.php +++ b/lib/symfony/http-kernel/Profiler/ProfilerStorageInterface.php @@ -35,7 +35,7 @@ interface ProfilerStorageInterface * @param string|null $statusCode The response status code * @param \Closure|null $filter A filter to apply on the list of tokens */ - public function find(?string $ip, ?string $url, ?int $limit, ?string $method, int $start = null, int $end = null/* , string $statusCode = null, \Closure $filter = null */): array; + public function find(?string $ip, ?string $url, ?int $limit, ?string $method, ?int $start = null, ?int $end = null/* , string $statusCode = null, \Closure $filter = null */): array; /** * Reads data associated with the given token. diff --git a/lib/symfony/http-kernel/Resources/welcome.html.php b/lib/symfony/http-kernel/Resources/welcome.html.php index d36b97527d..03453c5c75 100644 --- a/lib/symfony/http-kernel/Resources/welcome.html.php +++ b/lib/symfony/http-kernel/Resources/welcome.html.php @@ -1,10 +1,10 @@ - - + + Welcome to Symfony! - +