【问题标题】:What is the correct way to add validation on the form level in ZF2?在 ZF2 中的表单级别添加验证的正确方法是什么?
【发布时间】:2016-08-23 09:53:45
【问题描述】:

有一个包含大量嵌套字段集的复杂表单。某些字段需要根据另一个字段集中的字段(-s)进行验证。所以我不能直接在FieldsetgetInputFilterSpecification() 中定义所有验证规则,因为在那里我无法访问其他字段集(只有子字段集)。这样做的唯一方法是扩展Form 验证。对?如果是这样,该怎么做?

MyForm extends Form
{
    public function isValid()
    {
        $isFormValid = parent::isValid();
        $isFieldXyzValid = // my additional validation logic
        if(! $isFieldXyzValid) {
            $fieldXyz->setMessages(...);
        }
        return $isFormValid && $isFieldXyzValid;
    }
}

像这样?还是有更简洁的方法来解决这个问题?

【问题讨论】:

    标签: validation zend-framework2 zend-form zend-form-element zend-form-fieldset


    【解决方案1】:

    我已经在之前的项目中开发了类似的东西。

    为此,我使用了一项服务,该服务采用我的表单并设置动态字段集,显然还有自定义验证规则。

    在您的控制器中,获取您的表单(通过依赖注入 formManager(填充或不填充)。

    $form = $this->formManager->get('{your form}');
    

    致电您的服务并提供您的表格。

    在您的服务中,您可以做任何您想做的事情:

    • 获取您的资料(来自 DB 或其他人)以确定哪些字段是强制性的
    • 在您的表单上使用 Foreach
    • 添加或删除字段集
    • 添加或删除验证组字段
    • 添加或删除过滤器
    • 添加或删除验证器

    我通过(示例)在 $stuff 是学说集合的一个元素的 foreach 中执行了这些操作

    $nameFieldset = 'my_fieldset-'.$stuff->getId();
                $globalValidator = new GlobalValidator();
                $globalValidator->setGlobalValue($gloablValue);
    
                $uoValidator = new UcValidator();
                $uoValidator->setOptions(array(
                    'idToValidate' => $stuff->getId(),
                    'translator' => $this->translator
                ));
    
                $globalValidator->setOptions(array(
                    'idToValidate' => $stuff->getId(),
                    'translator' => $this->translator
                ));
    
                $name = 'qty-'.$stuff->getId();
    
                $form = $this->setFilters($form, $name, $nameFieldset);
                $globalValidator->setData($data);
                $form = $this->setValidators($form, $name, $globalValidator, $uoValidator, $nameFieldset);
    

    setFilters 和 setValidators 是自定义方法,可以将过滤器和验证器添加到我的字段(也是自定义的)

    /**
     * @param myForm $form
     * @param $name
     * @param string $nameFieldset
     * @return myForm
     */
    public function setFilters($form, $name, $nameFieldset)
    {
        $form->getInputFilter()->get('items')->get($nameFieldset)
            ->get($name)
            ->getFilterChain()
            ->getFilters()
            ->insert(new StripTags())
            ->insert(new StringTrim());
    
        return $form;
    }
    
    
    /**
     * @param myForm $form
     * @param $name
     * @param $globalValidator
     * @param $uoValidator
     * @param $nameFieldset
     * @return myForm
     */
    public function setValidators($form, $name, $globalValidator, $uoValidator, $nameFieldset)
    {
        $optionsSpace = [
            'translator' => $this->translator,
            'type' => NotEmpty::SPACE
        ];
        $optionsString = [
            'translator' => $this->translator,
            'type' => NotEmpty::STRING
        ];
        $optionsDigits = [
            'translator' => $this->translator,
        ];
        $form->getInputFilter()->get('items')
            ->get($nameFieldset)
            ->get($name)
            ->setRequired(true)
            ->getValidatorChain()
            ->attach($uoValidator, true, 1)
            ->attach($globalValidator, true, 1)
            // We authorize zéro but not space nor strings
            ->attach(new NotEmpty($optionsSpace), true, 2)
            ->attach(new NotEmpty($optionsString), true, 2)
            ->attach(new Digits($optionsDigits), true, 2);
        return $form;
    }
    

    【讨论】:

    • 感谢您的详细解答!但我认为,我正在寻找的不是: 1. 我以另一种方式“编译”我的 Form - 只有一个 Form 并且它(及其 Fieldsets)变得不同(sub -)Fieldsets 取决于上下文。 2.实际问题是验证字段,当这个验证依赖于另一个Fieldset的字段时。
    • 在这个示例中,我也只有一个表单,就像你在这个答案中看到的那样,我添加了尽可能多的字段集,因为我的收藏中有东西。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-06-05
    相关资源
    最近更新 更多