diff --git a/composer.json b/composer.json
index a45bc60f..571b84ce 100644
--- a/composer.json
+++ b/composer.json
@@ -34,8 +34,8 @@
"require": {
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
"ext-mbstring": "*",
- "laminas/laminas-servicemanager": "^3.21.0",
- "laminas/laminas-stdlib": "^3.13.0"
+ "laminas/laminas-servicemanager": "^4.1.0",
+ "laminas/laminas-stdlib": "^3.19.0"
},
"require-dev": {
"laminas/laminas-coding-standard": "~2.5.0",
diff --git a/composer.lock b/composer.lock
index d8f54751..14f056fb 100644
--- a/composer.lock
+++ b/composer.lock
@@ -4,63 +4,111 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
- "content-hash": "dc7ab9e282128061526953709d8bd29f",
+ "content-hash": "494a41a79c1b61ce078ae5eb5e230184",
"packages": [
+ {
+ "name": "brick/varexporter",
+ "version": "0.4.0",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/brick/varexporter.git",
+ "reference": "2fd038f7c9d12d468130c6e1b3ce06e4160a7dbb"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/brick/varexporter/zipball/2fd038f7c9d12d468130c6e1b3ce06e4160a7dbb",
+ "reference": "2fd038f7c9d12d468130c6e1b3ce06e4160a7dbb",
+ "shasum": ""
+ },
+ "require": {
+ "nikic/php-parser": "^4.0",
+ "php": "^7.4 || ^8.0"
+ },
+ "require-dev": {
+ "php-coveralls/php-coveralls": "^2.2",
+ "phpunit/phpunit": "^8.5 || ^9.0",
+ "vimeo/psalm": "5.15.0"
+ },
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "Brick\\VarExporter\\": "src/"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "MIT"
+ ],
+ "description": "A powerful alternative to var_export(), which can export closures and objects without __set_state()",
+ "keywords": [
+ "var_export"
+ ],
+ "support": {
+ "issues": "https://github.com/brick/varexporter/issues",
+ "source": "https://github.com/brick/varexporter/tree/0.4.0"
+ },
+ "funding": [
+ {
+ "url": "https://github.com/BenMorel",
+ "type": "github"
+ }
+ ],
+ "time": "2023-09-01T21:10:07+00:00"
+ },
{
"name": "laminas/laminas-servicemanager",
- "version": "3.22.1",
+ "version": "4.1.0",
"source": {
"type": "git",
"url": "https://github.com/laminas/laminas-servicemanager.git",
- "reference": "de98d297d4743956a0558a6d71616979ff779328"
+ "reference": "ae01570ecdf4559aef2f15d4e79e8c36874f7416"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/de98d297d4743956a0558a6d71616979ff779328",
- "reference": "de98d297d4743956a0558a6d71616979ff779328",
+ "url": "https://api.github.com/repos/laminas/laminas-servicemanager/zipball/ae01570ecdf4559aef2f15d4e79e8c36874f7416",
+ "reference": "ae01570ecdf4559aef2f15d4e79e8c36874f7416",
"shasum": ""
},
"require": {
+ "brick/varexporter": "^0.3.8 || ^0.4.0",
"laminas/laminas-stdlib": "^3.17",
"php": "~8.1.0 || ~8.2.0 || ~8.3.0",
- "psr/container": "^1.0"
+ "psr/container": "^1.1 || ^2.0"
},
"conflict": {
- "ext-psr": "*",
"laminas/laminas-code": "<4.10.0",
- "zendframework/zend-code": "<3.3.1",
- "zendframework/zend-servicemanager": "*"
+ "zendframework/zend-code": "<3.3.1"
},
"provide": {
- "psr/container-implementation": "^1.0"
- },
- "replace": {
- "container-interop/container-interop": "^1.2.0"
+ "psr/container-implementation": "^1.0 || ^2.0"
},
"require-dev": {
+ "boesing/psalm-plugin-stringf": "^1.4",
"composer/package-versions-deprecated": "^1.11.99.5",
- "friendsofphp/proxy-manager-lts": "^1.0.14",
- "laminas/laminas-code": "^4.10.0",
+ "friendsofphp/proxy-manager-lts": "^1",
+ "laminas/laminas-cli": "^1.8",
"laminas/laminas-coding-standard": "~2.5.0",
- "laminas/laminas-container-config-test": "^0.8",
- "mikey179/vfsstream": "^1.6.11",
- "phpbench/phpbench": "^1.2.9",
+ "laminas/laminas-container-config-test": "^1.0",
+ "lctrs/psalm-psr-container-plugin": "^1.9",
+ "mikey179/vfsstream": "^1.6.11@alpha",
+ "phpbench/phpbench": "^1.2.7",
"phpunit/phpunit": "^10.4",
"psalm/plugin-phpunit": "^0.18.4",
- "vimeo/psalm": "^5.8.0"
+ "symfony/console": "^6.0",
+ "vimeo/psalm": "^5.22"
},
"suggest": {
- "friendsofphp/proxy-manager-lts": "ProxyManager ^2.1.1 to handle lazy initialization of services"
+ "friendsofphp/proxy-manager-lts": "To handle lazy initialization of services",
+ "laminas/laminas-cli": "To consume CLI commands provided by this component"
},
- "bin": [
- "bin/generate-deps-for-config-factory",
- "bin/generate-factory-for-class"
- ],
"type": "library",
+ "extra": {
+ "laminas": {
+ "config-provider": "Laminas\\ServiceManager\\ConfigProvider",
+ "module": "Laminas\\ServiceManager"
+ }
+ },
"autoload": {
- "files": [
- "src/autoload.php"
- ],
"psr-4": {
"Laminas\\ServiceManager\\": "src/"
}
@@ -82,11 +130,9 @@
],
"support": {
"chat": "https://laminas.dev/chat",
- "docs": "https://docs.laminas.dev/laminas-servicemanager/",
"forum": "https://discourse.laminas.dev",
"issues": "https://github.com/laminas/laminas-servicemanager/issues",
- "rss": "https://github.com/laminas/laminas-servicemanager/releases.atom",
- "source": "https://github.com/laminas/laminas-servicemanager"
+ "source": "https://github.com/laminas/laminas-servicemanager/tree/4.1.0"
},
"funding": [
{
@@ -94,7 +140,7 @@
"type": "community_bridge"
}
],
- "time": "2023-10-24T11:19:47+00:00"
+ "time": "2024-04-03T20:39:36+00:00"
},
{
"name": "laminas/laminas-stdlib",
@@ -155,24 +201,85 @@
],
"time": "2024-01-19T12:39:49+00:00"
},
+ {
+ "name": "nikic/php-parser",
+ "version": "v4.19.1",
+ "source": {
+ "type": "git",
+ "url": "https://github.com/nikic/PHP-Parser.git",
+ "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b"
+ },
+ "dist": {
+ "type": "zip",
+ "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b",
+ "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b",
+ "shasum": ""
+ },
+ "require": {
+ "ext-tokenizer": "*",
+ "php": ">=7.1"
+ },
+ "require-dev": {
+ "ircmaxell/php-yacc": "^0.0.7",
+ "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
+ },
+ "bin": [
+ "bin/php-parse"
+ ],
+ "type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "4.9-dev"
+ }
+ },
+ "autoload": {
+ "psr-4": {
+ "PhpParser\\": "lib/PhpParser"
+ }
+ },
+ "notification-url": "https://packagist.org/downloads/",
+ "license": [
+ "BSD-3-Clause"
+ ],
+ "authors": [
+ {
+ "name": "Nikita Popov"
+ }
+ ],
+ "description": "A PHP parser written in PHP",
+ "keywords": [
+ "parser",
+ "php"
+ ],
+ "support": {
+ "issues": "https://github.com/nikic/PHP-Parser/issues",
+ "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1"
+ },
+ "time": "2024-03-17T08:10:35+00:00"
+ },
{
"name": "psr/container",
- "version": "1.1.2",
+ "version": "2.0.2",
"source": {
"type": "git",
"url": "https://github.com/php-fig/container.git",
- "reference": "513e0666f7216c7459170d56df27dfcefe1689ea"
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea",
- "reference": "513e0666f7216c7459170d56df27dfcefe1689ea",
+ "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963",
+ "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963",
"shasum": ""
},
"require": {
"php": ">=7.4.0"
},
"type": "library",
+ "extra": {
+ "branch-alias": {
+ "dev-master": "2.0.x-dev"
+ }
+ },
"autoload": {
"psr-4": {
"Psr\\Container\\": "src/"
@@ -199,9 +306,9 @@
],
"support": {
"issues": "https://github.com/php-fig/container/issues",
- "source": "https://github.com/php-fig/container/tree/1.1.2"
+ "source": "https://github.com/php-fig/container/tree/2.0.2"
},
- "time": "2021-11-05T16:50:12+00:00"
+ "time": "2021-11-05T16:47:00+00:00"
}
],
"packages-dev": [
@@ -1102,62 +1209,6 @@
},
"time": "2024-01-31T06:18:54+00:00"
},
- {
- "name": "nikic/php-parser",
- "version": "v4.19.1",
- "source": {
- "type": "git",
- "url": "https://github.com/nikic/PHP-Parser.git",
- "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b"
- },
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/4e1b88d21c69391150ace211e9eaf05810858d0b",
- "reference": "4e1b88d21c69391150ace211e9eaf05810858d0b",
- "shasum": ""
- },
- "require": {
- "ext-tokenizer": "*",
- "php": ">=7.1"
- },
- "require-dev": {
- "ircmaxell/php-yacc": "^0.0.7",
- "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0"
- },
- "bin": [
- "bin/php-parse"
- ],
- "type": "library",
- "extra": {
- "branch-alias": {
- "dev-master": "4.9-dev"
- }
- },
- "autoload": {
- "psr-4": {
- "PhpParser\\": "lib/PhpParser"
- }
- },
- "notification-url": "https://packagist.org/downloads/",
- "license": [
- "BSD-3-Clause"
- ],
- "authors": [
- {
- "name": "Nikita Popov"
- }
- ],
- "description": "A PHP parser written in PHP",
- "keywords": [
- "parser",
- "php"
- ],
- "support": {
- "issues": "https://github.com/nikic/PHP-Parser/issues",
- "source": "https://github.com/nikic/PHP-Parser/tree/v4.19.1"
- },
- "time": "2024-03-17T08:10:35+00:00"
- },
{
"name": "pear/archive_tar",
"version": "1.5.0",
@@ -3476,16 +3527,16 @@
},
{
"name": "symfony/console",
- "version": "v6.4.4",
+ "version": "v6.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/console.git",
- "reference": "0d9e4eb5ad413075624378f474c4167ea202de78"
+ "reference": "a2708a5da5c87d1d0d52937bdeac625df659e11f"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/console/zipball/0d9e4eb5ad413075624378f474c4167ea202de78",
- "reference": "0d9e4eb5ad413075624378f474c4167ea202de78",
+ "url": "https://api.github.com/repos/symfony/console/zipball/a2708a5da5c87d1d0d52937bdeac625df659e11f",
+ "reference": "a2708a5da5c87d1d0d52937bdeac625df659e11f",
"shasum": ""
},
"require": {
@@ -3550,7 +3601,7 @@
"terminal"
],
"support": {
- "source": "https://github.com/symfony/console/tree/v6.4.4"
+ "source": "https://github.com/symfony/console/tree/v6.4.6"
},
"funding": [
{
@@ -3566,7 +3617,7 @@
"type": "tidelift"
}
],
- "time": "2024-02-22T20:27:10+00:00"
+ "time": "2024-03-29T19:07:53+00:00"
},
{
"name": "symfony/deprecation-contracts",
@@ -3637,16 +3688,16 @@
},
{
"name": "symfony/filesystem",
- "version": "v6.4.3",
+ "version": "v6.4.6",
"source": {
"type": "git",
"url": "https://github.com/symfony/filesystem.git",
- "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb"
+ "reference": "9919b5509ada52cc7f66f9a35c86a4a29955c9d3"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/filesystem/zipball/7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb",
- "reference": "7f3b1755eb49297a0827a7575d5d2b2fd11cc9fb",
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/9919b5509ada52cc7f66f9a35c86a4a29955c9d3",
+ "reference": "9919b5509ada52cc7f66f9a35c86a4a29955c9d3",
"shasum": ""
},
"require": {
@@ -3680,7 +3731,7 @@
"description": "Provides basic utilities for the filesystem",
"homepage": "https://symfony.com",
"support": {
- "source": "https://github.com/symfony/filesystem/tree/v6.4.3"
+ "source": "https://github.com/symfony/filesystem/tree/v6.4.6"
},
"funding": [
{
@@ -3696,7 +3747,7 @@
"type": "tidelift"
}
],
- "time": "2024-01-23T14:51:35+00:00"
+ "time": "2024-03-21T19:36:20+00:00"
},
{
"name": "symfony/polyfill-ctype",
@@ -4018,16 +4069,16 @@
},
{
"name": "symfony/service-contracts",
- "version": "v3.4.1",
+ "version": "v3.4.2",
"source": {
"type": "git",
"url": "https://github.com/symfony/service-contracts.git",
- "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0"
+ "reference": "11bbf19a0fb7b36345861e85c5768844c552906e"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/symfony/service-contracts/zipball/fe07cbc8d837f60caf7018068e350cc5163681a0",
- "reference": "fe07cbc8d837f60caf7018068e350cc5163681a0",
+ "url": "https://api.github.com/repos/symfony/service-contracts/zipball/11bbf19a0fb7b36345861e85c5768844c552906e",
+ "reference": "11bbf19a0fb7b36345861e85c5768844c552906e",
"shasum": ""
},
"require": {
@@ -4080,7 +4131,7 @@
"standards"
],
"support": {
- "source": "https://github.com/symfony/service-contracts/tree/v3.4.1"
+ "source": "https://github.com/symfony/service-contracts/tree/v3.4.2"
},
"funding": [
{
@@ -4096,7 +4147,7 @@
"type": "tidelift"
}
],
- "time": "2023-12-26T14:02:43+00:00"
+ "time": "2023-12-19T21:51:00+00:00"
},
{
"name": "symfony/string",
diff --git a/psalm-baseline.xml b/psalm-baseline.xml
index f6f10e24..5e0205e4 100644
--- a/psalm-baseline.xml
+++ b/psalm-baseline.xml
@@ -512,34 +512,10 @@
-
-
-
-
-
- InvokableFactory::class]]>
- InvokableFactory::class]]>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
@@ -616,6 +592,7 @@
+
@@ -623,6 +600,8 @@
+ getPluginManager()->get($rule)]]>
+ getPluginManager()->get($rule)]]>
rules[$spec]]]>
rules[$spec][$index]]]>
@@ -655,9 +634,6 @@
-
-
-
@@ -1040,6 +1016,17 @@
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/ConfigProvider.php b/src/ConfigProvider.php
index bf00a070..254c31e3 100644
--- a/src/ConfigProvider.php
+++ b/src/ConfigProvider.php
@@ -4,19 +4,19 @@
namespace Laminas\Filter;
-use Laminas\ServiceManager\ConfigInterface;
+use Laminas\ServiceManager\ServiceManager;
/**
- * @psalm-import-type ServiceManagerConfigurationType from ConfigInterface
+ * @psalm-import-type ServiceManagerConfiguration from ServiceManager
*/
-class ConfigProvider
+final class ConfigProvider
{
/**
* Return configuration for this component.
*
- * @return array
+ * @return array{dependencies: ServiceManagerConfiguration}
*/
- public function __invoke()
+ public function __invoke(): array
{
return [
'dependencies' => $this->getDependencyConfig(),
@@ -26,16 +26,13 @@ public function __invoke()
/**
* Return dependency mappings for this component.
*
- * @return ServiceManagerConfigurationType
+ * @return ServiceManagerConfiguration
*/
public function getDependencyConfig()
{
return [
'aliases' => [
'FilterManager' => FilterPluginManager::class,
-
- // Legacy Zend Framework aliases
- 'Zend\Filter\FilterPluginManager' => FilterPluginManager::class,
],
'factories' => [
FilterPluginManager::class => FilterPluginManagerFactory::class,
diff --git a/src/FilterChain.php b/src/FilterChain.php
index 2e35ce5f..2a12972c 100644
--- a/src/FilterChain.php
+++ b/src/FilterChain.php
@@ -8,7 +8,6 @@
use IteratorAggregate;
use Laminas\ServiceManager\ServiceManager;
use Laminas\Stdlib\PriorityQueue;
-use ReturnTypeWillChange;
use Traversable;
use function call_user_func;
@@ -21,6 +20,7 @@
use function strtolower;
/**
+ * @psalm-type InstanceType = FilterInterface|callable(mixed): mixed
* @psalm-type FilterChainConfiguration = array{
* filters?: list,
@@ -33,7 +33,7 @@
* }>
* }
* @extends AbstractFilter
- * @implements IteratorAggregate
+ * @implements IteratorAggregate
*/
final class FilterChain extends AbstractFilter implements Countable, IteratorAggregate
{
@@ -48,7 +48,7 @@ final class FilterChain extends AbstractFilter implements Countable, IteratorAgg
/**
* Filter chain
*
- * @var PriorityQueue
+ * @var PriorityQueue
*/
protected $filters;
@@ -110,23 +110,14 @@ public function setOptions($options)
return $this;
}
- /**
- * Return the count of attached filters
- *
- * @return int
- */
- #[ReturnTypeWillChange]
- public function count()
+ /** Return the count of attached filters */
+ public function count(): int
{
return count($this->filters);
}
- /**
- * Get plugin manager instance
- *
- * @return FilterPluginManager
- */
- public function getPluginManager()
+ /** Get plugin manager instance */
+ public function getPluginManager(): FilterPluginManager
{
$plugins = $this->plugins;
if (! $plugins instanceof FilterPluginManager) {
@@ -151,24 +142,24 @@ public function setPluginManager(FilterPluginManager $plugins)
/**
* Retrieve a filter plugin by name
*
- * @param string $name
- * @return FilterInterface|callable(mixed): mixed
+ * @template T of FilterInterface
+ * @param class-string|string $name
+ * @return ($name is class-string ? T : InstanceType)
*/
- public function plugin($name, array $options = [])
+ public function plugin(string $name, array $options = [])
{
- $plugins = $this->getPluginManager();
- return $plugins->get($name, $options);
+ return $this->getPluginManager()->build($name, $options);
}
/**
* Attach a filter to the chain
*
- * @param callable(mixed): mixed|FilterInterface $callback A Filter implementation or valid PHP callback
+ * @param InstanceType $callback A Filter implementation or valid PHP callback
* @param int $priority Priority at which to enqueue filter; defaults to 1000 (higher executes earlier)
* @throws Exception\InvalidArgumentException
* @return self
*/
- public function attach($callback, $priority = self::DEFAULT_PRIORITY)
+ public function attach(FilterInterface|callable $callback, int $priority = self::DEFAULT_PRIORITY)
{
if (! is_callable($callback)) {
if (! $callback instanceof FilterInterface) {
@@ -189,19 +180,13 @@ public function attach($callback, $priority = self::DEFAULT_PRIORITY)
* Retrieves the filter from the attached plugin manager, and then calls attach()
* with the retrieved instance.
*
- * @param string $name
+ * @param class-string|string $name
* @param int $priority Priority at which to enqueue filter; defaults to 1000 (higher executes earlier)
* @return self
*/
- public function attachByName($name, mixed $options = [], $priority = self::DEFAULT_PRIORITY)
+ public function attachByName(string $name, array $options = [], int $priority = self::DEFAULT_PRIORITY)
{
- if (! is_array($options)) {
- $options = (array) $options;
- } elseif (empty($options)) {
- $options = null;
- }
- $filter = $this->getPluginManager()->get($name, $options);
- return $this->attach($filter, $priority);
+ return $this->attach($this->plugin($name, $options), $priority);
}
/**
diff --git a/src/FilterPluginManager.php b/src/FilterPluginManager.php
index c21b3aee..15aa6e04 100644
--- a/src/FilterPluginManager.php
+++ b/src/FilterPluginManager.php
@@ -4,401 +4,250 @@
namespace Laminas\Filter;
-use Laminas\Filter\Exception\RuntimeException;
use Laminas\ServiceManager\AbstractPluginManager;
use Laminas\ServiceManager\Exception\InvalidServiceException;
use Laminas\ServiceManager\Factory\InvokableFactory;
+use Laminas\ServiceManager\ServiceManager;
+use Psr\Container\ContainerInterface;
+use function array_replace_recursive;
use function get_debug_type;
use function is_callable;
use function sprintf;
/**
- * Plugin manager implementation for the filter chain.
+ * Plugin manager implementation for filters
*
- * Enforces that filters retrieved are either callbacks or instances of
- * FilterInterface. Additionally, it registers a number of default filters
- * available, as well as aliases for them.
+ * Enforces that filters retrieved are either callbacks or instances of FilterInterface.
*
- * @extends AbstractPluginManager
+ * @psalm-type InstanceType = FilterInterface|callable(mixed): mixed
+ * @extends AbstractPluginManager
+ * @psalm-import-type ServiceManagerConfiguration from ServiceManager
*/
final class FilterPluginManager extends AbstractPluginManager
{
- protected $aliases = [
- // @codingStandardsIgnoreStart
- // For the future
- 'int' => ToInt::class,
- 'Int' => ToInt::class,
- 'null' => ToNull::class,
- 'Null' => ToNull::class,
+ private const CONFIGURATION = [
+ 'factories' => [
+ AllowList::class => InvokableFactory::class,
+ BaseName::class => InvokableFactory::class,
+ Boolean::class => InvokableFactory::class,
+ Callback::class => InvokableFactory::class,
+ Compress::class => InvokableFactory::class,
+ DataUnitFormatter::class => InvokableFactory::class,
+ DateSelect::class => InvokableFactory::class,
+ DateTimeFormatter::class => InvokableFactory::class,
+ DateTimeSelect::class => InvokableFactory::class,
+ Decompress::class => InvokableFactory::class,
+ DenyList::class => InvokableFactory::class,
+ Digits::class => InvokableFactory::class,
+ Dir::class => InvokableFactory::class,
+ File\LowerCase::class => InvokableFactory::class,
+ File\Rename::class => InvokableFactory::class,
+ File\RenameUpload::class => InvokableFactory::class,
+ File\UpperCase::class => InvokableFactory::class,
+ HtmlEntities::class => InvokableFactory::class,
+ Inflector::class => InvokableFactory::class,
+ ToFloat::class => InvokableFactory::class,
+ MonthSelect::class => InvokableFactory::class,
+ UpperCaseWords::class => InvokableFactory::class,
+ PregReplace::class => InvokableFactory::class,
+ RealPath::class => InvokableFactory::class,
+ StringPrefix::class => InvokableFactory::class,
+ StringSuffix::class => InvokableFactory::class,
+ StringToLower::class => InvokableFactory::class,
+ StringToUpper::class => InvokableFactory::class,
+ StringTrim::class => InvokableFactory::class,
+ StripNewlines::class => InvokableFactory::class,
+ StripTags::class => InvokableFactory::class,
+ ToInt::class => InvokableFactory::class,
+ ToNull::class => InvokableFactory::class,
+ Word\CamelCaseToDash::class => InvokableFactory::class,
+ Word\CamelCaseToSeparator::class => InvokableFactory::class,
+ Word\CamelCaseToUnderscore::class => InvokableFactory::class,
+ Word\DashToCamelCase::class => InvokableFactory::class,
+ Word\DashToSeparator::class => InvokableFactory::class,
+ Word\DashToUnderscore::class => InvokableFactory::class,
+ Word\SeparatorToCamelCase::class => InvokableFactory::class,
+ Word\SeparatorToDash::class => InvokableFactory::class,
+ Word\SeparatorToSeparator::class => Word\Service\SeparatorToSeparatorFactory::class,
+ Word\UnderscoreToCamelCase::class => InvokableFactory::class,
+ Word\UnderscoreToStudlyCase::class => InvokableFactory::class,
+ Word\UnderscoreToDash::class => InvokableFactory::class,
+ Word\UnderscoreToSeparator::class => InvokableFactory::class,
+ ],
+ 'aliases' => [
+ // For the future
+ 'int' => ToInt::class,
+ 'Int' => ToInt::class,
+ 'null' => ToNull::class,
+ 'Null' => ToNull::class,
- // Standard filters
- 'allowlist' => AllowList::class,
- 'allowList' => AllowList::class,
- 'AllowList' => AllowList::class,
- 'basename' => BaseName::class,
- 'Basename' => BaseName::class,
- 'boolean' => Boolean::class,
- 'Boolean' => Boolean::class,
- 'callback' => Callback::class,
- 'Callback' => Callback::class,
- 'compress' => Compress::class,
- 'Compress' => Compress::class,
- 'dataunitformatter' => DataUnitFormatter::class,
- 'dataUnitFormatter' => DataUnitFormatter::class,
- 'DataUnitFormatter' => DataUnitFormatter::class,
- 'dateselect' => DateSelect::class,
- 'dateSelect' => DateSelect::class,
- 'DateSelect' => DateSelect::class,
- 'datetimeformatter' => DateTimeFormatter::class,
- 'datetimeFormatter' => DateTimeFormatter::class,
- 'DatetimeFormatter' => DateTimeFormatter::class,
- 'dateTimeFormatter' => DateTimeFormatter::class,
- 'DateTimeFormatter' => DateTimeFormatter::class,
- 'datetimeselect' => DateTimeSelect::class,
- 'datetimeSelect' => DateTimeSelect::class,
- 'DatetimeSelect' => DateTimeSelect::class,
- 'dateTimeSelect' => DateTimeSelect::class,
- 'DateTimeSelect' => DateTimeSelect::class,
- 'decompress' => Decompress::class,
- 'Decompress' => Decompress::class,
- 'denylist' => DenyList::class,
- 'denyList' => DenyList::class,
- 'DenyList' => DenyList::class,
- 'digits' => Digits::class,
- 'Digits' => Digits::class,
- 'dir' => Dir::class,
- 'Dir' => Dir::class,
- 'filelowercase' => File\LowerCase::class,
- 'fileLowercase' => File\LowerCase::class,
- 'FileLowercase' => File\LowerCase::class,
- 'fileLowerCase' => File\LowerCase::class,
- 'FileLowerCase' => File\LowerCase::class,
- 'filerename' => File\Rename::class,
- 'fileRename' => File\Rename::class,
- 'FileRename' => File\Rename::class,
- 'filerenameupload' => File\RenameUpload::class,
- 'fileRenameUpload' => File\RenameUpload::class,
- 'FileRenameUpload' => File\RenameUpload::class,
- 'fileuppercase' => File\UpperCase::class,
- 'fileUppercase' => File\UpperCase::class,
- 'FileUppercase' => File\UpperCase::class,
- 'fileUpperCase' => File\UpperCase::class,
- 'FileUpperCase' => File\UpperCase::class,
- 'htmlentities' => HtmlEntities::class,
- 'htmlEntities' => HtmlEntities::class,
- 'HtmlEntities' => HtmlEntities::class,
- 'inflector' => Inflector::class,
- 'Inflector' => Inflector::class,
- 'monthselect' => MonthSelect::class,
- 'monthSelect' => MonthSelect::class,
- 'MonthSelect' => MonthSelect::class,
- 'pregreplace' => PregReplace::class,
- 'pregReplace' => PregReplace::class,
- 'PregReplace' => PregReplace::class,
- 'realpath' => RealPath::class,
- 'realPath' => RealPath::class,
- 'RealPath' => RealPath::class,
- 'stringprefix' => StringPrefix::class,
- 'stringPrefix' => StringPrefix::class,
- 'StringPrefix' => StringPrefix::class,
- 'stringsuffix' => StringSuffix::class,
- 'stringSuffix' => StringSuffix::class,
- 'StringSuffix' => StringSuffix::class,
- 'stringtolower' => StringToLower::class,
- 'stringToLower' => StringToLower::class,
- 'StringToLower' => StringToLower::class,
- 'stringtoupper' => StringToUpper::class,
- 'stringToUpper' => StringToUpper::class,
- 'StringToUpper' => StringToUpper::class,
- 'stringtrim' => StringTrim::class,
- 'stringTrim' => StringTrim::class,
- 'StringTrim' => StringTrim::class,
- 'stripnewlines' => StripNewlines::class,
- 'stripNewlines' => StripNewlines::class,
- 'StripNewlines' => StripNewlines::class,
- 'striptags' => StripTags::class,
- 'stripTags' => StripTags::class,
- 'StripTags' => StripTags::class,
- 'toint' => ToInt::class,
- 'toInt' => ToInt::class,
- 'ToInt' => ToInt::class,
- 'tofloat' => ToFloat::class,
- 'toFloat' => ToFloat::class,
- 'ToFloat' => ToFloat::class,
- 'tonull' => ToNull::class,
- 'toNull' => ToNull::class,
- 'ToNull' => ToNull::class,
- 'uppercasewords' => UpperCaseWords::class,
- 'upperCaseWords' => UpperCaseWords::class,
- 'UpperCaseWords' => UpperCaseWords::class,
- 'wordcamelcasetodash' => Word\CamelCaseToDash::class,
- 'wordCamelCaseToDash' => Word\CamelCaseToDash::class,
- 'WordCamelCaseToDash' => Word\CamelCaseToDash::class,
- 'wordcamelcasetoseparator' => Word\CamelCaseToSeparator::class,
- 'wordCamelCaseToSeparator' => Word\CamelCaseToSeparator::class,
- 'WordCamelCaseToSeparator' => Word\CamelCaseToSeparator::class,
- 'wordcamelcasetounderscore' => Word\CamelCaseToUnderscore::class,
- 'wordCamelCaseToUnderscore' => Word\CamelCaseToUnderscore::class,
- 'WordCamelCaseToUnderscore' => Word\CamelCaseToUnderscore::class,
- 'worddashtocamelcase' => Word\DashToCamelCase::class,
- 'wordDashToCamelCase' => Word\DashToCamelCase::class,
- 'WordDashToCamelCase' => Word\DashToCamelCase::class,
- 'worddashtoseparator' => Word\DashToSeparator::class,
- 'wordDashToSeparator' => Word\DashToSeparator::class,
- 'WordDashToSeparator' => Word\DashToSeparator::class,
- 'worddashtounderscore' => Word\DashToUnderscore::class,
- 'wordDashToUnderscore' => Word\DashToUnderscore::class,
- 'WordDashToUnderscore' => Word\DashToUnderscore::class,
- 'wordseparatortocamelcase' => Word\SeparatorToCamelCase::class,
- 'wordSeparatorToCamelCase' => Word\SeparatorToCamelCase::class,
- 'WordSeparatorToCamelCase' => Word\SeparatorToCamelCase::class,
- 'wordseparatortodash' => Word\SeparatorToDash::class,
- 'wordSeparatorToDash' => Word\SeparatorToDash::class,
- 'WordSeparatorToDash' => Word\SeparatorToDash::class,
- 'wordseparatortoseparator' => Word\SeparatorToSeparator::class,
- 'wordSeparatorToSeparator' => Word\SeparatorToSeparator::class,
- 'WordSeparatorToSeparator' => Word\SeparatorToSeparator::class,
- 'wordunderscoretocamelcase' => Word\UnderscoreToCamelCase::class,
- 'wordUnderscoreToCamelCase' => Word\UnderscoreToCamelCase::class,
- 'WordUnderscoreToCamelCase' => Word\UnderscoreToCamelCase::class,
- 'wordunderscoretostudlycase' => Word\UnderscoreToStudlyCase::class,
- 'wordUnderscoreToStudlyCase' => Word\UnderscoreToStudlyCase::class,
- 'WordUnderscoreToStudlyCase' => Word\UnderscoreToStudlyCase::class,
- 'wordunderscoretodash' => Word\UnderscoreToDash::class,
- 'wordUnderscoreToDash' => Word\UnderscoreToDash::class,
- 'WordUnderscoreToDash' => Word\UnderscoreToDash::class,
- 'wordunderscoretoseparator' => Word\UnderscoreToSeparator::class,
- 'wordUnderscoreToSeparator' => Word\UnderscoreToSeparator::class,
- 'WordUnderscoreToSeparator' => Word\UnderscoreToSeparator::class,
-
- // Legacy Zend Framework aliases
- 'Zend\Filter\BaseName' => BaseName::class,
- 'Zend\Filter\Boolean' => Boolean::class,
- 'Zend\Filter\Callback' => Callback::class,
- 'Zend\Filter\Compress' => Compress::class,
- 'Zend\Filter\DataUnitFormatter' => DataUnitFormatter::class,
- 'Zend\Filter\DateSelect' => DateSelect::class,
- 'Zend\Filter\DateTimeFormatter' => DateTimeFormatter::class,
- 'Zend\Filter\DateTimeSelect' => DateTimeSelect::class,
- 'Zend\Filter\Decompress' => Decompress::class,
- 'Zend\Filter\Digits' => Digits::class,
- 'Zend\Filter\Dir' => Dir::class,
- 'Zend\Filter\File\LowerCase' => File\LowerCase::class,
- 'Zend\Filter\File\Rename' => File\Rename::class,
- 'Zend\Filter\File\RenameUpload' => File\RenameUpload::class,
- 'Zend\Filter\File\UpperCase' => File\UpperCase::class,
- 'Zend\Filter\HtmlEntities' => HtmlEntities::class,
- 'Zend\Filter\Inflector' => Inflector::class,
- 'Zend\Filter\ToInt' => ToInt::class,
- 'Zend\Filter\ToFloat' => ToFloat::class,
- 'Zend\Filter\MonthSelect' => MonthSelect::class,
- 'Zend\Filter\ToNull' => ToNull::class,
- 'Zend\Filter\UpperCaseWords' => UpperCaseWords::class,
- 'Zend\Filter\PregReplace' => PregReplace::class,
- 'Zend\Filter\RealPath' => RealPath::class,
- 'Zend\Filter\StringPrefix' => StringPrefix::class,
- 'Zend\Filter\StringSuffix' => StringSuffix::class,
- 'Zend\Filter\StringToLower' => StringToLower::class,
- 'Zend\Filter\StringToUpper' => StringToUpper::class,
- 'Zend\Filter\StringTrim' => StringTrim::class,
- 'Zend\Filter\StripNewlines' => StripNewlines::class,
- 'Zend\Filter\StripTags' => StripTags::class,
- 'Zend\Filter\Word\CamelCaseToDash' => Word\CamelCaseToDash::class,
- 'Zend\Filter\Word\CamelCaseToSeparator' => Word\CamelCaseToSeparator::class,
- 'Zend\Filter\Word\CamelCaseToUnderscore' => Word\CamelCaseToUnderscore::class,
- 'Zend\Filter\Word\DashToCamelCase' => Word\DashToCamelCase::class,
- 'Zend\Filter\Word\DashToSeparator' => Word\DashToSeparator::class,
- 'Zend\Filter\Word\DashToUnderscore' => Word\DashToUnderscore::class,
- 'Zend\Filter\Word\SeparatorToCamelCase' => Word\SeparatorToCamelCase::class,
- 'Zend\Filter\Word\SeparatorToDash' => Word\SeparatorToDash::class,
- 'Zend\Filter\Word\SeparatorToSeparator' => Word\SeparatorToSeparator::class,
- 'Zend\Filter\Word\UnderscoreToCamelCase' => Word\UnderscoreToCamelCase::class,
- 'Zend\Filter\Word\UnderscoreToStudlyCase' => Word\UnderscoreToStudlyCase::class,
- 'Zend\Filter\Word\UnderscoreToDash' => Word\UnderscoreToDash::class,
- 'Zend\Filter\Word\UnderscoreToSeparator' => Word\UnderscoreToSeparator::class,
-
- // v2 normalized FQCNs
- 'zendfiltertoint' => ToInt::class,
- 'zendfiltertofloat' => ToFloat::class,
- 'zendfiltertonull' => ToNull::class,
- 'zendfilterbasename' => BaseName::class,
- 'zendfilterboolean' => Boolean::class,
- 'zendfiltercallback' => Callback::class,
- 'zendfiltercompress' => Compress::class,
- 'zendfilterdataunitformatter' => DataUnitFormatter::class,
- 'zendfilterdateselect' => DateSelect::class,
- 'zendfilterdatetimeformatter' => DateTimeFormatter::class,
- 'zendfilterdatetimeselect' => DateTimeSelect::class,
- 'zendfilterdecompress' => Decompress::class,
- 'zendfilterdigits' => Digits::class,
- 'zendfilterdir' => Dir::class,
- 'zendfilterfilelowercase' => File\LowerCase::class,
- 'zendfilterfilerename' => File\Rename::class,
- 'zendfilterfilerenameupload' => File\RenameUpload::class,
- 'zendfilterfileuppercase' => File\UpperCase::class,
- 'zendfilterhtmlentities' => HtmlEntities::class,
- 'zendfilterinflector' => Inflector::class,
- 'zendfiltermonthselect' => MonthSelect::class,
- 'zendfilterpregreplace' => PregReplace::class,
- 'zendfilterrealpath' => RealPath::class,
- 'zendfilterstringprefix' => StringPrefix::class,
- 'zendfilterstringsuffix' => StringSuffix::class,
- 'zendfilterstringtolower' => StringToLower::class,
- 'zendfilterstringtoupper' => StringToUpper::class,
- 'zendfilterstringtrim' => StringTrim::class,
- 'zendfilterstripnewlines' => StripNewlines::class,
- 'zendfilterstriptags' => StripTags::class,
- 'zendfilteruppercasewords' => UpperCaseWords::class,
- 'zendfilterwordcamelcasetodash' => Word\CamelCaseToDash::class,
- 'zendfilterwordcamelcasetoseparator' => Word\CamelCaseToSeparator::class,
- 'zendfilterwordcamelcasetounderscore' => Word\CamelCaseToUnderscore::class,
- 'zendfilterworddashtocamelcase' => Word\DashToCamelCase::class,
- 'zendfilterworddashtoseparator' => Word\DashToSeparator::class,
- 'zendfilterworddashtounderscore' => Word\DashToUnderscore::class,
- 'zendfilterwordseparatortocamelcase' => Word\SeparatorToCamelCase::class,
- 'zendfilterwordseparatortodash' => Word\SeparatorToDash::class,
- 'zendfilterwordseparatortoseparator' => Word\SeparatorToSeparator::class,
- 'zendfilterwordunderscoretocamelcase' => Word\UnderscoreToCamelCase::class,
- 'zendfilterwordunderscoretostudlycase' => Word\UnderscoreToStudlyCase::class,
- 'zendfilterwordunderscoretodash' => Word\UnderscoreToDash::class,
- 'zendfilterwordunderscoretoseparator' => Word\UnderscoreToSeparator::class,
- // @codingStandardsIgnoreEnd
+ // Standard filters
+ 'allowlist' => AllowList::class,
+ 'allowList' => AllowList::class,
+ 'AllowList' => AllowList::class,
+ 'basename' => BaseName::class,
+ 'Basename' => BaseName::class,
+ 'boolean' => Boolean::class,
+ 'Boolean' => Boolean::class,
+ 'callback' => Callback::class,
+ 'Callback' => Callback::class,
+ 'compress' => Compress::class,
+ 'Compress' => Compress::class,
+ 'dataunitformatter' => DataUnitFormatter::class,
+ 'dataUnitFormatter' => DataUnitFormatter::class,
+ 'DataUnitFormatter' => DataUnitFormatter::class,
+ 'dateselect' => DateSelect::class,
+ 'dateSelect' => DateSelect::class,
+ 'DateSelect' => DateSelect::class,
+ 'datetimeformatter' => DateTimeFormatter::class,
+ 'datetimeFormatter' => DateTimeFormatter::class,
+ 'DatetimeFormatter' => DateTimeFormatter::class,
+ 'dateTimeFormatter' => DateTimeFormatter::class,
+ 'DateTimeFormatter' => DateTimeFormatter::class,
+ 'datetimeselect' => DateTimeSelect::class,
+ 'datetimeSelect' => DateTimeSelect::class,
+ 'DatetimeSelect' => DateTimeSelect::class,
+ 'dateTimeSelect' => DateTimeSelect::class,
+ 'DateTimeSelect' => DateTimeSelect::class,
+ 'decompress' => Decompress::class,
+ 'Decompress' => Decompress::class,
+ 'denylist' => DenyList::class,
+ 'denyList' => DenyList::class,
+ 'DenyList' => DenyList::class,
+ 'digits' => Digits::class,
+ 'Digits' => Digits::class,
+ 'dir' => Dir::class,
+ 'Dir' => Dir::class,
+ 'filelowercase' => File\LowerCase::class,
+ 'fileLowercase' => File\LowerCase::class,
+ 'FileLowercase' => File\LowerCase::class,
+ 'fileLowerCase' => File\LowerCase::class,
+ 'FileLowerCase' => File\LowerCase::class,
+ 'filerename' => File\Rename::class,
+ 'fileRename' => File\Rename::class,
+ 'FileRename' => File\Rename::class,
+ 'filerenameupload' => File\RenameUpload::class,
+ 'fileRenameUpload' => File\RenameUpload::class,
+ 'FileRenameUpload' => File\RenameUpload::class,
+ 'fileuppercase' => File\UpperCase::class,
+ 'fileUppercase' => File\UpperCase::class,
+ 'FileUppercase' => File\UpperCase::class,
+ 'fileUpperCase' => File\UpperCase::class,
+ 'FileUpperCase' => File\UpperCase::class,
+ 'htmlentities' => HtmlEntities::class,
+ 'htmlEntities' => HtmlEntities::class,
+ 'HtmlEntities' => HtmlEntities::class,
+ 'inflector' => Inflector::class,
+ 'Inflector' => Inflector::class,
+ 'monthselect' => MonthSelect::class,
+ 'monthSelect' => MonthSelect::class,
+ 'MonthSelect' => MonthSelect::class,
+ 'pregreplace' => PregReplace::class,
+ 'pregReplace' => PregReplace::class,
+ 'PregReplace' => PregReplace::class,
+ 'realpath' => RealPath::class,
+ 'realPath' => RealPath::class,
+ 'RealPath' => RealPath::class,
+ 'stringprefix' => StringPrefix::class,
+ 'stringPrefix' => StringPrefix::class,
+ 'StringPrefix' => StringPrefix::class,
+ 'stringsuffix' => StringSuffix::class,
+ 'stringSuffix' => StringSuffix::class,
+ 'StringSuffix' => StringSuffix::class,
+ 'stringtolower' => StringToLower::class,
+ 'stringToLower' => StringToLower::class,
+ 'StringToLower' => StringToLower::class,
+ 'stringtoupper' => StringToUpper::class,
+ 'stringToUpper' => StringToUpper::class,
+ 'StringToUpper' => StringToUpper::class,
+ 'stringtrim' => StringTrim::class,
+ 'stringTrim' => StringTrim::class,
+ 'StringTrim' => StringTrim::class,
+ 'stripnewlines' => StripNewlines::class,
+ 'stripNewlines' => StripNewlines::class,
+ 'StripNewlines' => StripNewlines::class,
+ 'striptags' => StripTags::class,
+ 'stripTags' => StripTags::class,
+ 'StripTags' => StripTags::class,
+ 'toint' => ToInt::class,
+ 'toInt' => ToInt::class,
+ 'ToInt' => ToInt::class,
+ 'tofloat' => ToFloat::class,
+ 'toFloat' => ToFloat::class,
+ 'ToFloat' => ToFloat::class,
+ 'tonull' => ToNull::class,
+ 'toNull' => ToNull::class,
+ 'ToNull' => ToNull::class,
+ 'uppercasewords' => UpperCaseWords::class,
+ 'upperCaseWords' => UpperCaseWords::class,
+ 'UpperCaseWords' => UpperCaseWords::class,
+ 'wordcamelcasetodash' => Word\CamelCaseToDash::class,
+ 'wordCamelCaseToDash' => Word\CamelCaseToDash::class,
+ 'WordCamelCaseToDash' => Word\CamelCaseToDash::class,
+ 'wordcamelcasetoseparator' => Word\CamelCaseToSeparator::class,
+ 'wordCamelCaseToSeparator' => Word\CamelCaseToSeparator::class,
+ 'WordCamelCaseToSeparator' => Word\CamelCaseToSeparator::class,
+ 'wordcamelcasetounderscore' => Word\CamelCaseToUnderscore::class,
+ 'wordCamelCaseToUnderscore' => Word\CamelCaseToUnderscore::class,
+ 'WordCamelCaseToUnderscore' => Word\CamelCaseToUnderscore::class,
+ 'worddashtocamelcase' => Word\DashToCamelCase::class,
+ 'wordDashToCamelCase' => Word\DashToCamelCase::class,
+ 'WordDashToCamelCase' => Word\DashToCamelCase::class,
+ 'worddashtoseparator' => Word\DashToSeparator::class,
+ 'wordDashToSeparator' => Word\DashToSeparator::class,
+ 'WordDashToSeparator' => Word\DashToSeparator::class,
+ 'worddashtounderscore' => Word\DashToUnderscore::class,
+ 'wordDashToUnderscore' => Word\DashToUnderscore::class,
+ 'WordDashToUnderscore' => Word\DashToUnderscore::class,
+ 'wordseparatortocamelcase' => Word\SeparatorToCamelCase::class,
+ 'wordSeparatorToCamelCase' => Word\SeparatorToCamelCase::class,
+ 'WordSeparatorToCamelCase' => Word\SeparatorToCamelCase::class,
+ 'wordseparatortodash' => Word\SeparatorToDash::class,
+ 'wordSeparatorToDash' => Word\SeparatorToDash::class,
+ 'WordSeparatorToDash' => Word\SeparatorToDash::class,
+ 'wordseparatortoseparator' => Word\SeparatorToSeparator::class,
+ 'wordSeparatorToSeparator' => Word\SeparatorToSeparator::class,
+ 'WordSeparatorToSeparator' => Word\SeparatorToSeparator::class,
+ 'wordunderscoretocamelcase' => Word\UnderscoreToCamelCase::class,
+ 'wordUnderscoreToCamelCase' => Word\UnderscoreToCamelCase::class,
+ 'WordUnderscoreToCamelCase' => Word\UnderscoreToCamelCase::class,
+ 'wordunderscoretostudlycase' => Word\UnderscoreToStudlyCase::class,
+ 'wordUnderscoreToStudlyCase' => Word\UnderscoreToStudlyCase::class,
+ 'WordUnderscoreToStudlyCase' => Word\UnderscoreToStudlyCase::class,
+ 'wordunderscoretodash' => Word\UnderscoreToDash::class,
+ 'wordUnderscoreToDash' => Word\UnderscoreToDash::class,
+ 'WordUnderscoreToDash' => Word\UnderscoreToDash::class,
+ 'wordunderscoretoseparator' => Word\UnderscoreToSeparator::class,
+ 'wordUnderscoreToSeparator' => Word\UnderscoreToSeparator::class,
+ 'WordUnderscoreToSeparator' => Word\UnderscoreToSeparator::class,
+ ],
];
- /**
- * Default set of plugins factories
- *
- * @var array
- */
- protected $factories = [
- // Standard filters
- AllowList::class => InvokableFactory::class,
- BaseName::class => InvokableFactory::class,
- Boolean::class => InvokableFactory::class,
- Callback::class => InvokableFactory::class,
- Compress::class => InvokableFactory::class,
- DataUnitFormatter::class => InvokableFactory::class,
- DateSelect::class => InvokableFactory::class,
- DateTimeFormatter::class => InvokableFactory::class,
- DateTimeSelect::class => InvokableFactory::class,
- Decompress::class => InvokableFactory::class,
- DenyList::class => InvokableFactory::class,
- Digits::class => InvokableFactory::class,
- Dir::class => InvokableFactory::class,
- File\LowerCase::class => InvokableFactory::class,
- File\Rename::class => InvokableFactory::class,
- File\RenameUpload::class => InvokableFactory::class,
- File\UpperCase::class => InvokableFactory::class,
- HtmlEntities::class => InvokableFactory::class,
- Inflector::class => InvokableFactory::class,
- ToInt::class => InvokableFactory::class,
- ToFloat::class => InvokableFactory::class,
- MonthSelect::class => InvokableFactory::class,
- ToNull::class => InvokableFactory::class,
- UpperCaseWords::class => InvokableFactory::class,
- PregReplace::class => InvokableFactory::class,
- RealPath::class => InvokableFactory::class,
- StringPrefix::class => InvokableFactory::class,
- StringSuffix::class => InvokableFactory::class,
- StringToLower::class => InvokableFactory::class,
- StringToUpper::class => InvokableFactory::class,
- StringTrim::class => InvokableFactory::class,
- StripNewlines::class => InvokableFactory::class,
- StripTags::class => InvokableFactory::class,
- ToInt::class => InvokableFactory::class,
- ToNull::class => InvokableFactory::class,
- Word\CamelCaseToDash::class => InvokableFactory::class,
- Word\CamelCaseToSeparator::class => InvokableFactory::class,
- Word\CamelCaseToUnderscore::class => InvokableFactory::class,
- Word\DashToCamelCase::class => InvokableFactory::class,
- Word\DashToSeparator::class => InvokableFactory::class,
- Word\DashToUnderscore::class => InvokableFactory::class,
- Word\SeparatorToCamelCase::class => InvokableFactory::class,
- Word\SeparatorToDash::class => InvokableFactory::class,
- Word\SeparatorToSeparator::class => Word\Service\SeparatorToSeparatorFactory::class,
- Word\UnderscoreToCamelCase::class => InvokableFactory::class,
- Word\UnderscoreToStudlyCase::class => InvokableFactory::class,
- Word\UnderscoreToDash::class => InvokableFactory::class,
- Word\UnderscoreToSeparator::class => InvokableFactory::class,
-
- // v2 canonical FQCNs
- 'laminasfiltertoint' => InvokableFactory::class,
- 'laminasfiltertofloat' => InvokableFactory::class,
- 'laminasfiltertonull' => InvokableFactory::class,
- 'laminasfilterbasename' => InvokableFactory::class,
- 'laminasfilterboolean' => InvokableFactory::class,
- 'laminasfiltercallback' => InvokableFactory::class,
- 'laminasfiltercompress' => InvokableFactory::class,
- 'laminasfilterdataunitformatter' => InvokableFactory::class,
- 'laminasfilterdateselect' => InvokableFactory::class,
- 'laminasfilterdatetimeformatter' => InvokableFactory::class,
- 'laminasfilterdatetimeselect' => InvokableFactory::class,
- 'laminasfilterdecompress' => InvokableFactory::class,
- 'laminasfilterdigits' => InvokableFactory::class,
- 'laminasfilterdir' => InvokableFactory::class,
- 'laminasfilterfilelowercase' => InvokableFactory::class,
- 'laminasfilterfilerename' => InvokableFactory::class,
- 'laminasfilterfilerenameupload' => InvokableFactory::class,
- 'laminasfilterfileuppercase' => InvokableFactory::class,
- 'laminasfilterhtmlentities' => InvokableFactory::class,
- 'laminasfilterinflector' => InvokableFactory::class,
- 'laminasfiltermonthselect' => InvokableFactory::class,
- 'laminasfilterpregreplace' => InvokableFactory::class,
- 'laminasfilterrealpath' => InvokableFactory::class,
- 'laminasfilterstringprefix' => InvokableFactory::class,
- 'laminasfilterstringsuffix' => InvokableFactory::class,
- 'laminasfilterstringtolower' => InvokableFactory::class,
- 'laminasfilterstringtoupper' => InvokableFactory::class,
- 'laminasfilterstringtrim' => InvokableFactory::class,
- 'laminasfilterstripnewlines' => InvokableFactory::class,
- 'laminasfilterstriptags' => InvokableFactory::class,
- 'laminasfilteruppercasewords' => InvokableFactory::class,
- 'laminasfilterwordcamelcasetodash' => InvokableFactory::class,
- 'laminasfilterwordcamelcasetoseparator' => InvokableFactory::class,
- 'laminasfilterwordcamelcasetounderscore' => InvokableFactory::class,
- 'laminasfilterworddashtocamelcase' => InvokableFactory::class,
- 'laminasfilterworddashtoseparator' => InvokableFactory::class,
- 'laminasfilterworddashtounderscore' => InvokableFactory::class,
- 'laminasfilterwordseparatortocamelcase' => InvokableFactory::class,
- 'laminasfilterwordseparatortodash' => InvokableFactory::class,
- 'laminasfilterwordseparatortoseparator' => Word\Service\SeparatorToSeparatorFactory::class,
- 'laminasfilterwordunderscoretocamelcase' => InvokableFactory::class,
- 'laminasfilterwordunderscoretostudlycase' => InvokableFactory::class,
- 'laminasfilterwordunderscoretodash' => InvokableFactory::class,
- 'laminasfilterwordunderscoretoseparator' => InvokableFactory::class,
- ];
+ /** Filter instances are never shared */
+ protected bool $sharedByDefault = false;
- protected $instanceOf = FilterInterface::class;
+ /** Generally speaking, filters can be constructed without arguments */
+ protected bool $autoAddInvokableClass = true;
/**
- * Whether or not to share by default; default to false (v2)
- *
- * @var bool
+ * @param ServiceManagerConfiguration $config
*/
- protected $shareByDefault = false;
-
- /**
- * Whether or not to share by default; default to false (v3)
- *
- * @var bool
- */
- protected $sharedByDefault = false;
+ public function __construct(ContainerInterface $creationContext, array $config = [])
+ {
+ /** @var ServiceManagerConfiguration $config */
+ $config = array_replace_recursive(self::CONFIGURATION, $config);
+ parent::__construct($creationContext, $config);
+ }
- /**
- * {@inheritdoc}
- *
- * @psalm-assert FilterInterface|callable(mixed): mixed $instance
- */
- public function validate(mixed $instance)
+ /** @inheritDoc */
+ public function validate(mixed $instance): void
{
- if ($instance instanceof $this->instanceOf) {
- // we're okay
+ if ($instance instanceof FilterInterface) {
return;
}
if (is_callable($instance)) {
- // also okay
return;
}
@@ -408,47 +257,4 @@ public function validate(mixed $instance)
__NAMESPACE__
));
}
-
- /**
- * Validate the plugin (v2)
- *
- * Checks that the filter loaded is either a valid callback or an instance
- * of FilterInterface.
- *
- * @return void
- * @throws RuntimeException If invalid.
- */
- public function validatePlugin(mixed $plugin)
- {
- try {
- $this->validate($plugin);
- } catch (InvalidServiceException $e) {
- throw new RuntimeException($e->getMessage(), $e->getCode(), $e);
- }
- }
-
- /**
- * @inheritDoc
- * @template InstanceType of FilterInterface
- * @param class-string|string $name Service name of plugin to retrieve.
- * @param null|array $options Options to use when creating the instance.
- * @return InstanceType|callable(mixed): mixed
- * @psalm-return ($name is class-string ? InstanceType : callable(mixed): mixed)
- */
- public function get($name, ?array $options = null)
- {
- /** @psalm-suppress MixedReturnStatement */
- return parent::get($name, $options);
- }
-
- /**
- * @param string $name
- * @param FilterInterface|callable(mixed): mixed $service
- * @return void
- * @psalm-suppress MoreSpecificImplementedParamType
- */
- public function setService($name, $service)
- {
- parent::setService($name, $service);
- }
}
diff --git a/src/FilterProviderInterface.php b/src/FilterProviderInterface.php
index 0a075cc4..72978d28 100644
--- a/src/FilterProviderInterface.php
+++ b/src/FilterProviderInterface.php
@@ -4,16 +4,20 @@
namespace Laminas\Filter;
+use Laminas\ServiceManager\ServiceManager;
+
/**
* Implement this interface within Module classes to indicate that your module
* provides filter configuration for the FilterPluginManager.
+ *
+ * @psalm-import-type ServiceManagerConfiguration from ServiceManager
*/
interface FilterProviderInterface
{
/**
* Provide plugin manager configuration for filters.
*
- * @return array
+ * @return ServiceManagerConfiguration
*/
- public function getFilterConfig();
+ public function getFilterConfig(): array;
}
diff --git a/src/Module.php b/src/Module.php
index a03522ca..4bb95a51 100644
--- a/src/Module.php
+++ b/src/Module.php
@@ -5,13 +5,19 @@
namespace Laminas\Filter;
use Laminas\ModuleManager\ModuleManager;
+use Laminas\ServiceManager\ServiceManager;
+/**
+ * @psalm-import-type ServiceManagerConfiguration from ServiceManager
+ */
class Module
{
/**
* Return default laminas-filter configuration for laminas-mvc applications.
+ *
+ * @return array{service_manager: ServiceManagerConfiguration}
*/
- public function getConfig()
+ public function getConfig(): array
{
$provider = new ConfigProvider();
@@ -24,9 +30,8 @@ public function getConfig()
* Register a specification for the FilterManager with the ServiceListener.
*
* @param ModuleManager $moduleManager
- * @return void
*/
- public function init($moduleManager)
+ public function init($moduleManager): void
{
$event = $moduleManager->getEvent();
$container = $event->getParam('ServiceManager');
diff --git a/test/AllowListTest.php b/test/AllowListTest.php
index d22c3581..c19ce1fa 100644
--- a/test/AllowListTest.php
+++ b/test/AllowListTest.php
@@ -5,8 +5,6 @@
namespace LaminasTest\Filter;
use Laminas\Filter\AllowList as AllowListFilter;
-use Laminas\Filter\FilterPluginManager;
-use Laminas\ServiceManager\ServiceManager;
use Laminas\Stdlib\ArrayObject;
use Laminas\Stdlib\Exception;
use PHPUnit\Framework\Attributes\DataProvider;
@@ -39,7 +37,7 @@ public function testConstructorDefaults(): void
public function testWithPluginManager(): void
{
- $pluginManager = new FilterPluginManager(new ServiceManager());
+ $pluginManager = CreatePluginManager::withDefaults();
$filter = $pluginManager->get('AllowList');
self::assertInstanceOf(AllowListFilter::class, $filter);
diff --git a/test/CreatePluginManager.php b/test/CreatePluginManager.php
new file mode 100644
index 00000000..6984e904
--- /dev/null
+++ b/test/CreatePluginManager.php
@@ -0,0 +1,19 @@
+get('DenyList');
self::assertInstanceOf(DenyListFilter::class, $filter);
diff --git a/test/FilterChainTest.php b/test/FilterChainTest.php
index 33b3df7f..649d1e34 100644
--- a/test/FilterChainTest.php
+++ b/test/FilterChainTest.php
@@ -62,7 +62,7 @@ public function testAllowsConnectingArbitraryCallbacks(): void
public function testAllowsConnectingViaClassShortName(): void
{
$chain = new FilterChain();
- $chain->attachByName(StringTrim::class, null, 100)
+ $chain->attachByName(StringTrim::class, [], 100)
->attachByName(StripTags::class)
->attachByName(StringToLower::class, ['encoding' => 'utf-8'], 900);
diff --git a/test/FilterPluginManagerCompatibilityTest.php b/test/FilterPluginManagerCompatibilityTest.php
index 99d9cba5..9df0e2fa 100644
--- a/test/FilterPluginManagerCompatibilityTest.php
+++ b/test/FilterPluginManagerCompatibilityTest.php
@@ -5,53 +5,84 @@
namespace LaminasTest\Filter;
use Generator;
-use Laminas\Filter\Exception\RuntimeException;
-use Laminas\Filter\FilterInterface;
use Laminas\Filter\FilterPluginManager;
-use Laminas\ServiceManager\ServiceManager;
-use Laminas\ServiceManager\Test\CommonPluginManagerTrait;
+use Laminas\ServiceManager\Exception\InvalidServiceException;
use PHPUnit\Framework\TestCase;
-use ReflectionProperty;
+use ReflectionClass;
+use stdClass;
+use Throwable;
+use function assert;
+use function class_exists;
+use function is_string;
use function strpos;
class FilterPluginManagerCompatibilityTest extends TestCase
{
- use CommonPluginManagerTrait;
-
protected static function getPluginManager(): FilterPluginManager
{
- return new FilterPluginManager(new ServiceManager());
- }
-
- protected function getV2InvalidPluginException(): string
- {
- return RuntimeException::class;
- }
-
- protected function getInstanceOf(): string
- {
- return FilterInterface::class;
+ return CreatePluginManager::withDefaults();
}
- /** @return Generator */
+ /** @return Generator */
public static function aliasProvider(): Generator
{
- $pluginManager = self::getPluginManager();
- $r = new ReflectionProperty($pluginManager, 'aliases');
- $aliases = $r->getValue($pluginManager);
- self::assertIsArray($aliases);
+ $class = new ReflectionClass(FilterPluginManager::class);
+ $config = $class->getConstant('CONFIGURATION');
+ self::assertIsArray($config);
+ self::assertArrayHasKey('aliases', $config);
+ self::assertIsArray($config['aliases']);
- foreach ($aliases as $alias => $target) {
- self::assertIsString($alias);
- self::assertIsString($target);
+ foreach ($config['aliases'] as $alias => $target) {
+ assert(is_string($alias) && is_string($target));
// Skipping as it has required options
if (strpos($target, 'DataUnitFormatter') !== false) {
continue;
}
+ assert(class_exists($target));
+
yield $alias => [$alias, $target];
}
}
+
+ /**
+ * @param class-string $expected
+ * @dataProvider aliasProvider
+ */
+ public function testPluginAliasesResolve(string $alias, string $expected): void
+ {
+ self::assertInstanceOf(
+ $expected,
+ self::getPluginManager()->get($alias),
+ "Alias '$alias' does not resolve'",
+ );
+ }
+
+ public function testLoadingInvalidElementRaisesException(): void
+ {
+ $manager = self::getPluginManager();
+ $manager->configure([
+ 'factories' => [
+ 'test' => static fn(): stdClass => new stdClass(),
+ ],
+ ]);
+ $this->expectException($this->getServiceNotFoundException());
+ $manager->get('test');
+ }
+
+ /** @return class-string */
+ protected function getServiceNotFoundException(): string
+ {
+ return InvalidServiceException::class;
+ }
+
+ public function testRegisteringInvalidElementRaisesException(): void
+ {
+ $manager = self::getPluginManager();
+ $this->expectException($this->getServiceNotFoundException());
+ /** @psalm-suppress InvalidArgument - Because we are testing an invalid argument */
+ $manager->setService('test', new stdClass());
+ }
}
diff --git a/test/FilterPluginManagerFactoryTest.php b/test/FilterPluginManagerFactoryTest.php
index 7079d40d..9ed3537a 100644
--- a/test/FilterPluginManagerFactoryTest.php
+++ b/test/FilterPluginManagerFactoryTest.php
@@ -8,10 +8,10 @@
use Laminas\Filter\FilterInterface;
use Laminas\Filter\FilterPluginManager;
use Laminas\Filter\FilterPluginManagerFactory;
+use Laminas\ServiceManager\Factory\InvokableFactory;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
-use ReflectionObject;
class FilterPluginManagerFactoryTest extends TestCase
{
@@ -21,10 +21,6 @@ public function testFactoryReturnsPluginManager(): void
$factory = new FilterPluginManagerFactory();
$filters = $factory($container);
self::assertInstanceOf(FilterPluginManager::class, $filters);
-
- $r = new ReflectionObject($filters);
- $p = $r->getProperty('creationContext');
- self::assertSame($container, $p->getValue($filters));
}
public function testConfiguresFilterServicesWhenFound(): void
@@ -36,7 +32,8 @@ public function testConfiguresFilterServicesWhenFound(): void
'test' => Boolean::class,
],
'factories' => [
- 'test-too' => static fn(): MockObject&FilterInterface => $filter,
+ Boolean::class => InvokableFactory::class,
+ 'test-too' => static fn(): MockObject&FilterInterface => $filter,
],
],
];
diff --git a/test/FilterPluginManagerTest.php b/test/FilterPluginManagerTest.php
index 0480e99e..cfac4f60 100644
--- a/test/FilterPluginManagerTest.php
+++ b/test/FilterPluginManagerTest.php
@@ -9,7 +9,6 @@
use Laminas\Filter\ToInt;
use Laminas\Filter\Word\SeparatorToSeparator;
use Laminas\ServiceManager\Exception\InvalidServiceException;
-use Laminas\ServiceManager\ServiceManager;
use LaminasTest\Filter\TestAsset\NotAValidFilter;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;
@@ -23,7 +22,7 @@ class FilterPluginManagerTest extends TestCase
public function setUp(): void
{
- $this->filters = new FilterPluginManager(new ServiceManager());
+ $this->filters = CreatePluginManager::withDefaults();
}
public function testFilterSuccessfullyRetrieved(): void
@@ -57,7 +56,7 @@ public function testFilterSuccessfullyConstructed(): void
'replacement_separator' => $replacementSeparator,
];
- $filter = $this->filters->get('wordseparatortoseparator', $options);
+ $filter = $this->filters->build('wordseparatortoseparator', $options);
self::assertInstanceOf(SeparatorToSeparator::class, $filter);
self::assertSame($searchSeparator, $filter->getSearchSeparator());
@@ -67,7 +66,7 @@ public function testFilterSuccessfullyConstructed(): void
#[Group('7169')]
public function testFiltersConstructedAreDifferent(): void
{
- $filterOne = $this->filters->get(
+ $filterOne = $this->filters->build(
'wordseparatortoseparator',
[
'search_separator' => ';',
@@ -75,7 +74,7 @@ public function testFiltersConstructedAreDifferent(): void
]
);
- $filterTwo = $this->filters->get(
+ $filterTwo = $this->filters->build(
'wordseparatortoseparator',
[
'search_separator' => '.',
diff --git a/test/StaticAnalysis/PluginRetrieval.php b/test/StaticAnalysis/PluginRetrieval.php
index 1778fde3..affcb520 100644
--- a/test/StaticAnalysis/PluginRetrieval.php
+++ b/test/StaticAnalysis/PluginRetrieval.php
@@ -4,6 +4,7 @@
namespace LaminasTest\Filter\StaticAnalysis;
+use Laminas\Filter\FilterInterface;
use Laminas\Filter\FilterPluginManager;
use Laminas\Filter\StringToUpper;
@@ -14,6 +15,21 @@ public function __construct(private FilterPluginManager $pluginManager)
{
}
+ public function fqcnPluginTypesAreInferredInGet(): StringToUpper
+ {
+ return $this->pluginManager->get(StringToUpper::class);
+ }
+
+ public function fqcnPluginTypesAreInferredInBuild(): StringToUpper
+ {
+ return $this->pluginManager->build(StringToUpper::class);
+ }
+
+ public function expectCallableOrFilterInterfaceForArbitraryString(): FilterInterface|callable
+ {
+ return $this->pluginManager->get('something');
+ }
+
public function filterSomethingWithAKnownFilterClass(string $value): string
{
$plugin = $this->pluginManager->get(StringToUpper::class);