IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Symfony PHP Discussion :

[Form] Validation d'un champ vide


Sujet :

Symfony PHP

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 155
    Points : 76
    Points
    76
    Par défaut [Form] Validation d'un champ vide
    Bonjour,

    J'ai un problème étrange que je n'arrive décidément pas à comprendre :

    - lorsque je crée un nouvel enregistrement d'une entité et que je laisse un champ vide qui est obligatoire, le formulaire ne passe pas la validation,
    - lorsque je modifie un enregistrement existant en laissant vide un champ qui était déjà vide, le formulaire ne passe pas non plus la validation.

    Jusque là tout va bien, c'est le comportement attendu.

    Par contre, lorsque je modifie un enregistrement en vidant un champ qui était renseigné, le formulaire passe la validation et évidemment une exception est levée :

    Catchable Fatal Error: Argument 1 passed to MyBundle\Entity\Offre::setContact() must be an instance of MyBundle\Entity\Contact, null given,
    Voici les parties de mon code qui peuvent être intéressante pour essayer de comprendre cette exception :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    class Offre {
        /**
         *
         * @var MyBundle\Entity\Contact contact
         * @ORM\ManyToOne(targetEntity="Contact", inversedBy="offresAdm")
         * @ORM\JoinColumn(name="contact_id", referencedColumnName="id")
         * @Assert\NotBlank(message="Veuillez indiquer un contact administratif")
         */
        protected $contact;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    class OffreType extends AbstractType
    {
        protected $offre;
     
        public function buildForm( FormBuilderInterface $builder, array $options )
        {        
            $this->offre = $builder->getData();
        	$builder->add('contact', 'entity', array(
        			'label'         =>  'Contact administratif',
        			'required'		=>	true,
        			'empty_value'	=>	'--- Choisir un contact ---',
        			'class'         =>  'MyBundle:Contact',
        			'query_builder' =>  function(EntityRepository $er) {
        				return $er->createQueryBuilder('q')
        				->where('q.type=?1')
        				->orderBy('q.nom','asc')
        				->setParameter(1,1);
        			}
        	));
        	$builder->add('cfc', 'entity', array(
        			'label'         =>  'Responsable pédagogique (CFC)',
        			'class'         =>  'MyBundle:Contact',
        			'empty_value'	=>	'--- Choisir un cfc ---',
        			'required'		=>	true,
        			'query_builder' =>  function(EntityRepository $er) {
        				return $er->createQueryBuilder('q')
        				->where('q.type=?1')
        				->orderBy('q.nom','asc')
        				->setParameter(1,2);
        			}
        	));
     
        	$builder->add('formacodes', null, array('label'=>"Formacodes"));
     
        	$builder->add('codesRome', 'entity', array(
    	            'label'         =>  "Codes ROME",
    	            'required'      =>  false,
    	            'multiple'      =>  true,
    	            'class'         =>  'MyBundle:CodeRome',
    	            'query_builder' =>  function(EntityRepository $er) {
    	                return $er->createQueryBuilder('q')
    	                          ->groupBy('q.nomV3')
    	                          ->orderBy('q.codeV3');
    	            }
    	        ));        
            $builder->add('codesNsf', null, array(
                'label'     =>  "Codes NSF",
                'required'  =>  false
            ));
     
        	if ( ! $this->offre->getConventionnement() )
        	{
    	        $builder->add('nom', null, array(
    	            'label'=>   'Intitulé de la formation'
    	        ));
    	        $builder->add('organisme', null, array(
    	            'property'      =>  'nom',
    	         	'empty_value'	=>	'--- Choisir un organisme ---'
    	        ));
    	        $builder->add('modaliteEnseignement', null, array(
    	            'label'         =>  "Modalité d'enseignement",
    	            'property'      =>  'nom',
    	        	'empty_value'	=>	"--- Choisir une modalité ---"
    	        ));
    	        $builder->add('objectifGeneral', null, array(
    	            'label'         =>  'Objectif général',
    	            'property'      =>  'nom',
    	         	'empty_value'	=>	'--- Choisir un objectif général ---'
    	        ));
    	        $builder->add('objectifDetaille',   'textarea', array(
    	            'label'=>"Objectif détaillé"
    	        ));
    	        $builder->add('nombreHeuresTotal', 'integer', array(
    	            'label'         => "Nombre total d'heures",
    	            'attr'          => array('maxlength'=>4) 
    	        ));
    	        $builder->add('niveauEntree', null, array(
    	            'label'         =>  "Niveau d'entrée",
    	            'property'      =>  'nom',
    	        	'empty_value'	=>	'--- Choisir un niveau d\'entree ---'
    	        ));
    	        $builder->add('priseEnChargeFrais', null, array('label'=>"Prise en charge des frais"));
    	        $builder->add('conditionsPriseEnCharge',   'textarea', array(
    	            'label'         =>  "Conditions de prise en charge des frais",
    	            'required'      =>  false
    	        ));
    	        $builder->add('certifiante', null, array('label'=>'Diplomant/certifiant'));
     
    	        $builder->add('diplomes', null, array(
    	            'label'         =>  'Diplômes',
    	            'property'      =>  'nom'
    	        ));
     
    	        $builder->add('infoDerniereMinute',  'textarea', array(
    	            'label'=>'Informations de dernière minute',
    	            'required'=>false
    	        ));
    	        $builder->add('contenu',   'textarea');
    	        $builder->add('resultatsAttendus',   'textarea', array(
    	            'label'=>"Résultat(s) attendu(s)",
    	            'required'=>false
    	        ));
    	        $builder->add('rythmeFormation', null, array(
    	            'label'         =>  'Rythme de formation',
    	            'property'      =>  'nom',
    	        	'empty_value'	=>	"--- Choisir un rythme de formation ---"
    	        ));
    	        $builder->add('modaliteAlternance', null, array(
    	            'label'         =>  "Modalité d'alternance",
    	            'property'      =>  'nom',
    	        	'empty_value'	=>	"--- Choisir une modalité ---"
    	        ));
    	        $builder->add('modaliteEntreesSorties', null, array(
    	            'label'         =>  "Modalité d'entrées-sorties",
    	            'property'      =>  'nom',
    	        	'empty_value'	=>	"--- Choisir une modalité ---"
    	        ));
    	        $builder->add('modalitePedagogique', null, array(
    	            'label'         =>  "Modalité pédagogique",
    	            'property'      =>  'nom',
    	        	'empty_value'	=>	"--- Choisir une modalité ---"
    	        ));
    	        $builder->add('publicsVises', null, array(
    	            'label'         =>  "Publics visés",
    	            'property'      =>  'nom'
    	        ));
        	}
        }
     
        public function getName()
        {
            return 'offre';
        }
     
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
        	$resolver->setDefaults(array(
                'data_class'    =>  'MyBundle\Entity\Offre'
            ));
        }
    }
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    /**
         * @Route("/offre/new", name="_offre_new")
         * @Secure(roles="ROLE_ADMIN")
         * @Template
         */
        public function newAction() 
        {
            $request = $this->get('request');
            $offre = new Offre();
            $form = $this->createForm( new OffreType(), $offre );
     
            $process = $this->processForm($request, $form, $offre);
            if ( $process === true )
            {
                $this->get('session')->getFlashBag()->add('success', 'Offre "'.$offre->getNom().'"  créée');
                return $this->redirect( $this->generateUrl('_offre_index'));
            }
            else if ( $process == "errors" )
            {
                return array('form'=>$form->createView(), 'offre'=>$offre, 'errors'=>true);
            }
     
            return array('form'=>$form->createView(), 'offre'=>$offre,);
        }
     
        /**
         * @Route("/offre/{slug}/edit", name="_offre_edit")
         * @Secure(roles="ROLE_ADMIN")
         * @Template
         */
        public function editAction($slug) 
        {
            $request = $this->get('request');
            $offre = $this->findOffre($slug);
            $form = $this->createForm( new OffreType(), $offre );
     
            $process = $this->processForm($request, $form, $offre);
            if ( $process === true )
            {
                $this->get('session')->getFlashBag()->add('success','Offre "'.$offre->getNom().'" modifiée');
                return $this->redirect( $this->generateUrl('_offre_index'));
            }
            else if ( $process === "errors" )
            {
                return array('form'=>$form->createView(), 'offre'=>$offre, 'errors'=>true);
            }
            return array('form'=>$form->createView(), 'offre'=>$offre);
        }   
     
        protected function processForm($request, $form, $offre)
        {        
            if ( $request->getMethod() == 'POST' )
            {
                $form->bindRequest($request);
     
                if ($form->isValid())
                {                
                    $em = $this->getEntityManager();
                    $em->getFilters()->disable('soft-deleteable');
                    $em->persist($offre);
                    $em->flush();
                    $em->getFilters()->enable('soft-deleteable');
                    return true;
                }
                return "errors";
            }
            return false;
        }
    Là j'ai pris le champ 'contact' en exemple, mais le problème se reproduit avec les champs 'organisme' ou 'cfc' et sans doute avec d'autres.
    Le formulaire pourrait-il être validé parce que la validation prend en compte l'ancienne valeur du champ (un résidu ?). J'avoue que je suis un peu perturbé par ce problème...

    Merci d'avance pour votre aide !

  2. #2
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Bonjour,

    l'erreur dit que la méthode setContact n'accepte que des objets contacts, en mettant ceci cela devrait fonctionner:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    public function setContact(Contact $contact=null){
           $this->contact=$contact;
    }
    //ou bien 
    public function setContact($contact){
           $this->contact=$contact;
    }
    si aprés cela il y a une Exception sql c'est qu'effectivement la validation ne fonctionne pas.

    D'aprés la doc:
    Symfony's form library uses the validator service internally to validate the underlying object after values have been submitted and bound.
    http://symfony.com/doc/current/book/...n.html#index-2

    à priori ça doit se passer dans cet ordre:
    ->s'il y a modification entre la valeur initiale et la valeur envoyé par l'utilisateur, le setter de l'objet est appelé.
    ->ensuite on valide l'entité
    c'est logique (mais pas pratique...) dans une certaine mesure puisque les contraintes de validation sont configuré sur une classe donnée et que l'on valide un objet et non pas un formulaire

  3. #3
    Membre régulier
    Homme Profil pro
    Inscrit en
    Novembre 2006
    Messages
    155
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 155
    Points : 76
    Points
    76
    Par défaut
    En effet, ça a bien résolu le problème. Je prenais le problème à l'envers, sans doute trop influencé par mes vieux restes de Symfony 1... et la fatigue de fin de journée.

    Merci pour ton aide !

    Dès lors, est-ce une bonne idée de rajouter quasi systématiquement =null dans les signatures des méthodes ?

  4. #4
    Membre éprouvé
    Homme Profil pro
    Inscrit en
    Juin 2011
    Messages
    725
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Juin 2011
    Messages : 725
    Points : 1 050
    Points
    1 050
    Par défaut
    Dès lors, est-ce une bonne idée de rajouter quasi systématiquement =null dans les signatures des méthodes ?
    vue du coté Doctrine, c'est sans doute une mauvaise idée mais vue du coté de Symfony, on a pas trop le choix.

    On peut également implémenter des solutions tel que celles-ci
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    $optionsContact=array(
        			'label'         =>  'Contact administratif',
        			'required'		=>	true,
        			'query_builder' =>  function(EntityRepository $er) {
        				return $er->createQueryBuilder('q')
        				->where('q.type=?1')
        				->orderBy('q.nom','asc')
        				->setParameter(1,1);
        			}
        	);
    if(!$builder->getData()->getId()){//si l'entité est déjà persisté on ne peut pas mettre la valeur nulle
      $optionsContact['empty_value']='--- Choisir un contact ---';
    }
    $builder->add('contact', 'entity',$optionsContact );

Discussions similaires

  1. [2.x] [Form] Valider un champ texte vide
    Par pc.bertineau dans le forum Symfony
    Réponses: 8
    Dernier message: 24/06/2011, 11h35
  2. Empêcher la validation d'un formulaire si champs à vide
    Par ghohm dans le forum Général JavaScript
    Réponses: 9
    Dernier message: 16/07/2007, 16h21
  3. Réponses: 12
    Dernier message: 18/07/2006, 17h36
  4. [ODBC] Valider formulaire avec champs vides
    Par dorot dans le forum PHP & Base de données
    Réponses: 14
    Dernier message: 12/07/2006, 17h15
  5. [Forms]champs vide d'oracle forms
    Par med_anis_dk dans le forum Forms
    Réponses: 2
    Dernier message: 29/05/2006, 01h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo