diff --git a/composer.json b/composer.json index af31b1c2..3cedc926 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,6 @@ "require-dev": { "laminas/laminas-coding-standard": "~2.5.0", "laminas/laminas-i18n": "^2.26.0", - "laminas/laminas-uri": "^2.11.0", "pear/archive_tar": "^1.4.14", "phpunit/phpunit": "^10.5.11", "psalm/plugin-phpunit": "^0.19.0", @@ -53,7 +52,6 @@ }, "suggest": { "laminas/laminas-i18n": "Laminas\\I18n component for filters depending on i18n functionality", - "laminas/laminas-uri": "Laminas\\Uri component, for the UriNormalize filter", "psr/http-factory-implementation": "psr/http-factory-implementation, for creating file upload instances when consuming PSR-7 in file upload filters" }, "autoload": { diff --git a/composer.lock b/composer.lock index 2f3b8916..bec238b8 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e237294a9c029f74451de1f079cfa992", + "content-hash": "a67875aec9e672b030c622d2b87849ff", "packages": [ { "name": "laminas/laminas-servicemanager", @@ -992,68 +992,6 @@ ], "time": "2023-01-05T15:53:40+00:00" }, - { - "name": "laminas/laminas-escaper", - "version": "2.13.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-escaper.git", - "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-escaper/zipball/af459883f4018d0f8a0c69c7a209daef3bf973ba", - "reference": "af459883f4018d0f8a0c69c7a209daef3bf973ba", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-mbstring": "*", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-escaper": "*" - }, - "require-dev": { - "infection/infection": "^0.27.0", - "laminas/laminas-coding-standard": "~2.5.0", - "maglnet/composer-require-checker": "^3.8.0", - "phpunit/phpunit": "^9.6.7", - "psalm/plugin-phpunit": "^0.18.4", - "vimeo/psalm": "^5.9" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Escaper\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Securely and safely escape HTML, HTML attributes, JavaScript, CSS, and URLs", - "homepage": "https://laminas.dev", - "keywords": [ - "escaper", - "laminas" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-escaper/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-escaper/issues", - "rss": "https://github.com/laminas/laminas-escaper/releases.atom", - "source": "https://github.com/laminas/laminas-escaper" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-10-10T08:35:13+00:00" - }, { "name": "laminas/laminas-i18n", "version": "2.26.0", @@ -1139,148 +1077,6 @@ ], "time": "2024-01-04T13:49:00+00:00" }, - { - "name": "laminas/laminas-uri", - "version": "2.11.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-uri.git", - "reference": "e662c685125061d3115906e5eb30f966842cc226" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-uri/zipball/e662c685125061d3115906e5eb30f966842cc226", - "reference": "e662c685125061d3115906e5eb30f966842cc226", - "shasum": "" - }, - "require": { - "laminas/laminas-escaper": "^2.9", - "laminas/laminas-validator": "^2.39", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0" - }, - "conflict": { - "zendframework/zend-uri": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "~2.4.0", - "phpunit/phpunit": "^9.5.25" - }, - "type": "library", - "autoload": { - "psr-4": { - "Laminas\\Uri\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "A component that aids in manipulating and validating ยป Uniform Resource Identifiers (URIs)", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "uri" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-uri/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-uri/issues", - "rss": "https://github.com/laminas/laminas-uri/releases.atom", - "source": "https://github.com/laminas/laminas-uri" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2023-10-18T09:56:55+00:00" - }, - { - "name": "laminas/laminas-validator", - "version": "2.53.0", - "source": { - "type": "git", - "url": "https://github.com/laminas/laminas-validator.git", - "reference": "dbcfc19cb7f2e3eb3a27ba5d059c200e8404d72c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/laminas/laminas-validator/zipball/dbcfc19cb7f2e3eb3a27ba5d059c200e8404d72c", - "reference": "dbcfc19cb7f2e3eb3a27ba5d059c200e8404d72c", - "shasum": "" - }, - "require": { - "laminas/laminas-servicemanager": "^3.21.0", - "laminas/laminas-stdlib": "^3.13", - "php": "~8.1.0 || ~8.2.0 || ~8.3.0", - "psr/http-message": "^1.0.1 || ^2.0.0" - }, - "conflict": { - "zendframework/zend-validator": "*" - }, - "require-dev": { - "laminas/laminas-coding-standard": "^2.5", - "laminas/laminas-db": "^2.19", - "laminas/laminas-filter": "^2.34", - "laminas/laminas-i18n": "^2.26.0", - "laminas/laminas-session": "^2.20", - "laminas/laminas-uri": "^2.11.0", - "phpunit/phpunit": "^10.5.15", - "psalm/plugin-phpunit": "^0.19.0", - "psr/http-client": "^1.0.3", - "psr/http-factory": "^1.0.2", - "vimeo/psalm": "^5.23.1" - }, - "suggest": { - "laminas/laminas-db": "Laminas\\Db component, required by the (No)RecordExists validator", - "laminas/laminas-filter": "Laminas\\Filter component, required by the Digits validator", - "laminas/laminas-i18n": "Laminas\\I18n component to allow translation of validation error messages", - "laminas/laminas-i18n-resources": "Translations of validator messages", - "laminas/laminas-servicemanager": "Laminas\\ServiceManager component to allow using the ValidatorPluginManager and validator chains", - "laminas/laminas-session": "Laminas\\Session component, ^2.8; required by the Csrf validator", - "laminas/laminas-uri": "Laminas\\Uri component, required by the Uri and Sitemap\\Loc validators", - "psr/http-message": "psr/http-message, required when validating PSR-7 UploadedFileInterface instances via the Upload and UploadFile validators" - }, - "type": "library", - "extra": { - "laminas": { - "component": "Laminas\\Validator", - "config-provider": "Laminas\\Validator\\ConfigProvider" - } - }, - "autoload": { - "psr-4": { - "Laminas\\Validator\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "Validation classes for a wide range of domains, and the ability to chain validators to create complex validation criteria", - "homepage": "https://laminas.dev", - "keywords": [ - "laminas", - "validator" - ], - "support": { - "chat": "https://laminas.dev/chat", - "docs": "https://docs.laminas.dev/laminas-validator/", - "forum": "https://discourse.laminas.dev", - "issues": "https://github.com/laminas/laminas-validator/issues", - "rss": "https://github.com/laminas/laminas-validator/releases.atom", - "source": "https://github.com/laminas/laminas-validator" - }, - "funding": [ - { - "url": "https://funding.communitybridge.org/projects/laminas-project", - "type": "community_bridge" - } - ], - "time": "2024-04-01T09:26:32+00:00" - }, { "name": "myclabs/deep-copy", "version": "1.11.1", diff --git a/docs/book/v3/standard-filters.md b/docs/book/v3/standard-filters.md index 665bcf2d..1f97f7f9 100644 --- a/docs/book/v3/standard-filters.md +++ b/docs/book/v3/standard-filters.md @@ -1464,27 +1464,3 @@ print $filter->filter($input); The above will return `A text with a picture click here!` as the result. - -## UriNormalize - -This filter sets the scheme on a URI if the scheme is missing. - -### Supported Options - -The following options are supported for `Laminas\Filter\UriNormalize`: - -- `defaultScheme`: This option can be used to set the default scheme to use when - parsing scheme-less URIs. -- `enforcedScheme`: Set a URI scheme to enforce on schemeless URIs. - -### Basic Usage - -```php -$filter = new Laminas\Filter\UriNormalize(array( - 'enforcedScheme' => 'https' -)); - -echo $filter->filter('www.example.com'); -``` - -The above results in the string `https://www.example.com`. diff --git a/psalm-baseline.xml b/psalm-baseline.xml index 88aa3368..0d68e12a 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -809,26 +809,6 @@ - - - enforcedScheme !== null && $uri->getScheme() === null) { - $this->enforceScheme($uri); - } - } catch (UriException) { - // We are unable to parse / enforce scheme with the given config and input - return $value; - }]]> - - - - - - - - - @@ -1323,13 +1303,6 @@ - - - - - - - diff --git a/src/FilterPluginManager.php b/src/FilterPluginManager.php index 86b29074..87fd06be 100644 --- a/src/FilterPluginManager.php +++ b/src/FilterPluginManager.php @@ -148,9 +148,6 @@ final class FilterPluginManager extends AbstractPluginManager 'uppercasewords' => UpperCaseWords::class, 'upperCaseWords' => UpperCaseWords::class, 'UpperCaseWords' => UpperCaseWords::class, - 'urinormalize' => UriNormalize::class, - 'uriNormalize' => UriNormalize::class, - 'UriNormalize' => UriNormalize::class, 'wordcamelcasetodash' => Word\CamelCaseToDash::class, 'wordCamelCaseToDash' => Word\CamelCaseToDash::class, 'WordCamelCaseToDash' => Word\CamelCaseToDash::class, @@ -227,7 +224,6 @@ final class FilterPluginManager extends AbstractPluginManager 'Zend\Filter\StringTrim' => StringTrim::class, 'Zend\Filter\StripNewlines' => StripNewlines::class, 'Zend\Filter\StripTags' => StripTags::class, - 'Zend\Filter\UriNormalize' => UriNormalize::class, 'Zend\Filter\Word\CamelCaseToDash' => Word\CamelCaseToDash::class, 'Zend\Filter\Word\CamelCaseToSeparator' => Word\CamelCaseToSeparator::class, 'Zend\Filter\Word\CamelCaseToUnderscore' => Word\CamelCaseToUnderscore::class, @@ -278,7 +274,6 @@ final class FilterPluginManager extends AbstractPluginManager 'zendfilterstripnewlines' => StripNewlines::class, 'zendfilterstriptags' => StripTags::class, 'zendfilteruppercasewords' => UpperCaseWords::class, - 'zendfilterurinormalize' => UriNormalize::class, 'zendfilterwordcamelcasetodash' => Word\CamelCaseToDash::class, 'zendfilterwordcamelcasetoseparator' => Word\CamelCaseToSeparator::class, 'zendfilterwordcamelcasetounderscore' => Word\CamelCaseToUnderscore::class, @@ -343,7 +338,6 @@ final class FilterPluginManager extends AbstractPluginManager StripTags::class => InvokableFactory::class, ToInt::class => InvokableFactory::class, ToNull::class => InvokableFactory::class, - UriNormalize::class => InvokableFactory::class, Word\CamelCaseToDash::class => InvokableFactory::class, Word\CamelCaseToSeparator::class => InvokableFactory::class, Word\CamelCaseToUnderscore::class => InvokableFactory::class, @@ -394,7 +388,6 @@ final class FilterPluginManager extends AbstractPluginManager 'laminasfilterstripnewlines' => InvokableFactory::class, 'laminasfilterstriptags' => InvokableFactory::class, 'laminasfilteruppercasewords' => InvokableFactory::class, - 'laminasfilterurinormalize' => InvokableFactory::class, 'laminasfilterwordcamelcasetodash' => InvokableFactory::class, 'laminasfilterwordcamelcasetoseparator' => InvokableFactory::class, 'laminasfilterwordcamelcasetounderscore' => InvokableFactory::class, diff --git a/src/UriNormalize.php b/src/UriNormalize.php deleted file mode 100644 index a923a6f5..00000000 --- a/src/UriNormalize.php +++ /dev/null @@ -1,157 +0,0 @@ - - */ -final class UriNormalize extends AbstractFilter -{ - /** - * The default scheme to use when parsing scheme-less URIs - * - * @var string|null - */ - protected $defaultScheme; - - /** - * Enforced scheme for scheme-less URIs. See setEnforcedScheme docs for info - * - * @var string|null - */ - protected $enforcedScheme; - - /** - * Sets filter options - * - * @param Options|Traversable|null $options - */ - public function __construct($options = null) - { - if ($options !== null) { - $this->setOptions($options); - } - } - - /** - * Set the default scheme to use when parsing scheme-less URIs - * - * The scheme used when parsing URIs may affect the specific object used to - * normalize the URI and thus may affect the resulting normalize URI. - * - * @param string $defaultScheme - * @return $this - */ - public function setDefaultScheme($defaultScheme) - { - $this->defaultScheme = $defaultScheme; - return $this; - } - - /** - * Set a URI scheme to enforce on schemeless URIs - * - * This allows forcing input values such as 'www.example.com/foo' into - * 'http://www.example.com/foo'. - * - * This should be used with caution, as a standard-compliant URI parser - * would regard 'www.example.com' in the above input URI to be the path and - * not host part of the URI. While this option can assist in solving - * real-world user mishaps, it may yield unexpected results at times. - * - * @param string $enforcedScheme - * @return $this - */ - public function setEnforcedScheme($enforcedScheme) - { - $this->enforcedScheme = $enforcedScheme; - return $this; - } - - /** - * Filter the URL by normalizing it and applying a default scheme if set - */ - public function filter(mixed $value): mixed - { - if (! is_scalar($value)) { - return $value; - } - $value = (string) $value; - - $defaultScheme = $this->defaultScheme ?? $this->enforcedScheme; - - // Reset default scheme if it is not a known scheme - if (UriFactory::getRegisteredSchemeClass($defaultScheme) === null) { - $defaultScheme = null; - } - - try { - $uri = UriFactory::factory($value, $defaultScheme); - if ($this->enforcedScheme !== null && $uri->getScheme() === null) { - $this->enforceScheme($uri); - } - } catch (UriException) { - // We are unable to parse / enforce scheme with the given config and input - return $value; - } - - $uri->normalize(); - - if (! $uri->isValid()) { - return $value; - } - - return $uri->toString(); - } - - /** - * Enforce the defined scheme on the URI - * - * This will also adjust the host and path parts of the URI as expected in - * the case of scheme-less network URIs - * - * @return void - */ - protected function enforceScheme(Uri $uri) - { - $path = $uri->getPath() ?? ''; - - if (str_contains($path, '/')) { - $parts = explode('/', $path, 2); - assert(count($parts) >= 2); - [$host, $path] = $parts; - $path = '/' . $path; - } else { - $host = $path; - $path = ''; - } - - // We have nothing to do if we have no host - if (! $host) { - return; - } - - $uri->setScheme($this->enforcedScheme) - ->setHost($host) - ->setPath($path); - } -} diff --git a/test/UriNormalizeTest.php b/test/UriNormalizeTest.php deleted file mode 100644 index 7cd7d9b1..00000000 --- a/test/UriNormalizeTest.php +++ /dev/null @@ -1,83 +0,0 @@ -filter($url); - self::assertSame($expected, $result); - } - - public function testDefaultSchemeAffectsNormalization(): void - { - $this->markTestIncomplete(); - } - - #[DataProvider('enforcedSchemeTestcaseProvider')] - public function testEnforcedScheme(string $scheme, string $input, string $expected): void - { - $filter = new UriNormalize(['enforcedScheme' => $scheme]); - $result = $filter->filter($input); - self::assertSame($expected, $result); - } - - /** @return list */ - public static function abnormalUriProvider(): array - { - return [ - ['http://www.example.com', 'http://www.example.com/'], - ['hTTp://www.example.com/ space', 'http://www.example.com/%20space'], - ['file:///www.example.com/foo/bar', 'file:///www.example.com/foo/bar'], // this should not be affected - ['file:///home/shahar/secret/../../otherguy/secret', 'file:///home/otherguy/secret'], - ['https://www.example.com:443/hasport', 'https://www.example.com/hasport'], - ['/foo/bar?q=%711', '/foo/bar?q=q1'], // no scheme enforced - ]; - } - - /** @return list */ - public static function enforcedSchemeTestcaseProvider(): array - { - return [ - ['ftp', 'http://www.example.com', 'http://www.example.com/'], // no effect - this one has a scheme - ['mailto', 'mailto:shahar@example.com', 'mailto:shahar@example.com'], - ['http', 'www.example.com/foo/bar?q=q', 'http://www.example.com/foo/bar?q=q'], - ['ftp', 'www.example.com/path/to/file.ext', 'ftp://www.example.com/path/to/file.ext'], - ['http', '/just/a/path', '/just/a/path'], // cannot be enforced, no host - ['http', '', ''], - ]; - } - - /** @return list */ - public static function returnUnfilteredDataProvider(): array - { - return [ - [null], - [new stdClass()], - [ - [ - 'http://www.example.com', - 'file:///home/shahar/secret/../../otherguy/secret', - ], - ], - ]; - } - - #[DataProvider('returnUnfilteredDataProvider')] - public function testReturnUnfiltered(mixed $input): void - { - $filter = new UriNormalize(); - - self::assertSame($input, $filter($input)); - } -}