Symfony2 - Validation ne fonctionne pas pour les systèmes embarqués de Type de Formulaire
J'ai un formulaire qui combine deux entités (l'Utilisateur et le Profil).
De Validation semble fonctionner sur la première partie de la forme qui vient de l'Entité Utilisateur et est à la base de la forme.
La ProfileType est inclus à l'intérieur de la UserType. Le formulaire s'affiche correctement et affiche les informations correctes, de sorte qu'il semble qu'il est correctement connecté au Profil de l'entité. C'est juste la validation de ce qui est cassé sur le ProfileType.
Aucune idée du pourquoi une partie de valider et de l'autre ne le serait pas?
Code ci-dessous:
De Validation.yml
DEMO\DemoBundle\Entity\User\Profile:
properties:
address1:
- NotBlank: { groups: [profile] }
name:
- NotBlank: { groups: [profile] }
companyName:
- NotBlank: { groups: [profile] }
DEMO\DemoBundle\Entity\User\User:
properties:
username:
- NotBlank:
groups: profile
message: Username cannot be left blank.
email:
- NotBlank:
groups: profile
message: Email cannot be left blank
- Email:
groups: profile
message: The email "{{ value }}" is not a valid email.
checkMX: true
password:
- MaxLength: { limit: 20, message: "Your password must not exceed {{ limit }} characters." }
- MinLength: { limit: 4, message: "Your password must have at least {{ limit }} characters." }
- NotBlank: ~
UserType.php
namespace DEMO\DemoBundle\Form\Type\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormError;
use DEMO\DemoBundle\Form\Type\User\ProfileType;
class UserType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('username');
$builder->add('email');
$builder->add('profile', new ProfileType());
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'DEMO\DemoBundle\Entity\User\User',
'validation_groups' => array('profile')
);
}
public function getName()
{
return 'user';
}
}
ProfileType.php
namespace DEMO\DemoBundle\Form\Type\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\CallbackValidator;
use Symfony\Component\Form\FormBuilder;
use Symfony\Component\Form\FormError;
class ProfileType extends AbstractType
{
public function buildForm(FormBuilder $builder, array $options)
{
$builder->add('name');
$builder->add('companyName', null, array('label' => 'Company Name'));
$builder->add('address1', null, array('label' => 'Address 1'));
$builder->add('address2', null, array('label' => 'Address 2'));
$builder->add('city');
$builder->add('county');
$builder->add('postcode');
$builder->add('telephone');
}
public function getDefaultOptions(array $options)
{
return array(
'data_class' => 'DEMO\DemoBundle\Entity\User\Profile',
);
}
public function getName()
{
return 'profile';
}
}
Contrôleur
$user = $this->get('security.context')->getToken()->getUser();
$form = $this->createForm(new UserType(), $user);
if ($request->getMethod() == 'POST') {
$form->bindRequest($request);
if ($form->isValid()) {
//Get $_POST data and submit to DB
$em = $this->getDoctrine()->getEntityManager();
$em->persist($user);
$em->flush();
//Set "success" flash notification
$this->get('session')->setFlash('success', 'Profile saved.');
}
}
return $this->render('DEMODemoBundle:User\Dashboard:profile.html.twig', array('form' => $form->createView()));
Vous devez vous connecter pour publier un commentaire.
J'ai passé l'âge de la recherche et trouvé que c'était l'ajout de
'cascade_validation' => true
à lasetDefaults()
tableau dans mon type parent classe qu'il fixe (comme déjà mentionné dans le fil). Cela provoque l'entité contrainte de validation de déclencher chez l'enfant les types indiqués dans le formulaire. par exemple,Pour les collections, aussi assurez-vous d'ajouter
'cascade_validation' => true
à la$options
tableau de la collection de champ sur le formulaire. par exemple,Ce sera le UniqueEntity de validation de prendre place comme il se doit dans l'entité enfant utilisé dans la collection.
Assert\Valid()
annotation est définie, la première entité ne sera pas cascade de validation pour cette propriété. Donccascade_validation
résoudre le problème.Une note à ceux qui utilisent Symfony 3.0 et jusqu': le
cascade_validation
option a été supprimé. Au lieu de cela, utiliser pour les formulaires imbriqués:Désolé pour ajouter à ce vieux thread avec un peu hors-sujet de la réponse (Symfony 3 vs 2), mais la recherche de cette information ici m'aurait évité quelques heures aujourd'hui.
use Symfony\Component\Validator\Constraints\Valid;
au top de la forme definitoin fichier. Symfony 4 ici.Selon formulaire type de documentation vous pouvez également utiliser
Valid
contrainte au lieu decascade_validation
option.Exemple ceux de l'entité propriétaire:
êtes-vous à l'aide de YML ou des Annotations?
J'ai essayé d'appliquer la
cascade_validation
option sur mon formulaire parent de la classe, mais la validation n'était pas encore produit. Après avoir lu un peu de documentation, je suis allé àapp/config/config.yml
et a constaté queenable_annotations
sousframework->validation
a été mis à vrai. Apparemment, si cela est vrai, le service de validation n'solitaire lit de validation.yml fichiers. Donc j'ai juste changé la faux, et maintenant, la forme est la validation de l'amende.Appartient à Symfony 2.3
Travailler avec des formulaires imbriqués et les groupes de validation pourrait être très douloureuse: l'Annotation @Assert\Valide() doesen " travailler pour moi (sans les groupes c'est ok). Insérer "cascade_validation' => true sur la DefaultOptions est la clé. Vous n'avez pas besoin de répéter ce sur l' ->add(). Prendre soin: HTML 5 de la validation de ne pas collaborer avec les groupes de validation.
Exemple:
Une Collection de 2 Adresses. 1:1 unidirectionnel. Chacun avec un autre (!) groupe de validation.
Entité Adresse
Type d'adresse - possibilité de changer de groupe de validation
Et, enfin, le CollectionType
Espère que cela aide..
Vous devez ajouter
validation_groups
dans votreProfiletType
aussi. La Validation est effectuée dans chaque type de formulaire séparément en fonction de leurdata_class
s'il existe.cascade_validation
option en 2.1?Je cherchais exactement la même chose et voici ce que j'ai trouvé
http://symfony.com/doc/master/book/forms.html#forms-embedding-single-object
Vous devez dire à la principale entité de valider l'ensemble des sous entités comme suit:
J'ai testé cela sur symfony 2.8 et il fonctionne.
De mon contrôleur:
Quatrième parametr dans ::createNamedBuilder -
array('cascade_validation' => true))