diff --git a/composer.json b/composer.json index ec1d51244..f60f13c52 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 cb66e47e4..e59227f3e 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" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.5" }, - "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" - }, - "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 d48128912..05f3c7d17 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 71c04755a..bf75c551e 100644 --- a/lib/apereo/phpcas/source/CAS.php +++ b/lib/apereo/phpcas/source/CAS.php @@ -57,7 +57,7 @@ if (!isset($_SERVER['REQUEST_URI']) && isset($_SERVER['SCRIPT_NAME']) && isset($ /** * 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 @@ 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 @@ -402,14 +402,14 @@ class phpCAS */ 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 @@ class phpCAS $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 @@ class phpCAS 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 @@ class phpCAS /** * 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 @@ class phpCAS * '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 @@ class phpCAS } /** - * 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 8ca9711f4..7f7c7d111 100644 --- a/lib/apereo/phpcas/source/CAS/Client.php +++ b/lib/apereo/phpcas/source/CAS/Client.php @@ -788,7 +788,7 @@ class CAS_Client '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 @@ class CAS_Client * 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 @@ class CAS_Client $server_uri, $service_base_url, $changeSessionID = true, - \SessionHandlerInterface $sessionHandler = null + ?\SessionHandlerInterface $sessionHandler = null ) { // Argument validation if (gettype($server_version) != 'string') @@ -3166,7 +3166,7 @@ class CAS_Client $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 2efe5a3e8..9f8baf37f 100644 --- a/lib/apereo/phpcas/source/CAS/PGTStorage/Db.php +++ b/lib/apereo/phpcas/source/CAS/PGTStorage/Db.php @@ -316,7 +316,7 @@ class CAS_PGTStorage_Db extends CAS_PGTStorage_AbstractStorage 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 fbacd3b7d..213ab40b7 100644 --- a/lib/apereo/phpcas/source/CAS/PGTStorage/File.php +++ b/lib/apereo/phpcas/source/CAS/PGTStorage/File.php @@ -127,6 +127,12 @@ class CAS_PGTStorage_File extends CAS_PGTStorage_AbstractStorage 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 850f6f0e4..18a810ef9 100644 --- a/lib/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php +++ b/lib/apereo/phpcas/source/CAS/Request/CurlMultiRequest.php @@ -139,7 +139,12 @@ implements CAS_Request_MultiRequestInterface $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 e30dd0d19..ac7f0ec95 100644 --- a/lib/apereo/phpcas/source/CAS/Request/CurlRequest.php +++ b/lib/apereo/phpcas/source/CAS/Request/CurlRequest.php @@ -86,7 +86,9 @@ implements CAS_Request_RequestInterface } // 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 2b0707968..000000000 --- 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 2c5096dc3..000000000 --- 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 6b83bf27c..000000000 --- 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 94333da54..000000000 --- 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 fa7663748..000000000 --- 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 87e682e8f..f33a4ce8f 100644 --- a/lib/composer/autoload_classmap.php +++ b/lib/composer/autoload_classmap.php @@ -958,6 +958,7 @@ return array( '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 @@ return array( '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 @@ return array( '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 @@ return array( '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 @@ return array( '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 @@ return array( '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 @@ return array( '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 6629b7e09..b29b4a97f 100644 --- a/lib/composer/autoload_namespaces.php +++ b/lib/composer/autoload_namespaces.php @@ -8,5 +8,4 @@ $baseDir = dirname($vendorDir); 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 c157af745..6e18001be 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 @@ class ComposerStaticInit7f81b4a2a468a061c306af5e447a9a9f $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 c59aaf010..2bacb38f9 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 f7908990c..f8012b9a7 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 644fa0bea..263760760 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 701de23a8..65b6c8609 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 e23dfe378..816cfd0bd 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 ee529f9f5..8e8e8d68c 100644 --- a/lib/firebase/php-jwt/src/CachedKeySet.php +++ b/lib/firebase/php-jwt/src/CachedKeySet.php @@ -80,9 +80,9 @@ class CachedKeySet implements ArrayAccess 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 @@ class CachedKeySet implements ArrayAccess $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 @@ class CachedKeySet implements ArrayAccess } $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 12fef0944..25f445132 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 @@ class ExpiredException extends \UnexpectedValueException implements JWTException { 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 63fb2484b..d5175b217 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 @@ class JWK * * @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 @@ class JWK // 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 @@ class JWK ) ); - 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 263492068..c18e4cc06 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 @@ class JWT 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 @@ class JWT // 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 @@ class JWT // 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 @@ class JWT 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 @@ class JWT * 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 @@ class JWT */ 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 @@ class JWT * 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 @@ class JWT */ public static function sign( string $msg, - $key, + #[\SensitiveParameter] $key, string $alg ): string { if (empty(static::$supported_algs[$alg])) { @@ -248,10 +261,19 @@ class JWT 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 @@ class JWT * * @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 @@ class JWT private static function verify( string $msg, string $signature, - $keyMaterial, + #[\SensitiveParameter] $keyMaterial, string $alg ): bool { if (empty(static::$supported_algs[$alg])) { @@ -310,7 +332,15 @@ class JWT 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 @@ class JWT 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 @@ class JWT */ 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 @@ class JWT * @return Key */ private static function getKey( - $keyOrKeyArray, + #[\SensitiveParameter] $keyOrKeyArray, ?string $kid ): Key { if ($keyOrKeyArray instanceof Key) { @@ -666,4 +692,57 @@ class JWT 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 00cf7f2ed..694d3b13b 100644 --- a/lib/firebase/php-jwt/src/Key.php +++ b/lib/firebase/php-jwt/src/Key.php @@ -9,26 +9,20 @@ use TypeError; 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 @@ class Key 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 @@ class Key } /** - * @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 13709d1b8..5fe721e03 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 6d78a9309..cdaebee3f 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 69583d7cc..0db75a950 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 6eca94ef9..761506dd0 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 @@ final class BodySummarizer implements BodySummarizerInterface 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 bc6efc90f..c78919a4f 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 @@ class Client implements ClientInterface, \Psr\Http\Client\ClientInterface * * @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 1788e16ab..6aaee61af 100644 --- a/lib/guzzlehttp/guzzle/src/ClientInterface.php +++ b/lib/guzzlehttp/guzzle/src/ClientInterface.php @@ -80,5 +80,5 @@ interface ClientInterface * * @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 c29b4b7e9..b616cf2ed 100644 --- a/lib/guzzlehttp/guzzle/src/Cookie/CookieJar.php +++ b/lib/guzzlehttp/guzzle/src/Cookie/CookieJar.php @@ -103,7 +103,7 @@ class CookieJar implements CookieJarInterface }, $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 8c55cc6f7..93ada58d2 100644 --- a/lib/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php +++ b/lib/guzzlehttp/guzzle/src/Cookie/CookieJarInterface.php @@ -62,7 +62,7 @@ interface CookieJarInterface extends \Countable, \IteratorAggregate * @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 c9806da88..47c4d10ae 100644 --- a/lib/guzzlehttp/guzzle/src/Cookie/SetCookie.php +++ b/lib/guzzlehttp/guzzle/src/Cookie/SetCookie.php @@ -62,6 +62,10 @@ class SetCookie 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 a80956c9d..ba67ad498 100644 --- a/lib/guzzlehttp/guzzle/src/Exception/BadResponseException.php +++ b/lib/guzzlehttp/guzzle/src/Exception/BadResponseException.php @@ -14,7 +14,7 @@ class BadResponseException extends RequestException 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 e1a31519c..eab51ca17 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 c2d0a9ccc..b42c88abf 100644 --- a/lib/guzzlehttp/guzzle/src/Exception/RequestException.php +++ b/lib/guzzlehttp/guzzle/src/Exception/RequestException.php @@ -7,7 +7,6 @@ use GuzzleHttp\BodySummarizerInterface; 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 @@ class RequestException extends TransferException implements RequestExceptionInte */ 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 @@ class RequestException extends TransferException implements RequestExceptionInte $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 @@ class RequestException extends TransferException implements RequestExceptionInte 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 16a942232..3c1fa9c13 100644 --- a/lib/guzzlehttp/guzzle/src/Handler/CurlFactory.php +++ b/lib/guzzlehttp/guzzle/src/Handler/CurlFactory.php @@ -11,6 +11,7 @@ use GuzzleHttp\Psr7\LazyOpenStream; 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 @@ class CurlFactory implements CurlFactoryInterface 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 @@ class CurlFactory implements CurlFactoryInterface 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 @@ class CurlFactory implements CurlFactoryInterface '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 @@ class CurlFactory implements CurlFactoryInterface 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 @@ class CurlFactory implements CurlFactoryInterface ); } + $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 @@ class CurlFactory implements CurlFactoryInterface 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 @@ class CurlFactory implements CurlFactoryInterface } $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 @@ class CurlFactory implements CurlFactoryInterface // 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 @@ class CurlFactory implements CurlFactoryInterface } 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 @@ class CurlFactory implements CurlFactoryInterface 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 a64e1821a..21abbedf3 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 @@ class CurlMultiHandler } } + // 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 @@ class CurlMultiHandler } 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 @@ class CurlMultiHandler $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 77ffed521..3ecd5964d 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 @@ class MockHandler implements \Countable 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 f045b526c..9df70cf23 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 @@ class Proxy * 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 61632f564..f24921f47 100644 --- a/lib/guzzlehttp/guzzle/src/Handler/StreamHandler.php +++ b/lib/guzzlehttp/guzzle/src/Handler/StreamHandler.php @@ -40,6 +40,12 @@ class StreamHandler \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 @@ class StreamHandler $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 @@ class StreamHandler 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 @@ class StreamHandler // 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 @@ class StreamHandler ); 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 6cb12f07a..03f9a18ff 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 @@ class HandlerStack /** * @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 @@ class HandlerStack * @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 04e9eb37a..9b77eee83 100644 --- a/lib/guzzlehttp/guzzle/src/MessageFormatter.php +++ b/lib/guzzlehttp/guzzle/src/MessageFormatter.php @@ -68,7 +68,7 @@ class MessageFormatter implements 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 { $cache = []; diff --git a/lib/guzzlehttp/guzzle/src/MessageFormatterInterface.php b/lib/guzzlehttp/guzzle/src/MessageFormatterInterface.php index 47934614a..a39ac248e 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 7e3eb6b3a..9901da44a 100644 --- a/lib/guzzlehttp/guzzle/src/Middleware.php +++ b/lib/guzzlehttp/guzzle/src/Middleware.php @@ -55,7 +55,7 @@ final class Middleware * * @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 @@ final class Middleware * * @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 @@ final class Middleware * * @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 @@ final class Middleware * 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 6277c61fb..ddc304bb1 100644 --- a/lib/guzzlehttp/guzzle/src/Pool.php +++ b/lib/guzzlehttp/guzzle/src/Pool.php @@ -86,7 +86,7 @@ class Pool implements PromisorInterface * @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 0a8de8128..7dde6c5f4 100644 --- a/lib/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php +++ b/lib/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php @@ -76,8 +76,8 @@ class PrepareBodyMiddleware $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 a38768c0c..84a3500e4 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 8f4d93ac4..65f49cb75 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 @@ class RetryMiddleware }; } - 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 2ce9e38f2..93fa334c8 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 93d6d39cd..c6a5893dd 100644 --- a/lib/guzzlehttp/guzzle/src/Utils.php +++ b/lib/guzzlehttp/guzzle/src/Utils.php @@ -71,7 +71,7 @@ final class Utils return \STDOUT; } - return \GuzzleHttp\Psr7\Utils::tryFopen('php://output', 'w'); + return Psr7\Utils::tryFopen('php://output', 'w'); } /** @@ -79,7 +79,7 @@ final class Utils * * 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 @@ final class Utils { $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 5edc66ab1..9ab4b9649 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 c73afb903..7df9c0ae6 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 a32d3d29c..493a9315b 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 6c5bdd662..9d6e85678 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 0b5b9c0a4..0da022834 100644 --- a/lib/guzzlehttp/promises/src/Coroutine.php +++ b/lib/guzzlehttp/promises/src/Coroutine.php @@ -84,8 +84,8 @@ final class Coroutine implements PromiseInterface } 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 c09d23c60..dd72c8310 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 @@ final class Each 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 @@ final class Each 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 ab7129659..727ec315c 100644 --- a/lib/guzzlehttp/promises/src/FulfilledPromise.php +++ b/lib/guzzlehttp/promises/src/FulfilledPromise.php @@ -31,8 +31,8 @@ class FulfilledPromise implements PromiseInterface } 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 1b07bdc9a..c0c5be2c0 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 2824802bb..c11721e4d 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 d947da1f5..1ebf0b2a6 100644 --- a/lib/guzzlehttp/promises/src/RejectedPromise.php +++ b/lib/guzzlehttp/promises/src/RejectedPromise.php @@ -31,8 +31,8 @@ class RejectedPromise implements PromiseInterface } 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 72a81ba20..47dca8624 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 e1570d727..3193d2a12 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 @@ final class Utils $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 fe3eda70a..4a2a12194 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 850fa9d70..24aad8605 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 70293fc40..96098f536 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 f34722cff..7e4554d5c 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 73d17e337..3ef15103a 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 65dbc4ba0..c15ee63fc 100644 --- a/lib/guzzlehttp/psr7/src/MessageTrait.php +++ b/lib/guzzlehttp/psr7/src/MessageTrait.php @@ -174,10 +174,6 @@ trait MessageTrait 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 d23fba8a3..43d718f65 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 8b9492797..ccf867a0b 100644 --- a/lib/guzzlehttp/psr7/src/Query.php +++ b/lib/guzzlehttp/psr7/src/Query.php @@ -63,12 +63,15 @@ final class Query * 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 @@ final class Query 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 @@ final class Query } 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 00f16e2d9..34e612fda 100644 --- a/lib/guzzlehttp/psr7/src/Response.php +++ b/lib/guzzlehttp/psr7/src/Response.php @@ -96,7 +96,7 @@ class Response implements ResponseInterface 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 ae8538814..77b04d747 100644 --- a/lib/guzzlehttp/psr7/src/StreamWrapper.php +++ b/lib/guzzlehttp/psr7/src/StreamWrapper.php @@ -69,7 +69,7 @@ final class StreamWrapper } } - 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 @@ final class StreamWrapper * 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 b26719937..d9b779f13 100644 --- a/lib/guzzlehttp/psr7/src/UploadedFile.php +++ b/lib/guzzlehttp/psr7/src/UploadedFile.php @@ -11,15 +11,15 @@ use RuntimeException; 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 @@ class UploadedFile implements UploadedFileInterface $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 @@ class UploadedFile implements UploadedFileInterface */ 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 @@ class UploadedFile implements UploadedFileInterface 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 f1feee871..a7cdfb003 100644 --- a/lib/guzzlehttp/psr7/src/Uri.php +++ b/lib/guzzlehttp/psr7/src/Uri.php @@ -107,7 +107,7 @@ class Uri implements UriInterface, \JsonSerializable { // 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 @@ class Uri implements UriInterface, \JsonSerializable * * @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 bf5ea9dba..5451e3dcd 100644 --- a/lib/guzzlehttp/psr7/src/Utils.php +++ b/lib/guzzlehttp/psr7/src/Utils.php @@ -231,7 +231,7 @@ final class Utils * @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 @@ final class Utils 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 @@ final class Utils restore_error_handler(); if ($ex) { - /** @var $ex \RuntimeException */ + /** @var \RuntimeException $ex */ throw $ex; } @@ -430,7 +444,7 @@ final class Utils 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 7dfa39b7c..9c8958afc 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 cbb449d48..05c8d457e 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 59201f48f..5dcc58355 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 293a54d6e..eb6241764 100644 --- a/lib/league/oauth2-client/src/Provider/AbstractProvider.php +++ b/lib/league/oauth2-client/src/Provider/AbstractProvider.php @@ -17,6 +17,7 @@ namespace League\OAuth2\Client\Provider; 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 @@ abstract class AbstractProvider * * @param array $options * @return array Authorization parameters + * @throws InvalidArgumentException */ protected function getAuthorizationParameters(array $options) { @@ -476,6 +478,7 @@ abstract class AbstractProvider * * @param array $options * @return string Authorization URL + * @throws InvalidArgumentException */ public function getAuthorizationUrl(array $options = []) { @@ -492,10 +495,11 @@ abstract class AbstractProvider * @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 @@ abstract class AbstractProvider * * @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 @@ abstract class AbstractProvider * * @param RequestInterface $request * @return ResponseInterface + * @throws GuzzleException */ public function getResponse(RequestInterface $request) { @@ -710,8 +722,10 @@ abstract class AbstractProvider * 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 @@ abstract class AbstractProvider */ protected function getContentType(ResponseInterface $response) { - return join(';', (array) $response->getHeader('content-type')); + return implode(';', $response->getHeader('content-type')); } /** @@ -815,7 +829,7 @@ abstract class AbstractProvider * 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 class AbstractProvider * * @param AccessToken $token * @return ResourceOwnerInterface + * @throws IdentityProviderException + * @throws UnexpectedValueException + * @throws GuzzleException */ public function getResourceOwner(AccessToken $token) { @@ -872,6 +889,9 @@ abstract class AbstractProvider * * @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 81533c307..331b0ace6 100644 --- a/lib/league/oauth2-client/src/Token/AccessToken.php +++ b/lib/league/oauth2-client/src/Token/AccessToken.php @@ -22,7 +22,7 @@ use RuntimeException; * * @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 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter } 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 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter return $this->refreshToken; } + /** + * @inheritdoc + */ + public function setRefreshToken($refreshToken) + { + $this->refreshToken = $refreshToken; + } + /** * @inheritdoc */ @@ -196,7 +204,7 @@ class AccessToken implements AccessTokenInterface, ResourceOwnerAccessTokenInter 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 d82a2ae17..d41761f51 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 38792d4af..e951f309b 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 d004e3c6d..58f0538d2 100644 --- a/lib/league/oauth2-google/src/Provider/GoogleUser.php +++ b/lib/league/oauth2-google/src/Provider/GoogleUser.php @@ -72,6 +72,36 @@ class GoogleUser implements ResourceOwnerInterface 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 36de23cde..3bca288b9 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 2fd064a21..ef416d942 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 a7fe129b0..7c1512d07 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 @@ class ClassConst implements PhpParser\Builder * 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 af010e028..0aae8738c 100644 --- a/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php +++ b/lib/nikic/php-parser/lib/PhpParser/BuilderFactory.php @@ -213,7 +213,7 @@ class BuilderFactory /** * 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 af6ceb996..05e7868f4 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\ComplexType; 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 @@ final class BuilderHelpers * 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 @@ final class BuilderHelpers 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 7131c3d25..ceb3f11f3 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 676322701..fc276ecb9 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 e15dd0a5d..60b809b8b 100644 --- a/lib/nikic/php-parser/lib/PhpParser/Lexer.php +++ b/lib/nikic/php-parser/lib/PhpParser/Lexer.php @@ -69,7 +69,7 @@ class Lexer * @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 b0929f3cc..a0e781d04 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 @@ class Emulative extends Lexer } } - 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 777a4afde..82c5acc2c 100644 --- a/lib/nikic/php-parser/lib/PhpParser/NameContext.php +++ b/lib/nikic/php-parser/lib/PhpParser/NameContext.php @@ -36,7 +36,7 @@ class NameContext * * @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 bcf130e68..17e680260 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 71694478e..46db975c4 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 1b078f821..5aaa9867e 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 b88a8f7e6..5469b8e4c 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 aef8fc333..f15336ede 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 f0a564ff0..0d6e4b1ff 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 @@ class Name extends NodeAbstract * * @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 1e90b7944..dfb77f629 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 6690a16bf..df2f6c1b6 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 @@ class String_ extends Scalar } 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 6adc5a6c6..d9464a1ae 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 9b9c09478..5d7b5c016 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 24882683b..f2b30d79f 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 f46ff0baf..a3a5bfaa5 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 5beff8b39..4b1079bcd 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 c63204577..fc249161a 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 205731e20..286b42961 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 efc578c58..53731254c 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 29584560d..0cc47b412 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 7fc158c57..74e004380 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 ba622efd1..e0c7f783a 100644 --- a/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php +++ b/lib/nikic/php-parser/lib/PhpParser/NodeDumper.php @@ -39,7 +39,7 @@ class NodeDumper * * @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 83f3ea831..dd2e9ca76 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 @@ class NameResolver extends NodeVisitorAbstract 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 8956c7671..7236c68e2 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 77fd1f3fb..083ff465d 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 @@ class Multiple implements Parser $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 59bd1e8cf..80ebdfb37 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 @@ class Php5 extends \PhpParser\ParserAbstract $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 @@ class Php5 extends \PhpParser\ParserAbstract $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 6d2b4b0f9..d41bb8369 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, - 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, + 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, - 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, 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, - 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, 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,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 @@ class Php7 extends \PhpParser\ParserAbstract $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 @@ class Php7 extends \PhpParser\ParserAbstract $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 9f9d00c76..567e09a97 100644 --- a/lib/nikic/php-parser/lib/PhpParser/ParserAbstract.php +++ b/lib/nikic/php-parser/lib/PhpParser/ParserAbstract.php @@ -155,7 +155,7 @@ abstract class ParserAbstract implements 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) { $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 baba23bdb..98b0aee34 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 7c32e5a3c..b8115d00a 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 @@ class Standard extends PrettyPrinterAbstract // 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 770d50092..5d87e5ce8 100644 --- a/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php +++ b/lib/nikic/php-parser/lib/PhpParser/PrettyPrinterAbstract.php @@ -658,7 +658,7 @@ abstract class PrettyPrinterAbstract $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 @@ abstract class PrettyPrinterAbstract \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 45c7017df..000000000 --- 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 b4a5ba31c..000000000 --- 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 f2b9c4e51..000000000 --- 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 eb50ebfcd..000000000 --- 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 6a1d7f300..000000000 --- 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 c7731a56f..000000000 --- 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 d71d1b818..000000000 --- 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 9e412fbd1..1804e16fa 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 d805f56ae..523305603 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 88cd65910..0e37a0956 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 @@ class OS_Guess 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 fee6638f4..0c9ab5694 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_destructor_object_list'] = array(); $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 @@ class 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 @@ class PEAR 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 96efff75d..000000000 --- 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 f6145abac..62ff649c0 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 9d5f6e336..af04db1bd 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 48b640809..d0d27977d 100644 --- a/lib/symfony/filesystem/Exception/FileNotFoundException.php +++ b/lib/symfony/filesystem/Exception/FileNotFoundException.php @@ -19,13 +19,13 @@ namespace Symfony\Component\Filesystem\Exception; */ 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 a3c544553..df3a0850a 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 78458d5b9..71628ceed 100644 --- a/lib/symfony/filesystem/Filesystem.php +++ b/lib/symfony/filesystem/Filesystem.php @@ -40,25 +40,25 @@ class Filesystem { $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 @@ class Filesystem 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 @@ class Filesystem } 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 @@ class Filesystem 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 @@ class Filesystem * * @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 @@ class Filesystem 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 @@ class Filesystem $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 @@ class Filesystem { 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 @@ class Filesystem /** * 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 @@ class Filesystem } 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 @@ class Filesystem /** * 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 @@ class Filesystem } 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 @@ class Filesystem { // 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 @@ class Filesystem 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 @@ class Filesystem $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 @@ class Filesystem } 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 @@ class Filesystem { 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 @@ class Filesystem 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 @@ class Filesystem * * @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 @@ class Filesystem } 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 @@ class Filesystem 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 @@ class Filesystem 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 @@ class Filesystem 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 @@ class Filesystem $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 @@ class Filesystem 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 664396235..093d19f5e 100644 --- a/lib/symfony/filesystem/Path.php +++ b/lib/symfony/filesystem/Path.php @@ -254,7 +254,7 @@ final class Path * @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 @@ final class Path } // Strip scheme - if (false !== $schemeSeparatorPosition = strpos($path, '://')) { + if (false !== ($schemeSeparatorPosition = strpos($path, '://')) && 1 !== $schemeSeparatorPosition) { $path = substr($path, $schemeSeparatorPosition + 3); } @@ -437,11 +437,11 @@ final class Path 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 @@ final class Path // 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 10a7a531c..fd75755b2 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 bd6858347..23e42f719 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 e0c523d05..bcf93cfb6 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 dd3082077..49cfcc4bc 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 0fd283c12..83e5d2a8b 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 @@ class Finder implements \IteratorAggregate, \Countable 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 @@ class Finder implements \IteratorAggregate, \Countable 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 @@ class Finder implements \IteratorAggregate, \Countable 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 @@ class Finder implements \IteratorAggregate, \Countable */ public function sortByExtension(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_EXTENSION; + $this->sort = SortableIterator::SORT_BY_EXTENSION; return $this; } @@ -454,7 +456,7 @@ class Finder implements \IteratorAggregate, \Countable */ 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 @@ class Finder implements \IteratorAggregate, \Countable */ 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 @@ class Finder implements \IteratorAggregate, \Countable */ public function sortBySize(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_SIZE; + $this->sort = SortableIterator::SORT_BY_SIZE; return $this; } @@ -502,7 +504,7 @@ class Finder implements \IteratorAggregate, \Countable */ public function sortByType(): static { - $this->sort = Iterator\SortableIterator::SORT_BY_TYPE; + $this->sort = SortableIterator::SORT_BY_TYPE; return $this; } @@ -520,7 +522,7 @@ class Finder implements \IteratorAggregate, \Countable */ 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 @@ class Finder implements \IteratorAggregate, \Countable */ 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 @@ class Finder implements \IteratorAggregate, \Countable */ 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 @@ class Finder implements \IteratorAggregate, \Countable 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 @@ class Finder implements \IteratorAggregate, \Countable */ 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; - } + 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); + } - $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); + 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 @@ class Finder implements \IteratorAggregate, \Countable * * 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 @@ class Finder implements \IteratorAggregate, \Countable $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 @@ class Finder implements \IteratorAggregate, \Countable } 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 7fe8b1a86..d950e48fc 100644 --- a/lib/symfony/finder/Glob.php +++ b/lib/symfony/finder/Glob.php @@ -44,6 +44,9 @@ class Glob $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 @@ class Glob $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 34cced688..f5fd2d4dc 100644 --- a/lib/symfony/finder/Iterator/RecursiveDirectoryIterator.php +++ b/lib/symfony/finder/Iterator/RecursiveDirectoryIterator.php @@ -63,8 +63,9 @@ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator $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 ddd700772..b278706e9 100644 --- a/lib/symfony/finder/Iterator/VcsIgnoredFilterIterator.php +++ b/lib/symfony/finder/Iterator/VcsIgnoredFilterIterator.php @@ -37,9 +37,9 @@ final class VcsIgnoredFilterIterator extends \FilterIterator { $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 949aad31c..639fe721d 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 7498a82d1..ae27502cf 100644 --- a/lib/symfony/framework-bundle/CacheWarmer/CachePoolClearerCacheWarmer.php +++ b/lib/symfony/framework-bundle/CacheWarmer/CachePoolClearerCacheWarmer.php @@ -37,7 +37,7 @@ final class CachePoolClearerCacheWarmer implements CacheWarmerInterface $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 7e039ae2f..c43fc8af1 100644 --- a/lib/symfony/framework-bundle/CacheWarmer/ConfigBuilderCacheWarmer.php +++ b/lib/symfony/framework-bundle/CacheWarmer/ConfigBuilderCacheWarmer.php @@ -15,10 +15,14 @@ use Psr\Log\LoggerInterface; 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 @@ class ConfigBuilderCacheWarmer implements CacheWarmerInterface $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 @@ class ConfigBuilderCacheWarmer implements CacheWarmerInterface 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 @@ class ConfigBuilderCacheWarmer implements CacheWarmerInterface 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 2af9a2fe8..b14bb74f1 100644 --- a/lib/symfony/framework-bundle/CacheWarmer/RouterCacheWarmer.php +++ b/lib/symfony/framework-bundle/CacheWarmer/RouterCacheWarmer.php @@ -34,7 +34,7 @@ class RouterCacheWarmer implements CacheWarmerInterface, ServiceSubscriberInterf $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 @@ class RouterCacheWarmer implements CacheWarmerInterface, ServiceSubscriberInterf 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 94b95e502..ac2c5c9e6 100644 --- a/lib/symfony/framework-bundle/Command/AbstractConfigCommand.php +++ b/lib/symfony/framework-bundle/Command/AbstractConfigCommand.php @@ -117,7 +117,7 @@ abstract class AbstractConfigCommand extends ContainerDebugCommand 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 @@ abstract class AbstractConfigCommand extends ContainerDebugCommand } 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 @@ abstract class AbstractConfigCommand extends ContainerDebugCommand 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 264955d79..936912876 100644 --- a/lib/symfony/framework-bundle/Command/AssetsInstallCommand.php +++ b/lib/symfony/framework-bundle/Command/AssetsInstallCommand.php @@ -97,7 +97,7 @@ EOT $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 @@ EOT $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 @@ EOT } 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 @@ EOT } $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 878157e87..df9f38a26 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 @@ EOF $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 @@ EOF $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 @@ EOF $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 @@ EOF } $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 @@ EOF } 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 @@ EOF $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 @@ EOF 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 @@ EOF 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 fcd70ca0e..9d1662e65 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 @@ EOF $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 @@ EOF 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 @@ EOF } 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 7b53ceb8b..3c5e49dbf 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 @@ EOF $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 9e6ef9330..8c56847e9 100644 --- a/lib/symfony/framework-bundle/Command/CachePoolInvalidateTagsCommand.php +++ b/lib/symfony/framework-bundle/Command/CachePoolInvalidateTagsCommand.php @@ -65,26 +65,26 @@ final class CachePoolInvalidateTagsCommand extends Command $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 fc0dc6d79..ff90a9dba 100644 --- a/lib/symfony/framework-bundle/Command/CachePoolPruneCommand.php +++ b/lib/symfony/framework-bundle/Command/CachePoolPruneCommand.php @@ -53,14 +53,21 @@ EOF 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 6f1073de4..08e6ebc4d 100644 --- a/lib/symfony/framework-bundle/Command/CacheWarmupCommand.php +++ b/lib/symfony/framework-bundle/Command/CacheWarmupCommand.php @@ -61,7 +61,7 @@ EOF $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 @@ EOF $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 cc116fc68..fcef7c1d6 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 @@ class ConfigDebugCommand extends AbstractConfigCommand 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 @@ EOF 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 @@ EOF 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 @@ EOF 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 @@ EOF $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 @@ EOF // 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 3231e5a47..27dc01b11 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 @@ EOF } 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 df6aef5dd..6847926ff 100644 --- a/lib/symfony/framework-bundle/Command/ContainerDebugCommand.php +++ b/lib/symfony/framework-bundle/Command/ContainerDebugCommand.php @@ -52,7 +52,7 @@ class ContainerDebugCommand extends Command 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 @@ EOF 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 @@ EOF $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 @@ EOF $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 b63ebe431..2cad0f349 100644 --- a/lib/symfony/framework-bundle/Command/ContainerLintCommand.php +++ b/lib/symfony/framework-bundle/Command/ContainerLintCommand.php @@ -80,7 +80,7 @@ final class ContainerLintCommand extends Command 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 @@ final class ContainerLintCommand extends Command $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 ab4793b68..3fde1407b 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 @@ EOF $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 @@ EOF $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 @@ EOF } } - $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 @@ EOF $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 1a74e8682..b6c644499 100644 --- a/lib/symfony/framework-bundle/Command/EventDispatcherDebugCommand.php +++ b/lib/symfony/framework-bundle/Command/EventDispatcherDebugCommand.php @@ -52,7 +52,7 @@ class EventDispatcherDebugCommand extends Command ->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 @@ EOF $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 @@ EOF // 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 8d4e38a29..9f689a142 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 @@ class RouterDebugCommand extends Command 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 @@ EOF } 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 7efd1f3ed..73e5c5d0d 100644 --- a/lib/symfony/framework-bundle/Command/RouterMatchCommand.php +++ b/lib/symfony/framework-bundle/Command/RouterMatchCommand.php @@ -97,21 +97,21 @@ EOF $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 22be89502..665c5c454 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 @@ The %command.name% command decrypts all secrets and copies them in %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 @@ EOF $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 @@ EOF 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 4c613ef7b..0eba8956c 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 @@ EOF } 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 761f6c260..c250258c1 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 @@ EOF $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 de8a7e772..4ba335e62 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 @@ EOF $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 e03afcd0c..3e75ba0c4 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 @@ EOF $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 0e831a343..e2fc39e04 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 @@ EOF } 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 @@ EOF } 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 79a67847a..46e90ed40 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 @@ class TranslationDebugCommand extends Command ->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 @@ EOF $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 @@ EOF // 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 @@ EOF $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 @@ EOF 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 4563779ba..b8759bc92 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\Exception\InvalidArgumentException; 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 @@ class TranslationUpdateCommand extends Command ->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 @@ EOF 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 @@ EOF $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 @@ EOF $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 @@ EOF } } - $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 f84a560c6..5abd98297 100644 --- a/lib/symfony/framework-bundle/Command/WorkflowDumpCommand.php +++ b/lib/symfony/framework-bundle/Command/WorkflowDumpCommand.php @@ -62,7 +62,7 @@ class WorkflowDumpCommand extends Command $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 @@ EOF 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 @@ EOF } 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 38dd8405a..a96336116 100644 --- a/lib/symfony/framework-bundle/Console/Application.php +++ b/lib/symfony/framework-bundle/Console/Application.php @@ -157,7 +157,7 @@ class Application extends BaseApplication return $command; } - public function all(string $namespace = null): array + public function all(?string $namespace = null): array { $this->registerCommands(); @@ -166,7 +166,7 @@ class Application extends BaseApplication 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 ba500adb2..af5c3b10a 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/Descriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/Descriptor.php @@ -62,7 +62,7 @@ abstract class Descriptor implements DescriptorInterface $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 class Descriptor implements DescriptorInterface * * @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 class Descriptor implements DescriptorInterface 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 @@ abstract class Descriptor implements DescriptorInterface } if (\is_object($value)) { - return sprintf('object(%s)', $value::class); + return \sprintf('object(%s)', $value::class); } if (\is_string($value)) { @@ -278,7 +278,7 @@ abstract class Descriptor implements DescriptorInterface 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 1dc567a3f..344db992f 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/JsonDescriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/JsonDescriptor.php @@ -70,7 +70,7 @@ class JsonDescriptor extends Descriptor $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 @@ class JsonDescriptor extends Descriptor $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 @@ class JsonDescriptor extends Descriptor $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 @@ class JsonDescriptor extends Descriptor 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 @@ class JsonDescriptor extends Descriptor $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 @@ class JsonDescriptor extends Descriptor 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 @@ class JsonDescriptor extends Descriptor 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 @@ class JsonDescriptor extends Descriptor $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 @@ class JsonDescriptor extends Descriptor 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 275294d7e..c84fd5b1c 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/MarkdownDescriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/MarkdownDescriptor.php @@ -40,7 +40,7 @@ class MarkdownDescriptor extends Descriptor } $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 @@ class MarkdownDescriptor extends Descriptor $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 @@ class MarkdownDescriptor extends Descriptor } } - 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 @@ class MarkdownDescriptor extends Descriptor } 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 @@ class MarkdownDescriptor extends Descriptor $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 @@ class MarkdownDescriptor extends Descriptor $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 @@ class MarkdownDescriptor extends Descriptor 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 @@ class MarkdownDescriptor extends Descriptor $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 @@ class MarkdownDescriptor extends Descriptor 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 @@ class MarkdownDescriptor extends Descriptor 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 @@ class MarkdownDescriptor extends Descriptor $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 @@ class MarkdownDescriptor extends Descriptor $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 @@ class MarkdownDescriptor extends Descriptor $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 @@ class MarkdownDescriptor extends Descriptor $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 @@ class MarkdownDescriptor extends Descriptor 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 b0fe7f2ac..9e05f90e3 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 @@ class TextDescriptor extends Descriptor 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 @@ class TextDescriptor extends Descriptor } 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 @@ class TextDescriptor extends Descriptor } 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 @@ class TextDescriptor extends Descriptor } 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 @@ class TextDescriptor extends Descriptor 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 @@ class TextDescriptor extends Descriptor } } 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 @@ class TextDescriptor extends Descriptor $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 @@ class TextDescriptor extends Descriptor $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 @@ class TextDescriptor extends Descriptor 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 @@ class TextDescriptor extends Descriptor $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 @@ class TextDescriptor extends Descriptor 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 @@ class TextDescriptor extends Descriptor $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 @@ class TextDescriptor extends Descriptor 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 @@ class TextDescriptor extends Descriptor $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 @@ class TextDescriptor extends Descriptor } 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 @@ class TextDescriptor extends Descriptor $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 @@ class TextDescriptor extends Descriptor $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 @@ class TextDescriptor extends Descriptor } 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 @@ class TextDescriptor extends Descriptor $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 @@ class TextDescriptor extends Descriptor { 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 f12e4583b..fb4ab11a6 100644 --- a/lib/symfony/framework-bundle/Console/Descriptor/XmlDescriptor.php +++ b/lib/symfony/framework-bundle/Console/Descriptor/XmlDescriptor.php @@ -53,7 +53,7 @@ class XmlDescriptor extends Descriptor $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 @@ class XmlDescriptor extends Descriptor $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 @@ class XmlDescriptor extends Descriptor 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 @@ class XmlDescriptor extends Descriptor 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 @@ class XmlDescriptor extends Descriptor $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 @@ class XmlDescriptor extends Descriptor 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 @@ class XmlDescriptor extends Descriptor 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 @@ class XmlDescriptor extends Descriptor 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 @@ class XmlDescriptor extends Descriptor 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 @@ class XmlDescriptor extends Descriptor /** * @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 @@ class XmlDescriptor extends Descriptor 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 @@ class XmlDescriptor extends Descriptor $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 @@ class XmlDescriptor extends Descriptor $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 47d69fef4..b12a8d862 100644 --- a/lib/symfony/framework-bundle/Console/Helper/DescriptorHelper.php +++ b/lib/symfony/framework-bundle/Console/Helper/DescriptorHelper.php @@ -25,7 +25,7 @@ use Symfony\Component\ErrorHandler\ErrorRenderer\FileLinkFormatter; */ 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 4ede883f7..b47449816 100644 --- a/lib/symfony/framework-bundle/Controller/AbstractController.php +++ b/lib/symfony/framework-bundle/Controller/AbstractController.php @@ -75,7 +75,7 @@ abstract class AbstractController implements ServiceSubscriberInterface 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 @@ abstract class AbstractController implements ServiceSubscriberInterface 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 @@ abstract class AbstractController implements ServiceSubscriberInterface * 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 @@ abstract class AbstractController implements ServiceSubscriberInterface * 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 @@ abstract class AbstractController implements ServiceSubscriberInterface * * @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 @@ abstract class AbstractController implements ServiceSubscriberInterface /** * 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 @@ abstract class AbstractController implements ServiceSubscriberInterface * * 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 @@ abstract class AbstractController implements ServiceSubscriberInterface * * @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 @@ abstract class AbstractController implements ServiceSubscriberInterface /** * @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 @@ abstract class AbstractController implements ServiceSubscriberInterface 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 3449740bf..8d7613d41 100644 --- a/lib/symfony/framework-bundle/Controller/ControllerResolver.php +++ b/lib/symfony/framework-bundle/Controller/ControllerResolver.php @@ -31,7 +31,7 @@ class ControllerResolver extends ContainerControllerResolver } 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 f5f42a7f7..91d1e67dd 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 @@ class RedirectController * * @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 @@ class RedirectController $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 @@ class RedirectController 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 @@ class RedirectController 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 437458a49..97631572c 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 @@ class TemplateController * @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 @@ class TemplateController /** * @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 700d0f22d..e383d48ae 100644 --- a/lib/symfony/framework-bundle/DataCollector/RouterDataCollector.php +++ b/lib/symfony/framework-bundle/DataCollector/RouterDataCollector.php @@ -28,7 +28,7 @@ class RouterDataCollector extends BaseRouterDataCollector $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 5b31f2884..b76b1f3ca 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/LoggingTranslatorPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/LoggingTranslatorPass.php @@ -41,7 +41,7 @@ class LoggingTranslatorPass implements CompilerPassInterface $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 8f3f9b220..f904e8b19 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/ProfilerPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/ProfilerPass.php @@ -45,7 +45,7 @@ class ProfilerPass implements CompilerPassInterface 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 6e7669a71..428137ff8 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/TestServiceContainerWeakRefPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/TestServiceContainerWeakRefPass.php @@ -34,7 +34,10 @@ class TestServiceContainerWeakRefPass implements CompilerPassInterface $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 5f975f868..1d151fb61 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/UnusedTagsPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/UnusedTagsPass.php @@ -132,9 +132,9 @@ class UnusedTagsPass implements CompilerPassInterface } $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 c07208311..6f40cc6a6 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Compiler/WorkflowGuardListenerPass.php @@ -45,7 +45,7 @@ class WorkflowGuardListenerPass implements CompilerPassInterface 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 46177a09e..7fe754e3d 100644 --- a/lib/symfony/framework-bundle/DependencyInjection/Configuration.php +++ b/lib/symfony/framework-bundle/DependencyInjection/Configuration.php @@ -146,7 +146,7 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface $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 @@ class Configuration implements ConfigurationInterface 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 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->end() ->end() ->arrayNode('to') + ->performNoDeepMerging() ->beforeNormalization() ->ifString() ->then(fn ($v) => [$v]) @@ -930,6 +921,10 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->end() ->arrayNode('extra') ->info('Extra options for specific HTTP client') + ->useAttributeAsKey('name') ->normalizeKeys(false) ->variablePrototype()->end() ->end() @@ -2089,8 +2085,12 @@ class Configuration implements ConfigurationInterface ->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 @@ class Configuration implements ConfigurationInterface ->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 32026a84d..a8ef96b65 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\Header\Headers; 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\Encoder\EncoderInterface; 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension ]; 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension // 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension } 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 @@ class FrameworkExtension extends Extension } } $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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension } // 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 @@ class FrameworkExtension extends Extension // 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension } } - 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension $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); + $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'])]; + } + $container->getDefinition('serializer.normalizer.object')->setArgument(6, $context); } - 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension ->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 @@ class FrameworkExtension extends Extension } $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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension $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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 @@ class FrameworkExtension extends Extension 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 c2a71d0a7..15318d979 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 @@ final class ConsoleProfilerListener implements EventSubscriberInterface $input = $event->getInput(); if (!$input->hasOption('profile') || !$input->getOption('profile')) { - $this->profiler->disable(); + $this->disabled = true; return; } @@ -92,7 +94,12 @@ final class ConsoleProfilerListener implements EventSubscriberInterface 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 @@ final class ConsoleProfilerListener implements EventSubscriberInterface 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 @@ final class ConsoleProfilerListener implements EventSubscriberInterface $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 @@ final class ConsoleProfilerListener implements EventSubscriberInterface 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 d7bdc8e66..a5a0d5d63 100644 --- a/lib/symfony/framework-bundle/EventListener/SuggestMissingPackageSubscriber.php +++ b/lib/symfony/framework-bundle/EventListener/SuggestMissingPackageSubscriber.php @@ -66,7 +66,7 @@ final class SuggestMissingPackageSubscriber implements EventSubscriberInterface 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 4ba30a5c8..c371d10db 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\ProfilerPass; 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\Mime\DependencyInjection\AddMimeTypeGuesserPass; 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 @@ class FrameworkBundle extends Bundle { $_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 @@ class FrameworkBundle extends Bundle // 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 f312a7afe..481e8cf3c 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 @@ class HttpCache extends BaseHttpCache 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 bbbfd5426..dd6f4eeff 100644 --- a/lib/symfony/framework-bundle/Kernel/MicroKernelTrait.php +++ b/lib/symfony/framework-bundle/Kernel/MicroKernelTrait.php @@ -178,7 +178,7 @@ trait MicroKernelTrait } $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 @@ trait MicroKernelTrait 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 @@ trait MicroKernelTrait 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 45120e42b..cf1d1652f 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 @@ class KernelBrowser extends HttpKernelBrowser $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 14c600fac..220d72a8a 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 f41574d3b..404e7af18 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 @@ return static function (ContainerConfigurator $container) { ]) ->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 @@ return static function (ContainerConfigurator $container) { 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 @@ return static function (ContainerConfigurator $container) { ]) ->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 @@ return static function (ContainerConfigurator $container) { ->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 87207cf95..8cb1a95f6 100644 --- a/lib/symfony/framework-bundle/Resources/config/cache.php +++ b/lib/symfony/framework-bundle/Resources/config/cache.php @@ -88,7 +88,7 @@ return static function (ContainerConfigurator $container) { '', // 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 @@ return static function (ContainerConfigurator $container) { ->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 aa6d4e33c..954ddeffa 100644 --- a/lib/symfony/framework-bundle/Resources/config/collectors.php +++ b/lib/symfony/framework-bundle/Resources/config/collectors.php @@ -56,7 +56,7 @@ return static function (ContainerConfigurator $container) { ->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 a4c78d0ec..593b78fdd 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 @@ return static function (ContainerConfigurator $container) { ->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 9eb545ca2..f1dc560ab 100644 --- a/lib/symfony/framework-bundle/Resources/config/mailer.php +++ b/lib/symfony/framework-bundle/Resources/config/mailer.php @@ -45,11 +45,7 @@ return static function (ContainerConfigurator $container) { 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 6ce674148..bcc124820 100644 --- a/lib/symfony/framework-bundle/Resources/config/notifier.php +++ b/lib/symfony/framework-bundle/Resources/config/notifier.php @@ -73,7 +73,10 @@ return static function (ContainerConfigurator $container) { ->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 eaef79597..4ae34649b 100644 --- a/lib/symfony/framework-bundle/Resources/config/profiling.php +++ b/lib/symfony/framework-bundle/Resources/config/profiling.php @@ -40,7 +40,7 @@ return static function (ContainerConfigurator $container) { ->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 @@ return static function (ContainerConfigurator $container) { ]) ->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 ffa47c384..4a650af6b 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 2311df0fc..c29258d52 100644 --- a/lib/symfony/framework-bundle/Resources/config/serializer.php +++ b/lib/symfony/framework-bundle/Resources/config/serializer.php @@ -60,7 +60,7 @@ return static function (ContainerConfigurator $container) { $container->services() ->set('serializer', Serializer::class) - ->args([[], []]) + ->args([[], [], []]) ->alias(SerializerInterface::class, 'serializer') ->alias(NormalizerInterface::class, 'serializer') @@ -116,7 +116,7 @@ return static function (ContainerConfigurator $container) { ->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 @@ return static function (ContainerConfigurator $container) { 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 905e16f9b..78daa3b87 100644 --- a/lib/symfony/framework-bundle/Resources/config/services.php +++ b/lib/symfony/framework-bundle/Resources/config/services.php @@ -100,6 +100,7 @@ return static function (ContainerConfigurator $container) { ->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 @@ return static function (ContainerConfigurator $container) { ->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 907b1b584..2e481359a 100644 --- a/lib/symfony/framework-bundle/Resources/config/session.php +++ b/lib/symfony/framework-bundle/Resources/config/session.php @@ -90,6 +90,7 @@ return static function (ContainerConfigurator $container) { '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 d1f1a5f34..13f8ff26a 100644 --- a/lib/symfony/framework-bundle/Routing/Attribute/AsRoutingConditionService.php +++ b/lib/symfony/framework-bundle/Routing/Attribute/AsRoutingConditionService.php @@ -42,7 +42,7 @@ use Symfony\Component\DependencyInjection\Attribute\AutoconfigureTag; 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 df7e9348c..3239d1094 100644 --- a/lib/symfony/framework-bundle/Routing/DelegatingLoader.php +++ b/lib/symfony/framework-bundle/Routing/DelegatingLoader.php @@ -40,7 +40,7 @@ class DelegatingLoader extends BaseDelegatingLoader 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 538427aae..609502bca 100644 --- a/lib/symfony/framework-bundle/Routing/RedirectableCompiledUrlMatcher.php +++ b/lib/symfony/framework-bundle/Routing/RedirectableCompiledUrlMatcher.php @@ -21,7 +21,7 @@ use Symfony\Component\Routing\Matcher\RedirectableUrlMatcherInterface; */ 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 3367ecec2..ac6cb03a3 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 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI } 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 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI } 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 @@ class Router extends BaseRouter implements WarmableInterface, ServiceSubscriberI } } - 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 b3eb0c6bc..1324b1409 100644 --- a/lib/symfony/framework-bundle/Secrets/AbstractVault.php +++ b/lib/symfony/framework-bundle/Secrets/AbstractVault.php @@ -36,7 +36,7 @@ abstract class AbstractVault 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 994b31d18..c1f08e977 100644 --- a/lib/symfony/framework-bundle/Secrets/DotenvVault.php +++ b/lib/symfony/framework-bundle/Secrets/DotenvVault.php @@ -45,7 +45,7 @@ class DotenvVault extends AbstractVault 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 @@ class DotenvVault extends AbstractVault $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 @@ class DotenvVault extends AbstractVault 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 b6bb058b3..1aa03ac51 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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface } 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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface $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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface $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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface $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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface $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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface $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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface 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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface } 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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface $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 @@ class SodiumVault extends AbstractVault implements EnvVarLoaderInterface 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 a6d4fed33..b09045b4f 100644 --- a/lib/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php +++ b/lib/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php @@ -43,7 +43,7 @@ trait BrowserKitAssertionsTrait 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 @@ trait BrowserKitAssertionsTrait 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 @@ trait BrowserKitAssertionsTrait 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 @@ trait BrowserKitAssertionsTrait 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 @@ trait BrowserKitAssertionsTrait } 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 a16709461..ede359bcc 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 @@ trait DomCrawlerAssertionsTrait 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 @@ trait DomCrawlerAssertionsTrait 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 @@ trait DomCrawlerAssertionsTrait 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 @@ trait DomCrawlerAssertionsTrait 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 @@ trait DomCrawlerAssertionsTrait 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 @@ trait DomCrawlerAssertionsTrait 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 @@ trait DomCrawlerAssertionsTrait 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 @@ trait DomCrawlerAssertionsTrait 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 @@ trait DomCrawlerAssertionsTrait 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 bed835fa1..4a8afbab4 100644 --- a/lib/symfony/framework-bundle/Test/HttpClientAssertionsTrait.php +++ b/lib/symfony/framework-bundle/Test/HttpClientAssertionsTrait.php @@ -14,13 +14,12 @@ namespace Symfony\Bundle\FrameworkBundle\Test; 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 @@ trait HttpClientAssertionsTrait $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 @@ trait HttpClientAssertionsTrait $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 @@ trait HttpClientAssertionsTrait } } - 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 8d27b757f..5c337b730 100644 --- a/lib/symfony/framework-bundle/Test/KernelTestCase.php +++ b/lib/symfony/framework-bundle/Test/KernelTestCase.php @@ -15,6 +15,7 @@ use PHPUnit\Framework\TestCase; 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 @@ abstract class KernelTestCase extends TestCase 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 @@ abstract class KernelTestCase extends TestCase 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 @@ abstract class KernelTestCase extends TestCase 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 @@ abstract class KernelTestCase extends TestCase 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 83643421e..2308c3e2f 100644 --- a/lib/symfony/framework-bundle/Test/MailerAssertionsTrait.php +++ b/lib/symfony/framework-bundle/Test/MailerAssertionsTrait.php @@ -20,12 +20,12 @@ use Symfony\Component\Mime\Test\Constraint as MimeConstraint; 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 @@ trait MailerAssertionsTrait /** * @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 @@ trait MailerAssertionsTrait /** * @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 53d24cb12..2c4c5467d 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\Event\NotificationEvents; 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 @@ trait NotificationAssertionsTrait 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 @@ trait NotificationAssertionsTrait /** * @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 @@ trait NotificationAssertionsTrait /** * @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 8bf365eb0..25d71d084 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 e1e7a8592..288fd76e8 100644 --- a/lib/symfony/framework-bundle/Test/TestContainer.php +++ b/lib/symfony/framework-bundle/Test/TestContainer.php @@ -71,15 +71,11 @@ class TestContainer extends Container $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 de31d4ba9..9c6ee9c98 100644 --- a/lib/symfony/framework-bundle/Test/WebTestCase.php +++ b/lib/symfony/framework-bundle/Test/WebTestCase.php @@ -38,7 +38,7 @@ abstract class WebTestCase extends KernelTestCase 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 04b56308f..d53296ee6 100644 --- a/lib/symfony/framework-bundle/Translation/Translator.php +++ b/lib/symfony/framework-bundle/Translation/Translator.php @@ -83,7 +83,7 @@ class Translator extends BaseTranslator implements WarmableInterface // 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 @@ class Translator extends BaseTranslator implements WarmableInterface 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 3aedebd74..c3aab8455 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 853c000e0..e735c7564 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 @@ class AcceptHeader */ 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); + $items[] = $item->setIndex($i); + } - $item = new AcceptHeaderItem($part[0], $attributes); - $item->setIndex($index++); - - return $item; - }, $parts)); + return new self($items); } /** @@ -73,7 +70,9 @@ class AcceptHeader */ 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 @@ class AcceptHeader */ 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 @@ class AcceptHeader */ 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 @@ class AcceptHeader */ 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 @@ class AcceptHeader private function sort(): void { if (!$this->sorted) { - uasort($this->items, function (AcceptHeaderItem $a, AcceptHeaderItem $b) { - $qA = $a->getQuality(); - $qB = $b->getQuality(); - - if ($qA === $qB) { - return $a->getIndex() > $b->getIndex() ? 1 : -1; - } - - return $qA > $qB ? -1 : 1; - }); + uasort($this->items, static fn ($a, $b) => $b->getQuality() <=> $a->getQuality() ?: $a->getIndex() <=> $b->getIndex()); $this->sorted = true; } } + + /** + * Generates the canonical key for storing/retrieving an item. + */ + private function getCanonicalKey(AcceptHeaderItem $item): string + { + $parts = []; + + // 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 a66312c8e..8a497a77c 100644 --- a/lib/symfony/http-foundation/Request.php +++ b/lib/symfony/http-foundation/Request.php @@ -857,7 +857,7 @@ class Request * * 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 48c219a7a..8d757f03f 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 @@ class PdoSessionHandler extends AbstractSessionHandler $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 @@ class PdoSessionHandler extends AbstractSessionHandler // - 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 @@ class PdoSessionHandler extends AbstractSessionHandler 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 @@ class PdoSessionHandler extends AbstractSessionHandler 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 @@ class PdoSessionHandler extends AbstractSessionHandler $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 43a9eb84e..e41d03539 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 @@ class SessionHandlerFactory 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 f83e331e4..bbc1fff27 100644 --- a/lib/symfony/http-kernel/Attribute/MapQueryParameter.php +++ b/lib/symfony/http-kernel/Attribute/MapQueryParameter.php @@ -22,7 +22,7 @@ use Symfony\Component\HttpKernel\Controller\ArgumentResolver\QueryParameterValue 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 762b07704..10ed3b8ea 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 09a19c480..0efc21a5e 100644 --- a/lib/symfony/http-kernel/Bundle/Bundle.php +++ b/lib/symfony/http-kernel/Bundle/Bundle.php @@ -70,7 +70,7 @@ abstract class Bundle implements BundleInterface 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 @@ abstract class Bundle implements BundleInterface $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 3c99b74af..87614e941 100644 --- a/lib/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php +++ b/lib/symfony/http-kernel/CacheClearer/Psr6CacheClearer.php @@ -39,7 +39,7 @@ class Psr6CacheClearer implements CacheClearerInterface 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 @@ class Psr6CacheClearer implements CacheClearerInterface 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 f940ba4a7..664110a22 100644 --- a/lib/symfony/http-kernel/CacheWarmer/CacheWarmer.php +++ b/lib/symfony/http-kernel/CacheWarmer/CacheWarmer.php @@ -30,6 +30,6 @@ abstract class CacheWarmer implements CacheWarmerInterface 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 a672956e0..9f1c53456 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 @@ class CacheWarmerAggregate implements CacheWarmerInterface /** * @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 @@ class CacheWarmerAggregate implements CacheWarmerInterface $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 f81f91925..fb6bb10f1 100644 --- a/lib/symfony/http-kernel/Config/FileLocator.php +++ b/lib/symfony/http-kernel/Config/FileLocator.php @@ -30,7 +30,7 @@ class FileLocator extends BaseFileLocator 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 6643cc58e..991e99bdc 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 @@ final class ArgumentResolver implements ArgumentResolverInterface 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 @@ final class ArgumentResolver implements ArgumentResolverInterface } 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 @@ final class ArgumentResolver implements ArgumentResolverInterface } 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 620e2de08..c29725dd2 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/BackedEnumValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/BackedEnumValueResolver.php @@ -78,7 +78,7 @@ class BackedEnumValueResolver implements ArgumentValueResolverInterface, ValueRe } 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 @@ class BackedEnumValueResolver implements ArgumentValueResolverInterface, ValueRe 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 0cfd42bad..388f02b31 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/DateTimeValueResolver.php @@ -90,7 +90,7 @@ final class DateTimeValueResolver implements ArgumentValueResolverInterface, Val } 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 264036128..594f1b8a6 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/NotTaggedControllerValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/NotTaggedControllerValueResolver.php @@ -82,8 +82,8 @@ final class NotTaggedControllerValueResolver implements ArgumentValueResolverInt 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 b186a39c5..0b64a444b 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/QueryParameterValueResolver.php @@ -38,7 +38,7 @@ final class QueryParameterValueResolver implements ValueResolverInterface 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 @@ final class QueryParameterValueResolver implements ValueResolverInterface $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 @@ final class QueryParameterValueResolver implements ValueResolverInterface 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 @@ final class QueryParameterValueResolver implements ValueResolverInterface } 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 @@ final class QueryParameterValueResolver implements ValueResolverInterface } 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 444be1b3f..0fb42944f 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php @@ -40,11 +40,9 @@ use Symfony\Contracts\Translation\TranslatorInterface; 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 @@ class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscr } 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 @@ class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscr $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 @@ class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscr } 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 @@ class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscr $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 @@ class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscr 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 @@ class RequestPayloadValueResolver implements ValueResolverInterface, EventSubscr 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 96e0337d6..fecf59caf 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/ServiceValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/ServiceValueResolver.php @@ -83,11 +83,11 @@ final class ServiceValueResolver implements ArgumentValueResolverInterface, Valu 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 7a12e21ea..afe702300 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/UidValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/UidValueResolver.php @@ -46,7 +46,7 @@ final class UidValueResolver implements ArgumentValueResolverInterface, ValueRes 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 4f6cba729..b4946698d 100644 --- a/lib/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php +++ b/lib/symfony/http-kernel/Controller/ArgumentResolver/VariadicValueResolver.php @@ -42,7 +42,7 @@ final class VariadicValueResolver implements ArgumentValueResolverInterface, Val $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 1c9254e73..5cd9edb31 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 @@ class ContainerControllerResolver extends ControllerResolver $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 d39508949..72ece351b 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 @@ class ControllerResolver implements ControllerResolverInterface } 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 @@ class ControllerResolver implements ControllerResolverInterface 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 @@ class ControllerResolver implements ControllerResolverInterface 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 @@ class ControllerResolver implements ControllerResolverInterface 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 @@ class ControllerResolver implements ControllerResolverInterface [$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 @@ class ControllerResolver implements ControllerResolverInterface 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 @@ class ControllerResolver implements ControllerResolverInterface $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 @@ class ControllerResolver implements ControllerResolverInterface } 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 @@ class ControllerResolver implements ControllerResolverInterface 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 a352090ea..d3ca53fa6 100644 --- a/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php +++ b/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadata.php @@ -94,7 +94,7 @@ class ArgumentMetadata 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 @@ class ArgumentMetadata * * @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 cb7f0a78c..7eafdc94b 100644 --- a/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php +++ b/lib/symfony/http-kernel/ControllerMetadata/ArgumentMetadataFactory.php @@ -18,7 +18,7 @@ namespace Symfony\Component\HttpKernel\ControllerMetadata; */ 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 016ef2ece..3c8d2f0f6 100644 --- a/lib/symfony/http-kernel/DataCollector/AjaxDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/AjaxDataCollector.php @@ -21,7 +21,7 @@ use Symfony\Component\HttpFoundation\Response; */ 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 8a75227d4..ba8fc0c31 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 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte $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 @@ class ConfigDataCollector extends DataCollector implements LateDataCollectorInte $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 d8b795d42..fdc73de06 100644 --- a/lib/symfony/http-kernel/DataCollector/DataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/DataCollector.php @@ -63,9 +63,21 @@ abstract class DataCollector implements DataCollectorInterface $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 8df94ccb8..5e8593d07 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 ce02b545b..8c45b4279 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 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface 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 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface $this->clonesIndex = 0; } - /** - * @internal - */ - public function __sleep(): array + public function __serialize(): array { if (!$this->dataCount) { $this->data = []; @@ -161,16 +158,12 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface $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 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface } } - 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 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface $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 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface $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 a6524ea04..3a94dbc32 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 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter $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 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter /** * @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 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter /** * @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 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter /** * @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 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter /** * @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 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter * * @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 @@ class EventDataCollector extends DataCollector implements LateDataCollectorInter /** * @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 16a29adc1..80156bc8d 100644 --- a/lib/symfony/http-kernel/DataCollector/ExceptionDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/ExceptionDataCollector.php @@ -22,7 +22,7 @@ use Symfony\Component\HttpFoundation\Response; */ 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 eb2b9c85c..cf17e7a73 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 @@ class LoggerDataCollector extends DataCollector implements LateDataCollectorInte 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 8b8894367..9715f94ee 100644 --- a/lib/symfony/http-kernel/DataCollector/MemoryDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/MemoryDataCollector.php @@ -26,7 +26,7 @@ class MemoryDataCollector extends DataCollector implements LateDataCollectorInte $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 eae5f24b7..4792f160c 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 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter $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 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter 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 @@ class RequestDataCollector extends DataCollector implements EventSubscriberInter '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 444138da7..75c21e4c5 100644 --- a/lib/symfony/http-kernel/DataCollector/RouterDataCollector.php +++ b/lib/symfony/http-kernel/DataCollector/RouterDataCollector.php @@ -34,13 +34,13 @@ class RouterDataCollector extends DataCollector /** * @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 a8b7ead94..9799a1333 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 49f188c22..5b3e1cddd 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 d31ce7581..f3101d5b1 100644 --- a/lib/symfony/http-kernel/Debug/TraceableEventDispatcher.php +++ b/lib/symfony/http-kernel/Debug/TraceableEventDispatcher.php @@ -66,7 +66,11 @@ class TraceableEventDispatcher extends BaseTraceableEventDispatcher 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 f41d58b81..9a32b8a4e 100644 --- a/lib/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php +++ b/lib/symfony/http-kernel/DependencyInjection/FragmentRendererPass.php @@ -41,10 +41,10 @@ class FragmentRendererPass implements CompilerPassInterface $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 6270875be..0061a577c 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 f2cf2422b..e2f50dcba 100644 --- a/lib/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php +++ b/lib/symfony/http-kernel/DependencyInjection/RegisterControllerArgumentLocatorsPass.php @@ -45,6 +45,7 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface $parameterBag = $container->getParameterBag(); $controllers = []; + $controllerClasses = []; $publicAliases = []; foreach ($container->getAliases() as $id => $alias) { @@ -58,6 +59,7 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface 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 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface $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 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface } 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 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface } 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 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface 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 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface 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 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface } 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 @@ class RegisterControllerArgumentLocatorsPass implements CompilerPassInterface } $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 7a21fe0e5..ef859a611 100644 --- a/lib/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php +++ b/lib/symfony/http-kernel/DependencyInjection/RemoveEmptyControllerArgumentLocatorsPass.php @@ -34,7 +34,7 @@ class RemoveEmptyControllerArgumentLocatorsPass implements CompilerPassInterface 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 @@ class RemoveEmptyControllerArgumentLocatorsPass implements CompilerPassInterface $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 da9f8d632..8479c8d63 100644 --- a/lib/symfony/http-kernel/DependencyInjection/ResettableServicePass.php +++ b/lib/symfony/http-kernel/DependencyInjection/ResettableServicePass.php @@ -39,7 +39,7 @@ class ResettableServicePass implements CompilerPassInterface 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 c90b7706f..4c804ccf1 100644 --- a/lib/symfony/http-kernel/Event/ControllerArgumentsEvent.php +++ b/lib/symfony/http-kernel/Event/ControllerArgumentsEvent.php @@ -52,7 +52,7 @@ final class ControllerArgumentsEvent extends KernelEvent /** * @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 @@ final class ControllerArgumentsEvent extends KernelEvent * * @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 239b00512..6db2c15f9 100644 --- a/lib/symfony/http-kernel/Event/ControllerEvent.php +++ b/lib/symfony/http-kernel/Event/ControllerEvent.php @@ -51,7 +51,7 @@ final class ControllerEvent extends KernelEvent /** * @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 @@ final class ControllerEvent extends KernelEvent 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 @@ final class ControllerEvent extends KernelEvent * * @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 @@ final class ControllerEvent extends KernelEvent } 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 e64cc419b..02426c52a 100644 --- a/lib/symfony/http-kernel/Event/KernelEvent.php +++ b/lib/symfony/http-kernel/Event/KernelEvent.php @@ -16,7 +16,7 @@ use Symfony\Component\HttpKernel\HttpKernelInterface; 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 bf96985b2..4d963aea1 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 2f012ab52..1ce490537 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 723e758cd..310e7f25a 100644 --- a/lib/symfony/http-kernel/EventListener/CacheAttributeListener.php +++ b/lib/symfony/http-kernel/EventListener/CacheAttributeListener.php @@ -13,6 +13,7 @@ namespace Symfony\Component\HttpKernel\EventListener; 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 @@ class CacheAttributeListener implements EventSubscriberInterface 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 @@ class CacheAttributeListener implements EventSubscriberInterface $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 @@ class CacheAttributeListener implements EventSubscriberInterface } } + $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 ce746bd12..ee720b1ea 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 @@ class DebugHandlersListener implements EventSubscriberInterface /** * 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 @@ class DebugHandlersListener implements EventSubscriberInterface return; } $this->firstCall = $this->hasTerminatedWithException = false; + $hasRun = null; if (!$this->exceptionHandler) { if ($event instanceof KernelEvent) { @@ -93,7 +95,7 @@ class DebugHandlersListener implements EventSubscriberInterface } } 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 @@ class DebugHandlersListener implements EventSubscriberInterface 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 b10bd37f4..07a4e7e6a 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 @@ class DumpListener implements EventSubscriberInterface $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 a2f6db57a..266d96cf8 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 @@ class ErrorListener implements EventSubscriberInterface $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 @@ class ErrorListener implements EventSubscriberInterface $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 @@ class ErrorListener implements EventSubscriberInterface } 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 @@ class ErrorListener implements EventSubscriberInterface /** * 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 65a3bfde4..9feaa0b4f 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 716d939fd..1f30582f4 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 @@ class ProfilerListener implements EventSubscriberInterface 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 bb393c779..fd8ac1a5c 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 @@ class RouterListener implements EventSubscriberInterface 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 17bdf2b39..a702a68f8 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 78e8fe37d..0f9ea715c 100644 --- a/lib/symfony/http-kernel/Exception/AccessDeniedHttpException.php +++ b/lib/symfony/http-kernel/Exception/AccessDeniedHttpException.php @@ -17,7 +17,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 c920fbd0d..57a7a2583 100644 --- a/lib/symfony/http-kernel/Exception/BadRequestHttpException.php +++ b/lib/symfony/http-kernel/Exception/BadRequestHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 a5a6f8405..997c4a681 100644 --- a/lib/symfony/http-kernel/Exception/ConflictHttpException.php +++ b/lib/symfony/http-kernel/Exception/ConflictHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 2893f05cb..c40d597cc 100644 --- a/lib/symfony/http-kernel/Exception/GoneHttpException.php +++ b/lib/symfony/http-kernel/Exception/GoneHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 e12abce00..6d2c253a3 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 a3dd8b3cd..ca8741e40 100644 --- a/lib/symfony/http-kernel/Exception/LengthRequiredHttpException.php +++ b/lib/symfony/http-kernel/Exception/LengthRequiredHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 069619bfc..3f05c2277 100644 --- a/lib/symfony/http-kernel/Exception/LockedHttpException.php +++ b/lib/symfony/http-kernel/Exception/LockedHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 cfbaf5cb0..33572e461 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 ec2bb596f..13e9c2312 100644 --- a/lib/symfony/http-kernel/Exception/NotAcceptableHttpException.php +++ b/lib/symfony/http-kernel/Exception/NotAcceptableHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 0e78fcc15..e1b489eed 100644 --- a/lib/symfony/http-kernel/Exception/NotFoundHttpException.php +++ b/lib/symfony/http-kernel/Exception/NotFoundHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 4431f89d0..8ec710e41 100644 --- a/lib/symfony/http-kernel/Exception/PreconditionFailedHttpException.php +++ b/lib/symfony/http-kernel/Exception/PreconditionFailedHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 f75afd370..848876939 100644 --- a/lib/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php +++ b/lib/symfony/http-kernel/Exception/PreconditionRequiredHttpException.php @@ -18,7 +18,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 6d9fb8a01..aa859d511 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 d4862bd10..842271dc9 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 b71fb2508..2f749aa26 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 c86686128..de8f314b4 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 d58af6c2b..162aa30d6 100644 --- a/lib/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php +++ b/lib/symfony/http-kernel/Exception/UnprocessableEntityHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 3060f1f91..736337bab 100644 --- a/lib/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php +++ b/lib/symfony/http-kernel/Exception/UnsupportedMediaTypeHttpException.php @@ -16,7 +16,7 @@ namespace Symfony\Component\HttpKernel\Exception; */ 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 55305d44e..7eea1aed4 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 62b21e6d4..745242419 100644 --- a/lib/symfony/http-kernel/Fragment/FragmentHandler.php +++ b/lib/symfony/http-kernel/Fragment/FragmentHandler.php @@ -73,7 +73,7 @@ class FragmentHandler } 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 @@ class FragmentHandler { 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 aeef41546..aeb1f7123 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 @@ final class FragmentUriGenerator implements FragmentUriGeneratorInterface 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 968c002b9..6b1317c3a 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 d5b6c4cd3..9cb01f321 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 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer 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 @@ class HIncludeFragmentRenderer extends RoutableFragmentRenderer } } - 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 ba3f6be70..1999603a3 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 95518bed2..152aedad0 100644 --- a/lib/symfony/http-kernel/HttpCache/AbstractSurrogate.php +++ b/lib/symfony/http-kernel/HttpCache/AbstractSurrogate.php @@ -56,7 +56,7 @@ abstract class AbstractSurrogate implements SurrogateInterface 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 @@ abstract class AbstractSurrogate implements SurrogateInterface 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 @@ abstract class AbstractSurrogate implements SurrogateInterface 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 @@ abstract class AbstractSurrogate implements SurrogateInterface $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 @@ abstract class AbstractSurrogate implements SurrogateInterface $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 5db840a80..92b41a5dd 100644 --- a/lib/symfony/http-kernel/HttpCache/Esi.php +++ b/lib/symfony/http-kernel/HttpCache/Esi.php @@ -42,16 +42,16 @@ class Esi extends AbstractSurrogate } } - 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 eabacfec6..8d1a3a579 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 @@ class HttpCache implements HttpKernelInterface, TerminableInterface { $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 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $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 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $response->prepare($request); - $response->isNotModified($request); + if (HttpKernelInterface::MAIN_REQUEST === $type) { + $response->isNotModified($request); + } return $response; } @@ -465,7 +474,7 @@ class HttpCache implements HttpKernelInterface, TerminableInterface * * @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 @@ class HttpCache implements HttpKernelInterface, TerminableInterface // 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 @@ class HttpCache implements HttpKernelInterface, TerminableInterface $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 57b5d2196..05670967a 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 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface 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 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface } } - 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 @@ class ResponseCacheStrategy implements ResponseCacheStrategyInterface * 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 b17c90ac6..9e0839d63 100644 --- a/lib/symfony/http-kernel/HttpCache/Ssi.php +++ b/lib/symfony/http-kernel/HttpCache/Ssi.php @@ -36,9 +36,9 @@ class Ssi extends AbstractSurrogate } } - 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 3f21e383f..4eba39337 100644 --- a/lib/symfony/http-kernel/HttpCache/Store.php +++ b/lib/symfony/http-kernel/HttpCache/Store.php @@ -45,7 +45,7 @@ class Store implements StoreInterface { $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 @@ class Store implements StoreInterface // 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 @@ class Store implements StoreInterface */ private function requestsMatch(?string $vary, array $env1, array $env2): bool { - if (empty($vary)) { + if ('' === ($vary ?? '')) { return true; } @@ -474,7 +470,7 @@ class Store implements StoreInterface /** * 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 253071f07..4caf3daf2 100644 --- a/lib/symfony/http-kernel/HttpCache/SubRequestHandler.php +++ b/lib/symfony/http-kernel/HttpCache/SubRequestHandler.php @@ -51,16 +51,16 @@ class SubRequestHandler $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 e444458f7..5ff10c963 100644 --- a/lib/symfony/http-kernel/HttpCache/SurrogateInterface.php +++ b/lib/symfony/http-kernel/HttpCache/SurrogateInterface.php @@ -58,7 +58,7 @@ interface SurrogateInterface * @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 1d8c30278..ebda2750d 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 d2cf4eaee..886fca9cf 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 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface /** * @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 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface // 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 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface 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 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface 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 @@ class HttpKernel implements HttpKernelInterface, TerminableInterface } 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 0f3630e7f..169789dda 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 6247db901..a2bf0f827 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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl $this->container = null; $this->requestStackSize = 0; $this->resetServices = false; + $this->handlingHttpCache = false; } /** @@ -108,7 +110,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ 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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl return; } - if (null === $this->container) { + if (!$this->container) { $this->preBoot(); } @@ -149,7 +151,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ public function terminate(Request $request, Response $response) { - if (false === $this->booted) { + if (!$this->booted) { return; } @@ -163,7 +165,7 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ public function shutdown() { - if (false === $this->booted) { + if (!$this->booted) { return; } @@ -181,17 +183,26 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl 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 ($container->has('http_cache')) { - return $container->get('http_cache')->handle($request, $type, $catch); + if (HttpKernelInterface::MAIN_REQUEST === $type && !$this->handlingHttpCache && $this->container->has('http_cache')) { + $this->handlingHttpCache = true; + + 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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl 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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl 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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl 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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl $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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl */ 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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl $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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl $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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl 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 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl { 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 537c10040..e036f398e 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 1940c80a9..956abc6f3 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 11d35b7e2..93c1dbc95 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 @@ class Logger extends AbstractLogger implements DebugLoggerInterface } 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 @@ class Logger extends AbstractLogger implements DebugLoggerInterface 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 @@ class Logger extends AbstractLogger implements DebugLoggerInterface } } - 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 @@ class Logger extends AbstractLogger implements DebugLoggerInterface 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 @@ class Logger extends AbstractLogger implements DebugLoggerInterface $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 df61f716f..f1e28bc2b 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 @@ class FileProfilerStorage implements ProfilerStorageInterface $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 @@ class FileProfilerStorage implements ProfilerStorageInterface // 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 @@ class FileProfilerStorage implements ProfilerStorageInterface $profile->getParentToken(), $profile->getStatusCode(), $profile->getVirtualType() ?? 'request', - ]); + ], ',', '"', '\\'); fclose($file); if (1 === mt_rand(1, 10)) { @@ -272,7 +272,7 @@ class FileProfilerStorage implements ProfilerStorageInterface /** * @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 @@ class FileProfilerStorage implements ProfilerStorageInterface 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 @@ class FileProfilerStorage implements ProfilerStorageInterface } 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 08e7b65a2..91ae51e95 100644 --- a/lib/symfony/http-kernel/Profiler/Profile.php +++ b/lib/symfony/http-kernel/Profiler/Profile.php @@ -232,7 +232,7 @@ class Profile 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 04ab0670d..65adf0f17 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 @@ class Profiler implements ResetInterface * * @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 @@ class Profiler implements ResetInterface /** * 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 @@ class Profiler implements ResetInterface 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 14b8993b6..e2a25bc99 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 d36b97527..03453c5c7 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! - +