Specify different validation groups for each item of a collection in Symfony 2?(在 Symfony 2 中为集合的每个项目指定不同的验证组?)
问题描述
[关于集合的文档] 嵌入表单时(集合类型)是否可以根据当前项目为每个项目指定验证组?ATM 好像不行.
[Documentation about collection] When embedding forms (collection type) is possible to specify validation groups for each item, based on the current item? It seems not working 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),并且使用添加"按钮(通过 JavaScript)添加了一个新标签:
For example we have two tags (tag 1 and tag 2) and a new tag is added using the "Add" button (via JavaScript):
-----------
| add tag |
-----------
- tag 1 (existing)
- tag 2 (added clicking the "add tag" button)
标签 1 应针对 Default
、Edit
组进行验证,而标签 2 应仅针对 Default
组进行验证.
Tag 1 should be validated against Default
, Edit
groups while tag 2 against Default
group only.
基于底层数据,如果标签是新的,它得到Default
组,如果存在Default
,Create
组:
Based on the underlying data, if tag is new it gets Default
group, if exists Default
, Create
groups:
// ...
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
定义两个属性的示例(省略了访问器):
Tag
entity with a constraint in the "Edit" group
An example with Tag
defining two properties (accessors omitted):
class Tag
{
/**
* @AssertNotBlank()
*/
protected $name;
/**
* @AssertNotBlank(groups={"Edit"})
* @AssertLength(max="255")
*/
protected $description;
// ...
}
对于现有标签:描述不应为空.对于新标签:说明可以为空.
For an existing tag: description should not be blank. For a new tag: description can be blank.
只需编辑现有标签并将说明留空.表单验证,但验证器服务显示错误:
Just edit an existing tag and leave the description blank. The form validates but the validator service shows errors:
$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
作为建议 这里:
Update 1: I've tried (without success) with a static method determineValidationGroups
as suggested here:
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'
),
));
}
只有一个现有标签和一个使用添加标签"链接创建的输出似乎是正确的.但现有标记没有错误,将描述留空:
Output with just one existing tag and one created using the "add tag" link seems correct. But no errors for the existing tag leaving the description blank:
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
约束强制 Validator 验证嵌入对象,而 AFAIK API 没有提供设置验证组的方法.
Valid
constraint force Validator to validate embed object, and AFAIK the API provides no way to set validation group.
但在更高的层次上,我们可以要求 Form 组件将 ValidationListener 级联到所有嵌入的表单,并使用 Form 组件 API 设置验证组.
But at a higher level, we can ask Form component to cascade ValidationListener to all embed forms, and use the Form component API to set validation group.
我们必须使用:
'cascade_validation' =>在 FormBuilder 中,所有级别的 true
选项.默认设置为false
.- 在 TagType 设置中设置验证组的回调.(你走对了.)
'error_bubbling' =>false
,因为它在集合中默认为 true
'cascade_validation' => true
option in the FormBuilder, at all levels. It is set tofalse
by default.- a callback in TagType settings to set validation group. (You were on the right track.)
'error_bubbling' => false
, as it is true by default in collections
我们完成了,我们可以在相应字段旁边显示包含所有错误的表单.
and we're done, we can display the form with all errors next to corresponding fields.
在 TaskType.php 中:
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
));
}
}
在 TagType.php 中:
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,
));
}
}
这篇关于在 Symfony 2 中为集合的每个项目指定不同的验证组?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在 Symfony 2 中为集合的每个项目指定不同的验证组?
基础教程推荐
- 如何在 XAMPP 上启用 mysqli? 2021-01-01
- 在 yii2 中迁移时出现异常“找不到驱动程序" 2022-01-01
- Doctrine 2 - 在多对多关系中记录更改 2022-01-01
- PHP 守护进程/worker 环境 2022-01-01
- 找不到类“AppHttpControllersDB",我也无法使用新模型 2022-01-01
- HTTP 与 FTP 上传 2021-01-01
- 如何在 Symfony 和 Doctrine 中实现多对多和一对多? 2022-01-01
- 使用 PDO 转义列名 2021-01-01
- 在 CakePHP 2.0 中使用 Html Helper 时未定义的变量 2021-01-01
- phpmyadmin 错误“#1062 - 密钥 1 的重复条目‘1’" 2022-01-01