From c1fdaccbebe17ac56b1e9e6210eca1347f205996 Mon Sep 17 00:00:00 2001 From: Sonny Le Date: Mon, 26 Jan 2026 10:07:59 +0700 Subject: [PATCH 1/5] Update unit value of article listing font config --- framework/options/article.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/options/article.xml b/framework/options/article.xml index 897d5b40..7a49a1ea 100644 --- a/framework/options/article.xml +++ b/framework/options/article.xml @@ -6,8 +6,8 @@ - - + + From 868edee63cb771bddc380cf2a8b274a7936267f3 Mon Sep 17 00:00:00 2001 From: Sonny Le Date: Thu, 29 Jan 2026 10:17:45 +0700 Subject: [PATCH 2/5] Fix issue load font size of Article --- framework/library/astroid/Component/Utility.php | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/framework/library/astroid/Component/Utility.php b/framework/library/astroid/Component/Utility.php index a7ceda2b..24ea7971 100644 --- a/framework/library/astroid/Component/Utility.php +++ b/framework/library/astroid/Component/Utility.php @@ -533,16 +533,22 @@ public static function article(): void $params = Framework::getTemplate()->getParams(); // Article listing $lead_heading_fontsize = $params->get('article_listing_lead_heading_fontsize', ''); + if (Helper::isJsonString($lead_heading_fontsize)) { + $lead_heading_fontsize = json_decode($lead_heading_fontsize, true); + } $intro_heading_fontsize = $params->get('article_listing_intro_heading_fontsize', ''); + if (Helper::isJsonString($intro_heading_fontsize)) { + $intro_heading_fontsize = json_decode($intro_heading_fontsize, true); + } if (!empty($lead_heading_fontsize)) { $article = new Style('.items-leading .article-title .page-header h2', '', true); - $article->addResponsiveCSS('font-size', $lead_heading_fontsize,'px'); + $article->addResponsiveCSS('font-size', $lead_heading_fontsize,!empty($lead_heading_fontsize['postfix']) ? $lead_heading_fontsize['postfix'] : 'px'); $article->render(); } if (!empty($intro_heading_fontsize)) { $article = new Style('.items-row .article-title .page-header h2', '', true); - $article->addResponsiveCSS('font-size', $intro_heading_fontsize,'px'); + $article->addResponsiveCSS('font-size', $intro_heading_fontsize,!empty($intro_heading_fontsize['postfix']) ? $intro_heading_fontsize['postfix'] : 'px'); $article->render(); } } From 26fe053f4d50b3425e2437918a2ecf3aec3b0d01 Mon Sep 17 00:00:00 2001 From: Sonny Le Date: Wed, 11 Feb 2026 08:56:59 +0700 Subject: [PATCH 3/5] Update vendor PHP Font 1.0.1 -> 1.0.2 ScssPHP 2.0.1 -> 2.1.0 --- framework/library/composer.lock | 142 +- .../vendor/composer/autoload_files.php | 2 +- .../vendor/composer/autoload_static.php | 2 +- .../library/vendor/composer/installed.json | 154 +- .../library/vendor/composer/installed.php | 36 +- .../vendor/composer/platform_check.php | 4 +- .../Contracts/Conditionable.php | 26 + .../Contracts/DomainHostInterface.php | 10 +- .../Contracts/FragmentDirective.php | 55 + .../Contracts/FragmentInterface.php | 3 + .../Contracts/HostInterface.php | 3 + .../Contracts/PathInterface.php | 3 + .../Contracts/QueryInterface.php | 27 +- .../Contracts/SegmentedPathInterface.php | 4 +- .../Contracts/Transformable.php | 27 + .../uri-interfaces/Contracts/UriAccess.php | 3 + .../Contracts/UriComponentInterface.php | 12 +- .../uri-interfaces/Contracts/UriInterface.php | 7 + .../vendor/league/uri-interfaces/Encoder.php | 448 +- .../Exceptions/ConversionFailed.php | 7 +- .../uri-interfaces/FeatureDetection.php | 26 +- .../league/uri-interfaces/HostFormat.php | 20 + .../league/uri-interfaces/HostRecord.php | 446 ++ .../vendor/league/uri-interfaces/HostType.php | 22 + .../uri-interfaces/IPv4/BCMathCalculator.php | 4 +- .../league/uri-interfaces/IPv4/Converter.php | 31 +- .../league/uri-interfaces/IPv6/Converter.php | 61 +- .../league/uri-interfaces/Idna/Converter.php | 31 +- .../uri-interfaces/KeyValuePair/Converter.php | 39 +- .../uri-interfaces/QueryComposeMode.php | 88 + .../uri-interfaces/QueryExtractMode.php | 50 + .../league/uri-interfaces/QueryString.php | 291 +- .../uri-interfaces/StringCoercionMode.php | 158 + .../uri-interfaces/UriComparisonMode.php | 20 + .../league/uri-interfaces/UriString.php | 538 ++- .../uri-interfaces/UrnComparisonMode.php | 20 + .../league/uri-interfaces/composer.json | 8 +- .../library/vendor/league/uri/BaseUri.php | 360 +- .../library/vendor/league/uri/Builder.php | 358 ++ framework/library/vendor/league/uri/Http.php | 85 +- .../library/vendor/league/uri/SchemeType.php | 36 + framework/library/vendor/league/uri/Uri.php | 1437 ++++-- .../library/vendor/league/uri/UriScheme.php | 199 + .../library/vendor/league/uri/UriTemplate.php | 193 +- .../league/uri/UriTemplate/Template.php | 13 +- .../league/uri/UriTemplate/VarSpecifier.php | 5 +- .../league/uri/UriTemplate/VariableBag.php | 15 +- framework/library/vendor/league/uri/Urn.php | 602 +++ .../library/vendor/league/uri/composer.json | 20 +- .../vendor/phenx/php-font-lib/AUTHORS.md | 17 - .../vendor/phenx/php-font-lib/composer.json | 8 +- .../php-font-lib/src/FontLib/BinaryStream.php | 8 +- .../src/FontLib/TrueType/Collection.php | 6 + .../library/vendor/scssphp/scssphp/bin/pscss | 244 - .../vendor/scssphp/scssphp/composer.json | 58 +- .../vendor/scssphp/scssphp/scss.inc.php | 26 - .../Css/MediaQuerySingletonMergeResult.php | 3 + .../scssphp/src/Ast/Css/ModifiableCssNode.php | 2 +- .../src/Ast/Sass/ArgumentDeclaration.php | 9 +- .../src/Ast/Sass/CallableInvocation.php | 3 + .../scssphp/src/Ast/Sass/Interpolation.php | 29 +- .../scssphp/src/Ast/Selector/SelectorList.php | 4 +- .../vendor/scssphp/scssphp/src/Base/Range.php | 57 - .../vendor/scssphp/scssphp/src/Block.php | 73 - .../scssphp/scssphp/src/Block/AtRootBlock.php | 37 - .../scssphp/src/Block/CallableBlock.php | 46 - .../scssphp/src/Block/ContentBlock.php | 38 - .../scssphp/src/Block/DirectiveBlock.php | 37 - .../scssphp/scssphp/src/Block/EachBlock.php | 37 - .../scssphp/scssphp/src/Block/ElseBlock.php | 27 - .../scssphp/scssphp/src/Block/ElseifBlock.php | 32 - .../scssphp/scssphp/src/Block/ForBlock.php | 47 - .../scssphp/scssphp/src/Block/IfBlock.php | 37 - .../scssphp/scssphp/src/Block/MediaBlock.php | 37 - .../scssphp/src/Block/NestedPropertyBlock.php | 37 - .../scssphp/scssphp/src/Block/WhileBlock.php | 32 - .../vendor/scssphp/scssphp/src/Cache.php | 272 -- .../scssphp/src/Compiler/CachedResult.php | 77 - .../scssphp/src/Compiler/Environment.php | 68 - .../src/Exception/CompilerException.php | 24 - .../MultiSpanSassFormatException.php | 3 + .../MultiSpanSassRuntimeException.php | 3 + .../scssphp/src/Exception/ParserException.php | 58 - .../scssphp/src/Exception/RangeException.php | 24 - .../scssphp/src/Exception/ServerException.php | 26 - .../Exception/SimpleSassFormatException.php | 3 +- .../src/Extend/ConcreteExtensionStore.php | 32 +- .../scssphp/scssphp/src/Extend/ObjectSet.php | 8 +- .../vendor/scssphp/scssphp/src/Formatter.php | 377 -- .../scssphp/scssphp/src/Formatter/Compact.php | 52 - .../scssphp/src/Formatter/Compressed.php | 83 - .../scssphp/src/Formatter/Crunched.php | 87 - .../scssphp/scssphp/src/Formatter/Debug.php | 127 - .../scssphp/src/Formatter/Expanded.php | 72 - .../scssphp/scssphp/src/Formatter/Nested.php | 238 - .../scssphp/src/Formatter/OutputBlock.php | 68 - .../scssphp/src/Function/ColorFunctions.php | 2 +- .../scssphp/src/Function/FunctionRegistry.php | 79 +- .../scssphp/src/Function/StringFunctions.php | 4 +- .../scssphp/src/Logger/StreamLogger.php | 5 +- .../vendor/scssphp/scssphp/src/Parser.php | 4220 ----------------- .../scssphp/src/Parser/InterpolationMap.php | 22 +- .../src/Parser/MultiSourceFormatException.php | 5 +- .../scssphp/scssphp/src/Parser/Parser.php | 6 +- .../scssphp/src/Parser/StringScanner.php | 32 +- .../src/SassCallable/BuiltInCallable.php | 12 +- .../src/Serializer/SerializeVisitor.php | 12 +- .../scssphp/src/Serializer/Serializer.php | 11 + .../src/SourceMap/SourceMapGenerator.php | 390 -- .../vendor/scssphp/scssphp/src/Util/Box.php | 2 + .../scssphp/scssphp/src/Util/Character.php | 12 +- .../scssphp/scssphp/src/Util/ErrorUtil.php | 30 - .../scssphp/scssphp/src/Util/ListUtil.php | 7 +- .../vendor/scssphp/scssphp/src/Util/Path.php | 9 +- .../scssphp/scssphp/src/Util/UriUtil.php | 133 +- .../scssphp/scssphp/src/Value/SassNumber.php | 5 +- .../scssphp/scssphp/src/ValueConverter.php | 30 +- .../vendor/scssphp/scssphp/src/Version.php | 2 +- .../vendor/scssphp/source-span/composer.json | 9 +- .../source-span/src/SimpleSourceLocation.php | 2 +- .../scssphp/source-span/src/SourceFile.php | 17 +- .../vendor/scssphp/source-span/src/Util.php | 10 +- .../vendor/symfony/filesystem/Filesystem.php | 20 +- .../vendor/symfony/filesystem/Path.php | 40 +- .../vendor/symfony/filesystem/composer.json | 4 +- 125 files changed, 5488 insertions(+), 8488 deletions(-) create mode 100644 framework/library/vendor/league/uri-interfaces/Contracts/Conditionable.php create mode 100644 framework/library/vendor/league/uri-interfaces/Contracts/FragmentDirective.php create mode 100644 framework/library/vendor/league/uri-interfaces/Contracts/Transformable.php create mode 100644 framework/library/vendor/league/uri-interfaces/HostFormat.php create mode 100644 framework/library/vendor/league/uri-interfaces/HostRecord.php create mode 100644 framework/library/vendor/league/uri-interfaces/HostType.php create mode 100644 framework/library/vendor/league/uri-interfaces/QueryComposeMode.php create mode 100644 framework/library/vendor/league/uri-interfaces/QueryExtractMode.php create mode 100644 framework/library/vendor/league/uri-interfaces/StringCoercionMode.php create mode 100644 framework/library/vendor/league/uri-interfaces/UriComparisonMode.php create mode 100644 framework/library/vendor/league/uri-interfaces/UrnComparisonMode.php create mode 100644 framework/library/vendor/league/uri/Builder.php create mode 100644 framework/library/vendor/league/uri/SchemeType.php create mode 100644 framework/library/vendor/league/uri/UriScheme.php create mode 100644 framework/library/vendor/league/uri/Urn.php delete mode 100644 framework/library/vendor/phenx/php-font-lib/AUTHORS.md delete mode 100644 framework/library/vendor/scssphp/scssphp/bin/pscss delete mode 100644 framework/library/vendor/scssphp/scssphp/scss.inc.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Base/Range.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/AtRootBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/CallableBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/ContentBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/DirectiveBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/EachBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/ElseBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/ElseifBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/ForBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/IfBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/MediaBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/NestedPropertyBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Block/WhileBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Cache.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Compiler/CachedResult.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Compiler/Environment.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Exception/CompilerException.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Exception/ParserException.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Exception/RangeException.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Exception/ServerException.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Formatter.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Formatter/Compact.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Formatter/Compressed.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Formatter/Crunched.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Formatter/Debug.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Formatter/Expanded.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Formatter/Nested.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Formatter/OutputBlock.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/Parser.php delete mode 100644 framework/library/vendor/scssphp/scssphp/src/SourceMap/SourceMapGenerator.php diff --git a/framework/library/composer.lock b/framework/library/composer.lock index 30344c6c..7814c19f 100644 --- a/framework/library/composer.lock +++ b/framework/library/composer.lock @@ -8,33 +8,38 @@ "packages": [ { "name": "league/uri", - "version": "7.5.1", + "version": "7.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "81fb5145d2644324614cc532b28efd0215bda430" + "reference": "4436c6ec8d458e4244448b069cc572d088230b76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", - "reference": "81fb5145d2644324614cc532b28efd0215bda430", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/4436c6ec8d458e4244448b069cc572d088230b76", + "reference": "4436c6ec8d458e4244448b069cc572d088230b76", "shasum": "" }, "require": { - "league/uri-interfaces": "^7.5", - "php": "^8.1" + "league/uri-interfaces": "^7.8", + "php": "^8.1", + "psr/http-factory": "^1" }, "conflict": { "league/uri-schemes": "^1.0" }, "suggest": { "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", "ext-fileinfo": "to create Data URI from file contennts", "ext-gmp": "to improve IPV4 host parsing", "ext-intl": "to handle IDN host with the best performance", - "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", - "league/uri-components": "Needed to easily manipulate URI objects components", + "ext-uri": "to use the PHP native URI class", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", @@ -62,6 +67,7 @@ "description": "URI manipulation library", "homepage": "https://uri.thephpleague.com", "keywords": [ + "URN", "data-uri", "file-uri", "ftp", @@ -74,9 +80,11 @@ "psr-7", "query-string", "querystring", + "rfc2141", "rfc3986", "rfc3987", "rfc6570", + "rfc8141", "uri", "uri-template", "url", @@ -86,7 +94,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.5.1" + "source": "https://github.com/thephpleague/uri/tree/7.8.0" }, "funding": [ { @@ -94,26 +102,25 @@ "type": "github" } ], - "time": "2024-12-08T08:40:02+00:00" + "time": "2026-01-14T17:24:56+00:00" }, { "name": "league/uri-interfaces", - "version": "7.5.0", + "version": "7.8.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" + "reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/c5c5cd056110fc8afaba29fa6b72a43ced42acd4", + "reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4", "shasum": "" }, "require": { "ext-filter": "*", "php": "^8.1", - "psr/http-factory": "^1", "psr/http-message": "^1.1 || ^2.0" }, "suggest": { @@ -121,6 +128,7 @@ "ext-gmp": "to improve IPV4 host parsing", "ext-intl": "to handle IDN host with the best performance", "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, "type": "library", @@ -145,7 +153,7 @@ "homepage": "https://nyamsprod.com" } ], - "description": "Common interfaces and classes for URI representation and interaction", + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", "homepage": "https://uri.thephpleague.com", "keywords": [ "data-uri", @@ -170,7 +178,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.0" }, "funding": [ { @@ -178,7 +186,7 @@ "type": "github" } ], - "time": "2024-12-08T08:18:47+00:00" + "time": "2026-01-15T06:54:53+00:00" }, { "name": "matthiasmullie/minify", @@ -305,16 +313,16 @@ }, { "name": "phenx/php-font-lib", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/dompdf/php-font-lib.git", - "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d" + "reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", - "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a6e9a688a2a80016ac080b97be73d3e10c444c9a", + "reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a", "shasum": "" }, "require": { @@ -322,7 +330,7 @@ "php": "^7.1 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6" + "phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11 || ^12" }, "type": "library", "autoload": { @@ -344,9 +352,9 @@ "homepage": "https://github.com/dompdf/php-font-lib", "support": { "issues": "https://github.com/dompdf/php-font-lib/issues", - "source": "https://github.com/dompdf/php-font-lib/tree/1.0.1" + "source": "https://github.com/dompdf/php-font-lib/tree/1.0.2" }, - "time": "2024-12-02T14:37:59+00:00" + "time": "2026-01-20T14:10:26+00:00" }, { "name": "psr/http-factory", @@ -458,50 +466,45 @@ }, { "name": "scssphp/scssphp", - "version": "v2.0.1", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/scssphp/scssphp.git", - "reference": "024f92cd9782e3033b41c2d1c66ab1c0e5c12c0f" + "reference": "d8450c2baf5fb07d00374999d0ea51276974d1b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scssphp/scssphp/zipball/024f92cd9782e3033b41c2d1c66ab1c0e5c12c0f", - "reference": "024f92cd9782e3033b41c2d1c66ab1c0e5c12c0f", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/d8450c2baf5fb07d00374999d0ea51276974d1b6", + "reference": "d8450c2baf5fb07d00374999d0ea51276974d1b6", "shasum": "" }, "require": { "ext-ctype": "*", "ext-json": "*", - "league/uri": "^7.4", - "league/uri-interfaces": "^7.4", + "ext-mbstring": "*", + "league/uri": "^7.6", + "league/uri-interfaces": "^7.6", "php": ">=8.1", - "scssphp/source-span": "^1.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", - "symfony/polyfill-mbstring": "^1.30" + "scssphp/source-span": "^1.1", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4", + "jgthms/bulma": "~0.9.4", + "jiripudil/phpstan-sealed-classes": "^1.3", + "phpstan/phpstan": "^2.1.31", + "phpstan/phpstan-deprecation-rules": "^2.0", "phpunit/phpunit": "^9.5.6", "sass/sass-spec": "*", - "squizlabs/php_codesniffer": "~3.5", - "symfony/phpunit-bridge": "^5.1", - "symfony/var-dumper": "^6.3", + "squizlabs/php_codesniffer": "^3.13", + "symfony/phpunit-bridge": "^7.3 || ^8.0", + "symfony/polyfill-php84": "^1.33", + "symfony/var-dumper": "^6.4 || ^7.3 || ^8.0", "thoughtbot/bourbon": "^7.0", - "twbs/bootstrap": "~5.0", + "twbs/bootstrap": "^5.3", "twbs/bootstrap4": "4.6.1", "zurb/foundation": "~6.7.0" }, - "suggest": { - "ext-mbstring": "For best performance, mbstring should be installed as it is faster than the polyfill" - }, "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": false, - "forward-command": false - } - }, "autoload": { "psr-4": { "ScssPhp\\ScssPhp\\": "src/" @@ -524,7 +527,7 @@ } ], "description": "scssphp is a compiler for SCSS written in PHP.", - "homepage": "http://scssphp.github.io/scssphp/", + "homepage": "https://scssphp.github.io/scssphp/", "keywords": [ "css", "less", @@ -534,27 +537,28 @@ ], "support": { "issues": "https://github.com/scssphp/scssphp/issues", - "source": "https://github.com/scssphp/scssphp/tree/v2.0.1" + "source": "https://github.com/scssphp/scssphp/tree/v2.1.0" }, - "time": "2025-01-31T12:28:20+00:00" + "time": "2025-11-21T17:27:59+00:00" }, { "name": "scssphp/source-span", - "version": "v1.0.0", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/scssphp/source-span.git", - "reference": "f08fc78765e6fb6fa8ca0573fc61b3f8860f0114" + "reference": "37d653206daf11da1ee60b333984101bc4c27ba2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scssphp/source-span/zipball/f08fc78765e6fb6fa8ca0573fc61b3f8860f0114", - "reference": "f08fc78765e6fb6fa8ca0573fc61b3f8860f0114", + "url": "https://api.github.com/repos/scssphp/source-span/zipball/37d653206daf11da1ee60b333984101bc4c27ba2", + "reference": "37d653206daf11da1ee60b333984101bc4c27ba2", "shasum": "" }, "require": { - "league/uri": "^7.4", - "league/uri-interfaces": "^7.4", + "ext-mbstring": "*", + "league/uri": "^7.6", + "league/uri-interfaces": "^7.6", "php": ">=8.1" }, "require-dev": { @@ -562,8 +566,8 @@ "phpstan/phpstan-deprecation-rules": "^2.0", "phpunit/phpunit": "^9.5.6", "squizlabs/php_codesniffer": "~3.5", - "symfony/phpunit-bridge": "^5.1", - "symfony/var-dumper": "^6.3" + "symfony/phpunit-bridge": "^6.4 || ^7.3 || ^8.0", + "symfony/var-dumper": "^6.4 || ^7.3 || ^8.0" }, "type": "library", "extra": { @@ -592,31 +596,31 @@ ], "support": { "issues": "https://github.com/scssphp/source-span/issues", - "source": "https://github.com/scssphp/source-span/tree/v1.0.0" + "source": "https://github.com/scssphp/source-span/tree/v1.1.0" }, - "time": "2024-12-09T23:08:15+00:00" + "time": "2025-11-21T16:28:19+00:00" }, { "name": "symfony/filesystem", - "version": "v7.3.2", + "version": "v8.0.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd" + "reference": "d937d400b980523dc9ee946bb69972b5e619058d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd", - "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/d937d400b980523dc9ee946bb69972b5e619058d", + "reference": "d937d400b980523dc9ee946bb69972b5e619058d", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^6.4|^7.0" + "symfony/process": "^7.4|^8.0" }, "type": "library", "autoload": { @@ -644,7 +648,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.3.2" + "source": "https://github.com/symfony/filesystem/tree/v8.0.1" }, "funding": [ { @@ -664,7 +668,7 @@ "type": "tidelift" } ], - "time": "2025-07-07T08:17:47+00:00" + "time": "2025-12-01T09:13:36+00:00" }, { "name": "symfony/polyfill-ctype", diff --git a/framework/library/vendor/composer/autoload_files.php b/framework/library/vendor/composer/autoload_files.php index aae6c427..c64234b5 100644 --- a/framework/library/vendor/composer/autoload_files.php +++ b/framework/library/vendor/composer/autoload_files.php @@ -6,6 +6,6 @@ $baseDir = dirname($vendorDir); return array( - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => $vendorDir . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => $vendorDir . '/symfony/polyfill-mbstring/bootstrap.php', ); diff --git a/framework/library/vendor/composer/autoload_static.php b/framework/library/vendor/composer/autoload_static.php index 16b05ecc..ba70abb6 100644 --- a/framework/library/vendor/composer/autoload_static.php +++ b/framework/library/vendor/composer/autoload_static.php @@ -7,8 +7,8 @@ class ComposerStaticInita7f239344f0f7f935f9220eec1fb9c70 { public static $files = array ( - '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', '320cde22f66dd4f5d3fd621d3e88b98f' => __DIR__ . '/..' . '/symfony/polyfill-ctype/bootstrap.php', + '0e6d7bf4a5811bfa5cf40c5ccd6fae6a' => __DIR__ . '/..' . '/symfony/polyfill-mbstring/bootstrap.php', ); public static $prefixLengthsPsr4 = array ( diff --git a/framework/library/vendor/composer/installed.json b/framework/library/vendor/composer/installed.json index dd44722b..8c2f7155 100644 --- a/framework/library/vendor/composer/installed.json +++ b/framework/library/vendor/composer/installed.json @@ -2,37 +2,42 @@ "packages": [ { "name": "league/uri", - "version": "7.5.1", - "version_normalized": "7.5.1.0", + "version": "7.8.0", + "version_normalized": "7.8.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri.git", - "reference": "81fb5145d2644324614cc532b28efd0215bda430" + "reference": "4436c6ec8d458e4244448b069cc572d088230b76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", - "reference": "81fb5145d2644324614cc532b28efd0215bda430", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/4436c6ec8d458e4244448b069cc572d088230b76", + "reference": "4436c6ec8d458e4244448b069cc572d088230b76", "shasum": "" }, "require": { - "league/uri-interfaces": "^7.5", - "php": "^8.1" + "league/uri-interfaces": "^7.8", + "php": "^8.1", + "psr/http-factory": "^1" }, "conflict": { "league/uri-schemes": "^1.0" }, "suggest": { "ext-bcmath": "to improve IPV4 host parsing", + "ext-dom": "to convert the URI into an HTML anchor tag", "ext-fileinfo": "to create Data URI from file contennts", "ext-gmp": "to improve IPV4 host parsing", "ext-intl": "to handle IDN host with the best performance", - "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", - "league/uri-components": "Needed to easily manipulate URI objects components", + "ext-uri": "to use the PHP native URI class", + "jeremykendall/php-domain-parser": "to further parse the URI host and resolve its Public Suffix and Top Level Domain", + "league/uri-components": "to provide additional tools to manipulate URI objects components", + "league/uri-polyfill": "to backport the PHP URI extension for older versions of PHP", "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, - "time": "2024-12-08T08:40:02+00:00", + "time": "2026-01-14T17:24:56+00:00", "type": "library", "extra": { "branch-alias": { @@ -59,6 +64,7 @@ "description": "URI manipulation library", "homepage": "https://uri.thephpleague.com", "keywords": [ + "URN", "data-uri", "file-uri", "ftp", @@ -71,9 +77,11 @@ "psr-7", "query-string", "querystring", + "rfc2141", "rfc3986", "rfc3987", "rfc6570", + "rfc8141", "uri", "uri-template", "url", @@ -83,7 +91,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri/tree/7.5.1" + "source": "https://github.com/thephpleague/uri/tree/7.8.0" }, "funding": [ { @@ -95,23 +103,22 @@ }, { "name": "league/uri-interfaces", - "version": "7.5.0", - "version_normalized": "7.5.0.0", + "version": "7.8.0", + "version_normalized": "7.8.0.0", "source": { "type": "git", "url": "https://github.com/thephpleague/uri-interfaces.git", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" + "reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", - "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/c5c5cd056110fc8afaba29fa6b72a43ced42acd4", + "reference": "c5c5cd056110fc8afaba29fa6b72a43ced42acd4", "shasum": "" }, "require": { "ext-filter": "*", "php": "^8.1", - "psr/http-factory": "^1", "psr/http-message": "^1.1 || ^2.0" }, "suggest": { @@ -119,9 +126,10 @@ "ext-gmp": "to improve IPV4 host parsing", "ext-intl": "to handle IDN host with the best performance", "php-64bit": "to improve IPV4 host parsing", + "rowbot/url": "to handle URLs using the WHATWG URL Living Standard specification", "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" }, - "time": "2024-12-08T08:18:47+00:00", + "time": "2026-01-15T06:54:53+00:00", "type": "library", "extra": { "branch-alias": { @@ -145,7 +153,7 @@ "homepage": "https://nyamsprod.com" } ], - "description": "Common interfaces and classes for URI representation and interaction", + "description": "Common tools for parsing and resolving RFC3987/RFC3986 URI", "homepage": "https://uri.thephpleague.com", "keywords": [ "data-uri", @@ -170,7 +178,7 @@ "docs": "https://uri.thephpleague.com", "forum": "https://thephpleague.slack.com", "issues": "https://github.com/thephpleague/uri-src/issues", - "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.8.0" }, "funding": [ { @@ -307,17 +315,17 @@ }, { "name": "phenx/php-font-lib", - "version": "1.0.1", - "version_normalized": "1.0.1.0", + "version": "1.0.2", + "version_normalized": "1.0.2.0", "source": { "type": "git", "url": "https://github.com/dompdf/php-font-lib.git", - "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d" + "reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", - "reference": "6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d", + "url": "https://api.github.com/repos/dompdf/php-font-lib/zipball/a6e9a688a2a80016ac080b97be73d3e10c444c9a", + "reference": "a6e9a688a2a80016ac080b97be73d3e10c444c9a", "shasum": "" }, "require": { @@ -325,9 +333,9 @@ "php": "^7.1 || ^8.0" }, "require-dev": { - "symfony/phpunit-bridge": "^3 || ^4 || ^5 || ^6" + "phpunit/phpunit": "^7.5 || ^8 || ^9 || ^10 || ^11 || ^12" }, - "time": "2024-12-02T14:37:59+00:00", + "time": "2026-01-20T14:10:26+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -349,7 +357,7 @@ "homepage": "https://github.com/dompdf/php-font-lib", "support": { "issues": "https://github.com/dompdf/php-font-lib/issues", - "source": "https://github.com/dompdf/php-font-lib/tree/1.0.1" + "source": "https://github.com/dompdf/php-font-lib/tree/1.0.2" }, "install-path": "../phenx/php-font-lib" }, @@ -469,52 +477,47 @@ }, { "name": "scssphp/scssphp", - "version": "v2.0.1", - "version_normalized": "2.0.1.0", + "version": "v2.1.0", + "version_normalized": "2.1.0.0", "source": { "type": "git", "url": "https://github.com/scssphp/scssphp.git", - "reference": "024f92cd9782e3033b41c2d1c66ab1c0e5c12c0f" + "reference": "d8450c2baf5fb07d00374999d0ea51276974d1b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scssphp/scssphp/zipball/024f92cd9782e3033b41c2d1c66ab1c0e5c12c0f", - "reference": "024f92cd9782e3033b41c2d1c66ab1c0e5c12c0f", + "url": "https://api.github.com/repos/scssphp/scssphp/zipball/d8450c2baf5fb07d00374999d0ea51276974d1b6", + "reference": "d8450c2baf5fb07d00374999d0ea51276974d1b6", "shasum": "" }, "require": { "ext-ctype": "*", "ext-json": "*", - "league/uri": "^7.4", - "league/uri-interfaces": "^7.4", + "ext-mbstring": "*", + "league/uri": "^7.6", + "league/uri-interfaces": "^7.6", "php": ">=8.1", - "scssphp/source-span": "^1.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", - "symfony/polyfill-mbstring": "^1.30" + "scssphp/source-span": "^1.1", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4", + "jgthms/bulma": "~0.9.4", + "jiripudil/phpstan-sealed-classes": "^1.3", + "phpstan/phpstan": "^2.1.31", + "phpstan/phpstan-deprecation-rules": "^2.0", "phpunit/phpunit": "^9.5.6", "sass/sass-spec": "*", - "squizlabs/php_codesniffer": "~3.5", - "symfony/phpunit-bridge": "^5.1", - "symfony/var-dumper": "^6.3", + "squizlabs/php_codesniffer": "^3.13", + "symfony/phpunit-bridge": "^7.3 || ^8.0", + "symfony/polyfill-php84": "^1.33", + "symfony/var-dumper": "^6.4 || ^7.3 || ^8.0", "thoughtbot/bourbon": "^7.0", - "twbs/bootstrap": "~5.0", + "twbs/bootstrap": "^5.3", "twbs/bootstrap4": "4.6.1", "zurb/foundation": "~6.7.0" }, - "suggest": { - "ext-mbstring": "For best performance, mbstring should be installed as it is faster than the polyfill" - }, - "time": "2025-01-31T12:28:20+00:00", + "time": "2025-11-21T17:27:59+00:00", "type": "library", - "extra": { - "bamarni-bin": { - "bin-links": false, - "forward-command": false - } - }, "installation-source": "dist", "autoload": { "psr-4": { @@ -538,7 +541,7 @@ } ], "description": "scssphp is a compiler for SCSS written in PHP.", - "homepage": "http://scssphp.github.io/scssphp/", + "homepage": "https://scssphp.github.io/scssphp/", "keywords": [ "css", "less", @@ -548,28 +551,29 @@ ], "support": { "issues": "https://github.com/scssphp/scssphp/issues", - "source": "https://github.com/scssphp/scssphp/tree/v2.0.1" + "source": "https://github.com/scssphp/scssphp/tree/v2.1.0" }, "install-path": "../scssphp/scssphp" }, { "name": "scssphp/source-span", - "version": "v1.0.0", - "version_normalized": "1.0.0.0", + "version": "v1.1.0", + "version_normalized": "1.1.0.0", "source": { "type": "git", "url": "https://github.com/scssphp/source-span.git", - "reference": "f08fc78765e6fb6fa8ca0573fc61b3f8860f0114" + "reference": "37d653206daf11da1ee60b333984101bc4c27ba2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/scssphp/source-span/zipball/f08fc78765e6fb6fa8ca0573fc61b3f8860f0114", - "reference": "f08fc78765e6fb6fa8ca0573fc61b3f8860f0114", + "url": "https://api.github.com/repos/scssphp/source-span/zipball/37d653206daf11da1ee60b333984101bc4c27ba2", + "reference": "37d653206daf11da1ee60b333984101bc4c27ba2", "shasum": "" }, "require": { - "league/uri": "^7.4", - "league/uri-interfaces": "^7.4", + "ext-mbstring": "*", + "league/uri": "^7.6", + "league/uri-interfaces": "^7.6", "php": ">=8.1" }, "require-dev": { @@ -577,10 +581,10 @@ "phpstan/phpstan-deprecation-rules": "^2.0", "phpunit/phpunit": "^9.5.6", "squizlabs/php_codesniffer": "~3.5", - "symfony/phpunit-bridge": "^5.1", - "symfony/var-dumper": "^6.3" + "symfony/phpunit-bridge": "^6.4 || ^7.3 || ^8.0", + "symfony/var-dumper": "^6.4 || ^7.3 || ^8.0" }, - "time": "2024-12-09T23:08:15+00:00", + "time": "2025-11-21T16:28:19+00:00", "type": "library", "extra": { "branch-alias": { @@ -609,34 +613,34 @@ ], "support": { "issues": "https://github.com/scssphp/source-span/issues", - "source": "https://github.com/scssphp/source-span/tree/v1.0.0" + "source": "https://github.com/scssphp/source-span/tree/v1.1.0" }, "install-path": "../scssphp/source-span" }, { "name": "symfony/filesystem", - "version": "v7.3.2", - "version_normalized": "7.3.2.0", + "version": "v8.0.1", + "version_normalized": "8.0.1.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd" + "reference": "d937d400b980523dc9ee946bb69972b5e619058d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/edcbb768a186b5c3f25d0643159a787d3e63b7fd", - "reference": "edcbb768a186b5c3f25d0643159a787d3e63b7fd", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/d937d400b980523dc9ee946bb69972b5e619058d", + "reference": "d937d400b980523dc9ee946bb69972b5e619058d", "shasum": "" }, "require": { - "php": ">=8.2", + "php": ">=8.4", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, "require-dev": { - "symfony/process": "^6.4|^7.0" + "symfony/process": "^7.4|^8.0" }, - "time": "2025-07-07T08:17:47+00:00", + "time": "2025-12-01T09:13:36+00:00", "type": "library", "installation-source": "dist", "autoload": { @@ -664,7 +668,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.3.2" + "source": "https://github.com/symfony/filesystem/tree/v8.0.1" }, "funding": [ { diff --git a/framework/library/vendor/composer/installed.php b/framework/library/vendor/composer/installed.php index b28bae53..e5d462b8 100644 --- a/framework/library/vendor/composer/installed.php +++ b/framework/library/vendor/composer/installed.php @@ -20,18 +20,18 @@ 'dev_requirement' => false, ), 'league/uri' => array( - 'pretty_version' => '7.5.1', - 'version' => '7.5.1.0', - 'reference' => '81fb5145d2644324614cc532b28efd0215bda430', + 'pretty_version' => '7.8.0', + 'version' => '7.8.0.0', + 'reference' => '4436c6ec8d458e4244448b069cc572d088230b76', 'type' => 'library', 'install_path' => __DIR__ . '/../league/uri', 'aliases' => array(), 'dev_requirement' => false, ), 'league/uri-interfaces' => array( - 'pretty_version' => '7.5.0', - 'version' => '7.5.0.0', - 'reference' => '08cfc6c4f3d811584fb09c37e2849e6a7f9b0742', + 'pretty_version' => '7.8.0', + 'version' => '7.8.0.0', + 'reference' => 'c5c5cd056110fc8afaba29fa6b72a43ced42acd4', 'type' => 'library', 'install_path' => __DIR__ . '/../league/uri-interfaces', 'aliases' => array(), @@ -56,9 +56,9 @@ 'dev_requirement' => false, ), 'phenx/php-font-lib' => array( - 'pretty_version' => '1.0.1', - 'version' => '1.0.1.0', - 'reference' => '6137b7d4232b7f16c882c75e4ca3991dbcf6fe2d', + 'pretty_version' => '1.0.2', + 'version' => '1.0.2.0', + 'reference' => 'a6e9a688a2a80016ac080b97be73d3e10c444c9a', 'type' => 'library', 'install_path' => __DIR__ . '/../phenx/php-font-lib', 'aliases' => array(), @@ -83,27 +83,27 @@ 'dev_requirement' => false, ), 'scssphp/scssphp' => array( - 'pretty_version' => 'v2.0.1', - 'version' => '2.0.1.0', - 'reference' => '024f92cd9782e3033b41c2d1c66ab1c0e5c12c0f', + 'pretty_version' => 'v2.1.0', + 'version' => '2.1.0.0', + 'reference' => 'd8450c2baf5fb07d00374999d0ea51276974d1b6', 'type' => 'library', 'install_path' => __DIR__ . '/../scssphp/scssphp', 'aliases' => array(), 'dev_requirement' => false, ), 'scssphp/source-span' => array( - 'pretty_version' => 'v1.0.0', - 'version' => '1.0.0.0', - 'reference' => 'f08fc78765e6fb6fa8ca0573fc61b3f8860f0114', + 'pretty_version' => 'v1.1.0', + 'version' => '1.1.0.0', + 'reference' => '37d653206daf11da1ee60b333984101bc4c27ba2', 'type' => 'library', 'install_path' => __DIR__ . '/../scssphp/source-span', 'aliases' => array(), 'dev_requirement' => false, ), 'symfony/filesystem' => array( - 'pretty_version' => 'v7.3.2', - 'version' => '7.3.2.0', - 'reference' => 'edcbb768a186b5c3f25d0643159a787d3e63b7fd', + 'pretty_version' => 'v8.0.1', + 'version' => '8.0.1.0', + 'reference' => 'd937d400b980523dc9ee946bb69972b5e619058d', 'type' => 'library', 'install_path' => __DIR__ . '/../symfony/filesystem', 'aliases' => array(), diff --git a/framework/library/vendor/composer/platform_check.php b/framework/library/vendor/composer/platform_check.php index d32d90c6..da85af87 100644 --- a/framework/library/vendor/composer/platform_check.php +++ b/framework/library/vendor/composer/platform_check.php @@ -4,8 +4,8 @@ $issues = array(); -if (!(PHP_VERSION_ID >= 80200)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 8.2.0". You are running ' . PHP_VERSION . '.'; +if (!(PHP_VERSION_ID >= 80400)) { + $issues[] = 'Your Composer dependencies require a PHP version ">= 8.4.0". You are running ' . PHP_VERSION . '.'; } if ($issues) { diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/Conditionable.php b/framework/library/vendor/league/uri-interfaces/Contracts/Conditionable.php new file mode 100644 index 00000000..385a78cc --- /dev/null +++ b/framework/library/vendor/league/uri-interfaces/Contracts/Conditionable.php @@ -0,0 +1,26 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +interface Conditionable +{ + /** + * Apply the callback if the given "condition" is (or resolves to) true. + * + * @param (callable(static): bool)|bool $condition + * @param callable(static): (static|null) $onSuccess + * @param ?callable(static): (static|null) $onFail + */ + public function when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null): static; +} diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/DomainHostInterface.php b/framework/library/vendor/league/uri-interfaces/Contracts/DomainHostInterface.php index 66758044..a2f1745f 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/DomainHostInterface.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/DomainHostInterface.php @@ -13,6 +13,7 @@ namespace League\Uri\Contracts; +use BackedEnum; use Countable; use Iterator; use IteratorAggregate; @@ -20,7 +21,14 @@ use Stringable; /** - * @extends IteratorAggregate + * @extends IteratorAggregate + * + * @method bool isSubdomainOf(BackedEnum|Stringable|string|null $parentHost) Tells whether the current domain instance is a subdomain of the parent host. + * @method bool hasSubdomain(BackedEnum|Stringable|string|null $childHost) Tells whether the submitted host is a subdomain of the current instance. + * @method bool isSiblingOf(BackedEnum|Stringable|string|null $siblingHost) Tells whether the submitted host share the same parent domain as the current instance. + * @method static commonAncestorWith(BackedEnum|Stringable|string|null $other) Returns the common longest ancestor between 2 domain. The returned domain is empty if no ancestor is found + * @method static parentHost() Returns the current parent domain for the current instance. The returned domain is empty if no ancestor is found + * @method bool isEmpty() Tells whether the domain contains any label. */ interface DomainHostInterface extends Countable, HostInterface, IteratorAggregate { diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/FragmentDirective.php b/framework/library/vendor/league/uri-interfaces/Contracts/FragmentDirective.php new file mode 100644 index 00000000..e85471c4 --- /dev/null +++ b/framework/library/vendor/league/uri-interfaces/Contracts/FragmentDirective.php @@ -0,0 +1,55 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +use Stringable; + +/** + * @see https://wicg.github.io/scroll-to-text-fragment/#the-fragment-directive + * + * @method string toFragmentValue() returns the encoded string representation of the directive as a fragment string + */ +interface FragmentDirective extends Stringable +{ + /** + * The decoded Directive name. + * + * @return non-empty-string + */ + public function name(): string; + + /** + * The decoded Directive value. + */ + public function value(): ?string; + + /** + * The encoded string representation of the directive. + */ + public function toString(): string; + + /** + * The encoded string representation of the fragment using + * the Stringable interface. + * + * @see FragmentDirective::toString() + */ + public function __toString(): string; + + /** + * Tells whether the submitted value is equals to the string + * representation of the given directive. + */ + public function equals(mixed $directive): bool; +} diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/FragmentInterface.php b/framework/library/vendor/league/uri-interfaces/Contracts/FragmentInterface.php index 3d80f066..440a0874 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/FragmentInterface.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/FragmentInterface.php @@ -13,6 +13,9 @@ namespace League\Uri\Contracts; +/** + * @method self normalize() returns the normalized string representation of the component + */ interface FragmentInterface extends UriComponentInterface { /** diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/HostInterface.php b/framework/library/vendor/league/uri-interfaces/Contracts/HostInterface.php index 16212bfe..48d8abea 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/HostInterface.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/HostInterface.php @@ -13,6 +13,9 @@ namespace League\Uri\Contracts; +/** + * @method string|null encoded() returns RFC3986 encoded host + */ interface HostInterface extends UriComponentInterface { /** diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/PathInterface.php b/framework/library/vendor/league/uri-interfaces/Contracts/PathInterface.php index f99b7627..1408eeca 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/PathInterface.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/PathInterface.php @@ -15,6 +15,9 @@ use League\Uri\Exceptions\SyntaxError; +/** + * @method static normalize() returns the normalized string representation of the component + */ interface PathInterface extends UriComponentInterface { /** diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/QueryInterface.php b/framework/library/vendor/league/uri-interfaces/Contracts/QueryInterface.php index fed486e3..1b2ac33f 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/QueryInterface.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/QueryInterface.php @@ -13,21 +13,40 @@ namespace League\Uri\Contracts; +use BackedEnum; use Countable; use Deprecated; use Iterator; use IteratorAggregate; +use League\Uri\QueryComposeMode; +use League\Uri\StringCoercionMode; use Stringable; /** * @extends IteratorAggregate * + * @method string|null toFormData() Returns the string representation using the application/www-form-urlencoded rules + * @method string|null toRFC3986() Returns the string representation using RFC3986 rules + * @method string|null first(string $key) Returns the first value associated with the given name + * @method string|null last(string $key) Returns the first value associated with the given name + * @method int|null indexOf(string $key, int $nth = 0) Returns the offset of the pair based on its key and its nth occurrence; negative occurrences are supported + * @method int|null indexOfValue(?string $value, int $nth = 0) Returns the offset of the pair based on its value and its nth occurrence; negative occurrences are supported + * @method array pair(int $offset) Returns the key/value pair at the given numeric offset; negative occurrences are supported + * @method int countDistinctKeys() Returns the total number of distinct keys + * @method string|null valueAt(int $offset): Returns the value at the given numeric offset; negative occurrences are supported + * @method string keyAt(int $offset): Returns the key at the given numeric offset; negative occurrences are supported + * @method self normalize() returns the normalized string representation of the component * @method self withoutPairByKey(string ...$keys) Returns an instance without pairs with the specified keys. - * @method self withoutPairByValue(Stringable|string|int|bool|null ...$values) Returns an instance without pairs with the specified values. - * @method self withoutPairByKeyValue(string $key, Stringable|string|int|bool|null $value) Returns an instance without pairs with the specified key/value pair + * @method self withoutPairByValue(array|BackedEnum|Stringable|string|int|bool|null $values, StringCoercionMode $coercionMode = StringCoercionMode::Native) Returns an instance without pairs with the specified values. + * @method self withoutPairByKeyValue(string $key, BackedEnum|Stringable|string|int|bool|null $value, StringCoercionMode $coercionMode = StringCoercionMode::Native) Returns an instance without pairs with the specified key/value pair * @method bool hasPair(string $key, ?string $value) Tells whether the pair exists in the query. - * @method ?string toFormData() Returns the string representation using the applicat/www-form-urlencoded rules - * @method ?string toRFC3986() Returns the string representation using RFC3986 rules + * @method array getList(string $name) Returns the list associated with the given name or an empty array if it does not exist. + * @method bool hasList(string ...$names) Tells whether the parameter list exists in the query. + * @method self appendList(string $name, array $values, QueryComposeMode $composeMode = QueryComposeMode::Native) Appends a parameter to the query string + * @method self withList(string $name, array $values, QueryComposeMode $composeMode = QueryComposeMode::Native) Adds a new parameter to the query string and remove any previously set values + * @method self withoutList(string ...$names) Removes any given list associated with the given names + * @method self withoutLists() Removes all lists from the query string + * @method self onlyLists() Removes all pairs without a valid PHP's bracket notation */ interface QueryInterface extends Countable, IteratorAggregate, UriComponentInterface { diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/SegmentedPathInterface.php b/framework/library/vendor/league/uri-interfaces/Contracts/SegmentedPathInterface.php index fa5a78d2..87355f4c 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/SegmentedPathInterface.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/SegmentedPathInterface.php @@ -71,7 +71,7 @@ public function keys(Stringable|string|null $segment = null): array; /** * Appends a segment to the path. */ - public function append(Stringable|string $segment): self; + public function append(Stringable|string $path): self; /** * Extracts a slice of $length elements starting at position $offset from the host. @@ -86,7 +86,7 @@ public function slice(int $offset, ?int $length = null): self; /** * Prepends a segment to the path. */ - public function prepend(Stringable|string $segment): self; + public function prepend(Stringable|string $path): self; /** * Returns an instance with the modified segment. diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/Transformable.php b/framework/library/vendor/league/uri-interfaces/Contracts/Transformable.php new file mode 100644 index 00000000..957fa50f --- /dev/null +++ b/framework/library/vendor/league/uri-interfaces/Contracts/Transformable.php @@ -0,0 +1,27 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri\Contracts; + +interface Transformable +{ + /** + * Apply a transformation to this instance and return a new instance. + * + * This method MUST retain the state of the current instance, and return + * a new instance of the same type. + * + * @param callable(static): static $callback + */ + public function transform(callable $callback): static; +} diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/UriAccess.php b/framework/library/vendor/league/uri-interfaces/Contracts/UriAccess.php index 7c37cdad..a74da577 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/UriAccess.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/UriAccess.php @@ -15,6 +15,9 @@ use Psr\Http\Message\UriInterface as Psr7UriInterface; +/** + * @deprecated since version 7.6.0 + */ interface UriAccess { public function getUri(): UriInterface|Psr7UriInterface; diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/UriComponentInterface.php b/framework/library/vendor/league/uri-interfaces/Contracts/UriComponentInterface.php index e478516e..fa550aaf 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/UriComponentInterface.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/UriComponentInterface.php @@ -16,6 +16,10 @@ use JsonSerializable; use Stringable; +/** + * @method static when(callable|bool $condition, callable $onSuccess, ?callable $onFail = null) conditionally return a new instance + * @method bool equals(mixed $value) tells whether the submitted value is equal to the current instance value + */ interface UriComponentInterface extends JsonSerializable, Stringable { /** @@ -36,7 +40,7 @@ public function value(): ?string; * but MUST NOT double-encode any characters. To determine what characters * to encode, please refer to RFC 3986, Sections 2 and 3. * - * If the instance is not defined an empty string is returned + * If the instance is not defined, an empty string is returned */ public function toString(): string; @@ -47,7 +51,7 @@ public function toString(): string; * but MUST NOT double-encode any characters. To determine what characters * to encode, please refer to RFC 3986, Sections 2 and 3. * - * If the instance is not defined an empty string is returned + * If the instance is not defined, an empty string is returned */ public function __toString(): string; @@ -58,7 +62,7 @@ public function __toString(): string; * but MUST NOT double-encode any characters. To determine what characters * to encode, please refer to RFC 3986 or RFC 1738. * - * If the instance is not defined null is returned + * If the instance is not defined, null is returned */ public function jsonSerialize(): ?string; @@ -69,7 +73,7 @@ public function jsonSerialize(): ?string; * characters. To determine what characters to encode, please refer to RFC 3986, * Sections 2 and 3. * - * If the instance is not defined an empty string is returned + * If the instance is not defined, an empty string is returned */ public function getUriComponent(): string; } diff --git a/framework/library/vendor/league/uri-interfaces/Contracts/UriInterface.php b/framework/library/vendor/league/uri-interfaces/Contracts/UriInterface.php index 1fde6b96..60e6c8e7 100644 --- a/framework/library/vendor/league/uri-interfaces/Contracts/UriInterface.php +++ b/framework/library/vendor/league/uri-interfaces/Contracts/UriInterface.php @@ -23,8 +23,15 @@ * @phpstan-import-type ComponentMap from UriString * * @method string|null getUsername() returns the user component of the URI. + * @method self withUsername(?string $user) returns a new URI instance with the user component updated. * @method string|null getPassword() returns the scheme-specific information about how to gain authorization to access the resource. + * @method self withPassword(?string $password) returns a new URI instance with the password component updated. + * @method string toAsciiString() returns the string representation of the URI in its RFC3986 form + * @method string toUnicodeString() returns the string representation of the URI in its RFC3987 form (the host is in its IDN form) * @method array toComponents() returns an associative array containing all the URI components. + * @method self normalize() returns a new URI instance with normalized components + * @method self resolve(UriInterface $uri) resolves a URI against a base URI using RFC3986 rules + * @method self relativize(UriInterface $uri) relativize a URI against a base URI using RFC3986 rules */ interface UriInterface extends JsonSerializable, Stringable { diff --git a/framework/library/vendor/league/uri-interfaces/Encoder.php b/framework/library/vendor/league/uri-interfaces/Encoder.php index 4324e03c..cbd3f2e6 100644 --- a/framework/library/vendor/league/uri-interfaces/Encoder.php +++ b/framework/library/vendor/league/uri-interfaces/Encoder.php @@ -13,18 +13,31 @@ namespace League\Uri; +use BackedEnum; use Closure; -use League\Uri\Contracts\UriComponentInterface; +use Deprecated; use League\Uri\Exceptions\SyntaxError; +use League\Uri\IPv6\Converter as IPv6Converter; use SensitiveParameter; use Stringable; +use Throwable; +use function explode; +use function filter_var; +use function gettype; +use function in_array; use function preg_match; use function preg_replace_callback; use function rawurldecode; use function rawurlencode; +use function sprintf; +use function str_starts_with; +use function strtolower; use function strtoupper; +use const FILTER_FLAG_IPV4; +use const FILTER_VALIDATE_IP; + final class Encoder { private const REGEXP_CHARS_INVALID = '/[\x00-\x1f\x7f]/'; @@ -41,16 +54,76 @@ final class Encoder private const REGEXP_PART_UNRESERVED = 'A-Za-z\d_\-.~'; private const REGEXP_PART_ENCODED = '%(?![A-Fa-f\d]{2})'; + /** + * Unreserved characters. + * + * @see https://www.rfc-editor.org/rfc/rfc3986.html#section-2.3 + */ + private const REGEXP_UNRESERVED_CHARACTERS = ',%(2[DdEe]|3[0-9]|4[1-9A-Fa-f]|5[AaFf]|6[1-9A-Fa-f]|7[0-9A-Ea-e]),'; + + /** + * Tell whether the user component is correctly encoded. + */ + public static function isUserEncoded(BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.']+|'.self::REGEXP_PART_ENCODED.'/'; + + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); + } + /** * Encode User. * * All generic delimiters MUST be encoded */ - public static function encodeUser(Stringable|string|null $component): ?string + public static function encodeUser(BackedEnum|Stringable|string|null $user): ?string { static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.']+|'.self::REGEXP_PART_ENCODED.'/'; - return self::encode($component, $pattern); + return self::encode($user, $pattern); + } + + /** + * Normalize user component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizeUser(BackedEnum|Stringable|string|null $user): ?string + { + return self::normalize(self::encodeUser(self::decodeUnreservedCharacters($user))); + } + + private static function normalize(?string $component): ?string + { + if (null === $component) { + return null; + } + + return (string) preg_replace_callback( + '/%[0-9a-f]{2}/i', + static fn (array $found) => strtoupper($found[0]), + $component + ); + } + + /** + * Tell whether the password component is correctly encoded. + */ + public static function isPasswordEncoded(#[SensitiveParameter] BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':]+|'.self::REGEXP_PART_ENCODED.'/'; + + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); } /** @@ -58,19 +131,146 @@ public static function encodeUser(Stringable|string|null $component): ?string * * Generic delimiters ":" MUST NOT be encoded */ - public static function encodePassword(#[SensitiveParameter] Stringable|string|null $component): ?string + public static function encodePassword(#[SensitiveParameter] BackedEnum|Stringable|string|null $component): ?string { static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':]+|'.self::REGEXP_PART_ENCODED.'/'; return self::encode($component, $pattern); } + /** + * Normalize password component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizePassword(#[SensitiveParameter] BackedEnum|Stringable|string|null $password): ?string + { + return self::normalize(self::encodePassword(self::decodeUnreservedCharacters($password))); + } + + /** + * Tell whether the userInfo component is correctly encoded. + */ + public static function isUserInfoEncoded(#[SensitiveParameter] BackedEnum|Stringable|string|null $userInfo): bool + { + if (null === $userInfo) { + return true; + } + + if ($userInfo instanceof BackedEnum) { + $userInfo = $userInfo->value; + } + + [$user, $password] = explode(':', (string) $userInfo, 2) + [1 => null]; + + return self::isUserEncoded($user) + && self::isPasswordEncoded($password); + } + + public static function encodeUserInfo(#[SensitiveParameter] BackedEnum|Stringable|string|null $userInfo): ?string + { + if (null === $userInfo) { + return null; + } + + if ($userInfo instanceof BackedEnum) { + $userInfo = $userInfo->value; + } + + [$user, $password] = explode(':', (string) $userInfo, 2) + [1 => null]; + $userInfo = self::encodeUser($user); + if (null === $password) { + return $userInfo; + } + + return $userInfo.':'.self::encodePassword($password); + } + + public static function normalizeUserInfo(#[SensitiveParameter] BackedEnum|Stringable|string|null $userInfo): ?string + { + if (null === $userInfo) { + return null; + } + + if ($userInfo instanceof BackedEnum) { + $userInfo = $userInfo->value; + } + + [$user, $password] = explode(':', (string) $userInfo, 2) + [1 => null]; + $userInfo = self::normalizeUser($user); + if (null === $password) { + return $userInfo; + } + + return $userInfo.':'.self::normalizePassword($password); + } + + /** + * Decodes all the URI component characters. + */ + public static function decodeAll(BackedEnum|Stringable|string|null $component): ?string + { + return self::decode($component, static fn (array $matches): string => rawurldecode($matches[0])); + } + + /** + * Decodes the URI component without decoding the unreserved characters which are already encoded. + */ + public static function decodeNecessary(BackedEnum|Stringable|string|int|null $component): ?string + { + $decoder = static function (array $matches): string { + if (1 === preg_match(self::REGEXP_CHARS_PREVENTS_DECODING, $matches[0])) { + return strtoupper($matches[0]); + } + + return rawurldecode($matches[0]); + }; + + return self::decode($component, $decoder); + } + + /** + * Decodes the component unreserved characters. + */ + public static function decodeUnreservedCharacters(BackedEnum|Stringable|string|null $str): ?string + { + if ($str instanceof BackedEnum) { + $str = $str->value; + } + + if (null === $str) { + return null; + } + + return preg_replace_callback( + self::REGEXP_UNRESERVED_CHARACTERS, + static fn (array $matches): string => rawurldecode($matches[0]), + (string) $str + ); + } + + /** + * Tell whether the path component is correctly encoded. + */ + public static function isPathEncoded(BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/]+|'.self::REGEXP_PART_ENCODED.'/'; + + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); + } + /** * Encode Path. * * Generic delimiters ":", "@", and "/" MUST NOT be encoded */ - public static function encodePath(Stringable|string|null $component): string + public static function encodePath(BackedEnum|Stringable|string|null $component): string { static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/]+|'.self::REGEXP_PART_ENCODED.'/'; @@ -78,99 +278,229 @@ public static function encodePath(Stringable|string|null $component): string } /** - * Encode Query or Fragment. + * Decodes the path component while preserving characters that should not be decoded in the context of a full valid URI. + */ + public static function decodePath(BackedEnum|Stringable|string|null $path): ?string + { + $decoder = static function (array $matches): string { + $encodedChar = strtoupper($matches[0]); + + return in_array($encodedChar, ['%2F', '%20', '%3F', '%23'], true) ? $encodedChar : rawurldecode($encodedChar); + }; + + return self::decode($path, $decoder); + } + + /** + * Normalize path component. * - * Generic delimiters ":", "@", "?", and "/" MUST NOT be encoded + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. */ - public static function encodeQueryOrFragment(Stringable|string|null $component): ?string + public static function normalizePath(BackedEnum|Stringable|string|null $component): ?string { - static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/?]+|'.self::REGEXP_PART_ENCODED.'/'; + return self::normalize(self::encodePath(self::decodePath($component))); + } - return self::encode($component, $pattern); + /** + * Tell whether the query component is correctly encoded. + */ + public static function isQueryEncoded(BackedEnum|Stringable|string|null $encoded): bool + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.'\/?%]+|'.self::REGEXP_PART_ENCODED.'/'; + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); } - public static function encodeQueryKeyValue(mixed $component): ?string + /** + * Decodes the query component while preserving characters that should not be decoded in the context of a full valid URI. + */ + public static function decodeQuery(BackedEnum|Stringable|string|null $path): ?string { - static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.']+|'.self::REGEXP_PART_ENCODED.'/'; + $decoder = static function (array $matches): string { + $encodedChar = strtoupper($matches[0]); - $encodeMatches = static fn (array $matches): string => match (1) { - preg_match('/[^'.self::REGEXP_PART_UNRESERVED.']/', rawurldecode($matches[0])) => rawurlencode($matches[0]), - default => $matches[0], + return in_array($encodedChar, ['%26', '%3D', '%20', '%23', '%3F'], true) ? $encodedChar : rawurldecode($encodedChar); }; - $component = self::filterComponent($component); + return self::decode($path, $decoder); + } - return match (true) { - !is_scalar($component) => throw new SyntaxError(sprintf('A pair key/value must be a scalar value `%s` given.', gettype($component))), - 1 === preg_match(self::REGEXP_CHARS_INVALID, $component) => rawurlencode($component), - 1 === preg_match($pattern, $component) => (string) preg_replace_callback($pattern, $encodeMatches(...), $component), - default => $component, - }; + /** + * Normalize the query component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizeQuery(BackedEnum|Stringable|string|null $query): ?string + { + return self::normalize(self::encodeQueryOrFragment(self::decodeQuery($query))); } /** - * Decodes the URI component without decoding the unreserved characters which are already encoded. + * Tell whether the query component is correctly encoded. */ - public static function decodePartial(Stringable|string|int|null $component): ?string + public static function isFragmentEncoded(BackedEnum|Stringable|string|null $encoded): bool { - $decodeMatches = static fn (array $matches): string => match (1) { - preg_match(self::REGEXP_CHARS_PREVENTS_DECODING, $matches[0]) => strtoupper($matches[0]), - default => rawurldecode($matches[0]), - }; + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/?%]|'.self::REGEXP_PART_ENCODED.'/'; - return self::decode($component, $decodeMatches); + if ($encoded instanceof BackedEnum) { + $encoded = $encoded->value; + } + + return null === $encoded || 1 !== preg_match($pattern, (string) $encoded); } /** - * Decodes all the URI component characters. + * Decodes the fragment component while preserving characters that should not be decoded in the context of a full valid URI. */ - public static function decodeAll(Stringable|string|int|null $component): ?string + public static function decodeFragment(BackedEnum|Stringable|string|null $path): ?string { - $decodeMatches = static fn (array $matches): string => rawurldecode($matches[0]); + return self::decode($path, static fn (array $matches): string => '%20' === $matches[0] ? $matches[0] : rawurldecode($matches[0])); + } - return self::decode($component, $decodeMatches); + /** + * Normalize the fragment component. + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizeFragment(BackedEnum|Stringable|string|null $fragment): ?string + { + return self::normalize(self::encodeQueryOrFragment(self::decodeFragment($fragment))); } - private static function filterComponent(mixed $component): ?string + /** + * Normalize the host component. + * + * @see https://www.rfc-editor.org/rfc/rfc3986.html#section-3.2.2 + * + * The value returned MUST be percent-encoded, but MUST NOT double-encode + * any characters. To determine what characters to encode, please refer to + * RFC 3986. + */ + public static function normalizeHost(BackedEnum|Stringable|string|null $host): ?string + { + if ($host instanceof BackedEnum) { + $host = (string) $host->value; + } + + if ($host instanceof Stringable) { + $host = (string) $host; + } + + if (null === $host || '' === $host || false !== filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) { + return $host; + } + + if (str_starts_with($host, '[')) { + return IPv6Converter::normalize($host); + } + + $host = strtolower($host); + + return (!str_contains($host, '%')) ? $host : preg_replace_callback( + '/%[a-f0-9]{2}/', + fn (array $matches) => 1 === preg_match('/%([0-7][0-9a-f])/', $matches[0]) ? rawurldecode($matches[0]) : strtoupper($matches[0]), + $host + ); + } + + /** + * Encode Query or Fragment. + * + * Generic delimiters ":", "@", "?", and "/" MUST NOT be encoded + */ + public static function encodeQueryOrFragment(BackedEnum|Stringable|string|null $component): ?string { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.self::REGEXP_PART_SUBDELIM.':@\/?]+|'.self::REGEXP_PART_ENCODED.'/'; + + return self::encode($component, $pattern); + } + + public static function encodeQueryKeyValue(mixed $component): ?string + { + static $pattern = '/[^'.self::REGEXP_PART_UNRESERVED.']+|'.self::REGEXP_PART_ENCODED.'/'; + $encoder = static fn (array $found): string => 1 === preg_match('/[^'.self::REGEXP_PART_UNRESERVED.']/', rawurldecode($found[0])) ? rawurlencode($found[0]) : $found[0]; + $filteredComponent = self::filterComponent($component); + return match (true) { - true === $component => '1', - false === $component => '0', - $component instanceof UriComponentInterface => $component->value(), - $component instanceof Stringable, - is_scalar($component) => (string) $component, - null === $component => null, - default => throw new SyntaxError(sprintf('The component must be a scalar value `%s` given.', gettype($component))), + null === $filteredComponent => throw new SyntaxError(sprintf('A pair key/value must be a scalar value `%s` given.', gettype($component))), + 1 === preg_match(self::REGEXP_CHARS_INVALID, $filteredComponent) => rawurlencode($filteredComponent), + default => (string) preg_replace_callback($pattern, $encoder, $filteredComponent), }; } - private static function encode(Stringable|string|int|bool|null $component, string $pattern): ?string + private static function filterComponent(mixed $component): ?string + { + try { + return StringCoercionMode::Native->coerce($component); + } catch (Throwable $exception) { + throw new SyntaxError( + sprintf('The component must be a scalar value `%s` given.', gettype($component)), + previous: $exception + ); + } + } + + /** + * Encodes the URI component characters using a regular expression to find which characters need encoding. + */ + private static function encode(BackedEnum|Stringable|string|int|bool|null $component, string $pattern): ?string { $component = self::filterComponent($component); - $encodeMatches = static fn (array $matches): string => match (1) { - preg_match('/[^'.self::REGEXP_PART_UNRESERVED.']/', rawurldecode($matches[0])) => rawurlencode($matches[0]), - default => $matches[0], - }; + if (null === $component || '' === $component) { + return $component; + } - return match (true) { - null === $component, - '' === $component => $component, - default => (string) preg_replace_callback($pattern, $encodeMatches(...), $component), - }; + return (string) preg_replace_callback( + $pattern, + static fn (array $found): string => 1 === preg_match('/[^'.self::REGEXP_PART_UNRESERVED.']/', rawurldecode($found[0])) ? rawurlencode($found[0]) : $found[0], + $component + ); } /** - * Decodes all the URI component characters. + * Decodes the URI component characters using a closure. */ - private static function decode(Stringable|string|int|null $component, Closure $decodeMatches): ?string + private static function decode(BackedEnum|Stringable|string|int|null $component, Closure $decoder): ?string { $component = self::filterComponent($component); + if (null === $component || '' === $component) { + return $component; + } - return match (true) { - null === $component => null, - 1 === preg_match(self::REGEXP_CHARS_INVALID, $component) => throw new SyntaxError('Invalid component string: '.$component.'.'), - 1 === preg_match(self::REGEXP_CHARS_ENCODED, $component) => preg_replace_callback(self::REGEXP_CHARS_ENCODED, $decodeMatches(...), $component), - default => $component, - }; + if (1 === preg_match(self::REGEXP_CHARS_INVALID, $component)) { + throw new SyntaxError('Invalid component string: '.$component.'.'); + } + + if (1 === preg_match(self::REGEXP_CHARS_ENCODED, $component)) { + return (string) preg_replace_callback(self::REGEXP_CHARS_ENCODED, $decoder, $component); + } + + return $component; + } + + /** + * Decodes the URI component without decoding the unreserved characters which are already encoded. + * + * DEPRECATION WARNING! This method will be removed in the next major point release. + * + * @deprecated Since version 7.6.0 + * @codeCoverageIgnore + * @see Encoder::decodeNecessary() + * + * Create a new instance from the environment. + */ + #[Deprecated(message:'use League\Uri\Encoder::decodeNecessary() instead', since:'league/uri:7.6.0')] + public static function decodePartial(BackedEnum|Stringable|string|int|null $component): ?string + { + return self::decodeNecessary($component); } } diff --git a/framework/library/vendor/league/uri-interfaces/Exceptions/ConversionFailed.php b/framework/library/vendor/league/uri-interfaces/Exceptions/ConversionFailed.php index 973ffb32..9063ceb0 100644 --- a/framework/library/vendor/league/uri-interfaces/Exceptions/ConversionFailed.php +++ b/framework/library/vendor/league/uri-interfaces/Exceptions/ConversionFailed.php @@ -13,6 +13,7 @@ namespace League\Uri\Exceptions; +use BackedEnum; use League\Uri\Idna\Error; use League\Uri\Idna\Result; use Stringable; @@ -27,10 +28,14 @@ private function __construct( parent::__construct($message); } - public static function dueToIdnError(Stringable|string $host, Result $result): self + public static function dueToIdnError(BackedEnum|Stringable|string $host, Result $result): self { $reasons = array_map(fn (Error $error): string => $error->description(), $result->errors()); + if ($host instanceof BackedEnum) { + $host = (string) $host->value; + } + return new self('Host `'.$host.'` is invalid: '.implode('; ', $reasons).'.', (string) $host, $result); } diff --git a/framework/library/vendor/league/uri-interfaces/FeatureDetection.php b/framework/library/vendor/league/uri-interfaces/FeatureDetection.php index b3e9b09c..be0c4d64 100644 --- a/framework/library/vendor/league/uri-interfaces/FeatureDetection.php +++ b/framework/library/vendor/league/uri-interfaces/FeatureDetection.php @@ -17,6 +17,11 @@ use League\Uri\Exceptions\MissingFeature; use League\Uri\IPv4\Calculator; +use function class_exists; +use function defined; +use function extension_loaded; +use function function_exists; + use const PHP_INT_SIZE; /** @@ -29,9 +34,8 @@ public static function supportsFileDetection(): void static $isSupported = null; $isSupported = $isSupported ?? class_exists(finfo::class); - if (!$isSupported) { - throw new MissingFeature('Support for file type detection requires the `fileinfo` extension.'); - } + $isSupported || throw new MissingFeature('Support for file type detection requires the `fileinfo` extension.'); + } public static function supportsIdn(): void @@ -39,9 +43,7 @@ public static function supportsIdn(): void static $isSupported = null; $isSupported = $isSupported ?? (function_exists('\idn_to_ascii') && defined('\INTL_IDNA_VARIANT_UTS46')); - if (!$isSupported) { - throw new MissingFeature('Support for IDN host requires the `intl` extension for best performance or run "composer require symfony/polyfill-intl-idn" to install a polyfill.'); - } + $isSupported || throw new MissingFeature('Support for IDN host requires the `intl` extension for best performance or run "composer require symfony/polyfill-intl-idn" to install a polyfill.'); } public static function supportsIPv4Conversion(): void @@ -49,8 +51,14 @@ public static function supportsIPv4Conversion(): void static $isSupported = null; $isSupported = $isSupported ?? (extension_loaded('gmp') || extension_loaded('bcmath') || (4 < PHP_INT_SIZE)); - if (!$isSupported) { - throw new MissingFeature('A '.Calculator::class.' implementation could not be automatically loaded. To perform IPv4 conversion use a x.64 PHP build or install one of the following extension GMP or BCMath. You can also ship your own implmentation.'); - } + $isSupported || throw new MissingFeature('A '.Calculator::class.' implementation could not be automatically loaded. To perform IPv4 conversion use a x.64 PHP build or install one of the following extension GMP or BCMath. You can also ship your own implementation.'); + } + + public static function supportsDom(): void + { + static $isSupported = null; + $isSupported = $isSupported ?? extension_loaded('dom'); + + $isSupported || throw new MissingFeature('To use a DOM related feature, the DOM extension must be installed in your system.'); } } diff --git a/framework/library/vendor/league/uri-interfaces/HostFormat.php b/framework/library/vendor/league/uri-interfaces/HostFormat.php new file mode 100644 index 00000000..baf73756 --- /dev/null +++ b/framework/library/vendor/league/uri-interfaces/HostFormat.php @@ -0,0 +1,20 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri; + +enum HostFormat +{ + case Ascii; + case Unicode; +} diff --git a/framework/library/vendor/league/uri-interfaces/HostRecord.php b/framework/library/vendor/league/uri-interfaces/HostRecord.php new file mode 100644 index 00000000..cb36f72a --- /dev/null +++ b/framework/library/vendor/league/uri-interfaces/HostRecord.php @@ -0,0 +1,446 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace League\Uri; + +use BackedEnum; +use Exception; +use JsonSerializable; +use League\Uri\Contracts\UriComponentInterface; +use League\Uri\Exceptions\SyntaxError; +use League\Uri\Idna\Converter as IdnConverter; +use Stringable; +use Throwable; + +use function array_key_first; +use function count; +use function explode; +use function filter_var; +use function get_object_vars; +use function in_array; +use function inet_pton; +use function is_object; +use function preg_match; +use function rawurldecode; +use function strpos; +use function strtolower; +use function substr; + +use const FILTER_FLAG_IPV4; +use const FILTER_FLAG_IPV6; +use const FILTER_VALIDATE_IP; + +/** + * @phpstan-type HostRecordSerializedShape array{0: array{host: ?string}, 1: array{}} + */ +final class HostRecord implements JsonSerializable +{ + /** + * Maximum number of host cached. + * + * @var int + */ + private const MAXIMUM_HOST_CACHED = 100; + + private const REGEXP_NON_ASCII_PATTERN = '/[^\x20-\x7f]/'; + + /** + * @see https://tools.ietf.org/html/rfc3986#section-3.2.2 + * + * invalid characters in host regular expression + */ + private const REGEXP_INVALID_HOST_CHARS = '/ + [:\/?#\[\]@ ] # gen-delims characters as well as the space character + /ix'; + + /** + * General registered name regular expression. + * + * @see https://tools.ietf.org/html/rfc3986#section-3.2.2 + * @see https://regex101.com/r/fptU8V/1 + */ + private const REGEXP_REGISTERED_NAME = '/ + (?(DEFINE) + (?[a-z0-9_~\-]) # . is missing as it is used to separate labels + (?[!$&\'()*+,;=]) + (?%[A-F0-9]{2}) + (?(?:(?&unreserved)|(?&sub_delims)|(?&encoded))*) + ) + ^(?:(?®_name)\.)*(?®_name)\.?$ + /ix'; + + /** + * Domain name regular expression. + * + * Everything but the domain name length is validated + * + * @see https://tools.ietf.org/html/rfc1034#section-3.5 + * @see https://tools.ietf.org/html/rfc1123#section-2.1 + * @see https://regex101.com/r/71j6rt/1 + */ + private const REGEXP_DOMAIN_NAME = '/ + (?(DEFINE) + (? [a-z0-9]) # alpha digit + (? [a-z0-9-]) # alpha digit and hyphen + (? (?&let_dig_hyp){0,61}(?&let_dig)) # domain label end + (?