Reputation: 123
I am writing several forms with symfony 3. My form is very like the given example in the symfony reference:
http://symfony.com/doc/current/reference/constraints/Valid.html I also have an user and an embedded address-entity. My configuration is done via yml:
PARENT User:
// src/Entity/User.php
namespace App\Entity;
class User
{
protected $firstName;
protected $lastName;
protected $address;
protected $mailOptIn;
}
CHILD Address:
// src/Entity/Address.php
namespace App\Entity;
class Address
{
protected $street;
protected $zipCode;
}
YML:
# config/validator/validation.yaml
App\Entity\Address:
properties:
street:
- NotBlank: { groups: [group01, group02] }
zipCode:
- NotBlank: { groups: [group01, group02] }
- Length: { min: 3, groups: [group01, group02] }
App\Entity\User:
properties:
firstName:
- NotBlank: ~
- Length:
min: 4
lastName:
- NotBlank: ~
address:
- Valid: { groups: [group01, group02] }
BUT in some cases (depending on other fields in the parent-user-entity) it is not necessary to validate the embedded address-entity.
Now I've read a lot about callback and getter-validators, but my problem is, that I do not know, how to handle this. Another part which makes the case even more complex for me is, that i need to use validation-groups (https://symfony.com/doc/current/form/validation_groups.html ) in the address entity, due to the fact, that i validate about 20 countries, where each of them has its own validation fields.
Can anybody give me hint, how to go on? The address-validation with the groups works perfectly, i think i just need to implement some cool magic stuff in the parent-user-entity, right?
I just added TWO things:
The validation with the valid-key works.
What I want to implement now is, that the address-validation is only done, if the user has set mailOptIn to true, because only in that case, I need the address. Please note, that i do need groups for the address-validation, depending on what country the given address is placed.
Upvotes: 0
Views: 1072
Reputation: 123
My solution is, to use MULTIPLE 'validation_groups' and a callback-function for them in my form-type class. I wasn't aware that it is possible to use more than one group for each form.
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults($this->addDefaults([
'data_class' => ContactGeneral::class,
'cascade_validation' => true,
]));
$resolver->setDefaults([
'validation_groups' => function (FormInterface $form) {
$data = $form->getData();
if ($data->getAddress()->isValidate()) {
return ['ContactGeneral', 'User', 'contactUser', 'Address', $this->alsLm->getGroupName()];
} else {
return ['ContactGeneral', 'User', 'contactUser', 'Address'];
}
},
]);
}
see:
Upvotes: 1
Reputation: 356
You can do it in your controller action :
use Symfony\Component\Form\FormError;
class MyClass {
public function createAction(Request $request) {
// your actual code
// dynamic form validation
if($form->isSubmitted()){
$zip= $form->get('address')->get('zip')->getData();
$street= $form->get('address')->get('street')->getData();
if($zip == '1234' && count($street)>150){
$form->get('address')->get('zip')->addError(new FormError('Address cant have more than 150 char for ZIP 1234')); // add error on the ZIP field
} else if($zip == '465' && count($street) < 3) {
$form->get('address')->get('street')->addError(new FormError('Address must have more than 3 char for ZIP 456')); // add error on the address field
}
}
// your actual code
if($form->isSubmitted() && $form->isValid()){
}
}
}
Upvotes: 0
Reputation: 2171
The documentation might not be so clear in this case, but you have to add the Valid: ~
key on it, like:
App\Entity\User:
properties:
firstName:
- NotBlank: ~
- Length:
min: 4
lastName:
- NotBlank: ~
address:
- Valid: ~
Upvotes: 0