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 :

Sélectionner une entité dans un formulaire


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juillet 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 34
    Par défaut Sélectionner une entité dans un formulaire
    Bonjour à tous,

    Pour mon site internet, j'ai du réaliser un "ManyToMany" à la main car mon entité reçoit des champs personnalisés. De plus, le "ManyToMany" pointe vers lui-même (self-referencing). Pour expliquer simplement : j'ai une page permettant d'ajouter des modules (ça, ça fonctionne) et quand j'ajoute des modules, je peux sélectionner des modules précédemment enregistrés pour les lier.

    Voici mon entité module AdministrationBundle\Entity\Module :

    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
     
    ...
     
         /**
         * @ORM\OneToMany(targetEntity="AdministrationBundle\Entity\ModuleModuleLie", mappedBy="moduleLie", cascade={"persist"})
         */
        private $modules;
     
        public function addModule(\AdministrationBundle\Entity\ModuleModuleLie $module)
        {
            $this->modules[] = $module;
            $module->setModule($this);
            return $this;
        }
     
        public function removeModule(\AdministrationBundle\Entity\ModuleModuleLie $module)
        {
            $this->modules->removeElement($module);
        }
    ...
    Voici mon entité module AdministrationBundle\Entity\ModuleModuleLie (la table de jointure) :
    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
     
    ...
        /**
        * @ORM\ManyToOne(targetEntity="AdministrationBundle\Entity\Module")
        */
        protected $module;
     
        /**
        * @ORM\ManyToOne(targetEntity="AdministrationBundle\Entity\Module", inversedBy="modules")
        */
        protected $moduleLie;
     
        public function setModule(\AdministrationBundle\Entity\Module $module)
        {
            $this->module = $module;
        }
     
        public function getModule()
        {
            return $this->module;
        }
     
        public function setModuleLie(\AdministrationBundle\Entity\Module $module)
        {
            $this->moduleLie = $module;
        }
     
        public function getModuleLie()
        {
            return $this->moduleLie;
        }
    ...
    Enfin, j'ai mon formulaire qui s'affiche correctement en listant notamment les modules préalablement enregistrés :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            $builder
    ...
                ->add('modules', 'entity', array(
                    'class' => 'AdministrationBundle\Entity\Module',
                    'property' => 'libelle',
                    'multiple' => true,
                    'expanded' => true,
                    'required' => true,
                    'label' => 'Module(s) importé(s)'
                )
            );
    Cependant, lors de la validation j'ai cette erreur que je ne parviens pas à résoudre :
    " Found entity of type AdministrationBundle\Entity\Module on association AdministrationBundle\Entity\Module#modules, but expecting AdministrationBundle\Entity\ModuleModuleLie "

    Quelqu'un a une idée ?
    Merci d'avance

  2. #2
    Membre Expert Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Par défaut
    Ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    /**
      * @ORM\OneToMany(targetEntity="AdministrationBundle\Entity\ModuleModuleLie", mappedBy="module")
      */
    private $modules;
    et ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ->add('modules', 'entity', array(
        'class' => 'AdministrationBundle\Entity\Module',
        // ...
    c'est contradictoire.

    L'erreur est explicite : dans le modèle l'attribut $modules pointe vers la table de liaison. Dans le formulaire (dont le data_class doit certainement être ta classe module) cet attribut pointe vers la classe module. Et ça, ça peut pas marcher.

    Si les deux te semblent logique, alors c'est que le formulaire ne correspond pas exactement au modèle, et c'est le data_class qu'il faut virer, et dans ce cas tu fais la bascule entre les résultats de ton POST et ton objet manuellement.

    ++

  3. #3
    Membre averti
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juillet 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 34
    Par défaut
    Salut et merci de ta réponse, j'avais compris l'erreur sans parvenir à la résoudre, je tourne en rond depuis des heures :-S

    Effectivement, le data_class pointe bien vers l'entité Module :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        public function setDefaultOptions(OptionsResolverInterface $resolver)
        {
            $resolver->setDefaults(array(
                'data_class' => 'AdministrationBundle\Entity\Module',
                'intention' => $this->getName() . '_token'
            ));
        }
    Cependant, si je l'enlève, l'erreur est la même : probablement car l'entité est envoyé dès la construction du formulaire dans le Controller :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
            $module = new \AdministrationBundle\Entity\Module;
            $form = $this->createForm('administration_module_form', $module);
    Je me vois mal retiré l'entité est construire un formulaire de A à Z sans entité pour ensuite tout reconstruire juste à cause d'un champ, surtout que le cas me semble assez banal en fin de compte, ce n'est qu'une jointure :/

    Encore merci

  4. #4
    Membre Expert Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Par défaut
    Ok, le problème vient donc du formulaire à mon sens : garde ton data_class.
    Il ne devrait pas y avoir une entité de type module, mais une entité de type ModuleLie (ta table intermédiaire) : en soit elle devrait être transparente mais à cause des params supplémentaire tu as été obligé de la modéliser, donc on va devoir la modéliser jusqu'au bout.

    Si tu veux pouvoir rajouter un module lié à un autre, il va falloir passer par un formulaire embarqué : concrètement on va faire un formulaire pour rajouter X entités ModuleLie : ce qui te permettra d'avoir tes associations.

    Tu remplaces ton :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    ->add('modules', 'entity', array(
        'class' => 'AdministrationBundle\Entity\Module',
        // ...
    par un :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    ->add('modules', CollectionType::class, array(
        'entry_type' => ModuleLieType::class,
        'allow_add' => true,
        'allow_remove' => true,
        // ...
    ))
    Tu crées ta class ModuleLieType dont le data_class devrait être ModuleLie.
    Dans ce form tu auras deux attributs entity qui te retourneront des Module. Un devra déjà être set avec le module du parent, et l'autre est à sélectionner dans une liste à choix multiple comme tu l'avais fait au départ.

    Voilà dans les grandes lignes, bon courage pour ton form embarqué

  5. #5
    Membre averti
    Homme Profil pro
    Directeur de projet
    Inscrit en
    Juillet 2011
    Messages
    34
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Directeur de projet

    Informations forums :
    Inscription : Juillet 2011
    Messages : 34
    Par défaut
    Salut et merci de tes conseils

    Je galère vraiment mais bon, je m'approche petit à petit. Dans le formulaire d'ajout de Module, j'ai donc bien à présent une collection :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
                ->add('modules', 'collection', array(
                    'label' => 'Module(s) importé(s)',
                    'type' => new ModuleModuleLieType(),
                    'allow_add' => false,
                    'allow_delete' => false
                ))
    Cependant est comme dit plus haut, je souhaite pouvoir sélectionner des modules précédemment enregistré, via. des checkbox. Du coup, j'ai d'abord ajouté ceci dans ModuleModuleLieType() (je n'ai volontairement pas mis le champ "module" auquel se référera la liaison, car je présume qu'elle sera ajoutée automatiquement lors de l'insertion) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
                ->add('moduleLie', 'entity', array(
                    'class' => 'AdministrationBundle\Entity\Module',
                    'property' => 'libelle',
                    'label' => false,
                    'expanded' => true,
                    'multiple' => true
                ))
    Par contre forcément, rien ne s'affiche puisque c'est une collection. J'ai donc ajouté un PRE_SET_DATA dans le premier formulaire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
            $builder->addEventListener(FormEvents::PRE_SET_DATA, function(FormEvent $event) {
                $module = $event->getData();
                $module->addModule(new ModuleModuleLie);
            });
    La, parfait, tout s'affiche bien. Par contre à l'enregistrement, j'ai cette erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     Catchable Fatal Error: Argument 1 passed to AdministrationBundle\Entity\ModuleModuleLie::setModuleLie() must be an instance of AdministrationBundle\Entity\Module, instance of Doctrine\Common\Collections\ArrayCollection given, called in C:\wamp\dometech\dev\vendor\symfony\symfony\src\Symfony\Component\PropertyAccess\PropertyAccessor.php on line 410 and defined 
    Logique en fin de compte. Puisque l'ArrayCollection devrait être sur l'entité Module et non ModuleType :/

    Aurais-tu une idée ?
    Merci d'avance

  6. #6
    Membre Expert Avatar de Nico_F
    Homme Profil pro
    Développeur Web
    Inscrit en
    Avril 2011
    Messages
    728
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Avril 2011
    Messages : 728
    Par défaut
    Je ne suis pas sûr que ce soit comme ça que je l'aurais abordé.

    Les paramètres allow_add et allow_delete sont sur la classe de liaison ModuleLie, pas vraiment sur Module.
    En l'occurrence tu ne vas pas ajouter de nouveaux modules, mais de nouvelles associations (et en supprimer également). Donc pour moi l'erreur se trouve là, il faut que tu permette l'ajout et la suppression sur la classe ModuleLie dans le form ModuleType.

    Et du coup, tu peux enlever le "multiple => true" dans ton form ModuleModuleLieType, qui te cause l'erreur ArrayCollection au lieu de l'objet.

Discussions similaires

  1. [2.x] Recupérer une entité dans un formulaire
    Par symfony_dev dans le forum Symfony
    Réponses: 6
    Dernier message: 11/07/2012, 10h38
  2. [2.x] [FORM] Utiliser un autre objet qu'une entité dans un formulaire
    Par benderpremier dans le forum Symfony
    Réponses: 5
    Dernier message: 21/10/2011, 19h48
  3. insere une date dans un formulaire
    Par lepeintre dans le forum ASP
    Réponses: 5
    Dernier message: 13/05/2005, 10h46
  4. Réponses: 4
    Dernier message: 01/09/2004, 16h56
  5. Sélectionner une ligne dans une DBGrid
    Par RBIK dans le forum Bases de données
    Réponses: 13
    Dernier message: 01/07/2004, 17h13

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