问题
I have form, and need to create inline validation:
$builder
->add('Count1', 'integer', [
'data' => 1,
'constraints' => [
new NotBlank(),
new NotNull(),
],
])
->add('Count2', 'integer', [
'constraints' => [
new NotBlank(),
new NotNull(),
],
])
->add('Count3', 'integer', [
'data' => 0,
'constraints' => [
new NotBlank(),
new NotNull(),
],
])
How white inline validation Expression for rules
- Count2 >=Count1
- Count3 <=Count2
- Count2 >= $someVariable
回答1:
Other solution by using Expression Constraint for cases 1 and 2.
use Symfony\Component\Validator\Constraints as Assert;
// ...
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults([
'constraints' => [
new Assert\Expression([
'expression' => 'value["Count2"] >= value["Count1"]',
'message' => 'count2 must be greater than or equal to count1'
]),
new Assert\Expression([
'expression' => 'value["Count3"] <= value["Count2"]',
'message' => 'count3 must be less than or equal to count2'
]),
],
]);
}
For case 3 you can use Assert\GreaterThanOrEqual
constraint directly on Count2
field.
I guess your form doesn't have a binding object model, otherwise to read the documentation referred is enough and better because you could use these expression on your properties directly.
回答2:
You can utilize CallbackValidator
(docs):
In your case, in order to validate one field againt another, you need to add constraint to a form type, not the field:
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'constraints' => array(
new Assert\Callback(function($data){
// $data is instance of object (or array) with all properties
// you can compare Count1, Count2 and Count 3
// and raise validation errors
});
)
));
}
You can also pass constraints
option while creating a form if you don't want to set it in setDefaultOptions
.
回答3:
Starting from easiest
3) Count2 >= $someVariable
->add('Count3', 'integer', [
'data' => 0,
'constraints' => [
new NotBlank(),
new NotNull(),
new GreaterThanOrEqual($someVariable),
],
])
1) As for two first, you must implement constraint for a class scope, rather than property scope. And assign these constraints for a whole form
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('Count1', 'integer', [
'data' => 1,
'constraints' => [
new NotBlank(),
new NotNull(),
],
])
->add('Count2', 'integer', [
'constraints' => [
new NotBlank(),
new NotNull(),
],
])
->add('Count3', 'integer', [
'data' => 0,
'constraints' => [
new NotBlank(),
new NotNull(),
],
])
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(['constraints' => [
new YourCustomConstraint(),
]]);
}
How to implement validator, see in the documentation.
But in your YourCustomConstraintValidator
you will have something like
public function validate($value, Constraint $constraint)
{
if ($value->getCount1() > $value->getCount2() {
$this->context->addViolation(...);
}
}
来源:https://stackoverflow.com/questions/40287266/symfony-form-validation-constraint-expression