我有一个自定义验证器:
class CustomValidator extends RecordExists
{
public function isValid($value, array $context = null)
{
// some behaviour
return parent::isValid($value);
}
}
此验证器有一个工厂:
class CustomValidatorFactory implements FactoryInterface
{
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
$validator = new CustomValidator();
// preparations for CustomValidator
return $validator;
}
}
CustomValidator
及其工厂已在module.config.php
下注册
'validators' => [
'factories' => [
CustomValidator::class => CustomValidatorFactory::class,
],
],
CustomValidator
附加到getInputFilterSpecification()
中的字段集输入
'validators' => [
['name' => CustomValidator::class],
]
通过表单的init()
方法调用字段集,并在控制器工厂中将表单调用为$container->get('FormElementManager')->get('TheNeededForm')
。
问题在于,出于某种原因,CustomValidator
不是通过CustomValidatorFactory
实例化,而是getInputFilterSpecification()
字段集只创建new CustomValidator()
的实例。
如何通过工厂进行自定义验证器实例化?
PS:我已经上网了,发现了类似的问题,但是那里给出的解决方案没有帮助:它建议在'abstract_factories' => [FormAbstractServiceFactory::class]
指令下的module.config.php
中添加'form_elements'
。
答案 0 :(得分:0)
我已经在这里回答了这个问题
https://stackoverflow.com/a/61287283/4685379
这里是:
在ZF3 / Laminas中,如果将验证器注册为可调用项,则可以使用表格的getInputFilterSpecification()
调用验证器,这没有问题。如果使用工厂实例化验证器,则会遇到麻烦。如果我理解正确,即使您的表格是这样注册的
'form_elements' => [
'factories' => [
SomeForm::class => SomeFormFactory::class,
]
]
和您的验证者:
'validators' => [
'factories' => [
SomeValidator::class => SomeValidatorFactory::class,
]
]
您将不会通过工厂实例化验证器。原因是表单工厂(您得到的$form->getFormFactory()
之类的表单工厂)具有输入过滤器工厂,并且其中存在默认验证程序链。并且此验证程序链没有附加ValidatorManager
。并且如果没有ValidatorManager
,则默认链无法将验证者名称映射到验证者工厂。
要解决所有这些头痛问题,请在您的控制器工厂中执行以下操作:
$form->('FormElementManager')->get(SomeForm::class);
$form->getFormFactory()->getInputFilterFactory()
->getDefaultValidatorChain()->setPluginManager($container->get('ValidatorManager'));
麻烦就过去了。