0

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

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

像这样?或者是一种更清洁的方法来解决这个问题?

4

1 回答 1

0

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

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

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

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

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

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

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

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

$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;
}
于 2016-08-23T10:07:38.290 回答