如何在Symfony2中动态添加验证器?
我有一个password
表单字段(映射到User
密码的 not )以及两个其他(映射的)字段first
和last
.
I've a password
form field (not mapped to User
password) to be used in a change password form, along with two other (mapped) fields, first
and last
.
我必须即时添加验证器:如果密码的值为空,则不进行验证.否则,应添加新的 MinLength
和MaxLength
验证器.
I've to add validators on the fly: if value for password is blank then no validation should occur. Otherwise a new MinLength
and MaxLength
validators should be added.
这是我到目前为止所做的:创建重复的password
字段,如果$form->getData()
是null
,则添加CallbackValidator
和return
.
Here is what i've done so far: create the repeated password
field, add a CallbackValidator
and return
if $form->getData()
is null
.
然后,如何为$ field添加最小和最大长度的验证器?
Then, how can i add validators for minimum and maximum length to $field?
$builder = $this->createFormBuilder($user);
$field = $builder->create('new_password', 'repeated', array(
'type' => 'password',
'first_name' => 'Password',
'second_name' => 'Confirm password',
'required' => false,
'property_path' => false // Not mapped to the entity password
));
// Add a callback validator the the password field
$field->addValidator(new Form\CallbackValidator(function($form) {
$data = $form->getData();
if(is_null($data)) return; // Field is blank
// Here password is provided and match confirm, check min = 3 max = 10
}));
// Add fields to the form
$form = $builder
->add('first', 'text', array('required' => false)) // Mapped
->add('last', 'text', array('required' => false)) // Mapped
->add($field) // Not mapped
->getForm();
哦,好了,经过几次实验,我自己找到了解决方案.
Oh well, found a solution myself after a few experiments.
我将在几天之内不回答这个问题,因为一个可以发布更好的解决方案,真的很受欢迎:)
I'm going to leave this question unanswered for a couple of days as one can post a better solution, that would be really really welcome :)
尤其是,我发现了new FormError
部分冗余,不知道是否有更好的方法将错误添加到表单中.老实说,不知道为什么new Form\CallbackValidator
起作用而new CallbackValidator
不能起作用.
In particular, i found the new FormError
part redundat, don't know if there is a better way to add the error to the form. And honestly, don't know why new Form\CallbackValidator
works while new CallbackValidator
won't.
因此,不要忘记添加如下的use
语句:
So, don't forget to add use
statements like these:
use Symfony\Component\Form as Form, // Mendatory
Symfony\Component\Form\FormInterface,
Symfony\Component\Validator\Constraints\MinLength,
Symfony\Component\Validator\Constraints\MinLengthValidator;
回调是:
$validation = function(FormInterface $form) {
// If $data is null then the field was blank, do nothing more
if(is_null($data = $form->getData())) return;
// Create a new MinLengthValidator
$validator = new MinLengthValidator();
// If $data is invalid against the MinLength constraint add the error
if(!$validator->isValid($data, new MinLength(array('limit' => 3)))) :
$template = $validator->getMessageTemplate(); // Default error msg
$parameters = $validator->getMessageParameters(); // Default parameters
// Add the error to the form (to the field "password")
$form->addError(new Form\FormError($template, $parameters));
endif;
};
好吧,这是我无法理解的部分(为什么我必须加Form
作为前缀),但这很好:
Well, and this is the part i can't understand (why i'm forced to prefix with Form
), but it's fine:
$builder->get('password')->addValidator(new Form\CallbackValidator($validation));