FormType 中的 Symfony5 自定义验证器 - 当复选框打开时验证密码字段
Symfony5 Custom Validator in FormType - Validate password field when check box is on
我想根据复选框的值验证表单中的输入密码字段。如果该值为 TRUE,则密码字段应为 NOTBlank 且 first to second 相等。这是我目前所拥有的:
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
class UsuarioFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombre',null,[
'required' => true,
'constraints'=> [
new NotBlank([
'message' => 'Escriba el nombre por favor',
]),
]
])
->add('apellido',null,[
'required' => true,
'constraints'=> [
new NotBlank([
'message' => 'Escriba el apellido por favor',
]),
]
])
->add('user_name',null,[
'required' => true,
'empty_data' => '',
'constraints'=> [
new NotBlank([
'message' => 'Escriba el nombre de usuario por favor',
]),
]
])
->add('active', CheckboxType::class, [
'required' => false
])
->add('email',EmailType::class,[
'constraints' => [
new Email([
'mode'=> 'html5',
'message' => 'El correo electrónico {{ value }} no es un correo electrónico válido',
]),
]
])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Los campos de contraseña deben ser iguales',
'mapped' => false,
'required' => false,
'constraints' => [
new Length([
'min' => 6,
'minMessage' => 'Your password should be at least {{ limit }} characters',
// max length allowed by Symfony for security reasons
'max' => 4096,
]),
],
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'constraints' => [
new Callback([$this, 'validate']),
],
]);
}
public function validate($data, ExecutionContextInterface $context): void
{
if ($data['chk_passUpdate']){
if (trim($data['plainPassword']['first']) == '' ) {
$context->buildViolation('El campo de contraseña no puede estar en blanco')
->atPath('plainPassword')
->addViolation();
}
if ($data['plainPassword']['first'] != $data['plainPassword']['second'] ) {
$context->buildViolation('Los campos de contraseña deben ser iguales')
->atPath('plainPassword')
->addViolation();
}
}
}
}
此代码抛出异常:
传递给 App\Form\UsuarioFormType::validate() 的参数 1 必须是数组类型,对象给定,在 C:\Csi\CsiWorkspace\SynfonyTest\SymfonyTest\vendor\symfony\validator\Constraints\CallbackValidator.php 中调用第 46 行
一周后我发现最好的解决方案是使用验证组。
所以我的代码将是这样的:
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\FormInterface;
class UsuarioFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombre',null,[
'required' => true,
'constraints'=> [
new NotBlank([
'message' => 'Escriba el nombre por favor',
]),
]
])
->add('apellido',null,[
'required' => true,
'constraints'=> [
new NotBlank([
'message' => 'Escriba el apellido por favor',
]),
]
])
->add('user_name',null,[
'required' => true,
'empty_data' => '',
'constraints'=> [
new NotBlank([
'message' => 'Escriba el nombre de usuario por favor',
]),
]
])
->add('active', CheckboxType::class, [
'required' => false
])
->add('password_update', CheckboxType::class, [
'required' => false,
'mapped' => false
])
->add('email',EmailType::class,[
'constraints' => [
new Email([
'mode'=> 'html5',
'message' => 'El correo electrónico {{ value }} no es un correo electrónico válido',
]),
]
])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Los campos de contraseña deben ser iguales',
'mapped' => false,
'required' => false,
'constraints' => [
new Length([
'min' => 6,
'minMessage' => 'Your password should be at least {{ limit }} characters',
// max length allowed by Symfony for security reasons
'max' => 4096,
]),
new NotBlank([
'message' => 'Escriba su contraseña',
'groups' => 'password_update'
]),
],
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'validation_groups' => function(FormInterface $form){
if ($form['password_update']->getData()){
return array('Default', 'password_update');
}else{
return array('Default');
}
}
]);
}
}
这样,当复选框打开时,表单将验证 2 个组(默认和 password_udpate)。如果它关闭,将只验证默认组。
希望有一天这对某人有所帮助。
我想根据复选框的值验证表单中的输入密码字段。如果该值为 TRUE,则密码字段应为 NOTBlank 且 first to second 相等。这是我目前所拥有的:
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
class UsuarioFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombre',null,[
'required' => true,
'constraints'=> [
new NotBlank([
'message' => 'Escriba el nombre por favor',
]),
]
])
->add('apellido',null,[
'required' => true,
'constraints'=> [
new NotBlank([
'message' => 'Escriba el apellido por favor',
]),
]
])
->add('user_name',null,[
'required' => true,
'empty_data' => '',
'constraints'=> [
new NotBlank([
'message' => 'Escriba el nombre de usuario por favor',
]),
]
])
->add('active', CheckboxType::class, [
'required' => false
])
->add('email',EmailType::class,[
'constraints' => [
new Email([
'mode'=> 'html5',
'message' => 'El correo electrónico {{ value }} no es un correo electrónico válido',
]),
]
])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Los campos de contraseña deben ser iguales',
'mapped' => false,
'required' => false,
'constraints' => [
new Length([
'min' => 6,
'minMessage' => 'Your password should be at least {{ limit }} characters',
// max length allowed by Symfony for security reasons
'max' => 4096,
]),
],
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'constraints' => [
new Callback([$this, 'validate']),
],
]);
}
public function validate($data, ExecutionContextInterface $context): void
{
if ($data['chk_passUpdate']){
if (trim($data['plainPassword']['first']) == '' ) {
$context->buildViolation('El campo de contraseña no puede estar en blanco')
->atPath('plainPassword')
->addViolation();
}
if ($data['plainPassword']['first'] != $data['plainPassword']['second'] ) {
$context->buildViolation('Los campos de contraseña deben ser iguales')
->atPath('plainPassword')
->addViolation();
}
}
}
}
此代码抛出异常:
传递给 App\Form\UsuarioFormType::validate() 的参数 1 必须是数组类型,对象给定,在 C:\Csi\CsiWorkspace\SynfonyTest\SymfonyTest\vendor\symfony\validator\Constraints\CallbackValidator.php 中调用第 46 行
一周后我发现最好的解决方案是使用验证组。
所以我的代码将是这样的:
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\Callback;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\FormInterface;
class UsuarioFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('nombre',null,[
'required' => true,
'constraints'=> [
new NotBlank([
'message' => 'Escriba el nombre por favor',
]),
]
])
->add('apellido',null,[
'required' => true,
'constraints'=> [
new NotBlank([
'message' => 'Escriba el apellido por favor',
]),
]
])
->add('user_name',null,[
'required' => true,
'empty_data' => '',
'constraints'=> [
new NotBlank([
'message' => 'Escriba el nombre de usuario por favor',
]),
]
])
->add('active', CheckboxType::class, [
'required' => false
])
->add('password_update', CheckboxType::class, [
'required' => false,
'mapped' => false
])
->add('email',EmailType::class,[
'constraints' => [
new Email([
'mode'=> 'html5',
'message' => 'El correo electrónico {{ value }} no es un correo electrónico válido',
]),
]
])
->add('plainPassword', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'Los campos de contraseña deben ser iguales',
'mapped' => false,
'required' => false,
'constraints' => [
new Length([
'min' => 6,
'minMessage' => 'Your password should be at least {{ limit }} characters',
// max length allowed by Symfony for security reasons
'max' => 4096,
]),
new NotBlank([
'message' => 'Escriba su contraseña',
'groups' => 'password_update'
]),
],
]);
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'data_class' => User::class,
'validation_groups' => function(FormInterface $form){
if ($form['password_update']->getData()){
return array('Default', 'password_update');
}else{
return array('Default');
}
}
]);
}
}
这样,当复选框打开时,表单将验证 2 个组(默认和 password_udpate)。如果它关闭,将只验证默认组。
希望有一天这对某人有所帮助。