0

问题

我有一个Form和一个FieldSet。我想验证FieldSet不是空的。另外,我想验证FieldSet.

到目前为止,我所尝试的都是验证一个或另一个,但不能同时验证两者。如果elements存在于表单的输入过滤器规范中,则它验证它elements不是空的,但不验证bar和的baz字段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']
                ]
            ]
        ];
    }
}

字段集

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

编辑:添加了完整的验证规范。

4

2 回答 2

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组件中的错误。此处此处报告的问题。但这完全是另一个问题。

于 2017-06-26T09:26:51.457 回答
1

通过指定要验证的输入字段数组来使用对象setValidationGroup()中的方法。Form请参考文档

你可以试试这种方式。虽然我在表单中添加了一些额外的字段,仅用于测试目的。

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

希望这会有所帮助!

于 2017-06-06T12:41:01.183 回答