我有一个表格,其中添加了额外的字段,选项mapped
到false
。但是当我尝试验证我的表单时,它不会在这些特定表单字段上方传递指示“此值无效”。这个选项不应该绕过验证吗?
这些表单字段仅用于填充其他字段,我不需要保存甚至检查它们。
我找到的唯一解决方案是在提交按钮单击时删除带有js的所有额外字段。
这是一些有关当前验证表单中无界或非映射字段的方法的stackoverflow问题的全局响应。
丰富的Symfony 2生态系统使我们的选择框架成为一种快速发展的工具。 Symfony 2.1版本带来了很多折旧。这意味着使用Symfony 2.0到2.1.2的内容将不再适用于Symfony 2.3。有关此内容的更多信息,请阅读UPGRADE FROM Symfony 2.0 to 2.1并阅读Symfony代码中的@deprecated注释。
构建表单时,通常使用实体,您可以在实体本身的验证注释中进行验证。
namespace Dj\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Dj\TestBundle\Entity\Post
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Dj\TestBundle\Entity\PostRepository")
*/
class Post
{
// ... some code
/**
* @var string $title
* @ORM\Column(name="title", type="string", length=200, nullable=false)
* @Assert\NotBlank()
*/
private $title;
// .. getters and setters
}
但有时(通常)您需要在表单中插入一些未映射到模型的字段。
我们的模型示例如下:
namespace Dj\TestBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Dj\TestBundle\Entity\Post
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Dj\TestBundle\Entity\PostRepository")
*/
class Post
{
/**
* @var integer $id
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**ghjkl
* @var string $title
* @ORM\Column(name="title", type="string", length=200, nullable=false)
* @Assert\NotBlank()
*/
private $title;
// ... getters and setters
}
如果我们想在我们的表单中添加一个名为myExtraField的额外字段,我们会:
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('title')
->add('myExtraField', 'choice', array(
'label' => 'myExtraField option :',
'choices' => array(
1 => 'Option One',
2 => 'Option Wat !'
),
'expanded' => true,
'mapped' => false
));
}
// other methods
}
注意 :
示例代码:
$builder->add('title')
->add('myExtraField', 'choice', array(
'label' => 'myExtraField option :',
'choices' => array(
1 => 'Option One',
2 => 'Option Wat !'
),
'data' => 1, // default selected option
'expanded' => true,
'mapped' => false
));
如果要验证myExtraField字段,则无法在Post Entity注释中执行此操作,您必须在表单中执行此操作。
2.0方法是向表单构建器添加验证器($ builder-> addValidator(..)),但不推荐使用此方法!
namespace Dj\TestBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
// needed namespaces for 2.0 validation
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormError;
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ... $builder->add()
// VALIDATING NON MAPPED FIELD Symfony 2.0 way
/** @var Symfony\Component\Form\CallbackValidator $myExtraFieldValidator **/
$myExtraFieldValidator = new CallbackValidator(function(FormInterface $form){
$myExtraField = $form->get('myExtraField')->getData();
if (empty($myExtraField)) {
$form['myExtraField']->addError(new FormError("myExtraField must not be empty"));
}
});
// adding the validator to the FormBuilderInterface
$builder->addValidator($myExtraFieldValidator);
}
// ... other methods
}
这正在验证myExtraField字段,但是$ builder-> addValidator将在Symfony 2.3中死掉!
正如UPGRADE FROM Symfony 2.0 to 2.1所述,由于不推荐使用FormValidatorInterface,我们现在必须将验证闭包函数传递给绑定到FormEvents :: POST_BIND事件的事件侦听器。
这是代码。
namespace Dj\TestBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
// needed namespaces for 2.1 validation
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormError;
class PostType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
// ... $builder->add()
// VALIDATING NON MAPPED FIELD Symfony 2.1.2 way (and forward)
/** @var \closure $myExtraFieldValidator **/
$myExtraFieldValidator = function(FormEvent $event){
$form = $event->getForm();
$myExtraField = $form->get('myExtraField')->getData();
if (empty($myExtraField)) {
$form['myExtraField']->addError(new FormError("myExtraField must not be empty"));
}
};
// adding the validator to the FormBuilderInterface
$builder->addEventListener(FormEvents::POST_BIND, $myExtraFieldValidator);
}
// ... other methods
}
这肯定可以通过一些Sf专家帮助来改进,但是现在它以前向兼容的方式验证未绑定的表单字段。
希望这有助于我们中的一些人。
大卫
As I mentionned in a question on a similar topic,since Symfony 2.1, you should use the 'constraints' option to add validation to your un-mapped fields:
use Symfony\Component\Validator\Constraints\MinLength;
use Symfony\Component\Validator\Constraints\NotBlank;
$builder
->add('firstName', 'text', array(
'constraints' => new MinLength(3),
))
->add('lastName', 'text', array(
'constraints' => array(
new NotBlank(),
new MinLength(3),
),
))
;
希望它会帮助像我这样的人在这方面失去一些时间......
如果您已经在使用约束,那么您可以这样做:
$builder
->add('new', 'repeated', array(
'type' => 'password',
'required' => true,
'invalid_message' => 'crmpicco.status.password_mismatch',
'constraints' => array(
new NotBlank(),
new Assert\Length([
'min' => 2,
'max' => 50,
'minMessage' => 'Your first name must be at least 2 characters long',
'maxMessage' => 'Your first name cannot be longer than 2 characters',
])
)
))
->add('save', 'submit', array(
'label' => 'password.form.fields.save',
))
;
其作品。检查symfony 2.1。代码应该是这样的:
$builder->add('password', 'password', ['required' => false, 'mapped' => false]);
当然,不需要财产“必需”。 Example from the documentation.
基于非映射字段的Symfony 3.4表达式约束:
$resolver->setDefaults([
'data_class' => MyClass::class,
'constraints' => [
new Expression([
'expression' => 'this["endTime"].getData() >= this["startTime"].getData()',
'message' => 'L\'heure de fin doit être plus grande ou égale à l\'heure de début'
])
]
]);