为Symfony 2中的每个集合中的每个项目指定不同的验证组



[关于集合的文档]嵌入表单(集合类型)可以根据当前项目为每个项目指定验证组吗?似乎无法使用ATM。

TaskType表单添加标签集合:

// src/Acme/TaskBundle/Form/Type/TaskType.php
// ...
public function buildForm(FormBuilderInterface $builder, array $options)
{
    // ...
    $builder->add('tags', 'collection', array(
        // ...
        'by_reference' => false,
    ));
}

例如,我们有两个标签(标签1和标签2),并且使用" add"按钮添加了一个新标签(通过JavaScript):

-----------
| add tag |
-----------
- tag 1 (existing)
- tag 2 (added clicking the "add tag" button)

标签1应针对DefaultEdit组验证,而TAG 2仅针对Default组。

TagType形式定义动态验证组

基于基础数据,如果标签是新的,则将获得Default组,如果存在DefaultCreate组:

// ...
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        'validation_groups' => function (FormInterface $form) {
            $tag = $form->getData();
            $groups = array('Default');
            if (null !== $tag && null !== $tag->getId()) {
                $groups[] = 'Edit';
            }
            return $groups;
        }
    ));
}
// ...

Tag实体在"编辑"组中具有约束

Tag定义两个属性的示例(省略了登录):

class Tag
{
    /**
     * @AssertNotBlank()
     */
    protected $name;
    /**
     * @AssertNotBlank(groups={"Edit"})
     * @AssertLength(max="255")
     */
    protected $description;
    // ...
}

对于现有标签:描述不应为空白。对于新标签:描述可以为空白。

证明表单有效,验证器显示错误(错误!)

只需编辑现有标签,然后将描述留为空白即可。表单验证,但验证器服务显示错误

$form = $this->createForm('task', $task)
    ->handleRequest($request);
$validator = $this->get('validator');
if ($form->isValid()) {
    foreach ($task->getTags() as $tag) {
        // Validate against Default, Edit groups
        $errors = $validator->validate($tag, array('Default', 'Edit'));
        if (null !== $tag && null !== $tag->getId()) {
            echo 'Existing tag #'.$tag->getId();
        } else {
            echo 'New tag';
        }
        echo ', errors: '.count($errors).'<br>';
    }
    die('Form is valid.')
    // ...
}

输出:

Existing tag #863, errors: 1
Form is valid.

更新1 :我尝试过(没有成功),使用静态方法determineValidationGroups,如下所示:

public static function determineValidationGroups(FormInterface $form)
{
    $groups =  array('Default');
    if ($form->getData() !== null && null !== $form->getData()->getId())
    {
        $groups =  array('Edit');
    }
    var_dump($groups);
    return $groups;
}

TagType表格中:

/**
 * {@inheritdoc}
 */
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
    $resolver->setDefaults(array(
        // ... 
        'validation_groups' => array(
            'AcmeTaskBundleEntityTag',
            'determineValidationGroups'
        ),
    ));
}

仅使用一个现有标签的输出,一个使用"添加标签"链接创建的标签似乎正确。但是没有对现有标签的错误,使描述空白:

array (size=1)
  0 => string 'Edit' (length=4)
array (size=1)
  0 => string 'Edit' (length=4)
rray (size=1)
  0 => string 'Default' (length=7)
rray (size=1)
  0 => string 'Default' (length=7)

我用来测试答案的完整代码是在https://github.com/guilro/symfonytests/tree/so21276662上。

Valid约束力验证器验证嵌入对象,AFAIK API无法提供设置验证组的方法。

但是,在较高级别,我们可以要求形式组件级联验证列表到所有嵌入式表单,并使用表单组件API设置验证组。

我们必须使用:

  • 'cascade_validation' => true在各个级别的formbuilder中选项。默认情况下将其设置为false
  • TagType设置中的回调要设置验证组。(您在正确的轨道上。)
  • 'error_bubbling' => false,因为默认情况下是collections

我们完成了,我们可以显示与相应字段旁边所有错误的表单。

in taskType.php:

class TaskType extends AbstractType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder
        ->add('name')
        ->add('tags', 'collection', array(
            'type' => 'tag',
            'error_bubbling' => false,
            'allow_add' => true,
            'by_reference' => false,
            'cascade_validation' => true
        ))
    ;
  }
  public function setDefaultOptions(OptionsResolverInterface $resolver)
  {
    $resolver->setDefaults(array(
        'data_class' => 'AcmeTaskBundleEntityTask',
        'cascade_validation' => true
    ));
  }
}

in tagtype.php:

class TagType extends AbstractType
{
  public function buildForm(FormBuilderInterface $builder, array $options)
  {
    $builder
        ->add('name')
        ->add('description', 'text', array('required' => false));
  }
  public function setDefaultOptions(OptionsResolverInterface $resolver)
  {
    $resolver->setDefaults(array(
        'data_class' => 'AcmeTaskBundleEntityTag',
        'validation_groups' => function(FormInterface $form) {
            if ($form->getData() !== null && null !== $form->getData()->getId())
            {
                return array('Edit');
            }
            return array('Default');
        },
        'error_bubbling' => false,
    ));
  }
}

相关内容

  • 没有找到相关文章

最新更新