diff --git a/.github/workflows/phpcs.yml b/.github/workflows/phpcs.yml index aca92bc4..f822fe5b 100644 --- a/.github/workflows/phpcs.yml +++ b/.github/workflows/phpcs.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: php-versions: - - 8.0 + - 8.1 steps: - uses: actions/checkout@v2 diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index dac93123..9da69f07 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -18,11 +18,11 @@ jobs: matrix: include: # Check lowest supported WP version, with the lowest supported PHP. - - php: "8.0" + - php: "8.1" wp: "6.0" allowed_failure: false # Check latest WP with the lowest supported PHP. - - php: "8.0" + - php: "8.1" wp: "master" allowed_failure: false # Check latest WP with the highest supported PHP. diff --git a/composer.json b/composer.json index 66b136e7..0ba31b2c 100644 --- a/composer.json +++ b/composer.json @@ -14,7 +14,7 @@ ] }, "require": { - "php": ">=8.0", + "php": ">=8.1", "masterminds/html5": "^2.8", "symfony/dom-crawler": "^6.0", "symfony/css-selector": "^6.0" diff --git a/composer.lock b/composer.lock index 33862a9b..02a5c57a 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": "0912de9090ec82c584107806ea84d177", + "content-hash": "6c55e96eae0472666466689b8b782260", "packages": [ { "name": "masterminds/html5", - "version": "2.9.0", + "version": "2.10.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" + "reference": "fcf91eb64359852f00d921887b219479b4f21251" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", - "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251", + "reference": "fcf91eb64359852f00d921887b219479b4f21251", "shasum": "" }, "require": { @@ -69,26 +69,26 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" + "source": "https://github.com/Masterminds/html5-php/tree/2.10.0" }, - "time": "2024-03-31T07:05:07+00:00" + "time": "2025-07-25T09:04:22+00:00" }, { "name": "symfony/css-selector", - "version": "v6.0.19", + "version": "v6.4.24", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "f1d00bddb83a4cb2138564b2150001cb6ce272b1" + "reference": "9b784413143701aa3c94ac1869a159a9e53e8761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/f1d00bddb83a4cb2138564b2150001cb6ce272b1", - "reference": "f1d00bddb83a4cb2138564b2150001cb6ce272b1", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/9b784413143701aa3c94ac1869a159a9e53e8761", + "reference": "9b784413143701aa3c94ac1869a159a9e53e8761", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "type": "library", "autoload": { @@ -120,7 +120,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.0.19" + "source": "https://github.com/symfony/css-selector/tree/v6.4.24" }, "funding": [ { @@ -131,41 +131,39 @@ "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-01T08:36:10+00:00" + "time": "2025-07-10T08:14:14+00:00" }, { "name": "symfony/dom-crawler", - "version": "v6.0.19", + "version": "v6.4.25", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "622578ff158318b1b49d95068bd6b66c713601e9" + "reference": "976302990f9f2a6d4c07206836dd4ca77cae9524" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/622578ff158318b1b49d95068bd6b66c713601e9", - "reference": "622578ff158318b1b49d95068bd6b66c713601e9", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/976302990f9f2a6d4c07206836dd4ca77cae9524", + "reference": "976302990f9f2a6d4c07206836dd4ca77cae9524", "shasum": "" }, "require": { - "php": ">=8.0.2", + "masterminds/html5": "^2.6", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0" }, - "conflict": { - "masterminds/html5": "<2.6" - }, "require-dev": { - "masterminds/html5": "^2.6", - "symfony/css-selector": "^5.4|^6.0" - }, - "suggest": { - "symfony/css-selector": "" + "symfony/css-selector": "^5.4|^6.0|^7.0" }, "type": "library", "autoload": { @@ -193,7 +191,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.0.19" + "source": "https://github.com/symfony/dom-crawler/tree/v6.4.25" }, "funding": [ { @@ -204,29 +202,33 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2023-01-20T17:44:14+00:00" + "time": "2025-08-05T18:56:08+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -237,8 +239,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -272,7 +274,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" }, "funding": [ { @@ -283,29 +285,34 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.33.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -316,8 +323,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -352,7 +359,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -363,12 +370,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-01-29T20:11:03+00:00" + "time": "2024-12-23T08:48:59+00:00" } ], "packages-dev": [ @@ -428,28 +439,28 @@ }, { "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v1.0.0", + "version": "v1.1.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/composer-installer.git", - "reference": "4be43904336affa5c2f70744a348312336afd0da" + "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/4be43904336affa5c2f70744a348312336afd0da", - "reference": "4be43904336affa5c2f70744a348312336afd0da", + "url": "https://api.github.com/repos/PHPCSStandards/composer-installer/zipball/e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", + "reference": "e9cf5e4bbf7eeaf9ef5db34938942602838fc2b1", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0 || ^2.0", + "composer-plugin-api": "^2.2", "php": ">=5.4", "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" }, "require-dev": { - "composer/composer": "*", + "composer/composer": "^2.2", "ext-json": "*", "ext-zip": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", + "php-parallel-lint/php-parallel-lint": "^1.4.0", "phpcompatibility/php-compatibility": "^9.0", "yoast/phpunit-polyfills": "^1.0" }, @@ -469,9 +480,9 @@ "authors": [ { "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" + "email": "opensource@frenck.dev", + "homepage": "https://frenck.dev", + "role": "Open source developer" }, { "name": "Contributors", @@ -479,7 +490,6 @@ } ], "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", "keywords": [ "PHPCodeSniffer", "PHP_CodeSniffer", @@ -500,9 +510,28 @@ ], "support": { "issues": "https://github.com/PHPCSStandards/composer-installer/issues", + "security": "https://github.com/PHPCSStandards/composer-installer/security/policy", "source": "https://github.com/PHPCSStandards/composer-installer" }, - "time": "2023-01-05T11:28:13+00:00" + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" + } + ], + "time": "2025-07-17T20:45:56+00:00" }, { "name": "dms/phpunit-arraysubset-asserts", @@ -550,30 +579,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.5.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^11", + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.30 || ^5.4" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -600,7 +629,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -616,20 +645,20 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:15:36+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.13.4", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/07d290f0c47959fd5eed98c95ee5602db07e0b6a", + "reference": "07d290f0c47959fd5eed98c95ee5602db07e0b6a", "shasum": "" }, "require": { @@ -637,11 +666,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -667,7 +697,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.13.4" }, "funding": [ { @@ -675,20 +705,20 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2025-08-01T08:46:24+00:00" }, { "name": "nikic/php-parser", - "version": "v5.0.2", + "version": "v5.6.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", + "reference": "f103601b29efebd7ff4a1ca7b3eeea9e3336a2a2", "shasum": "" }, "require": { @@ -699,7 +729,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -707,7 +737,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-master": "5.x-dev" } }, "autoload": { @@ -731,9 +761,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.6.1" }, - "time": "2024-03-05T20:51:40+00:00" + "time": "2025-08-13T20:13:15+00:00" }, { "name": "phar-io/manifest", @@ -989,21 +1019,22 @@ }, { "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.5", + "version": "2.1.7", "source": { "type": "git", "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082" + "reference": "5bfbbfbabb3df2b9a83e601de9153e4a7111962c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/01c1ff2704a58e46f0cb1ca9d06aee07b3589082", - "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/5bfbbfbabb3df2b9a83e601de9153e4a7111962c", + "reference": "5bfbbfbabb3df2b9a83e601de9153e4a7111962c", "shasum": "" }, "require": { "phpcompatibility/php-compatibility": "^9.0", - "phpcompatibility/phpcompatibility-paragonie": "^1.0" + "phpcompatibility/phpcompatibility-paragonie": "^1.0", + "squizlabs/php_codesniffer": "^3.3" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^1.0" @@ -1053,35 +1084,39 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcompatibility", + "type": "thanks_dev" } ], - "time": "2024-04-24T21:37:59+00:00" + "time": "2025-05-12T16:38:37+00:00" }, { "name": "phpcsstandards/phpcsextra", - "version": "1.2.1", + "version": "1.4.0", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHPCSExtra.git", - "reference": "11d387c6642b6e4acaf0bd9bf5203b8cca1ec489" + "reference": "fa4b8d051e278072928e32d817456a7fdb57b6ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/11d387c6642b6e4acaf0bd9bf5203b8cca1ec489", - "reference": "11d387c6642b6e4acaf0bd9bf5203b8cca1ec489", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/fa4b8d051e278072928e32d817456a7fdb57b6ca", + "reference": "fa4b8d051e278072928e32d817456a7fdb57b6ca", "shasum": "" }, "require": { "php": ">=5.4", - "phpcsstandards/phpcsutils": "^1.0.9", - "squizlabs/php_codesniffer": "^3.8.0" + "phpcsstandards/phpcsutils": "^1.1.0", + "squizlabs/php_codesniffer": "^3.13.0 || ^4.0" }, "require-dev": { "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", + "php-parallel-lint/php-parallel-lint": "^1.4.0", "phpcsstandards/phpcsdevcs": "^1.1.6", "phpcsstandards/phpcsdevtools": "^1.2.1", - "phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.3.4" }, "type": "phpcodesniffer-standard", "extra": { @@ -1131,35 +1166,39 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2023-12-08T16:49:07+00:00" + "time": "2025-06-14T07:40:39+00:00" }, { "name": "phpcsstandards/phpcsutils", - "version": "1.0.12", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHPCSUtils.git", - "reference": "87b233b00daf83fb70f40c9a28692be017ea7c6c" + "reference": "f7eb16f2fa4237d5db9e8fed8050239bee17a9bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/87b233b00daf83fb70f40c9a28692be017ea7c6c", - "reference": "87b233b00daf83fb70f40c9a28692be017ea7c6c", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/f7eb16f2fa4237d5db9e8fed8050239bee17a9bd", + "reference": "f7eb16f2fa4237d5db9e8fed8050239bee17a9bd", "shasum": "" }, "require": { "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0", "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.10.0 || 4.0.x-dev@dev" + "squizlabs/php_codesniffer": "^3.13.0 || ^4.0" }, "require-dev": { "ext-filter": "*", "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", + "php-parallel-lint/php-parallel-lint": "^1.4.0", "phpcsstandards/phpcsdevcs": "^1.1.6", - "yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0" + "yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0 || ^3.0.0" }, "type": "phpcodesniffer-standard", "extra": { @@ -1196,6 +1235,7 @@ "phpcodesniffer-standard", "phpcs", "phpcs3", + "phpcs4", "standards", "static analysis", "tokens", @@ -1219,41 +1259,45 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2024-05-20T13:34:27+00:00" + "time": "2025-08-10T01:04:45+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.31", + "version": "9.2.32", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", + "nikic/php-parser": "^4.19.1 || ^5.1.0", "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.6" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -1262,7 +1306,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "9.2.x-dev" } }, "autoload": { @@ -1291,7 +1335,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" }, "funding": [ { @@ -1299,7 +1343,7 @@ "type": "github" } ], - "time": "2024-03-02T06:37:42+00:00" + "time": "2024-08-22T04:23:01+00:00" }, { "name": "phpunit/php-file-iterator", @@ -1544,45 +1588,45 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.19", + "version": "9.6.25", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8" + "reference": "049c011e01be805202d8eebedef49f769a8ec7b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1a54a473501ef4cdeaae4e06891674114d79db8", - "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/049c011e01be805202d8eebedef49f769a8ec7b7", + "reference": "049c011e01be805202d8eebedef49f769a8ec7b7", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1 || ^2", + "doctrine/instantiator": "^1.5.0 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.28", - "phpunit/php-file-iterator": "^3.0.5", + "phpunit/php-code-coverage": "^9.2.32", + "phpunit/php-file-iterator": "^3.0.6", "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", + "phpunit/php-text-template": "^2.0.4", + "phpunit/php-timer": "^5.0.3", + "sebastian/cli-parser": "^1.0.2", + "sebastian/code-unit": "^1.0.8", + "sebastian/comparator": "^4.0.9", + "sebastian/diff": "^4.0.6", + "sebastian/environment": "^5.1.5", + "sebastian/exporter": "^4.0.6", + "sebastian/global-state": "^5.0.8", + "sebastian/object-enumerator": "^4.0.4", + "sebastian/resource-operations": "^3.0.4", + "sebastian/type": "^3.2.1", "sebastian/version": "^3.0.2" }, "suggest": { @@ -1627,7 +1671,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.19" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.25" }, "funding": [ { @@ -1638,12 +1682,20 @@ "url": "https://github.com/sebastianbergmann", "type": "github" }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, { "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", "type": "tidelift" } ], - "time": "2024-04-05T04:35:58+00:00" + "time": "2025-08-20T14:38:31+00:00" }, { "name": "sebastian/cli-parser", @@ -1814,16 +1866,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "4.0.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/67a2df3a62639eab2cc5906065e9805d4fd5dfc5", + "reference": "67a2df3a62639eab2cc5906065e9805d4fd5dfc5", "shasum": "" }, "require": { @@ -1876,15 +1928,27 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.9" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2025-08-10T06:51:50+00:00" }, { "name": "sebastian/complexity", @@ -2151,16 +2215,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.7", + "version": "5.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6", + "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6", "shasum": "" }, "require": { @@ -2203,15 +2267,27 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" } ], - "time": "2024-03-02T06:35:11+00:00" + "time": "2025-08-10T07:10:35+00:00" }, { "name": "sebastian/lines-of-code", @@ -2384,16 +2460,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "reference": "539c6691e0623af6dc6f9c20384c120f963465a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/539c6691e0623af6dc6f9c20384c120f963465a0", + "reference": "539c6691e0623af6dc6f9c20384c120f963465a0", "shasum": "" }, "require": { @@ -2435,15 +2511,27 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.6" }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" } ], - "time": "2023-02-03T06:07:39+00:00" + "time": "2025-08-10T06:57:39+00:00" }, { "name": "sebastian/resource-operations", @@ -2610,16 +2698,16 @@ }, { "name": "sirbrillig/phpcs-variable-analysis", - "version": "v2.11.18", + "version": "v2.12.0", "source": { "type": "git", "url": "https://github.com/sirbrillig/phpcs-variable-analysis.git", - "reference": "ca242a0b7309e0f9d1f73b236e04ecf4ca3248d0" + "reference": "4debf5383d9ade705e0a25121f16c3fecaf433a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/ca242a0b7309e0f9d1f73b236e04ecf4ca3248d0", - "reference": "ca242a0b7309e0f9d1f73b236e04ecf4ca3248d0", + "url": "https://api.github.com/repos/sirbrillig/phpcs-variable-analysis/zipball/4debf5383d9ade705e0a25121f16c3fecaf433a7", + "reference": "4debf5383d9ade705e0a25121f16c3fecaf433a7", "shasum": "" }, "require": { @@ -2630,9 +2718,8 @@ "dealerdirect/phpcodesniffer-composer-installer": "^0.7 || ^1.0", "phpcsstandards/phpcsdevcs": "^1.1", "phpstan/phpstan": "^1.7", - "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.5 || ^7.0 || ^8.0 || ^9.0", - "sirbrillig/phpcs-import-detection": "^1.1", - "vimeo/psalm": "^0.2 || ^0.3 || ^1.1 || ^4.24 || ^5.0@beta" + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.5 || ^7.0 || ^8.0 || ^9.0 || ^10.5.32 || ^11.3.3", + "vimeo/psalm": "^0.2 || ^0.3 || ^1.1 || ^4.24 || ^5.0" }, "type": "phpcodesniffer-standard", "autoload": { @@ -2664,20 +2751,20 @@ "source": "https://github.com/sirbrillig/phpcs-variable-analysis", "wiki": "https://github.com/sirbrillig/phpcs-variable-analysis/wiki" }, - "time": "2024-04-13T16:42:46+00:00" + "time": "2025-03-17T16:17:38+00:00" }, { "name": "squizlabs/php_codesniffer", - "version": "3.10.1", + "version": "3.13.2", "source": { "type": "git", "url": "https://github.com/PHPCSStandards/PHP_CodeSniffer.git", - "reference": "8f90f7a53ce271935282967f53d0894f8f1ff877" + "reference": "5b5e3821314f947dd040c70f7992a64eac89025c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/8f90f7a53ce271935282967f53d0894f8f1ff877", - "reference": "8f90f7a53ce271935282967f53d0894f8f1ff877", + "url": "https://api.github.com/repos/PHPCSStandards/PHP_CodeSniffer/zipball/5b5e3821314f947dd040c70f7992a64eac89025c", + "reference": "5b5e3821314f947dd040c70f7992a64eac89025c", "shasum": "" }, "require": { @@ -2742,9 +2829,13 @@ { "url": "https://opencollective.com/php_codesniffer", "type": "open_collective" + }, + { + "url": "https://thanks.dev/u/gh/phpcsstandards", + "type": "thanks_dev" } ], - "time": "2024-05-22T21:24:41+00:00" + "time": "2025-06-17T22:17:01+00:00" }, { "name": "theseer/tokenizer", @@ -2798,16 +2889,16 @@ }, { "name": "wp-coding-standards/wpcs", - "version": "3.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "9333efcbff231f10dfd9c56bb7b65818b4733ca7" + "reference": "d2421de7cec3274ae622c22c744de9a62c7925af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/9333efcbff231f10dfd9c56bb7b65818b4733ca7", - "reference": "9333efcbff231f10dfd9c56bb7b65818b4733ca7", + "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/d2421de7cec3274ae622c22c744de9a62c7925af", + "reference": "d2421de7cec3274ae622c22c744de9a62c7925af", "shasum": "" }, "require": { @@ -2816,13 +2907,13 @@ "ext-tokenizer": "*", "ext-xmlreader": "*", "php": ">=5.4", - "phpcsstandards/phpcsextra": "^1.2.1", - "phpcsstandards/phpcsutils": "^1.0.10", - "squizlabs/php_codesniffer": "^3.9.0" + "phpcsstandards/phpcsextra": "^1.4.0", + "phpcsstandards/phpcsutils": "^1.1.0", + "squizlabs/php_codesniffer": "^3.13.0" }, "require-dev": { "php-parallel-lint/php-console-highlighter": "^1.0.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", + "php-parallel-lint/php-parallel-lint": "^1.4.0", "phpcompatibility/php-compatibility": "^9.0", "phpcsstandards/phpcsdevtools": "^1.2.0", "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" @@ -2860,20 +2951,20 @@ "type": "custom" } ], - "time": "2024-03-25T16:39:00+00:00" + "time": "2025-07-24T20:08:31+00:00" }, { "name": "wp-phpunit/wp-phpunit", - "version": "6.5.3", + "version": "6.8.2", "source": { "type": "git", "url": "https://github.com/wp-phpunit/wp-phpunit.git", - "reference": "ef2cb44c0d991ac0c3a7a3ed0d2d1cf3fe8d8f2f" + "reference": "a33d328dab5a4a9ddf0c560bcadbabb58b5ee67f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/ef2cb44c0d991ac0c3a7a3ed0d2d1cf3fe8d8f2f", - "reference": "ef2cb44c0d991ac0c3a7a3ed0d2d1cf3fe8d8f2f", + "url": "https://api.github.com/repos/wp-phpunit/wp-phpunit/zipball/a33d328dab5a4a9ddf0c560bcadbabb58b5ee67f", + "reference": "a33d328dab5a4a9ddf0c560bcadbabb58b5ee67f", "shasum": "" }, "type": "library", @@ -2908,20 +2999,20 @@ "issues": "https://github.com/wp-phpunit/issues", "source": "https://github.com/wp-phpunit/wp-phpunit" }, - "time": "2024-05-07T16:46:52+00:00" + "time": "2025-04-16T01:40:54+00:00" }, { "name": "yoast/phpunit-polyfills", - "version": "2.0.1", + "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", - "reference": "4a088f125c970d6d6ea52c927f96fe39b330d0f1" + "reference": "1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/4a088f125c970d6d6ea52c927f96fe39b330d0f1", - "reference": "4a088f125c970d6d6ea52c927f96fe39b330d0f1", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27", + "reference": "1a6aecc9ebe4a9cea4e1047d0e6c496e52314c27", "shasum": "" }, "require": { @@ -2931,12 +3022,12 @@ "require-dev": { "php-parallel-lint/php-console-highlighter": "^1.0.0", "php-parallel-lint/php-parallel-lint": "^1.4.0", - "yoast/yoastcs": "^3.1.0" + "yoast/yoastcs": "^3.2.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.x-dev" + "dev-main": "4.x-dev" } }, "autoload": { @@ -2971,17 +3062,17 @@ "security": "https://github.com/Yoast/PHPUnit-Polyfills/security/policy", "source": "https://github.com/Yoast/PHPUnit-Polyfills" }, - "time": "2024-04-05T16:36:44+00:00" + "time": "2025-08-10T05:13:49+00:00" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=8.0" + "php": ">=8.1" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/phpcs.xml.dist b/phpcs.xml.dist index d7f04d55..f307934f 100644 --- a/phpcs.xml.dist +++ b/phpcs.xml.dist @@ -34,7 +34,7 @@ - + /tests diff --git a/vendor/autoload.php b/vendor/autoload.php index debeea13..a8cd7be8 100644 --- a/vendor/autoload.php +++ b/vendor/autoload.php @@ -14,10 +14,7 @@ echo $err; } } - trigger_error( - $err, - E_USER_ERROR - ); + throw new RuntimeException($err); } require_once __DIR__ . '/composer/autoload_real.php'; diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php index 51e734a7..2052022f 100644 --- a/vendor/composer/InstalledVersions.php +++ b/vendor/composer/InstalledVersions.php @@ -26,12 +26,23 @@ */ class InstalledVersions { + /** + * @var string|null if set (by reflection by Composer), this should be set to the path where this class is being copied to + * @internal + */ + private static $selfDir = null; + /** * @var mixed[]|null * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null */ private static $installed; + /** + * @var bool + */ + private static $installedIsLocalDir; + /** * @var bool|null */ @@ -309,6 +320,24 @@ public static function reload($data) { self::$installed = $data; self::$installedByVendor = array(); + + // when using reload, we disable the duplicate protection to ensure that self::$installed data is + // always returned, but we cannot know whether it comes from the installed.php in __DIR__ or not, + // so we have to assume it does not, and that may result in duplicate data being returned when listing + // all installed packages for example + self::$installedIsLocalDir = false; + } + + /** + * @return string + */ + private static function getSelfDir() + { + if (self::$selfDir === null) { + self::$selfDir = strtr(__DIR__, '\\', '/'); + } + + return self::$selfDir; } /** @@ -322,19 +351,27 @@ private static function getInstalled() } $installed = array(); + $copiedLocalDir = false; if (self::$canGetVendors) { + $selfDir = self::getSelfDir(); foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { + $vendorDir = strtr($vendorDir, '\\', '/'); if (isset(self::$installedByVendor[$vendorDir])) { $installed[] = self::$installedByVendor[$vendorDir]; } elseif (is_file($vendorDir.'/composer/installed.php')) { /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; + self::$installedByVendor[$vendorDir] = $required; + $installed[] = $required; + if (self::$installed === null && $vendorDir.'/composer' === $selfDir) { + self::$installed = $required; + self::$installedIsLocalDir = true; } } + if (self::$installedIsLocalDir && $vendorDir.'/composer' === $selfDir) { + $copiedLocalDir = true; + } } } @@ -350,7 +387,7 @@ private static function getInstalled() } } - if (self::$installed !== array()) { + if (self::$installed !== array() && !$copiedLocalDir) { $installed[] = self::$installed; } diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json index ff1d4b6d..502d2f77 100644 --- a/vendor/composer/installed.json +++ b/vendor/composer/installed.json @@ -2,17 +2,17 @@ "packages": [ { "name": "masterminds/html5", - "version": "2.9.0", - "version_normalized": "2.9.0.0", + "version": "2.10.0", + "version_normalized": "2.10.0.0", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6" + "reference": "fcf91eb64359852f00d921887b219479b4f21251" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", - "reference": "f5ac2c0b0a2eefca70b2ce32a5809992227e75a6", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/fcf91eb64359852f00d921887b219479b4f21251", + "reference": "fcf91eb64359852f00d921887b219479b4f21251", "shasum": "" }, "require": { @@ -22,7 +22,7 @@ "require-dev": { "phpunit/phpunit": "^4.8.35 || ^5.7.21 || ^6 || ^7 || ^8 || ^9" }, - "time": "2024-03-31T07:05:07+00:00", + "time": "2025-07-25T09:04:22+00:00", "type": "library", "extra": { "branch-alias": { @@ -66,29 +66,29 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.9.0" + "source": "https://github.com/Masterminds/html5-php/tree/2.10.0" }, "install-path": "../masterminds/html5" }, { "name": "symfony/css-selector", - "version": "v6.0.19", - "version_normalized": "6.0.19.0", + "version": "v6.4.24", + "version_normalized": "6.4.24.0", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "f1d00bddb83a4cb2138564b2150001cb6ce272b1" + "reference": "9b784413143701aa3c94ac1869a159a9e53e8761" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/f1d00bddb83a4cb2138564b2150001cb6ce272b1", - "reference": "f1d00bddb83a4cb2138564b2150001cb6ce272b1", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/9b784413143701aa3c94ac1869a159a9e53e8761", + "reference": "9b784413143701aa3c94ac1869a159a9e53e8761", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, - "time": "2023-01-01T08:36:10+00:00", + "time": "2025-07-10T08:14:14+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -120,7 +120,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v6.0.19" + "source": "https://github.com/symfony/css-selector/tree/v6.4.24" }, "funding": [ { @@ -131,6 +131,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" @@ -140,35 +144,29 @@ }, { "name": "symfony/dom-crawler", - "version": "v6.0.19", - "version_normalized": "6.0.19.0", + "version": "v6.4.25", + "version_normalized": "6.4.25.0", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "622578ff158318b1b49d95068bd6b66c713601e9" + "reference": "976302990f9f2a6d4c07206836dd4ca77cae9524" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/622578ff158318b1b49d95068bd6b66c713601e9", - "reference": "622578ff158318b1b49d95068bd6b66c713601e9", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/976302990f9f2a6d4c07206836dd4ca77cae9524", + "reference": "976302990f9f2a6d4c07206836dd4ca77cae9524", "shasum": "" }, "require": { - "php": ">=8.0.2", + "masterminds/html5": "^2.6", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0" }, - "conflict": { - "masterminds/html5": "<2.6" - }, "require-dev": { - "masterminds/html5": "^2.6", - "symfony/css-selector": "^5.4|^6.0" - }, - "suggest": { - "symfony/css-selector": "" + "symfony/css-selector": "^5.4|^6.0|^7.0" }, - "time": "2023-01-20T17:44:14+00:00", + "time": "2025-08-05T18:56:08+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -196,7 +194,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v6.0.19" + "source": "https://github.com/symfony/dom-crawler/tree/v6.4.25" }, "funding": [ { @@ -207,6 +205,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" @@ -216,21 +218,21 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -238,12 +240,12 @@ "suggest": { "ext-ctype": "For best performance" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-09-09T11:45:10+00:00", "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -278,7 +280,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.33.0" }, "funding": [ { @@ -289,6 +291,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" @@ -298,21 +304,22 @@ }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", - "version_normalized": "1.29.0.0", + "version": "v1.33.0", + "version_normalized": "1.33.0.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/6d857f4d76bd4b343eac26d6b539585d2bc56493", + "reference": "6d857f4d76bd4b343eac26d6b539585d2bc56493", "shasum": "" }, "require": { - "php": ">=7.1" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -320,12 +327,12 @@ "suggest": { "ext-mbstring": "For best performance" }, - "time": "2024-01-29T20:11:03+00:00", + "time": "2024-12-23T08:48:59+00:00", "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "installation-source": "dist", @@ -361,7 +368,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.33.0" }, "funding": [ { @@ -372,6 +379,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" diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php index 90280aec..24943e6e 100644 --- a/vendor/composer/installed.php +++ b/vendor/composer/installed.php @@ -3,7 +3,7 @@ 'name' => 'automattic/vip-block-data-api', 'pretty_version' => 'dev-trunk', 'version' => 'dev-trunk', - 'reference' => '5539d360dc829a7ee143d046a5783789651d9e32', + 'reference' => '203b0abed8739e0a1e7923f226b2eb92794fd988', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), @@ -13,52 +13,52 @@ 'automattic/vip-block-data-api' => array( 'pretty_version' => 'dev-trunk', 'version' => 'dev-trunk', - 'reference' => '5539d360dc829a7ee143d046a5783789651d9e32', + 'reference' => '203b0abed8739e0a1e7923f226b2eb92794fd988', 'type' => 'wordpress-plugin', 'install_path' => __DIR__ . '/../../', 'aliases' => array(), 'dev_requirement' => false, ), 'masterminds/html5' => array( - 'pretty_version' => '2.9.0', - 'version' => '2.9.0.0', - 'reference' => 'f5ac2c0b0a2eefca70b2ce32a5809992227e75a6', + 'pretty_version' => '2.10.0', + 'version' => '2.10.0.0', + 'reference' => 'fcf91eb64359852f00d921887b219479b4f21251', 'type' => 'library', 'install_path' => __DIR__ . '/../masterminds/html5', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/css-selector' => array( - 'pretty_version' => 'v6.0.19', - 'version' => '6.0.19.0', - 'reference' => 'f1d00bddb83a4cb2138564b2150001cb6ce272b1', + '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/dom-crawler' => array( - 'pretty_version' => 'v6.0.19', - 'version' => '6.0.19.0', - 'reference' => '622578ff158318b1b49d95068bd6b66c713601e9', + 'pretty_version' => 'v6.4.25', + 'version' => '6.4.25.0', + 'reference' => '976302990f9f2a6d4c07206836dd4ca77cae9524', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/dom-crawler', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/polyfill-ctype' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => 'ef4d7e442ca910c4764bce785146269b30cb5fc4', + '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-mbstring' => array( - 'pretty_version' => 'v1.29.0', - 'version' => '1.29.0.0', - 'reference' => '9773676c8a1bb1f8d4340a62efe641cf76eda7ec', + 'pretty_version' => 'v1.33.0', + 'version' => '1.33.0.0', + 'reference' => '6d857f4d76bd4b343eac26d6b539585d2bc56493', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/polyfill-mbstring', 'aliases' => array(), diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php index b168ddd5..4c3a5d68 100644 --- a/vendor/composer/platform_check.php +++ b/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 80002)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.0.2". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80100)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.1.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/vendor/masterminds/html5/src/HTML5.php b/vendor/masterminds/html5/src/HTML5.php index c857145f..49a90daf 100644 --- a/vendor/masterminds/html5/src/HTML5.php +++ b/vendor/masterminds/html5/src/HTML5.php @@ -146,7 +146,6 @@ public function hasErrors() * Parse an input string. * * @param string $input - * @param array $options * * @return \DOMDocument */ diff --git a/vendor/masterminds/html5/src/HTML5/Parser/CharacterReference.php b/vendor/masterminds/html5/src/HTML5/Parser/CharacterReference.php index 490b5487..56a206cb 100644 --- a/vendor/masterminds/html5/src/HTML5/Parser/CharacterReference.php +++ b/vendor/masterminds/html5/src/HTML5/Parser/CharacterReference.php @@ -48,7 +48,7 @@ public static function lookupDecimal($int) } /** - * Given a hexidecimal number, return the UTF-8 character. + * Given a hexadecimal number, return the UTF-8 character. * * @param $hexdec * diff --git a/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php b/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php index d165b66b..85651179 100644 --- a/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php +++ b/vendor/masterminds/html5/src/HTML5/Parser/DOMTreeBuilder.php @@ -231,8 +231,6 @@ public function fragment() * * This is used for handling Processor Instructions as they are * inserted. If omitted, PI's are inserted directly into the DOM tree. - * - * @param InstructionProcessor $proc */ public function setInstructionProcessor(InstructionProcessor $proc) { diff --git a/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php b/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php index e8b4aa09..77e268fb 100644 --- a/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php +++ b/vendor/masterminds/html5/src/HTML5/Parser/Tokenizer.php @@ -507,7 +507,7 @@ protected function attribute(&$attributes) $this->scanner->whitespace(); $val = $this->attributeValue(); - if ($isValidAttribute) { + if ($isValidAttribute && !array_key_exists($name, $attributes)) { $attributes[$name] = $val; } @@ -729,6 +729,7 @@ protected function isCommentEnd() // Test for '!>' if ('!' == $this->scanner->current() && '>' == $this->scanner->peek()) { $this->scanner->consume(); // Consume the last '>' + return true; } // Unread '-' and one of '!' or '>'; @@ -1127,7 +1128,7 @@ protected function decodeCharacterReference($inAttribute = false) return '&'; } - // Hexidecimal encoding. + // Hexadecimal encoding. // X[0-9a-fA-F]+; // x[0-9a-fA-F]+; if ('x' === $tok || 'X' === $tok) { diff --git a/vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php b/vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php index 00d3951f..4c6983b2 100644 --- a/vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php +++ b/vendor/masterminds/html5/src/HTML5/Parser/TreeBuildingRules.php @@ -80,7 +80,6 @@ public function evaluate($new, $current) case 'thead': case 'tfoot': case 'table': // Spec isn't explicit about this, but it's necessary. - return $this->closeIfCurrentMatches($new, $current, array( 'thead', 'tfoot', diff --git a/vendor/masterminds/html5/src/HTML5/Serializer/OutputRules.php b/vendor/masterminds/html5/src/HTML5/Serializer/OutputRules.php index ec467f22..13cbdc66 100644 --- a/vendor/masterminds/html5/src/HTML5/Serializer/OutputRules.php +++ b/vendor/masterminds/html5/src/HTML5/Serializer/OutputRules.php @@ -206,6 +206,9 @@ protected function doctype() $this->nl(); } + /** + * @param \DOMElement $ele + */ public function element($ele) { $name = $ele->tagName; @@ -227,6 +230,9 @@ public function element($ele) } $this->openTag($ele); + // The tag is already self-closed (`` or ``) in `openTag` if there are no child nodes. + $handledAsVoidTag = $this->outputMode !== static::IM_IN_HTML && !$ele->hasChildNodes(); + if (Elements::isA($name, Elements::TEXT_RAW)) { foreach ($ele->childNodes as $child) { if ($child instanceof \DOMCharacterData) { @@ -248,7 +254,7 @@ public function element($ele) } // If not unary, add a closing tag. - if (!Elements::isA($name, Elements::VOID_TAG)) { + if (!$handledAsVoidTag && !Elements::isA($name, Elements::VOID_TAG)) { $this->closeTag($ele); } } diff --git a/vendor/symfony/css-selector/CHANGELOG.md b/vendor/symfony/css-selector/CHANGELOG.md index de81fa2e..c035d6b3 100644 --- a/vendor/symfony/css-selector/CHANGELOG.md +++ b/vendor/symfony/css-selector/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +6.3 +----- + + * Add support for `:scope` + 4.4.0 ----- diff --git a/vendor/symfony/css-selector/CssSelectorConverter.php b/vendor/symfony/css-selector/CssSelectorConverter.php index 86ccb795..7120a295 100644 --- a/vendor/symfony/css-selector/CssSelectorConverter.php +++ b/vendor/symfony/css-selector/CssSelectorConverter.php @@ -26,7 +26,7 @@ */ class CssSelectorConverter { - private $translator; + private Translator $translator; private array $cache; private static array $xmlCache = []; @@ -62,6 +62,6 @@ public function __construct(bool $html = true) */ public function toXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string { - return $this->cache[$prefix][$cssExpr] ?? $this->cache[$prefix][$cssExpr] = $this->translator->cssToXPath($cssExpr, $prefix); + return $this->cache[$prefix][$cssExpr] ??= $this->translator->cssToXPath($cssExpr, $prefix); } } diff --git a/vendor/symfony/css-selector/Exception/SyntaxErrorException.php b/vendor/symfony/css-selector/Exception/SyntaxErrorException.php index f73860ce..52d8259b 100644 --- a/vendor/symfony/css-selector/Exception/SyntaxErrorException.php +++ b/vendor/symfony/css-selector/Exception/SyntaxErrorException.php @@ -25,17 +25,17 @@ class SyntaxErrorException extends ParseException { public static function unexpectedToken(string $expectedValue, Token $foundToken): self { - return new self(sprintf('Expected %s, but %s found.', $expectedValue, $foundToken)); + return new self(\sprintf('Expected %s, but %s found.', $expectedValue, $foundToken)); } public static function pseudoElementFound(string $pseudoElement, string $unexpectedLocation): self { - return new self(sprintf('Unexpected pseudo-element "::%s" found %s.', $pseudoElement, $unexpectedLocation)); + return new self(\sprintf('Unexpected pseudo-element "::%s" found %s.', $pseudoElement, $unexpectedLocation)); } public static function unclosedString(int $position): self { - return new self(sprintf('Unclosed/invalid string at %s.', $position)); + return new self(\sprintf('Unclosed/invalid string at %s.', $position)); } public static function nestedNot(): self @@ -43,6 +43,11 @@ public static function nestedNot(): self return new self('Got nested ::not().'); } + public static function notAtTheStartOfASelector(string $pseudoElement): self + { + return new self(\sprintf('Got immediate child pseudo-element ":%s" not at the start of a selector', $pseudoElement)); + } + public static function stringAsFunctionArgument(): self { return new self('String not allowed as function argument.'); diff --git a/vendor/symfony/css-selector/LICENSE b/vendor/symfony/css-selector/LICENSE index 00837045..0138f8f0 100644 --- a/vendor/symfony/css-selector/LICENSE +++ b/vendor/symfony/css-selector/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2023 Fabien Potencier +Copyright (c) 2004-present Fabien Potencier 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/vendor/symfony/css-selector/Node/AttributeNode.php b/vendor/symfony/css-selector/Node/AttributeNode.php index bca91eb8..967cb7ce 100644 --- a/vendor/symfony/css-selector/Node/AttributeNode.php +++ b/vendor/symfony/css-selector/Node/AttributeNode.php @@ -23,7 +23,7 @@ */ class AttributeNode extends AbstractNode { - private $selector; + private NodeInterface $selector; private ?string $namespace; private string $attribute; private string $operator; @@ -63,9 +63,6 @@ public function getValue(): ?string return $this->value; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0)); @@ -76,7 +73,7 @@ public function __toString(): string $attribute = $this->namespace ? $this->namespace.'|'.$this->attribute : $this->attribute; return 'exists' === $this->operator - ? sprintf('%s[%s[%s]]', $this->getNodeName(), $this->selector, $attribute) - : sprintf("%s[%s[%s %s '%s']]", $this->getNodeName(), $this->selector, $attribute, $this->operator, $this->value); + ? \sprintf('%s[%s[%s]]', $this->getNodeName(), $this->selector, $attribute) + : \sprintf("%s[%s[%s %s '%s']]", $this->getNodeName(), $this->selector, $attribute, $this->operator, $this->value); } } diff --git a/vendor/symfony/css-selector/Node/ClassNode.php b/vendor/symfony/css-selector/Node/ClassNode.php index 0e937688..7cca6d90 100644 --- a/vendor/symfony/css-selector/Node/ClassNode.php +++ b/vendor/symfony/css-selector/Node/ClassNode.php @@ -23,7 +23,7 @@ */ class ClassNode extends AbstractNode { - private $selector; + private NodeInterface $selector; private string $name; public function __construct(NodeInterface $selector, string $name) @@ -42,9 +42,6 @@ public function getName(): string return $this->name; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0)); @@ -52,6 +49,6 @@ public function getSpecificity(): Specificity public function __toString(): string { - return sprintf('%s[%s.%s]', $this->getNodeName(), $this->selector, $this->name); + return \sprintf('%s[%s.%s]', $this->getNodeName(), $this->selector, $this->name); } } diff --git a/vendor/symfony/css-selector/Node/CombinedSelectorNode.php b/vendor/symfony/css-selector/Node/CombinedSelectorNode.php index f5f99697..1db62a22 100644 --- a/vendor/symfony/css-selector/Node/CombinedSelectorNode.php +++ b/vendor/symfony/css-selector/Node/CombinedSelectorNode.php @@ -23,9 +23,9 @@ */ class CombinedSelectorNode extends AbstractNode { - private $selector; + private NodeInterface $selector; private string $combinator; - private $subSelector; + private NodeInterface $subSelector; public function __construct(NodeInterface $selector, string $combinator, NodeInterface $subSelector) { @@ -49,9 +49,6 @@ public function getSubSelector(): NodeInterface return $this->subSelector; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity()); @@ -61,6 +58,6 @@ public function __toString(): string { $combinator = ' ' === $this->combinator ? '' : $this->combinator; - return sprintf('%s[%s %s %s]', $this->getNodeName(), $this->selector, $combinator, $this->subSelector); + return \sprintf('%s[%s %s %s]', $this->getNodeName(), $this->selector, $combinator, $this->subSelector); } } diff --git a/vendor/symfony/css-selector/Node/ElementNode.php b/vendor/symfony/css-selector/Node/ElementNode.php index b05164fe..bd4a7fe4 100644 --- a/vendor/symfony/css-selector/Node/ElementNode.php +++ b/vendor/symfony/css-selector/Node/ElementNode.php @@ -26,7 +26,7 @@ class ElementNode extends AbstractNode private ?string $namespace; private ?string $element; - public function __construct(string $namespace = null, string $element = null) + public function __construct(?string $namespace = null, ?string $element = null) { $this->namespace = $namespace; $this->element = $element; @@ -42,9 +42,6 @@ public function getElement(): ?string return $this->element; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return new Specificity(0, 0, $this->element ? 1 : 0); @@ -54,6 +51,6 @@ public function __toString(): string { $element = $this->element ?: '*'; - return sprintf('%s[%s]', $this->getNodeName(), $this->namespace ? $this->namespace.'|'.$element : $element); + return \sprintf('%s[%s]', $this->getNodeName(), $this->namespace ? $this->namespace.'|'.$element : $element); } } diff --git a/vendor/symfony/css-selector/Node/FunctionNode.php b/vendor/symfony/css-selector/Node/FunctionNode.php index e91a1662..09342a1b 100644 --- a/vendor/symfony/css-selector/Node/FunctionNode.php +++ b/vendor/symfony/css-selector/Node/FunctionNode.php @@ -25,7 +25,7 @@ */ class FunctionNode extends AbstractNode { - private $selector; + private NodeInterface $selector; private string $name; private array $arguments; @@ -57,9 +57,6 @@ public function getArguments(): array return $this->arguments; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0)); @@ -67,10 +64,8 @@ public function getSpecificity(): Specificity public function __toString(): string { - $arguments = implode(', ', array_map(function (Token $token) { - return "'".$token->getValue()."'"; - }, $this->arguments)); + $arguments = implode(', ', array_map(fn (Token $token) => "'".$token->getValue()."'", $this->arguments)); - return sprintf('%s[%s:%s(%s)]', $this->getNodeName(), $this->selector, $this->name, $arguments ? '['.$arguments.']' : ''); + return \sprintf('%s[%s:%s(%s)]', $this->getNodeName(), $this->selector, $this->name, $arguments ? '['.$arguments.']' : ''); } } diff --git a/vendor/symfony/css-selector/Node/HashNode.php b/vendor/symfony/css-selector/Node/HashNode.php index 119b0d57..014ae54e 100644 --- a/vendor/symfony/css-selector/Node/HashNode.php +++ b/vendor/symfony/css-selector/Node/HashNode.php @@ -23,7 +23,7 @@ */ class HashNode extends AbstractNode { - private $selector; + private NodeInterface $selector; private string $id; public function __construct(NodeInterface $selector, string $id) @@ -42,9 +42,6 @@ public function getId(): string return $this->id; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(1, 0, 0)); @@ -52,6 +49,6 @@ public function getSpecificity(): Specificity public function __toString(): string { - return sprintf('%s[%s#%s]', $this->getNodeName(), $this->selector, $this->id); + return \sprintf('%s[%s#%s]', $this->getNodeName(), $this->selector, $this->id); } } diff --git a/vendor/symfony/css-selector/Node/NegationNode.php b/vendor/symfony/css-selector/Node/NegationNode.php index f00522fb..967b65bb 100644 --- a/vendor/symfony/css-selector/Node/NegationNode.php +++ b/vendor/symfony/css-selector/Node/NegationNode.php @@ -23,8 +23,8 @@ */ class NegationNode extends AbstractNode { - private $selector; - private $subSelector; + private NodeInterface $selector; + private NodeInterface $subSelector; public function __construct(NodeInterface $selector, NodeInterface $subSelector) { @@ -42,9 +42,6 @@ public function getSubSelector(): NodeInterface return $this->subSelector; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus($this->subSelector->getSpecificity()); @@ -52,6 +49,6 @@ public function getSpecificity(): Specificity public function __toString(): string { - return sprintf('%s[%s:not(%s)]', $this->getNodeName(), $this->selector, $this->subSelector); + return \sprintf('%s[%s:not(%s)]', $this->getNodeName(), $this->selector, $this->subSelector); } } diff --git a/vendor/symfony/css-selector/Node/NodeInterface.php b/vendor/symfony/css-selector/Node/NodeInterface.php index b078d26d..7d541f9c 100644 --- a/vendor/symfony/css-selector/Node/NodeInterface.php +++ b/vendor/symfony/css-selector/Node/NodeInterface.php @@ -21,11 +21,9 @@ * * @internal */ -interface NodeInterface +interface NodeInterface extends \Stringable { public function getNodeName(): string; public function getSpecificity(): Specificity; - - public function __toString(): string; } diff --git a/vendor/symfony/css-selector/Node/PseudoNode.php b/vendor/symfony/css-selector/Node/PseudoNode.php index 5d6325a5..cbebd9f4 100644 --- a/vendor/symfony/css-selector/Node/PseudoNode.php +++ b/vendor/symfony/css-selector/Node/PseudoNode.php @@ -23,7 +23,7 @@ */ class PseudoNode extends AbstractNode { - private $selector; + private NodeInterface $selector; private string $identifier; public function __construct(NodeInterface $selector, string $identifier) @@ -42,9 +42,6 @@ public function getIdentifier(): string return $this->identifier; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return $this->selector->getSpecificity()->plus(new Specificity(0, 1, 0)); @@ -52,6 +49,6 @@ public function getSpecificity(): Specificity public function __toString(): string { - return sprintf('%s[%s:%s]', $this->getNodeName(), $this->selector, $this->identifier); + return \sprintf('%s[%s:%s]', $this->getNodeName(), $this->selector, $this->identifier); } } diff --git a/vendor/symfony/css-selector/Node/SelectorNode.php b/vendor/symfony/css-selector/Node/SelectorNode.php index 55fae1e7..6b70535c 100644 --- a/vendor/symfony/css-selector/Node/SelectorNode.php +++ b/vendor/symfony/css-selector/Node/SelectorNode.php @@ -23,10 +23,10 @@ */ class SelectorNode extends AbstractNode { - private $tree; + private NodeInterface $tree; private ?string $pseudoElement; - public function __construct(NodeInterface $tree, string $pseudoElement = null) + public function __construct(NodeInterface $tree, ?string $pseudoElement = null) { $this->tree = $tree; $this->pseudoElement = $pseudoElement ? strtolower($pseudoElement) : null; @@ -42,9 +42,6 @@ public function getPseudoElement(): ?string return $this->pseudoElement; } - /** - * {@inheritdoc} - */ public function getSpecificity(): Specificity { return $this->tree->getSpecificity()->plus(new Specificity(0, 0, $this->pseudoElement ? 1 : 0)); @@ -52,6 +49,6 @@ public function getSpecificity(): Specificity public function __toString(): string { - return sprintf('%s[%s%s]', $this->getNodeName(), $this->tree, $this->pseudoElement ? '::'.$this->pseudoElement : ''); + return \sprintf('%s[%s%s]', $this->getNodeName(), $this->tree, $this->pseudoElement ? '::'.$this->pseudoElement : ''); } } diff --git a/vendor/symfony/css-selector/Parser/Handler/CommentHandler.php b/vendor/symfony/css-selector/Parser/Handler/CommentHandler.php index 93f31884..cc01d1e6 100644 --- a/vendor/symfony/css-selector/Parser/Handler/CommentHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/CommentHandler.php @@ -26,9 +26,6 @@ */ class CommentHandler implements HandlerInterface { - /** - * {@inheritdoc} - */ public function handle(Reader $reader, TokenStream $stream): bool { if ('/*' !== $reader->getSubstring(2)) { diff --git a/vendor/symfony/css-selector/Parser/Handler/HashHandler.php b/vendor/symfony/css-selector/Parser/Handler/HashHandler.php index 7ae9b438..b29042f5 100644 --- a/vendor/symfony/css-selector/Parser/Handler/HashHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/HashHandler.php @@ -29,8 +29,8 @@ */ class HashHandler implements HandlerInterface { - private $patterns; - private $escaping; + private TokenizerPatterns $patterns; + private TokenizerEscaping $escaping; public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $escaping) { @@ -38,9 +38,6 @@ public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $esca $this->escaping = $escaping; } - /** - * {@inheritdoc} - */ public function handle(Reader $reader, TokenStream $stream): bool { $match = $reader->findPattern($this->patterns->getHashPattern()); diff --git a/vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php b/vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php index 7b2a14e2..25c0761e 100644 --- a/vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/IdentifierHandler.php @@ -29,8 +29,8 @@ */ class IdentifierHandler implements HandlerInterface { - private $patterns; - private $escaping; + private TokenizerPatterns $patterns; + private TokenizerEscaping $escaping; public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $escaping) { @@ -38,9 +38,6 @@ public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $esca $this->escaping = $escaping; } - /** - * {@inheritdoc} - */ public function handle(Reader $reader, TokenStream $stream): bool { $match = $reader->findPattern($this->patterns->getIdentifierPattern()); diff --git a/vendor/symfony/css-selector/Parser/Handler/NumberHandler.php b/vendor/symfony/css-selector/Parser/Handler/NumberHandler.php index 8291a68d..e3eb7afe 100644 --- a/vendor/symfony/css-selector/Parser/Handler/NumberHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/NumberHandler.php @@ -28,16 +28,13 @@ */ class NumberHandler implements HandlerInterface { - private $patterns; + private TokenizerPatterns $patterns; public function __construct(TokenizerPatterns $patterns) { $this->patterns = $patterns; } - /** - * {@inheritdoc} - */ public function handle(Reader $reader, TokenStream $stream): bool { $match = $reader->findPattern($this->patterns->getNumberPattern()); diff --git a/vendor/symfony/css-selector/Parser/Handler/StringHandler.php b/vendor/symfony/css-selector/Parser/Handler/StringHandler.php index 6ce83cdc..d5c6d361 100644 --- a/vendor/symfony/css-selector/Parser/Handler/StringHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/StringHandler.php @@ -31,8 +31,8 @@ */ class StringHandler implements HandlerInterface { - private $patterns; - private $escaping; + private TokenizerPatterns $patterns; + private TokenizerEscaping $escaping; public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $escaping) { @@ -40,9 +40,6 @@ public function __construct(TokenizerPatterns $patterns, TokenizerEscaping $esca $this->escaping = $escaping; } - /** - * {@inheritdoc} - */ public function handle(Reader $reader, TokenStream $stream): bool { $quote = $reader->getSubstring(1); @@ -55,7 +52,7 @@ public function handle(Reader $reader, TokenStream $stream): bool $match = $reader->findPattern($this->patterns->getQuotedStringPattern($quote)); if (!$match) { - throw new InternalErrorException(sprintf('Should have found at least an empty match at %d.', $reader->getPosition())); + throw new InternalErrorException(\sprintf('Should have found at least an empty match at %d.', $reader->getPosition())); } // check unclosed strings diff --git a/vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php b/vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php index 21345e32..eb41c3f7 100644 --- a/vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php +++ b/vendor/symfony/css-selector/Parser/Handler/WhitespaceHandler.php @@ -27,9 +27,6 @@ */ class WhitespaceHandler implements HandlerInterface { - /** - * {@inheritdoc} - */ public function handle(Reader $reader, TokenStream $stream): bool { $match = $reader->findPattern('~^[ \t\r\n\f]+~'); diff --git a/vendor/symfony/css-selector/Parser/Parser.php b/vendor/symfony/css-selector/Parser/Parser.php index d73489ed..309c9b52 100644 --- a/vendor/symfony/css-selector/Parser/Parser.php +++ b/vendor/symfony/css-selector/Parser/Parser.php @@ -19,7 +19,7 @@ * CSS selector parser. * * This component is a port of the Python cssselect library, - * which is copyright Ian Bicking, @see https://github.com/SimonSapin/cssselect. + * which is copyright Ian Bicking, @see https://github.com/scrapy/cssselect. * * @author Jean-François Simon * @@ -27,16 +27,13 @@ */ class Parser implements ParserInterface { - private $tokenizer; + private Tokenizer $tokenizer; - public function __construct(Tokenizer $tokenizer = null) + public function __construct(?Tokenizer $tokenizer = null) { $this->tokenizer = $tokenizer ?? new Tokenizer(); } - /** - * {@inheritdoc} - */ public function parse(string $source): array { $reader = new Reader($source); @@ -60,9 +57,7 @@ public static function parseSeries(array $tokens): array } } - $joined = trim(implode('', array_map(function (Token $token) { - return $token->getValue(); - }, $tokens))); + $joined = trim(implode('', array_map(fn (Token $token) => $token->getValue(), $tokens))); $int = function ($string) { if (!is_numeric($string)) { @@ -197,7 +192,18 @@ private function parseSimpleSelector(TokenStream $stream, bool $insideNegation = if (!$stream->getPeek()->isDelimiter(['('])) { $result = new Node\PseudoNode($result, $identifier); - + if ('Pseudo[Element[*]:scope]' === $result->__toString()) { + $used = \count($stream->getUsed()); + if (!(2 === $used + || 3 === $used && $stream->getUsed()[0]->isWhiteSpace() + || $used >= 3 && $stream->getUsed()[$used - 3]->isDelimiter([',']) + || $used >= 4 + && $stream->getUsed()[$used - 3]->isWhiteSpace() + && $stream->getUsed()[$used - 4]->isDelimiter([',']) + )) { + throw SyntaxErrorException::notAtTheStartOfASelector('scope'); + } + } continue; } @@ -242,7 +248,7 @@ private function parseSimpleSelector(TokenStream $stream, bool $insideNegation = } } - if (empty($arguments)) { + if (!$arguments) { throw SyntaxErrorException::unexpectedToken('at least one argument', $next); } diff --git a/vendor/symfony/css-selector/Parser/Reader.php b/vendor/symfony/css-selector/Parser/Reader.php index c0b6923a..7f6ae7a6 100644 --- a/vendor/symfony/css-selector/Parser/Reader.php +++ b/vendor/symfony/css-selector/Parser/Reader.php @@ -53,7 +53,10 @@ public function getSubstring(int $length, int $offset = 0): string return substr($this->source, $this->position + $offset, $length); } - public function getOffset(string $string) + /** + * @return int|false + */ + public function getOffset(string $string): int|bool { $position = strpos($this->source, $string, $this->position); @@ -71,12 +74,12 @@ public function findPattern(string $pattern): array|false return false; } - public function moveForward(int $length) + public function moveForward(int $length): void { $this->position += $length; } - public function moveToEnd() + public function moveToEnd(): void { $this->position = $this->length; } diff --git a/vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php b/vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php index 17fa8c27..f0ce6118 100644 --- a/vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php +++ b/vendor/symfony/css-selector/Parser/Shortcut/ClassParser.php @@ -28,9 +28,6 @@ */ class ClassParser implements ParserInterface { - /** - * {@inheritdoc} - */ public function parse(string $source): array { // Matches an optional namespace, optional element, and required class diff --git a/vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php b/vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php index 8b9a8638..a448e4a8 100644 --- a/vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php +++ b/vendor/symfony/css-selector/Parser/Shortcut/ElementParser.php @@ -27,9 +27,6 @@ */ class ElementParser implements ParserInterface { - /** - * {@inheritdoc} - */ public function parse(string $source): array { // Matches an optional namespace, required element or `*` diff --git a/vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php b/vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php index 222df5cd..a6391912 100644 --- a/vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php +++ b/vendor/symfony/css-selector/Parser/Shortcut/EmptyStringParser.php @@ -31,9 +31,6 @@ */ class EmptyStringParser implements ParserInterface { - /** - * {@inheritdoc} - */ public function parse(string $source): array { // Matches an empty string diff --git a/vendor/symfony/css-selector/Parser/Shortcut/HashParser.php b/vendor/symfony/css-selector/Parser/Shortcut/HashParser.php index fb07ee6c..6683126a 100644 --- a/vendor/symfony/css-selector/Parser/Shortcut/HashParser.php +++ b/vendor/symfony/css-selector/Parser/Shortcut/HashParser.php @@ -28,9 +28,6 @@ */ class HashParser implements ParserInterface { - /** - * {@inheritdoc} - */ public function parse(string $source): array { // Matches an optional namespace, optional element, and required id diff --git a/vendor/symfony/css-selector/Parser/Token.php b/vendor/symfony/css-selector/Parser/Token.php index a538d07f..5bf8c22e 100644 --- a/vendor/symfony/css-selector/Parser/Token.php +++ b/vendor/symfony/css-selector/Parser/Token.php @@ -68,7 +68,7 @@ public function isDelimiter(array $values = []): bool return false; } - if (empty($values)) { + if (!$values) { return true; } @@ -103,9 +103,9 @@ public function isString(): bool public function __toString(): string { if ($this->value) { - return sprintf('<%s "%s" at %s>', $this->type, $this->value, $this->position); + return \sprintf('<%s "%s" at %s>', $this->type, $this->value, $this->position); } - return sprintf('<%s at %s>', $this->type, $this->position); + return \sprintf('<%s at %s>', $this->type, $this->position); } } diff --git a/vendor/symfony/css-selector/Parser/TokenStream.php b/vendor/symfony/css-selector/Parser/TokenStream.php index e2c15a64..8b72d5db 100644 --- a/vendor/symfony/css-selector/Parser/TokenStream.php +++ b/vendor/symfony/css-selector/Parser/TokenStream.php @@ -37,7 +37,7 @@ class TokenStream private array $used = []; private int $cursor = 0; - private $peeked; + private ?Token $peeked; private bool $peeking = false; /** @@ -145,7 +145,7 @@ public function getNextIdentifierOrStar(): ?string /** * Skips next whitespace if any. */ - public function skipWhitespace() + public function skipWhitespace(): void { $peek = $this->getPeek(); diff --git a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php index 013e827d..8c4b9f74 100644 --- a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php +++ b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerEscaping.php @@ -23,7 +23,7 @@ */ class TokenizerEscaping { - private $patterns; + private TokenizerPatterns $patterns; public function __construct(TokenizerPatterns $patterns) { diff --git a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php index 3c77cf09..1825bbf3 100644 --- a/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php +++ b/vendor/symfony/css-selector/Parser/Tokenizer/TokenizerPatterns.php @@ -84,6 +84,6 @@ public function getNumberPattern(): string public function getQuotedStringPattern(string $quote): string { - return '~^'.sprintf($this->quotedStringPattern, $quote).'~i'; + return '~^'.\sprintf($this->quotedStringPattern, $quote).'~i'; } } diff --git a/vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php b/vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php index 44e0035a..495f8829 100644 --- a/vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/AbstractExtension.php @@ -23,41 +23,26 @@ */ abstract class AbstractExtension implements ExtensionInterface { - /** - * {@inheritdoc} - */ public function getNodeTranslators(): array { return []; } - /** - * {@inheritdoc} - */ public function getCombinationTranslators(): array { return []; } - /** - * {@inheritdoc} - */ public function getFunctionTranslators(): array { return []; } - /** - * {@inheritdoc} - */ public function getPseudoClassTranslators(): array { return []; } - /** - * {@inheritdoc} - */ public function getAttributeMatchingTranslators(): array { return []; diff --git a/vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php b/vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php index a9879f1b..28a16c1b 100644 --- a/vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/AttributeMatchingExtension.php @@ -26,20 +26,17 @@ */ class AttributeMatchingExtension extends AbstractExtension { - /** - * {@inheritdoc} - */ public function getAttributeMatchingTranslators(): array { return [ - 'exists' => [$this, 'translateExists'], - '=' => [$this, 'translateEquals'], - '~=' => [$this, 'translateIncludes'], - '|=' => [$this, 'translateDashMatch'], - '^=' => [$this, 'translatePrefixMatch'], - '$=' => [$this, 'translateSuffixMatch'], - '*=' => [$this, 'translateSubstringMatch'], - '!=' => [$this, 'translateDifferent'], + 'exists' => $this->translateExists(...), + '=' => $this->translateEquals(...), + '~=' => $this->translateIncludes(...), + '|=' => $this->translateDashMatch(...), + '^=' => $this->translatePrefixMatch(...), + '$=' => $this->translateSuffixMatch(...), + '*=' => $this->translateSubstringMatch(...), + '!=' => $this->translateDifferent(...), ]; } @@ -50,12 +47,12 @@ public function translateExists(XPathExpr $xpath, string $attribute, ?string $va public function translateEquals(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { - return $xpath->addCondition(sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value))); + return $xpath->addCondition(\sprintf('%s = %s', $attribute, Translator::getXpathLiteral($value))); } public function translateIncludes(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { - return $xpath->addCondition($value ? sprintf( + return $xpath->addCondition($value ? \sprintf( '%1$s and contains(concat(\' \', normalize-space(%1$s), \' \'), %2$s)', $attribute, Translator::getXpathLiteral(' '.$value.' ') @@ -64,7 +61,7 @@ public function translateIncludes(XPathExpr $xpath, string $attribute, ?string $ public function translateDashMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { - return $xpath->addCondition(sprintf( + return $xpath->addCondition(\sprintf( '%1$s and (%1$s = %2$s or starts-with(%1$s, %3$s))', $attribute, Translator::getXpathLiteral($value), @@ -74,7 +71,7 @@ public function translateDashMatch(XPathExpr $xpath, string $attribute, ?string public function translatePrefixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { - return $xpath->addCondition($value ? sprintf( + return $xpath->addCondition($value ? \sprintf( '%1$s and starts-with(%1$s, %2$s)', $attribute, Translator::getXpathLiteral($value) @@ -83,7 +80,7 @@ public function translatePrefixMatch(XPathExpr $xpath, string $attribute, ?strin public function translateSuffixMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { - return $xpath->addCondition($value ? sprintf( + return $xpath->addCondition($value ? \sprintf( '%1$s and substring(%1$s, string-length(%1$s)-%2$s) = %3$s', $attribute, \strlen($value) - 1, @@ -93,7 +90,7 @@ public function translateSuffixMatch(XPathExpr $xpath, string $attribute, ?strin public function translateSubstringMatch(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { - return $xpath->addCondition($value ? sprintf( + return $xpath->addCondition($value ? \sprintf( '%1$s and contains(%1$s, %2$s)', $attribute, Translator::getXpathLiteral($value) @@ -102,16 +99,13 @@ public function translateSubstringMatch(XPathExpr $xpath, string $attribute, ?st public function translateDifferent(XPathExpr $xpath, string $attribute, ?string $value): XPathExpr { - return $xpath->addCondition(sprintf( + return $xpath->addCondition(\sprintf( $value ? 'not(%1$s) or %1$s != %2$s' : '%s != %s', $attribute, Translator::getXpathLiteral($value) )); } - /** - * {@inheritdoc} - */ public function getName(): string { return 'attribute-matching'; diff --git a/vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php b/vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php index aee976e9..f78d4888 100644 --- a/vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/CombinationExtension.php @@ -25,16 +25,13 @@ */ class CombinationExtension extends AbstractExtension { - /** - * {@inheritdoc} - */ public function getCombinationTranslators(): array { return [ - ' ' => [$this, 'translateDescendant'], - '>' => [$this, 'translateChild'], - '+' => [$this, 'translateDirectAdjacent'], - '~' => [$this, 'translateIndirectAdjacent'], + ' ' => $this->translateDescendant(...), + '>' => $this->translateChild(...), + '+' => $this->translateDirectAdjacent(...), + '~' => $this->translateIndirectAdjacent(...), ]; } @@ -61,9 +58,6 @@ public function translateIndirectAdjacent(XPathExpr $xpath, XPathExpr $combinedX return $xpath->join('/following-sibling::', $combinedXpath); } - /** - * {@inheritdoc} - */ public function getName(): string { return 'combination'; diff --git a/vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php b/vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php index d3f7222a..557e3052 100644 --- a/vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/FunctionExtension.php @@ -30,18 +30,15 @@ */ class FunctionExtension extends AbstractExtension { - /** - * {@inheritdoc} - */ public function getFunctionTranslators(): array { return [ - 'nth-child' => [$this, 'translateNthChild'], - 'nth-last-child' => [$this, 'translateNthLastChild'], - 'nth-of-type' => [$this, 'translateNthOfType'], - 'nth-last-of-type' => [$this, 'translateNthLastOfType'], - 'contains' => [$this, 'translateContains'], - 'lang' => [$this, 'translateLang'], + 'nth-child' => $this->translateNthChild(...), + 'nth-last-child' => $this->translateNthLastChild(...), + 'nth-of-type' => $this->translateNthOfType(...), + 'nth-last-of-type' => $this->translateNthLastOfType(...), + 'contains' => $this->translateContains(...), + 'lang' => $this->translateLang(...), ]; } @@ -53,7 +50,7 @@ public function translateNthChild(XPathExpr $xpath, FunctionNode $function, bool try { [$a, $b] = Parser::parseSeries($function->getArguments()); } catch (SyntaxErrorException $e) { - throw new ExpressionErrorException(sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e); + throw new ExpressionErrorException(\sprintf('Invalid series: "%s".', implode('", "', $function->getArguments())), 0, $e); } $xpath->addStarPrefix(); @@ -86,10 +83,10 @@ public function translateNthChild(XPathExpr $xpath, FunctionNode $function, bool $expr .= ' - '.$b; } - $conditions = [sprintf('%s %s 0', $expr, $sign)]; + $conditions = [\sprintf('%s %s 0', $expr, $sign)]; if (1 !== $a && -1 !== $a) { - $conditions[] = sprintf('(%s) mod %d = 0', $expr, $a); + $conditions[] = \sprintf('(%s) mod %d = 0', $expr, $a); } return $xpath->addCondition(implode(' and ', $conditions)); @@ -137,7 +134,7 @@ public function translateContains(XPathExpr $xpath, FunctionNode $function): XPa } } - return $xpath->addCondition(sprintf( + return $xpath->addCondition(\sprintf( 'contains(string(.), %s)', Translator::getXpathLiteral($arguments[0]->getValue()) )); @@ -155,15 +152,12 @@ public function translateLang(XPathExpr $xpath, FunctionNode $function): XPathEx } } - return $xpath->addCondition(sprintf( + return $xpath->addCondition(\sprintf( 'lang(%s)', Translator::getXpathLiteral($arguments[0]->getValue()) )); } - /** - * {@inheritdoc} - */ public function getName(): string { return 'function'; diff --git a/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php b/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php index 6edc0858..b3bf1320 100644 --- a/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/HtmlExtension.php @@ -36,30 +36,24 @@ public function __construct(Translator $translator) ->setFlag(NodeExtension::ATTRIBUTE_NAME_IN_LOWER_CASE, true); } - /** - * {@inheritdoc} - */ public function getPseudoClassTranslators(): array { return [ - 'checked' => [$this, 'translateChecked'], - 'link' => [$this, 'translateLink'], - 'disabled' => [$this, 'translateDisabled'], - 'enabled' => [$this, 'translateEnabled'], - 'selected' => [$this, 'translateSelected'], - 'invalid' => [$this, 'translateInvalid'], - 'hover' => [$this, 'translateHover'], - 'visited' => [$this, 'translateVisited'], + 'checked' => $this->translateChecked(...), + 'link' => $this->translateLink(...), + 'disabled' => $this->translateDisabled(...), + 'enabled' => $this->translateEnabled(...), + 'selected' => $this->translateSelected(...), + 'invalid' => $this->translateInvalid(...), + 'hover' => $this->translateHover(...), + 'visited' => $this->translateVisited(...), ]; } - /** - * {@inheritdoc} - */ public function getFunctionTranslators(): array { return [ - 'lang' => [$this, 'translateLang'], + 'lang' => $this->translateLang(...), ]; } @@ -148,7 +142,7 @@ public function translateLang(XPathExpr $xpath, FunctionNode $function): XPathEx } } - return $xpath->addCondition(sprintf( + return $xpath->addCondition(\sprintf( 'ancestor-or-self::*[@lang][1][starts-with(concat(' ."translate(@%s, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'), '-')" .', %s)]', @@ -177,9 +171,6 @@ public function translateVisited(XPathExpr $xpath): XPathExpr return $xpath->addCondition('0'); } - /** - * {@inheritdoc} - */ public function getName(): string { return 'html'; diff --git a/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php b/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php index 642702bb..2ccf71a4 100644 --- a/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/NodeExtension.php @@ -59,21 +59,18 @@ public function hasFlag(int $flag): bool return (bool) ($this->flags & $flag); } - /** - * {@inheritdoc} - */ public function getNodeTranslators(): array { return [ - 'Selector' => [$this, 'translateSelector'], - 'CombinedSelector' => [$this, 'translateCombinedSelector'], - 'Negation' => [$this, 'translateNegation'], - 'Function' => [$this, 'translateFunction'], - 'Pseudo' => [$this, 'translatePseudo'], - 'Attribute' => [$this, 'translateAttribute'], - 'Class' => [$this, 'translateClass'], - 'Hash' => [$this, 'translateHash'], - 'Element' => [$this, 'translateElement'], + 'Selector' => $this->translateSelector(...), + 'CombinedSelector' => $this->translateCombinedSelector(...), + 'Negation' => $this->translateNegation(...), + 'Function' => $this->translateFunction(...), + 'Pseudo' => $this->translatePseudo(...), + 'Attribute' => $this->translateAttribute(...), + 'Class' => $this->translateClass(...), + 'Hash' => $this->translateHash(...), + 'Element' => $this->translateElement(...), ]; } @@ -94,7 +91,7 @@ public function translateNegation(Node\NegationNode $node, Translator $translato $subXpath->addNameTest(); if ($subXpath->getCondition()) { - return $xpath->addCondition(sprintf('not(%s)', $subXpath->getCondition())); + return $xpath->addCondition(\sprintf('not(%s)', $subXpath->getCondition())); } return $xpath->addCondition('0'); @@ -124,11 +121,11 @@ public function translateAttribute(Node\AttributeNode $node, Translator $transla } if ($node->getNamespace()) { - $name = sprintf('%s:%s', $node->getNamespace(), $name); + $name = \sprintf('%s:%s', $node->getNamespace(), $name); $safe = $safe && $this->isSafeName($node->getNamespace()); } - $attribute = $safe ? '@'.$name : sprintf('attribute::*[name() = %s]', Translator::getXpathLiteral($name)); + $attribute = $safe ? '@'.$name : \sprintf('attribute::*[name() = %s]', Translator::getXpathLiteral($name)); $value = $node->getValue(); $xpath = $translator->nodeToXPath($node->getSelector()); @@ -169,7 +166,7 @@ public function translateElement(Node\ElementNode $node): XPathExpr } if ($node->getNamespace()) { - $element = sprintf('%s:%s', $node->getNamespace(), $element); + $element = \sprintf('%s:%s', $node->getNamespace(), $element); $safe = $safe && $this->isSafeName($node->getNamespace()); } @@ -182,9 +179,6 @@ public function translateElement(Node\ElementNode $node): XPathExpr return $xpath; } - /** - * {@inheritdoc} - */ public function getName(): string { return 'node'; diff --git a/vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php b/vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php index a50b0486..397f06f7 100644 --- a/vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php +++ b/vendor/symfony/css-selector/XPath/Extension/PseudoClassExtension.php @@ -26,20 +26,18 @@ */ class PseudoClassExtension extends AbstractExtension { - /** - * {@inheritdoc} - */ public function getPseudoClassTranslators(): array { return [ - 'root' => [$this, 'translateRoot'], - 'first-child' => [$this, 'translateFirstChild'], - 'last-child' => [$this, 'translateLastChild'], - 'first-of-type' => [$this, 'translateFirstOfType'], - 'last-of-type' => [$this, 'translateLastOfType'], - 'only-child' => [$this, 'translateOnlyChild'], - 'only-of-type' => [$this, 'translateOnlyOfType'], - 'empty' => [$this, 'translateEmpty'], + 'root' => $this->translateRoot(...), + 'scope' => $this->translateScopePseudo(...), + 'first-child' => $this->translateFirstChild(...), + 'last-child' => $this->translateLastChild(...), + 'first-of-type' => $this->translateFirstOfType(...), + 'last-of-type' => $this->translateLastOfType(...), + 'only-child' => $this->translateOnlyChild(...), + 'only-of-type' => $this->translateOnlyOfType(...), + 'empty' => $this->translateEmpty(...), ]; } @@ -48,6 +46,11 @@ public function translateRoot(XPathExpr $xpath): XPathExpr return $xpath->addCondition('not(parent::*)'); } + public function translateScopePseudo(XPathExpr $xpath): XPathExpr + { + return $xpath->addCondition('1'); + } + public function translateFirstChild(XPathExpr $xpath): XPathExpr { return $xpath @@ -104,7 +107,7 @@ public function translateOnlyOfType(XPathExpr $xpath): XPathExpr { $element = $xpath->getElement(); - return $xpath->addCondition(sprintf('count(preceding-sibling::%s)=0 and count(following-sibling::%s)=0', $element, $element)); + return $xpath->addCondition(\sprintf('count(preceding-sibling::%s)=0 and count(following-sibling::%s)=0', $element, $element)); } public function translateEmpty(XPathExpr $xpath): XPathExpr @@ -112,9 +115,6 @@ public function translateEmpty(XPathExpr $xpath): XPathExpr return $xpath->addCondition('not(*) and not(string-length())'); } - /** - * {@inheritdoc} - */ public function getName(): string { return 'pseudo-class'; diff --git a/vendor/symfony/css-selector/XPath/Translator.php b/vendor/symfony/css-selector/XPath/Translator.php index c0bb29de..b2623e50 100644 --- a/vendor/symfony/css-selector/XPath/Translator.php +++ b/vendor/symfony/css-selector/XPath/Translator.php @@ -30,7 +30,7 @@ */ class Translator implements TranslatorInterface { - private $mainParser; + private ParserInterface $mainParser; /** * @var ParserInterface[] @@ -48,7 +48,7 @@ class Translator implements TranslatorInterface private array $pseudoClassTranslators = []; private array $attributeMatchingTranslators = []; - public function __construct(ParserInterface $parser = null) + public function __construct(?ParserInterface $parser = null) { $this->mainParser = $parser ?? new Parser(); @@ -75,7 +75,7 @@ public static function getXpathLiteral(string $element): string $parts = []; while (true) { if (false !== $pos = strpos($string, "'")) { - $parts[] = sprintf("'%s'", substr($string, 0, $pos)); + $parts[] = \sprintf("'%s'", substr($string, 0, $pos)); $parts[] = "\"'\""; $string = substr($string, $pos + 1); } else { @@ -84,12 +84,9 @@ public static function getXpathLiteral(string $element): string } } - return sprintf('concat(%s)', implode(', ', $parts)); + return \sprintf('concat(%s)', implode(', ', $parts)); } - /** - * {@inheritdoc} - */ public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self::'): string { $selectors = $this->parseSelectors($cssExpr); @@ -106,9 +103,6 @@ public function cssToXPath(string $cssExpr, string $prefix = 'descendant-or-self return implode(' | ', $selectors); } - /** - * {@inheritdoc} - */ public function selectorToXPath(SelectorNode $selector, string $prefix = 'descendant-or-self::'): string { return ($prefix ?: '').$this->nodeToXPath($selector); @@ -136,7 +130,7 @@ public function registerExtension(Extension\ExtensionInterface $extension): stat public function getExtension(string $name): Extension\ExtensionInterface { if (!isset($this->extensions[$name])) { - throw new ExpressionErrorException(sprintf('Extension "%s" not registered.', $name)); + throw new ExpressionErrorException(\sprintf('Extension "%s" not registered.', $name)); } return $this->extensions[$name]; @@ -158,7 +152,7 @@ public function registerParserShortcut(ParserInterface $shortcut): static public function nodeToXPath(NodeInterface $node): XPathExpr { if (!isset($this->nodeTranslators[$node->getNodeName()])) { - throw new ExpressionErrorException(sprintf('Node "%s" not supported.', $node->getNodeName())); + throw new ExpressionErrorException(\sprintf('Node "%s" not supported.', $node->getNodeName())); } return $this->nodeTranslators[$node->getNodeName()]($node, $this); @@ -170,7 +164,7 @@ public function nodeToXPath(NodeInterface $node): XPathExpr public function addCombination(string $combiner, NodeInterface $xpath, NodeInterface $combinedXpath): XPathExpr { if (!isset($this->combinationTranslators[$combiner])) { - throw new ExpressionErrorException(sprintf('Combiner "%s" not supported.', $combiner)); + throw new ExpressionErrorException(\sprintf('Combiner "%s" not supported.', $combiner)); } return $this->combinationTranslators[$combiner]($this->nodeToXPath($xpath), $this->nodeToXPath($combinedXpath)); @@ -182,7 +176,7 @@ public function addCombination(string $combiner, NodeInterface $xpath, NodeInter public function addFunction(XPathExpr $xpath, FunctionNode $function): XPathExpr { if (!isset($this->functionTranslators[$function->getName()])) { - throw new ExpressionErrorException(sprintf('Function "%s" not supported.', $function->getName())); + throw new ExpressionErrorException(\sprintf('Function "%s" not supported.', $function->getName())); } return $this->functionTranslators[$function->getName()]($xpath, $function); @@ -194,7 +188,7 @@ public function addFunction(XPathExpr $xpath, FunctionNode $function): XPathExpr public function addPseudoClass(XPathExpr $xpath, string $pseudoClass): XPathExpr { if (!isset($this->pseudoClassTranslators[$pseudoClass])) { - throw new ExpressionErrorException(sprintf('Pseudo-class "%s" not supported.', $pseudoClass)); + throw new ExpressionErrorException(\sprintf('Pseudo-class "%s" not supported.', $pseudoClass)); } return $this->pseudoClassTranslators[$pseudoClass]($xpath); @@ -206,7 +200,7 @@ public function addPseudoClass(XPathExpr $xpath, string $pseudoClass): XPathExpr public function addAttributeMatching(XPathExpr $xpath, string $operator, string $attribute, ?string $value): XPathExpr { if (!isset($this->attributeMatchingTranslators[$operator])) { - throw new ExpressionErrorException(sprintf('Attribute matcher operator "%s" not supported.', $operator)); + throw new ExpressionErrorException(\sprintf('Attribute matcher operator "%s" not supported.', $operator)); } return $this->attributeMatchingTranslators[$operator]($xpath, $attribute, $value); @@ -220,7 +214,7 @@ private function parseSelectors(string $css): array foreach ($this->shortcutParsers as $shortcut) { $tokens = $shortcut->parse($css); - if (!empty($tokens)) { + if ($tokens) { return $tokens; } } diff --git a/vendor/symfony/css-selector/XPath/XPathExpr.php b/vendor/symfony/css-selector/XPath/XPathExpr.php index a76e30be..4b1ffaa6 100644 --- a/vendor/symfony/css-selector/XPath/XPathExpr.php +++ b/vendor/symfony/css-selector/XPath/XPathExpr.php @@ -48,7 +48,7 @@ public function getElement(): string */ public function addCondition(string $condition): static { - $this->condition = $this->condition ? sprintf('(%s) and (%s)', $this->condition, $condition) : $condition; + $this->condition = $this->condition ? \sprintf('(%s) and (%s)', $this->condition, $condition) : $condition; return $this; } diff --git a/vendor/symfony/css-selector/composer.json b/vendor/symfony/css-selector/composer.json index 7c9551cd..c08fdc2c 100644 --- a/vendor/symfony/css-selector/composer.json +++ b/vendor/symfony/css-selector/composer.json @@ -20,7 +20,7 @@ } ], "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "autoload": { "psr-4": { "Symfony\\Component\\CssSelector\\": "" }, diff --git a/vendor/symfony/dom-crawler/AbstractUriElement.php b/vendor/symfony/dom-crawler/AbstractUriElement.php index c1417425..bc00b3ba 100644 --- a/vendor/symfony/dom-crawler/AbstractUriElement.php +++ b/vendor/symfony/dom-crawler/AbstractUriElement.php @@ -40,16 +40,16 @@ abstract class AbstractUriElement * * @throws \InvalidArgumentException if the node is not a link */ - public function __construct(\DOMElement $node, string $currentUri = null, ?string $method = 'GET') + public function __construct(\DOMElement $node, ?string $currentUri = null, ?string $method = 'GET') { $this->setNode($node); $this->method = $method ? strtoupper($method) : null; $this->currentUri = $currentUri; - $elementUriIsRelative = null === parse_url(trim($this->getRawUri()), \PHP_URL_SCHEME); + $elementUriIsRelative = !parse_url(trim($this->getRawUri()), \PHP_URL_SCHEME); $baseUriIsAbsolute = null !== $this->currentUri && \in_array(strtolower(substr($this->currentUri, 0, 4)), ['http', 'file']); if ($elementUriIsRelative && !$baseUriIsAbsolute) { - throw new \InvalidArgumentException(sprintf('The URL of the element is relative, so you must define its base URI passing an absolute URL to the constructor of the "%s" class ("%s" was passed).', __CLASS__, $this->currentUri)); + throw new \InvalidArgumentException(\sprintf('The URL of the element is relative, so you must define its base URI passing an absolute URL to the constructor of the "%s" class ("%s" was passed).', __CLASS__, $this->currentUri)); } } @@ -115,6 +115,8 @@ protected function canonicalizePath(string $path): string * * @param \DOMElement $node A \DOMElement instance * + * @return void + * * @throws \LogicException If given node is not an anchor */ abstract protected function setNode(\DOMElement $node); diff --git a/vendor/symfony/dom-crawler/CHANGELOG.md b/vendor/symfony/dom-crawler/CHANGELOG.md index 12542964..9f8f204e 100644 --- a/vendor/symfony/dom-crawler/CHANGELOG.md +++ b/vendor/symfony/dom-crawler/CHANGELOG.md @@ -1,6 +1,21 @@ CHANGELOG ========= +6.4 +--- + + * Add `CrawlerAnySelectorTextContains` test constraint + * Add `CrawlerAnySelectorTextSame` test constraint + * Add argument `$default` to `Crawler::attr()` + +6.3 +--- + + * Add `$useHtml5Parser` argument to `Crawler` + * Add `CrawlerSelectorCount` test constraint + * Add argument `$normalizeWhitespace` to `Crawler::innerText()` + * Make `Crawler::innerText()` return the first non-empty text + 6.0 --- diff --git a/vendor/symfony/dom-crawler/Crawler.php b/vendor/symfony/dom-crawler/Crawler.php index 3cd410fd..4e966cc4 100644 --- a/vendor/symfony/dom-crawler/Crawler.php +++ b/vendor/symfony/dom-crawler/Crawler.php @@ -58,16 +58,16 @@ class Crawler implements \Countable, \IteratorAggregate */ private bool $isHtml = true; - private $html5Parser; + private ?HTML5 $html5Parser = null; /** * @param \DOMNodeList|\DOMNode|\DOMNode[]|string|null $node A Node to use as the base for the crawling */ - public function __construct(\DOMNodeList|\DOMNode|array|string $node = null, string $uri = null, string $baseHref = null) + public function __construct(\DOMNodeList|\DOMNode|array|string|null $node = null, ?string $uri = null, ?string $baseHref = null, bool $useHtml5Parser = true) { $this->uri = $uri; $this->baseHref = $baseHref ?: $uri; - $this->html5Parser = class_exists(HTML5::class) ? new HTML5(['disable_html_ns' => true]) : null; + $this->html5Parser = $useHtml5Parser ? new HTML5(['disable_html_ns' => true]) : null; $this->cachedNamespaces = new \ArrayObject(); $this->add($node); @@ -91,6 +91,8 @@ public function getBaseHref(): ?string /** * Removes all the nodes. + * + * @return void */ public function clear() { @@ -107,6 +109,8 @@ public function clear() * * @param \DOMNodeList|\DOMNode|\DOMNode[]|string|null $node A node * + * @return void + * * @throws \InvalidArgumentException when node is not the expected type */ public function add(\DOMNodeList|\DOMNode|array|string|null $node) @@ -120,7 +124,7 @@ public function add(\DOMNodeList|\DOMNode|array|string|null $node) } elseif (\is_string($node)) { $this->addContent($node); } elseif (null !== $node) { - throw new \InvalidArgumentException(sprintf('Expecting a DOMNodeList or DOMNode instance, an array, a string, or null, but got "%s".', get_debug_type($node))); + throw new \InvalidArgumentException(\sprintf('Expecting a DOMNodeList or DOMNode instance, an array, a string, or null, but got "%s".', get_debug_type($node))); } } @@ -130,8 +134,10 @@ public function add(\DOMNodeList|\DOMNode|array|string|null $node) * If the charset is not set via the content type, it is assumed to be UTF-8, * or ISO-8859-1 as a fallback, which is the default charset defined by the * HTTP 1.1 specification. + * + * @return void */ - public function addContent(string $content, string $type = null) + public function addContent(string $content, ?string $type = null) { if (empty($type)) { $type = str_starts_with($content, 'document) { - $this->document = $node->ownerDocument; - } + $this->document ??= $node->ownerDocument; // Don't add duplicate nodes in the Crawler if (\in_array($node, $this->nodes, true)) { @@ -334,7 +350,7 @@ public function each(\Closure $closure): array /** * Slices the list of nodes by $offset and $length. */ - public function slice(int $offset = 0, int $length = null): static + public function slice(int $offset = 0, ?int $length = null): static { return $this->createSubCrawler(\array_slice($this->nodes, $offset, $length)); } @@ -415,7 +431,7 @@ public function closest(string $selector): ?self $domNode = $this->getNode(0); - while (\XML_ELEMENT_NODE === $domNode->nodeType) { + while (null !== $domNode && \XML_ELEMENT_NODE === $domNode->nodeType) { $node = $this->createSubCrawler($domNode); if ($node->matches($selector)) { return $node; @@ -484,7 +500,7 @@ public function ancestors(): static * @throws \InvalidArgumentException When current node is empty * @throws \RuntimeException If the CssSelector Component is not available and $selector is provided */ - public function children(string $selector = null): static + public function children(?string $selector = null): static { if (!$this->nodes) { throw new \InvalidArgumentException('The current node list is empty.'); @@ -505,17 +521,24 @@ public function children(string $selector = null): static /** * Returns the attribute value of the first node of the list. * + * @param string|null $default When not null: the value to return when the node or attribute is empty + * * @throws \InvalidArgumentException When current node is empty */ - public function attr(string $attribute): ?string + public function attr(string $attribute/* , string $default = null */): ?string { + $default = \func_num_args() > 1 ? func_get_arg(1) : null; if (!$this->nodes) { + if (null !== $default) { + return $default; + } + throw new \InvalidArgumentException('The current node list is empty.'); } $node = $this->getNode(0); - return $node->hasAttribute($attribute) ? $node->getAttribute($attribute) : null; + return $node->hasAttribute($attribute) ? $node->getAttribute($attribute) : $default; } /** @@ -542,7 +565,7 @@ public function nodeName(): string * * @throws \InvalidArgumentException When current node is empty */ - public function text(string $default = null, bool $normalizeWhitespace = true): string + public function text(?string $default = null, bool $normalizeWhitespace = true): string { if (!$this->nodes) { if (null !== $default) { @@ -555,7 +578,7 @@ public function text(string $default = null, bool $normalizeWhitespace = true): $text = $this->getNode(0)->nodeValue; if ($normalizeWhitespace) { - return trim(preg_replace("/(?:[ \n\r\t\x0C]{2,}+|[\n\r\t\x0C])/", ' ', $text), " \n\r\t\x0C"); + return $this->normalizeWhitespace($text); } return $text; @@ -563,10 +586,26 @@ public function text(string $default = null, bool $normalizeWhitespace = true): /** * Returns only the inner text that is the direct descendent of the current node, excluding any child nodes. + * + * @param bool $normalizeWhitespace Whether whitespaces should be trimmed and normalized to single spaces */ - public function innerText(): string + public function innerText(/* bool $normalizeWhitespace = true */): string { - return $this->filterXPath('.//text()')->text(); + $normalizeWhitespace = 1 <= \func_num_args() ? func_get_arg(0) : true; + + foreach ($this->getNode(0)->childNodes as $childNode) { + if (\XML_TEXT_NODE !== $childNode->nodeType && \XML_CDATA_SECTION_NODE !== $childNode->nodeType) { + continue; + } + if (!$normalizeWhitespace) { + return $childNode->nodeValue; + } + if ('' !== trim($childNode->nodeValue)) { + return $this->normalizeWhitespace($childNode->nodeValue); + } + } + + return ''; } /** @@ -576,7 +615,7 @@ public function innerText(): string * * @throws \InvalidArgumentException When current node is empty */ - public function html(string $default = null): string + public function html(?string $default = null): string { if (!$this->nodes) { if (null !== $default) { @@ -589,7 +628,7 @@ public function html(string $default = null): string $node = $this->getNode(0); $owner = $node->ownerDocument; - if (null !== $this->html5Parser && '' === $owner->saveXML($owner->childNodes[0])) { + if ($this->html5Parser && '' === $owner->saveXML($owner->childNodes[0])) { $owner = $this->html5Parser; } @@ -610,7 +649,7 @@ public function outerHtml(): string $node = $this->getNode(0); $owner = $node->ownerDocument; - if (null !== $this->html5Parser && '' === $owner->saveXML($owner->childNodes[0])) { + if ($this->html5Parser && '' === $owner->saveXML($owner->childNodes[0])) { $owner = $this->html5Parser; } @@ -623,7 +662,7 @@ public function outerHtml(): string * Since an XPath expression might evaluate to either a simple type or a \DOMNodeList, * this method will return either an array of simple types or a new Crawler instance. */ - public function evaluate(string $xpath): array|Crawler + public function evaluate(string $xpath): array|self { if (null === $this->document) { throw new \LogicException('Cannot evaluate the expression on an uninitialized crawler.'); @@ -700,7 +739,7 @@ public function filterXPath(string $xpath): static * * This method only works if you have installed the CssSelector Symfony Component. * - * @throws \RuntimeException if the CssSelector Component is not available + * @throws \LogicException if the CssSelector Component is not available */ public function filter(string $selector): static { @@ -716,7 +755,7 @@ public function filter(string $selector): static public function selectLink(string $value): static { return $this->filterRelativeXPath( - sprintf('descendant-or-self::a[contains(concat(\' \', normalize-space(string(.)), \' \'), %1$s) or ./img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %1$s)]]', static::xpathLiteral(' '.$value.' ')) + \sprintf('descendant-or-self::a[contains(concat(\' \', normalize-space(string(.)), \' \'), %1$s) or ./img[contains(concat(\' \', normalize-space(string(@alt)), \' \'), %1$s)]]', static::xpathLiteral(' '.$value.' ')) ); } @@ -725,18 +764,18 @@ public function selectLink(string $value): static */ public function selectImage(string $value): static { - $xpath = sprintf('descendant-or-self::img[contains(normalize-space(string(@alt)), %s)]', static::xpathLiteral($value)); + $xpath = \sprintf('descendant-or-self::img[contains(normalize-space(string(@alt)), %s)]', static::xpathLiteral($value)); return $this->filterRelativeXPath($xpath); } /** - * Selects a button by name or alt value for images. + * Selects a button by its text content, id, value, name or alt attribute. */ public function selectButton(string $value): static { return $this->filterRelativeXPath( - sprintf('descendant-or-self::input[((contains(%1$s, "submit") or contains(%1$s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %2$s)) or (contains(%1$s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %2$s)) or @id=%3$s or @name=%3$s] | descendant-or-self::button[contains(concat(\' \', normalize-space(string(.)), \' \'), %2$s) or @id=%3$s or @name=%3$s]', 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")', static::xpathLiteral(' '.$value.' '), static::xpathLiteral($value)) + \sprintf('descendant-or-self::input[((contains(%1$s, "submit") or contains(%1$s, "button")) and contains(concat(\' \', normalize-space(string(@value)), \' \'), %2$s)) or (contains(%1$s, "image") and contains(concat(\' \', normalize-space(string(@alt)), \' \'), %2$s)) or @id=%3$s or @name=%3$s] | descendant-or-self::button[contains(concat(\' \', normalize-space(string(.)), \' \'), %2$s) or contains(concat(\' \', normalize-space(string(@value)), \' \'), %2$s) or @id=%3$s or @name=%3$s]', 'translate(@type, "ABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyz")', static::xpathLiteral(' '.$value.' '), static::xpathLiteral($value)) ); } @@ -754,7 +793,7 @@ public function link(string $method = 'get'): Link $node = $this->getNode(0); if (!$node instanceof \DOMElement) { - throw new \InvalidArgumentException(sprintf('The selected node should be instance of DOMElement, got "%s".', get_debug_type($node))); + throw new \InvalidArgumentException(\sprintf('The selected node should be instance of DOMElement, got "%s".', get_debug_type($node))); } return new Link($node, $this->baseHref, $method); @@ -772,7 +811,7 @@ public function links(): array $links = []; foreach ($this->nodes as $node) { if (!$node instanceof \DOMElement) { - throw new \InvalidArgumentException(sprintf('The current node list should contain only DOMElement instances, "%s" found.', get_debug_type($node))); + throw new \InvalidArgumentException(\sprintf('The current node list should contain only DOMElement instances, "%s" found.', get_debug_type($node))); } $links[] = new Link($node, $this->baseHref, 'get'); @@ -795,7 +834,7 @@ public function image(): Image $node = $this->getNode(0); if (!$node instanceof \DOMElement) { - throw new \InvalidArgumentException(sprintf('The selected node should be instance of DOMElement, got "%s".', get_debug_type($node))); + throw new \InvalidArgumentException(\sprintf('The selected node should be instance of DOMElement, got "%s".', get_debug_type($node))); } return new Image($node, $this->baseHref); @@ -811,7 +850,7 @@ public function images(): array $images = []; foreach ($this as $node) { if (!$node instanceof \DOMElement) { - throw new \InvalidArgumentException(sprintf('The current node list should contain only DOMElement instances, "%s" found.', get_debug_type($node))); + throw new \InvalidArgumentException(\sprintf('The current node list should contain only DOMElement instances, "%s" found.', get_debug_type($node))); } $images[] = new Image($node, $this->baseHref); @@ -825,7 +864,7 @@ public function images(): array * * @throws \InvalidArgumentException If the current node list is empty or the selected node is not instance of DOMElement */ - public function form(array $values = null, string $method = null): Form + public function form(?array $values = null, ?string $method = null): Form { if (!$this->nodes) { throw new \InvalidArgumentException('The current node list is empty.'); @@ -834,7 +873,7 @@ public function form(array $values = null, string $method = null): Form $node = $this->getNode(0); if (!$node instanceof \DOMElement) { - throw new \InvalidArgumentException(sprintf('The selected node should be instance of DOMElement, got "%s".', get_debug_type($node))); + throw new \InvalidArgumentException(\sprintf('The selected node should be instance of DOMElement, got "%s".', get_debug_type($node))); } $form = new Form($node, $this->uri, $method, $this->baseHref); @@ -848,12 +887,17 @@ public function form(array $values = null, string $method = null): Form /** * Overloads a default namespace prefix to be used with XPath and CSS expressions. + * + * @return void */ public function setDefaultNamespacePrefix(string $prefix) { $this->defaultNamespacePrefix = $prefix; } + /** + * @return void + */ public function registerNamespace(string $prefix, string $namespace) { $this->namespaces[$prefix] = $namespace; @@ -878,18 +922,18 @@ public function registerNamespace(string $prefix, string $namespace) public static function xpathLiteral(string $s): string { if (!str_contains($s, "'")) { - return sprintf("'%s'", $s); + return \sprintf("'%s'", $s); } if (!str_contains($s, '"')) { - return sprintf('"%s"', $s); + return \sprintf('"%s"', $s); } $string = $s; $parts = []; while (true) { if (false !== $pos = strpos($string, "'")) { - $parts[] = sprintf("'%s'", substr($string, 0, $pos)); + $parts[] = \sprintf("'%s'", substr($string, 0, $pos)); $parts[] = "\"'\""; $string = substr($string, $pos + 1); } else { @@ -898,7 +942,7 @@ public static function xpathLiteral(string $s): string } } - return sprintf('concat(%s)', implode(', ', $parts)); + return \sprintf('concat(%s)', implode(', ', $parts)); } /** @@ -1046,12 +1090,30 @@ protected function sibling(\DOMNode $node, string $siblingDir = 'nextSibling'): private function parseHtml5(string $htmlContent, string $charset = 'UTF-8'): \DOMDocument { - return $this->html5Parser->parse($this->convertToHtmlEntities($htmlContent, $charset)); + if (!$this->supportsEncoding($charset)) { + $htmlContent = $this->convertToHtmlEntities($htmlContent, $charset); + $charset = 'UTF-8'; + } + + return $this->html5Parser->parse($htmlContent, ['encoding' => $charset]); + } + + private function supportsEncoding(string $encoding): bool + { + try { + return '' === @mb_convert_encoding('', $encoding, 'UTF-8'); + } catch (\Throwable $e) { + return false; + } } private function parseXhtml(string $htmlContent, string $charset = 'UTF-8'): \DOMDocument { - $htmlContent = $this->convertToHtmlEntities($htmlContent, $charset); + if ('UTF-8' === $charset && preg_match('//u', $htmlContent)) { + $htmlContent = ''.$htmlContent; + } else { + $htmlContent = $this->convertToHtmlEntities($htmlContent, $charset); + } $internalErrors = libxml_use_internal_errors(true); @@ -1072,15 +1134,15 @@ private function parseXhtml(string $htmlContent, string $charset = 'UTF-8'): \DO */ private function convertToHtmlEntities(string $htmlContent, string $charset = 'UTF-8'): string { - set_error_handler(function () { throw new \Exception(); }); + set_error_handler(static fn () => throw new \Exception()); try { return mb_encode_numericentity($htmlContent, [0x80, 0x10FFFF, 0, 0x1FFFFF], $charset); - } catch (\Exception|\ValueError $e) { + } catch (\Exception|\ValueError) { try { $htmlContent = iconv($charset, 'UTF-8', $htmlContent); $htmlContent = mb_encode_numericentity($htmlContent, [0x80, 0x10FFFF, 0, 0x1FFFFF], 'UTF-8'); - } catch (\Exception|\ValueError $e) { + } catch (\Exception|\ValueError) { } return $htmlContent; @@ -1120,7 +1182,7 @@ private function discoverNamespace(\DOMXPath $domxpath, string $prefix): ?string } // ask for one namespace, otherwise we'd get a collection with an item for each node - $namespaces = $domxpath->query(sprintf('(//namespace::*[name()="%s"])[last()]', $this->defaultNamespacePrefix === $prefix ? '' : $prefix)); + $namespaces = $domxpath->query(\sprintf('(//namespace::*[name()="%s"])[last()]', $this->defaultNamespacePrefix === $prefix ? '' : $prefix)); return $this->cachedNamespaces[$prefix] = ($node = $namespaces->item(0)) ? $node->nodeValue : null; } @@ -1178,12 +1240,14 @@ private function parseHtmlString(string $content, string $charset): \DOMDocument private function canParseHtml5String(string $content): bool { - if (null === $this->html5Parser) { + if (!$this->html5Parser) { return false; } + if (false === ($pos = stripos($content, ''))) { return false; } + $header = substr($content, 0, $pos); return '' === $header || $this->isValidHtml5Heading($header); @@ -1193,4 +1257,9 @@ private function isValidHtml5Heading(string $heading): bool { return 1 === preg_match('/^\x{FEFF}?\s*(\s*)*$/u', $heading); } + + private function normalizeWhitespace(string $string): string + { + return trim(preg_replace("/(?:[ \n\r\t\x0C]{2,}+|[\n\r\t\x0C])/", ' ', $string), " \n\r\t\x0C"); + } } diff --git a/vendor/symfony/dom-crawler/Field/ChoiceFormField.php b/vendor/symfony/dom-crawler/Field/ChoiceFormField.php index 918a18e2..02285730 100644 --- a/vendor/symfony/dom-crawler/Field/ChoiceFormField.php +++ b/vendor/symfony/dom-crawler/Field/ChoiceFormField.php @@ -45,6 +45,10 @@ public function hasValue(): bool */ public function isDisabled(): bool { + if ('checkbox' === $this->type) { + return parent::isDisabled(); + } + if (parent::isDisabled() && 'select' === $this->type) { return true; } @@ -60,6 +64,8 @@ public function isDisabled(): bool /** * Sets the value of the field. + * + * @return void */ public function select(string|array|bool $value) { @@ -69,12 +75,14 @@ public function select(string|array|bool $value) /** * Ticks a checkbox. * + * @return void + * * @throws \LogicException When the type provided is not correct */ public function tick() { if ('checkbox' !== $this->type) { - throw new \LogicException(sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); + throw new \LogicException(\sprintf('You cannot tick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); } $this->setValue(true); @@ -83,12 +91,14 @@ public function tick() /** * Unticks a checkbox. * + * @return void + * * @throws \LogicException When the type provided is not correct */ public function untick() { if ('checkbox' !== $this->type) { - throw new \LogicException(sprintf('You cannot untick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); + throw new \LogicException(\sprintf('You cannot untick "%s" as it is not a checkbox (%s).', $this->name, $this->type)); } $this->setValue(false); @@ -97,6 +107,8 @@ public function untick() /** * Sets the value of the field. * + * @return void + * * @throws \InvalidArgumentException When value type provided is not correct */ public function setValue(string|array|bool|null $value) @@ -110,16 +122,16 @@ public function setValue(string|array|bool|null $value) } else { if (\is_array($value)) { if (!$this->multiple) { - throw new \InvalidArgumentException(sprintf('The value for "%s" cannot be an array.', $this->name)); + throw new \InvalidArgumentException(\sprintf('The value for "%s" cannot be an array.', $this->name)); } foreach ($value as $v) { if (!$this->containsOption($v, $this->options)) { - throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: "%s").', $this->name, $v, implode('", "', $this->availableOptionValues()))); + throw new \InvalidArgumentException(\sprintf('Input "%s" cannot take "%s" as a value (possible values: "%s").', $this->name, $v, implode('", "', $this->availableOptionValues()))); } } } elseif (!$this->containsOption($value, $this->options)) { - throw new \InvalidArgumentException(sprintf('Input "%s" cannot take "%s" as a value (possible values: "%s").', $this->name, $value, implode('", "', $this->availableOptionValues()))); + throw new \InvalidArgumentException(\sprintf('Input "%s" cannot take "%s" as a value (possible values: "%s").', $this->name, $value, implode('", "', $this->availableOptionValues()))); } if ($this->multiple) { @@ -141,10 +153,10 @@ public function setValue(string|array|bool|null $value) * * @internal */ - public function addChoice(\DOMElement $node) + public function addChoice(\DOMElement $node): void { if (!$this->multiple && 'radio' !== $this->type) { - throw new \LogicException(sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name)); + throw new \LogicException(\sprintf('Unable to add a choice for "%s" as it is not multiple or is not a radio button.', $this->name)); } $option = $this->buildOptionValue($node); @@ -174,16 +186,18 @@ public function isMultiple(): bool /** * Initializes the form field. * + * @return void + * * @throws \LogicException When node type is incorrect */ protected function initialize() { if ('input' !== $this->node->nodeName && 'select' !== $this->node->nodeName) { - throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName)); + throw new \LogicException(\sprintf('A ChoiceFormField can only be created from an input or select tag (%s given).', $this->node->nodeName)); } if ('input' === $this->node->nodeName && 'checkbox' !== strtolower($this->node->getAttribute('type')) && 'radio' !== strtolower($this->node->getAttribute('type'))) { - throw new \LogicException(sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is "%s").', $this->node->getAttribute('type'))); + throw new \LogicException(\sprintf('A ChoiceFormField can only be created from an input tag with a type of checkbox or radio (given type is "%s").', $this->node->getAttribute('type'))); } $this->value = null; @@ -222,7 +236,7 @@ protected function initialize() } // if no option is selected and if it is a simple select box, take the first option as the value - if (!$found && !$this->multiple && !empty($this->options)) { + if (!$found && !$this->multiple && $this->options) { $this->value = $this->options[0]['value']; } } diff --git a/vendor/symfony/dom-crawler/Field/FileFormField.php b/vendor/symfony/dom-crawler/Field/FileFormField.php index bd97e768..3307017e 100644 --- a/vendor/symfony/dom-crawler/Field/FileFormField.php +++ b/vendor/symfony/dom-crawler/Field/FileFormField.php @@ -23,13 +23,15 @@ class FileFormField extends FormField * * @param int $error The error code (one of UPLOAD_ERR_INI_SIZE, UPLOAD_ERR_FORM_SIZE, UPLOAD_ERR_PARTIAL, UPLOAD_ERR_NO_FILE, UPLOAD_ERR_NO_TMP_DIR, UPLOAD_ERR_CANT_WRITE, or UPLOAD_ERR_EXTENSION) * + * @return void + * * @throws \InvalidArgumentException When error code doesn't exist */ public function setErrorCode(int $error) { $codes = [\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]; if (!\in_array($error, $codes)) { - throw new \InvalidArgumentException(sprintf('The error code "%s" is not valid.', $error)); + throw new \InvalidArgumentException(\sprintf('The error code "%s" is not valid.', $error)); } $this->value = ['name' => '', 'type' => '', 'tmp_name' => '', 'error' => $error, 'size' => 0]; @@ -37,6 +39,8 @@ public function setErrorCode(int $error) /** * Sets the value of the field. + * + * @return void */ public function upload(?string $value) { @@ -45,6 +49,8 @@ public function upload(?string $value) /** * Sets the value of the field. + * + * @return void */ public function setValue(?string $value) { @@ -76,6 +82,8 @@ public function setValue(?string $value) /** * Sets path to the file as string for simulating HTTP request. + * + * @return void */ public function setFilePath(string $path) { @@ -85,16 +93,18 @@ public function setFilePath(string $path) /** * Initializes the form field. * + * @return void + * * @throws \LogicException When node type is incorrect */ protected function initialize() { if ('input' !== $this->node->nodeName) { - throw new \LogicException(sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName)); + throw new \LogicException(\sprintf('A FileFormField can only be created from an input tag (%s given).', $this->node->nodeName)); } if ('file' !== strtolower($this->node->getAttribute('type'))) { - throw new \LogicException(sprintf('A FileFormField can only be created from an input tag with a type of file (given type is "%s").', $this->node->getAttribute('type'))); + throw new \LogicException(\sprintf('A FileFormField can only be created from an input tag with a type of file (given type is "%s").', $this->node->getAttribute('type'))); } $this->setValue(null); diff --git a/vendor/symfony/dom-crawler/Field/FormField.php b/vendor/symfony/dom-crawler/Field/FormField.php index 2edb1090..dba06a62 100644 --- a/vendor/symfony/dom-crawler/Field/FormField.php +++ b/vendor/symfony/dom-crawler/Field/FormField.php @@ -63,7 +63,7 @@ public function getLabel(): ?\DOMElement $xpath = new \DOMXPath($this->node->ownerDocument); if ($this->node->hasAttribute('id')) { - $labels = $xpath->query(sprintf('descendant::label[@for="%s"]', $this->node->getAttribute('id'))); + $labels = $xpath->query(\sprintf('descendant::label[@for="%s"]', $this->node->getAttribute('id'))); if ($labels->length > 0) { return $labels->item(0); } @@ -92,6 +92,8 @@ public function getValue(): string|array|null /** * Sets the value of the field. + * + * @return void */ public function setValue(?string $value) { @@ -116,6 +118,8 @@ public function isDisabled(): bool /** * Initializes the form field. + * + * @return void */ abstract protected function initialize(); } diff --git a/vendor/symfony/dom-crawler/Field/InputFormField.php b/vendor/symfony/dom-crawler/Field/InputFormField.php index 1c3c84d7..f283a47f 100644 --- a/vendor/symfony/dom-crawler/Field/InputFormField.php +++ b/vendor/symfony/dom-crawler/Field/InputFormField.php @@ -24,12 +24,14 @@ class InputFormField extends FormField /** * Initializes the form field. * + * @return void + * * @throws \LogicException When node type is incorrect */ protected function initialize() { if ('input' !== $this->node->nodeName && 'button' !== $this->node->nodeName) { - throw new \LogicException(sprintf('An InputFormField can only be created from an input or button tag (%s given).', $this->node->nodeName)); + throw new \LogicException(\sprintf('An InputFormField can only be created from an input or button tag (%s given).', $this->node->nodeName)); } $type = strtolower($this->node->getAttribute('type')); diff --git a/vendor/symfony/dom-crawler/Field/TextareaFormField.php b/vendor/symfony/dom-crawler/Field/TextareaFormField.php index 15526e1c..c647efad 100644 --- a/vendor/symfony/dom-crawler/Field/TextareaFormField.php +++ b/vendor/symfony/dom-crawler/Field/TextareaFormField.php @@ -21,12 +21,14 @@ class TextareaFormField extends FormField /** * Initializes the form field. * + * @return void + * * @throws \LogicException When node type is incorrect */ protected function initialize() { if ('textarea' !== $this->node->nodeName) { - throw new \LogicException(sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $this->node->nodeName)); + throw new \LogicException(\sprintf('A TextareaFormField can only be created from a textarea tag (%s given).', $this->node->nodeName)); } $this->value = ''; diff --git a/vendor/symfony/dom-crawler/Form.php b/vendor/symfony/dom-crawler/Form.php index 8d0b2aa4..7ecf68bc 100644 --- a/vendor/symfony/dom-crawler/Form.php +++ b/vendor/symfony/dom-crawler/Form.php @@ -22,7 +22,7 @@ class Form extends Link implements \ArrayAccess { private \DOMElement $button; - private $fields; + private FormFieldRegistry $fields; private ?string $baseHref; /** @@ -33,7 +33,7 @@ class Form extends Link implements \ArrayAccess * * @throws \LogicException if the node is not a button inside a form tag */ - public function __construct(\DOMElement $node, string $currentUri = null, string $method = null, string $baseHref = null) + public function __construct(\DOMElement $node, ?string $currentUri = null, ?string $method = null, ?string $baseHref = null) { parent::__construct($node, $currentUri, $method); $this->baseHref = $baseHref; @@ -180,9 +180,8 @@ public function getUri(): string $uri = parent::getUri(); if (!\in_array($this->getMethod(), ['POST', 'PUT', 'DELETE', 'PATCH'])) { - $query = parse_url($uri, \PHP_URL_QUERY); $currentParameters = []; - if ($query) { + if ($query = parse_url($uri, \PHP_URL_QUERY)) { parse_str($query, $currentParameters); } @@ -245,6 +244,8 @@ public function has(string $name): bool /** * Removes a field from the form. + * + * @return void */ public function remove(string $name) { @@ -265,6 +266,8 @@ public function get(string $name): FormField|array /** * Sets a named field. + * + * @return void */ public function set(FormField $field) { @@ -336,7 +339,7 @@ public function offsetUnset(mixed $name): void public function disableValidation(): static { foreach ($this->fields->all() as $field) { - if ($field instanceof Field\ChoiceFormField) { + if ($field instanceof ChoiceFormField) { $field->disableValidation(); } } @@ -349,6 +352,8 @@ public function disableValidation(): static * * Expects a 'submit' button \DOMElement and finds the corresponding form element, or the form element itself. * + * @return void + * * @throws \LogicException If given node is not a button or input or does not have a form ancestor */ protected function setNode(\DOMElement $node) @@ -360,7 +365,7 @@ protected function setNode(\DOMElement $node) $formId = $node->getAttribute('form'); $form = $node->ownerDocument->getElementById($formId); if (null === $form) { - throw new \LogicException(sprintf('The selected node has an invalid form attribute (%s).', $formId)); + throw new \LogicException(\sprintf('The selected node has an invalid form attribute (%s).', $formId)); } $this->node = $form; @@ -373,7 +378,7 @@ protected function setNode(\DOMElement $node) } } while ('form' !== $node->nodeName); } elseif ('form' !== $node->nodeName) { - throw new \LogicException(sprintf('Unable to submit on a "%s" tag.', $node->nodeName)); + throw new \LogicException(\sprintf('Unable to submit on a "%s" tag.', $node->nodeName)); } $this->node = $node; @@ -386,7 +391,7 @@ protected function setNode(\DOMElement $node) * the form node or the entire document depending on whether we need * to find non-descendant elements through HTML5 'form' attribute. */ - private function initialize() + private function initialize(): void { $this->fields = new FormFieldRegistry(); @@ -418,14 +423,14 @@ private function initialize() // corresponding elements are either descendants or have a matching HTML5 form attribute $formId = Crawler::xpathLiteral($this->node->getAttribute('id')); - $fieldNodes = $xpath->query(sprintf('( descendant::input[@form=%s] | descendant::button[@form=%1$s] | descendant::textarea[@form=%1$s] | descendant::select[@form=%1$s] | //form[@id=%1$s]//input[not(@form)] | //form[@id=%1$s]//button[not(@form)] | //form[@id=%1$s]//textarea[not(@form)] | //form[@id=%1$s]//select[not(@form)] )[not(ancestor::template)]', $formId)); + $fieldNodes = $xpath->query(\sprintf('( descendant::input[@form=%s] | descendant::button[@form=%1$s] | descendant::textarea[@form=%1$s] | descendant::select[@form=%1$s] | //form[@id=%1$s]//input[not(@form)] | //form[@id=%1$s]//button[not(@form)] | //form[@id=%1$s]//textarea[not(@form)] | //form[@id=%1$s]//select[not(@form)] )[( not(ancestor::template) or ancestor::turbo-stream )]', $formId)); foreach ($fieldNodes as $node) { $this->addField($node); } } else { // do the xpath query with $this->node as the context node, to only find descendant elements // however, descendant elements with form attribute are not part of this form - $fieldNodes = $xpath->query('( descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)] )[not(ancestor::template)]', $this->node); + $fieldNodes = $xpath->query('( descendant::input[not(@form)] | descendant::button[not(@form)] | descendant::textarea[not(@form)] | descendant::select[not(@form)] )[( not(ancestor::template) or ancestor::turbo-stream )]', $this->node); foreach ($fieldNodes as $node) { $this->addField($node); } @@ -436,7 +441,7 @@ private function initialize() } } - private function addField(\DOMElement $node) + private function addField(\DOMElement $node): void { if (!$node->hasAttribute('name') || !$node->getAttribute('name')) { return; @@ -444,14 +449,14 @@ private function addField(\DOMElement $node) $nodeName = $node->nodeName; if ('select' == $nodeName || 'input' == $nodeName && 'checkbox' == strtolower($node->getAttribute('type'))) { - $this->set(new Field\ChoiceFormField($node)); + $this->set(new ChoiceFormField($node)); } elseif ('input' == $nodeName && 'radio' == strtolower($node->getAttribute('type'))) { // there may be other fields with the same name that are no choice // fields already registered (see https://github.com/symfony/symfony/issues/11689) if ($this->has($node->getAttribute('name')) && $this->get($node->getAttribute('name')) instanceof ChoiceFormField) { $this->get($node->getAttribute('name'))->addChoice($node); } else { - $this->set(new Field\ChoiceFormField($node)); + $this->set(new ChoiceFormField($node)); } } elseif ('input' == $nodeName && 'file' == strtolower($node->getAttribute('type'))) { $this->set(new Field\FileFormField($node)); diff --git a/vendor/symfony/dom-crawler/FormFieldRegistry.php b/vendor/symfony/dom-crawler/FormFieldRegistry.php index 3db15b8f..8b8b5098 100644 --- a/vendor/symfony/dom-crawler/FormFieldRegistry.php +++ b/vendor/symfony/dom-crawler/FormFieldRegistry.php @@ -26,7 +26,7 @@ class FormFieldRegistry /** * Adds a field to the registry. */ - public function add(FormField $field) + public function add(FormField $field): void { $segments = $this->getSegments($field->getName()); @@ -48,7 +48,7 @@ public function add(FormField $field) /** * Removes a field based on the fully qualified name and its children from the registry. */ - public function remove(string $name) + public function remove(string $name): void { $segments = $this->getSegments($name); $target = &$this->fields; @@ -76,7 +76,7 @@ public function &get(string $name): FormField|array while ($segments) { $path = array_shift($segments); if (!\is_array($target) || !\array_key_exists($path, $target)) { - throw new \InvalidArgumentException(sprintf('Unreachable field "%s".', $path)); + throw new \InvalidArgumentException(\sprintf('Unreachable field "%s".', $path)); } $target = &$target[$path]; } @@ -93,7 +93,7 @@ public function has(string $name): bool $this->get($name); return true; - } catch (\InvalidArgumentException $e) { + } catch (\InvalidArgumentException) { return false; } } @@ -103,10 +103,10 @@ public function has(string $name): bool * * @throws \InvalidArgumentException if the field does not exist */ - public function set(string $name, mixed $value) + public function set(string $name, mixed $value): void { $target = &$this->get($name); - if ((!\is_array($value) && $target instanceof Field\FormField) || $target instanceof Field\ChoiceFormField) { + if ((!\is_array($value) && $target instanceof FormField) || $target instanceof Field\ChoiceFormField) { $target->setValue($value); } elseif (\is_array($value)) { $registry = new static(); @@ -116,7 +116,7 @@ public function set(string $name, mixed $value) $this->set($k, $v); } } else { - throw new \InvalidArgumentException(sprintf('Cannot set value on a compound field "%s".', $name)); + throw new \InvalidArgumentException(\sprintf('Cannot set value on a compound field "%s".', $name)); } } @@ -136,7 +136,7 @@ public function all(): array private function walk(array $array, ?string $base = '', array &$output = []): array { foreach ($array as $k => $v) { - $path = empty($base) ? $k : sprintf('%s[%s]', $base, $k); + $path = empty($base) ? $k : \sprintf('%s[%s]', $base, $k); if (\is_array($v)) { $this->walk($v, $path, $output); } else { diff --git a/vendor/symfony/dom-crawler/Image.php b/vendor/symfony/dom-crawler/Image.php index e5736415..277c0a6a 100644 --- a/vendor/symfony/dom-crawler/Image.php +++ b/vendor/symfony/dom-crawler/Image.php @@ -16,7 +16,7 @@ */ class Image extends AbstractUriElement { - public function __construct(\DOMElement $node, string $currentUri = null) + public function __construct(\DOMElement $node, ?string $currentUri = null) { parent::__construct($node, $currentUri, 'GET'); } @@ -26,10 +26,13 @@ protected function getRawUri(): string return $this->node->getAttribute('src'); } + /** + * @return void + */ protected function setNode(\DOMElement $node) { if ('img' !== $node->nodeName) { - throw new \LogicException(sprintf('Unable to visualize a "%s" tag.', $node->nodeName)); + throw new \LogicException(\sprintf('Unable to visualize a "%s" tag.', $node->nodeName)); } $this->node = $node; diff --git a/vendor/symfony/dom-crawler/LICENSE b/vendor/symfony/dom-crawler/LICENSE index 00837045..0138f8f0 100644 --- a/vendor/symfony/dom-crawler/LICENSE +++ b/vendor/symfony/dom-crawler/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2004-2023 Fabien Potencier +Copyright (c) 2004-present Fabien Potencier 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/vendor/symfony/dom-crawler/Link.php b/vendor/symfony/dom-crawler/Link.php index 658b4fd8..40bad51c 100644 --- a/vendor/symfony/dom-crawler/Link.php +++ b/vendor/symfony/dom-crawler/Link.php @@ -23,10 +23,13 @@ protected function getRawUri(): string return $this->node->getAttribute('href'); } + /** + * @return void + */ protected function setNode(\DOMElement $node) { if ('a' !== $node->nodeName && 'area' !== $node->nodeName && 'link' !== $node->nodeName) { - throw new \LogicException(sprintf('Unable to navigate from a "%s" tag.', $node->nodeName)); + throw new \LogicException(\sprintf('Unable to navigate from a "%s" tag.', $node->nodeName)); } $this->node = $node; diff --git a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerAnySelectorTextContains.php b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerAnySelectorTextContains.php new file mode 100644 index 00000000..27dc42db --- /dev/null +++ b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerAnySelectorTextContains.php @@ -0,0 +1,69 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DomCrawler\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\DomCrawler\Crawler; + +final class CrawlerAnySelectorTextContains extends Constraint +{ + private string $selector; + private string $expectedText; + private bool $hasNode = false; + + public function __construct(string $selector, string $expectedText) + { + $this->selector = $selector; + $this->expectedText = $expectedText; + } + + public function toString(): string + { + if ($this->hasNode) { + return \sprintf('the text of any node matching selector "%s" contains "%s"', $this->selector, $this->expectedText); + } + + return \sprintf('the Crawler has a node matching selector "%s"', $this->selector); + } + + protected function matches($other): bool + { + if (!$other instanceof Crawler) { + throw new \InvalidArgumentException(\sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other))); + } + + $other = $other->filter($this->selector); + if (!\count($other)) { + $this->hasNode = false; + + return false; + } + + $this->hasNode = true; + + $nodes = $other->each(fn (Crawler $node) => $node->text(null, true)); + $matches = array_filter($nodes, function (string $node): bool { + return str_contains($node, $this->expectedText); + }); + + return 0 < \count($matches); + } + + protected function failureDescription($other): string + { + if (!$other instanceof Crawler) { + throw new \InvalidArgumentException(\sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other))); + } + + return $this->toString(); + } +} diff --git a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerAnySelectorTextSame.php b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerAnySelectorTextSame.php new file mode 100644 index 00000000..736d1128 --- /dev/null +++ b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerAnySelectorTextSame.php @@ -0,0 +1,57 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DomCrawler\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\DomCrawler\Crawler; + +final class CrawlerAnySelectorTextSame extends Constraint +{ + private string $selector; + private string $expectedText; + + public function __construct(string $selector, string $expectedText) + { + $this->selector = $selector; + $this->expectedText = $expectedText; + } + + public function toString(): string + { + return \sprintf('has at least a node matching selector "%s" with content "%s"', $this->selector, $this->expectedText); + } + + protected function matches($other): bool + { + if (!$other instanceof Crawler) { + throw new \InvalidArgumentException(\sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other))); + } + + $other = $other->filter($this->selector); + if (!\count($other)) { + return false; + } + + $nodes = $other->each(fn (Crawler $node) => trim($node->text(null, true))); + + return \in_array($this->expectedText, $nodes, true); + } + + protected function failureDescription($other): string + { + if (!$other instanceof Crawler) { + throw new \InvalidArgumentException(\sprintf('"%s" constraint expected an argument of type "%s", got "%s".', self::class, Crawler::class, get_debug_type($other))); + } + + return 'the Crawler '.$this->toString(); + } +} diff --git a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorAttributeValueSame.php b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorAttributeValueSame.php index 8c4248c0..7230d8b5 100644 --- a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorAttributeValueSame.php +++ b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorAttributeValueSame.php @@ -27,18 +27,13 @@ public function __construct(string $selector, string $attribute, string $expecte $this->expectedText = $expectedText; } - /** - * {@inheritdoc} - */ public function toString(): string { - return sprintf('has a node matching selector "%s" with attribute "%s" of value "%s"', $this->selector, $this->attribute, $this->expectedText); + return \sprintf('has a node matching selector "%s" with attribute "%s" of value "%s"', $this->selector, $this->attribute, $this->expectedText); } /** * @param Crawler $crawler - * - * {@inheritdoc} */ protected function matches($crawler): bool { @@ -52,8 +47,6 @@ protected function matches($crawler): bool /** * @param Crawler $crawler - * - * {@inheritdoc} */ protected function failureDescription($crawler): string { diff --git a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorCount.php b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorCount.php new file mode 100644 index 00000000..f56ad3b9 --- /dev/null +++ b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorCount.php @@ -0,0 +1,45 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Component\DomCrawler\Test\Constraint; + +use PHPUnit\Framework\Constraint\Constraint; +use Symfony\Component\DomCrawler\Crawler; + +final class CrawlerSelectorCount extends Constraint +{ + public function __construct( + private readonly int $count, + private readonly string $selector, + ) { + } + + public function toString(): string + { + return \sprintf('selector "%s" count is "%d"', $this->selector, $this->count); + } + + /** + * @param Crawler $crawler + */ + protected function matches($crawler): bool + { + return $this->count === \count($crawler->filter($this->selector)); + } + + /** + * @param Crawler $crawler + */ + protected function failureDescription($crawler): string + { + return \sprintf('the Crawler selector "%s" was expected to be found %d time(s) but was found %d time(s)', $this->selector, $this->count, \count($crawler->filter($this->selector))); + } +} diff --git a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorExists.php b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorExists.php index 710ce551..59075600 100644 --- a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorExists.php +++ b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorExists.php @@ -23,18 +23,13 @@ public function __construct(string $selector) $this->selector = $selector; } - /** - * {@inheritdoc} - */ public function toString(): string { - return sprintf('matches selector "%s"', $this->selector); + return \sprintf('matches selector "%s"', $this->selector); } /** * @param Crawler $crawler - * - * {@inheritdoc} */ protected function matches($crawler): bool { @@ -43,8 +38,6 @@ protected function matches($crawler): bool /** * @param Crawler $crawler - * - * {@inheritdoc} */ protected function failureDescription($crawler): string { diff --git a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorTextContains.php b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorTextContains.php index 83305808..01e92fa0 100644 --- a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorTextContains.php +++ b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorTextContains.php @@ -27,22 +27,17 @@ public function __construct(string $selector, string $expectedText) $this->expectedText = $expectedText; } - /** - * {@inheritdoc} - */ public function toString(): string { if ($this->hasNode) { - return sprintf('the text "%s" of the node matching selector "%s" contains "%s"', $this->nodeText, $this->selector, $this->expectedText); + return \sprintf('the text "%s" of the node matching selector "%s" contains "%s"', $this->nodeText, $this->selector, $this->expectedText); } - return sprintf('the Crawler has a node matching selector "%s"', $this->selector); + return \sprintf('the Crawler has a node matching selector "%s"', $this->selector); } /** * @param Crawler $crawler - * - * {@inheritdoc} */ protected function matches($crawler): bool { @@ -56,13 +51,11 @@ protected function matches($crawler): bool $this->hasNode = true; $this->nodeText = $crawler->text(null, true); - return false !== mb_strpos($this->nodeText, $this->expectedText); + return str_contains($this->nodeText, $this->expectedText); } /** * @param Crawler $crawler - * - * {@inheritdoc} */ protected function failureDescription($crawler): string { diff --git a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorTextSame.php b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorTextSame.php index e24b152f..b5f5d3e0 100644 --- a/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorTextSame.php +++ b/vendor/symfony/dom-crawler/Test/Constraint/CrawlerSelectorTextSame.php @@ -25,18 +25,13 @@ public function __construct(string $selector, string $expectedText) $this->expectedText = $expectedText; } - /** - * {@inheritdoc} - */ public function toString(): string { - return sprintf('has a node matching selector "%s" with content "%s"', $this->selector, $this->expectedText); + return \sprintf('has a node matching selector "%s" with content "%s"', $this->selector, $this->expectedText); } /** * @param Crawler $crawler - * - * {@inheritdoc} */ protected function matches($crawler): bool { @@ -50,8 +45,6 @@ protected function matches($crawler): bool /** * @param Crawler $crawler - * - * {@inheritdoc} */ protected function failureDescription($crawler): string { diff --git a/vendor/symfony/dom-crawler/UriResolver.php b/vendor/symfony/dom-crawler/UriResolver.php index be64f525..398cb7bc 100644 --- a/vendor/symfony/dom-crawler/UriResolver.php +++ b/vendor/symfony/dom-crawler/UriResolver.php @@ -33,7 +33,7 @@ public static function resolve(string $uri, ?string $baseUri): string $uri = trim($uri); // absolute URL? - if (null !== parse_url($uri, \PHP_URL_SCHEME)) { + if (null !== parse_url(\strlen($uri) !== strcspn($uri, '?#') ? $uri : $uri.'#', \PHP_URL_SCHEME)) { return $uri; } @@ -58,7 +58,7 @@ public static function resolve(string $uri, ?string $baseUri): string } // absolute URL with relative schema - if (0 === strpos($uri, '//')) { + if (str_starts_with($uri, '//')) { return preg_replace('#^([^/]*)//.*$#', '$1', $baseUriCleaned).$uri; } @@ -70,7 +70,7 @@ public static function resolve(string $uri, ?string $baseUri): string } // relative path - $path = parse_url(substr($baseUri, \strlen($baseUriCleaned)), \PHP_URL_PATH); + $path = parse_url(substr($baseUri, \strlen($baseUriCleaned)), \PHP_URL_PATH) ?? ''; $path = self::canonicalizePath(substr($path, 0, strrpos($path, '/')).'/'.$uri); return $baseUriCleaned.('' === $path || '/' !== $path[0] ? '/' : '').$path; @@ -85,7 +85,7 @@ private static function canonicalizePath(string $path): string return $path; } - if ('.' === substr($path, -1)) { + if (str_ends_with($path, '.')) { $path .= '/'; } diff --git a/vendor/symfony/dom-crawler/composer.json b/vendor/symfony/dom-crawler/composer.json index 6d113dcb..d703acbe 100644 --- a/vendor/symfony/dom-crawler/composer.json +++ b/vendor/symfony/dom-crawler/composer.json @@ -16,19 +16,13 @@ } ], "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "symfony/css-selector": "^5.4|^6.0", + "symfony/polyfill-mbstring": "~1.0", "masterminds/html5": "^2.6" }, - "conflict": { - "masterminds/html5": "<2.6" - }, - "suggest": { - "symfony/css-selector": "" + "require-dev": { + "symfony/css-selector": "^5.4|^6.0|^7.0" }, "autoload": { "psr-4": { "Symfony\\Component\\DomCrawler\\": "" }, diff --git a/vendor/symfony/polyfill-ctype/composer.json b/vendor/symfony/polyfill-ctype/composer.json index b222fdab..131ca7ad 100644 --- a/vendor/symfony/polyfill-ctype/composer.json +++ b/vendor/symfony/polyfill-ctype/composer.json @@ -16,7 +16,7 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" diff --git a/vendor/symfony/polyfill-mbstring/Mbstring.php b/vendor/symfony/polyfill-mbstring/Mbstring.php index 2e0b9694..31e36a36 100644 --- a/vendor/symfony/polyfill-mbstring/Mbstring.php +++ b/vendor/symfony/polyfill-mbstring/Mbstring.php @@ -48,6 +48,11 @@ * - mb_strstr - Finds first occurrence of a string within another * - mb_strwidth - Return width of string * - mb_substr_count - Count the number of substring occurrences + * - mb_ucfirst - Make a string's first character uppercase + * - mb_lcfirst - Make a string's first character lowercase + * - mb_trim - Strip whitespace (or other characters) from the beginning and end of a string + * - mb_ltrim - Strip whitespace (or other characters) from the beginning of a string + * - mb_rtrim - Strip whitespace (or other characters) from the end of a string * * Not implemented: * - mb_convert_kana - Convert "kana" one from another ("zen-kaku", "han-kaku" and more) @@ -80,6 +85,15 @@ final class Mbstring public static function mb_convert_encoding($s, $toEncoding, $fromEncoding = null) { + if (\is_array($s)) { + $r = []; + foreach ($s as $str) { + $r[] = self::mb_convert_encoding($str, $toEncoding, $fromEncoding); + } + + return $r; + } + if (\is_array($fromEncoding) || (null !== $fromEncoding && false !== strpos($fromEncoding, ','))) { $fromEncoding = self::mb_detect_encoding($s, $fromEncoding); } else { @@ -410,12 +424,6 @@ public static function mb_encoding_aliases($encoding) public static function mb_check_encoding($var = null, $encoding = null) { - if (PHP_VERSION_ID < 70200 && \is_array($var)) { - trigger_error('mb_check_encoding() expects parameter 1 to be string, array given', \E_USER_WARNING); - - return null; - } - if (null === $encoding) { if (null === $var) { return false; @@ -437,7 +445,6 @@ public static function mb_check_encoding($var = null, $encoding = null) } return true; - } public static function mb_detect_encoding($str, $encodingList = null, $strict = false) @@ -827,7 +834,7 @@ public static function mb_ord($s, $encoding = null) return $code; } - public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, string $encoding = null): string + public static function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = \STR_PAD_RIGHT, ?string $encoding = null): string { if (!\in_array($pad_type, [\STR_PAD_RIGHT, \STR_PAD_LEFT, \STR_PAD_BOTH], true)) { throw new \ValueError('mb_str_pad(): Argument #4 ($pad_type) must be STR_PAD_LEFT, STR_PAD_RIGHT, or STR_PAD_BOTH'); @@ -835,17 +842,8 @@ public static function mb_str_pad(string $string, int $length, string $pad_strin if (null === $encoding) { $encoding = self::mb_internal_encoding(); - } - - try { - $validEncoding = @self::mb_check_encoding('', $encoding); - } catch (\ValueError $e) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); - } - - // BC for PHP 7.3 and lower - if (!$validEncoding) { - throw new \ValueError(sprintf('mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given', $encoding)); + } else { + self::assertEncoding($encoding, 'mb_str_pad(): Argument #5 ($encoding) must be a valid encoding, "%s" given'); } if (self::mb_strlen($pad_string, $encoding) <= 0) { @@ -871,6 +869,34 @@ public static function mb_str_pad(string $string, int $length, string $pad_strin } } + public static function mb_ucfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_ucfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_TITLE, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + + public static function mb_lcfirst(string $string, ?string $encoding = null): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, 'mb_lcfirst(): Argument #2 ($encoding) must be a valid encoding, "%s" given'); + } + + $firstChar = mb_substr($string, 0, 1, $encoding); + $firstChar = mb_convert_case($firstChar, \MB_CASE_LOWER, $encoding); + + return $firstChar.mb_substr($string, 1, null, $encoding); + } + private static function getSubpart($pos, $part, $haystack, $encoding) { if (false === $pos) { @@ -944,4 +970,76 @@ private static function getEncoding($encoding) return $encoding; } + + public static function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+|[%1$s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{^[%s]+}Du', $string, $characters, $encoding, __FUNCTION__); + } + + public static function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string + { + return self::mb_internal_trim('{[%s]+$}Du', $string, $characters, $encoding, __FUNCTION__); + } + + private static function mb_internal_trim(string $regex, string $string, ?string $characters, ?string $encoding, string $function): string + { + if (null === $encoding) { + $encoding = self::mb_internal_encoding(); + } else { + self::assertEncoding($encoding, $function.'(): Argument #3 ($encoding) must be a valid encoding, "%s" given'); + } + + if ('' === $characters) { + return null === $encoding ? $string : self::mb_convert_encoding($string, $encoding); + } + + if ('UTF-8' === $encoding) { + $encoding = null; + if (!preg_match('//u', $string)) { + $string = @iconv('UTF-8', 'UTF-8//IGNORE', $string); + } + if (null !== $characters && !preg_match('//u', $characters)) { + $characters = @iconv('UTF-8', 'UTF-8//IGNORE', $characters); + } + } else { + $string = iconv($encoding, 'UTF-8//IGNORE', $string); + + if (null !== $characters) { + $characters = iconv($encoding, 'UTF-8//IGNORE', $characters); + } + } + + if (null === $characters) { + $characters = "\\0 \f\n\r\t\v\u{00A0}\u{1680}\u{2000}\u{2001}\u{2002}\u{2003}\u{2004}\u{2005}\u{2006}\u{2007}\u{2008}\u{2009}\u{200A}\u{2028}\u{2029}\u{202F}\u{205F}\u{3000}\u{0085}\u{180E}"; + } else { + $characters = preg_quote($characters); + } + + $string = preg_replace(sprintf($regex, $characters), '', $string); + + if (null === $encoding) { + return $string; + } + + return iconv('UTF-8', $encoding.'//IGNORE', $string); + } + + private static function assertEncoding(string $encoding, string $errorFormat): void + { + try { + $validEncoding = @self::mb_check_encoding('', $encoding); + } catch (\ValueError $e) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + + // BC for PHP 7.3 and lower + if (!$validEncoding) { + throw new \ValueError(sprintf($errorFormat, $encoding)); + } + } } diff --git a/vendor/symfony/polyfill-mbstring/bootstrap.php b/vendor/symfony/polyfill-mbstring/bootstrap.php index ecf1a035..ff51ae07 100644 --- a/vendor/symfony/polyfill-mbstring/bootstrap.php +++ b/vendor/symfony/polyfill-mbstring/bootstrap.php @@ -136,6 +136,27 @@ function mb_str_split($string, $length = 1, $encoding = null) { return p\Mbstrin function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } } +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } +} + + if (extension_loaded('mbstring')) { return; } diff --git a/vendor/symfony/polyfill-mbstring/bootstrap80.php b/vendor/symfony/polyfill-mbstring/bootstrap80.php index 2f9fb5b4..5236e6dc 100644 --- a/vendor/symfony/polyfill-mbstring/bootstrap80.php +++ b/vendor/symfony/polyfill-mbstring/bootstrap80.php @@ -93,7 +93,7 @@ function mb_strrpos(?string $haystack, ?string $needle, ?int $offset = 0, ?strin function mb_strstr(?string $haystack, ?string $needle, ?bool $before_needle = false, ?string $encoding = null): string|false { return p\Mbstring::mb_strstr((string) $haystack, (string) $needle, (bool) $before_needle, $encoding); } } if (!function_exists('mb_get_info')) { - function mb_get_info(?string $type = 'all'): array|string|int|false { return p\Mbstring::mb_get_info((string) $type); } + function mb_get_info(?string $type = 'all'): array|string|int|false|null { return p\Mbstring::mb_get_info((string) $type); } } if (!function_exists('mb_http_output')) { function mb_http_output(?string $encoding = null): string|bool { return p\Mbstring::mb_http_output($encoding); } @@ -132,6 +132,26 @@ function mb_str_split(?string $string, ?int $length = 1, ?string $encoding = nul function mb_str_pad(string $string, int $length, string $pad_string = ' ', int $pad_type = STR_PAD_RIGHT, ?string $encoding = null): string { return p\Mbstring::mb_str_pad($string, $length, $pad_string, $pad_type, $encoding); } } +if (!function_exists('mb_ucfirst')) { + function mb_ucfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_ucfirst($string, $encoding); } +} + +if (!function_exists('mb_lcfirst')) { + function mb_lcfirst(string $string, ?string $encoding = null): string { return p\Mbstring::mb_lcfirst($string, $encoding); } +} + +if (!function_exists('mb_trim')) { + function mb_trim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_trim($string, $characters, $encoding); } +} + +if (!function_exists('mb_ltrim')) { + function mb_ltrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_ltrim($string, $characters, $encoding); } +} + +if (!function_exists('mb_rtrim')) { + function mb_rtrim(string $string, ?string $characters = null, ?string $encoding = null): string { return p\Mbstring::mb_rtrim($string, $characters, $encoding); } +} + if (extension_loaded('mbstring')) { return; } diff --git a/vendor/symfony/polyfill-mbstring/composer.json b/vendor/symfony/polyfill-mbstring/composer.json index bd99d4b9..daa07f86 100644 --- a/vendor/symfony/polyfill-mbstring/composer.json +++ b/vendor/symfony/polyfill-mbstring/composer.json @@ -16,7 +16,8 @@ } ], "require": { - "php": ">=7.1" + "php": ">=7.2", + "ext-iconv": "*" }, "provide": { "ext-mbstring": "*" diff --git a/vip-block-data-api.php b/vip-block-data-api.php index 2ff25380..1ff542d2 100644 --- a/vip-block-data-api.php +++ b/vip-block-data-api.php @@ -5,10 +5,10 @@ * Description: Access Gutenberg block data in JSON via the REST API. * Author: WordPress VIP * Text Domain: vip-block-data-api - * Version: 1.4.4 + * Version: 1.4.5 * Requires at least: 6.0 - * Tested up to: 6.7 - * Requires PHP: 8.0 + * Tested up to: 6.8 + * Requires PHP: 8.1 * License: GPL-3 * License URI: https://www.gnu.org/licenses/gpl-3.0.html * @@ -22,18 +22,18 @@ // ToDo: When 6.4 is our min version, switch to wp_admin_notice. global $wp_version; - if ( version_compare( phpversion(), '8.0', '<' ) || version_compare( $wp_version, '6.0', '<' ) ) { + if ( version_compare( phpversion(), '8.1', '<' ) || version_compare( $wp_version, '6.0', '<' ) ) { add_action( 'admin_notices', function () { ?>
-

+