在ZF2 FieldSet中至少需要一个元素

时间:2017-06-06 09:01:32

标签: php zend-framework zend-framework2 zend-form zend-form2

问题

我有FormFieldSet。我想验证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']
                ]
            ]
        ];
    }
}

修改:添加了完整的验证规范。

2 个答案:

答案 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组件中的错误引起的。报告的问题herehere。但这完全是另一个问题。

答案 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']
                ]
            ]
        ];
    }
} 

希望这会有所帮助!