问题
我有Form
和FieldSet
。我想验证FieldSet
不是空的。另外,我想验证FieldSet
中的每个字段。
到目前为止,无论我尝试过什么,都要验证其中一个,但不是两个。如果表单的输入过滤器规范中存在elements
,则它会验证elements
不为空,但不验证bar
的{{1}}和baz
字段}。而且,当然,反过来。任何关于如何处理这个问题的线索都将非常感激。
表格
FieldSet
FieldSet
class FooForm extends Form implements InputFilterProviderInterface
{
public function init()
{
$this->add([
'name' => 'elements',
'type' => Collection::class,
'required' => true,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class
]
]
]);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'elements',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
]
];
}
}
修改:添加了完整的验证规范。
答案 0 :(得分:2)
在获得谷歌的一些提示并挖掘源代码后,我找到了解决方案。遗憾的是,zend-inputfilter
实施有点儿错误,并且无法与getInputFilterSpecification()
很好地协作,但我们可以构建自己的InputFilter
并直接返回:
表格
class FooForm extends BaseForm
{
public function init()
{
$this->add([
'name' => 'elements',
'type' => Collection::class,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class
]
]
]);
}
public function getInputFilter()
{
if (!$this->filter) {
$this->filter = new InputFilter();
/** @var Collection $elementsCollection */
$elementsCollection = $this->fieldsets['elements'];
/** @var SomeElementFieldSet $elementsFieldSet */
$elementsFieldSet = $elementsCollection->getTargetElement();
$collectionFilter = new CollectionInputFilter();
$collectionFilter->setIsRequired(true);
$collectionFilter->setInputFilter(
$elementsFieldSet->getInputFilterSpecification()
);
$this->filter->add($collectionFilter, 'elements');
}
return $this->filter;
}
}
这将验证集合中至少有一个元素。并将通过FieldSet的规范逐个验证所有元素。
但仍存在一个问题。每当集合为空时,验证将返回false
,但不会返回任何消息。这是由zend-inputfilter
组件中的错误引起的。报告的问题here和here。但这完全是另一个问题。
答案 1 :(得分:1)
通过指定要验证的输入字段数组,在setValidationGroup()
对象中使用Form
方法。请参阅Doc!
您可以尝试这种方式。虽然我已经在表单中添加了一些额外的字段,仅用于测试目的。
class FooForm extends Form implements InputFilterProviderInterface
{
public function __construct($name = null, $options = array())
{
parent::__construct($name, $options);
$this->add(['name' => 'title']);
$this->add([
'name' => 'elements',
'type' => Collection::class,
'required' => true,
'options' => [
'target_element' => [
'type' => SomeElementFieldSet::class,
],
],
]);
$this->add([
'type' => 'submit',
'name' => 'submit',
'attributes' => [
'value' => 'Post'
],
]);
// I pointed this. Here you can specify fields to be validated
$this->setValidationGroup([
'title',
'elements' => [
'bar',
],
]);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'title',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
],
];
}
}
你的字段集类应该是
class SomeElementFieldSet extends Fieldset implements InputFilterProviderInterface
{
public function init()
{
$this->add(['name' => 'bar']);
$this->add(['name' => 'baz']);
}
public function getInputFilterSpecification()
{
return [
[
'name' => 'bar',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
],
[
'name' => 'baz',
'required' => true,
'validators' => [
['name' => 'NotEmpty']
]
]
];
}
}
希望这会有所帮助!