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 :

Formulaire pour relation n:n [1.x]


Sujet :

Symfony PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2008
    Messages : 186
    Par défaut Formulaire pour relation n:n
    Bonjour,

    J'ai un soucis pour ma gestion de formulaire dans mon backend.

    Mon schéma de base de données ressemblent à ça:
    Journée[id, date] 0:n --- JourneeActivites [idJournee, idActivites, heure_acti] --- 0:n Activites[id, intitule]

    Donc une relation n:n, et je n'arrive pas à trouver comment faire dans mon backend, quand je créé un module en me basant sur la table Journée, pour pouvoir afficher pour chaque activités un champs pour sélectionner l'heure appropriée.

    Mon formulaire devrait être du genre:
    Date du jour
    Choix activités 1, choix heure
    Choix activités 2, choix heure
    ...
    Dois je utiliser un embed form ? Si oui comment le pré-configurer ?
    Merci

  2. #2
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    On est dans une double confusion classique dans symfony, qui n'est pas très claire sur ces points.

    Dans Doctrine, ORM de symfony, une relation n-n s'entend par une relation directe entre deux tables simulée (la relation) par une troisième table qui ne peut comprendre que 2 champs. Doctrine ne supporte pas d'attribut dans la table de liaison. Ce qui fait que dans la relation que tu décris, il y a deux relation 0-n et trois tables et non pas une relation n-n entre deux tables avec un attribut sur la relation. La première définition est propre au couple symfony - doctrine, la seconde est parfaitement justifier dans le cadre d'une analyse conceptuel et du MPD qui en résulterait. Mais là, on est dans symfony et c'est lui qui a raison, même si...

    Deuxième confusion, la notion de backend qui est/doit être composé de modules dit d'administration, générés essentiellement par symfony. En réalité il n'y a pas de différence structurelles entre les applications de frontend, backend et toutes autres applications que l'on pourraient avoir la nécessité de mettre en œuvre. On peut donc mettre des modules dit d'administration dans le frontend et des modules fait "à la mano" dans les deux applications.

    Pour le formulaire que tu souhaites créé, et à ma connaissance (mais si j'ai le temps, je vais faire un essai, c'est un sujet intéressant) il n'est pas possible de réaliser ce que tu souhaites dans le cadre d'un formulaire générés par le système d'administration.

    Dans l'immédiat, je verrais bien une solution. Dans ton module d'administration, tu as en fait deux fichiers intéressants, le config/generator.yml où on a tendance à croire que toute la configuration doit se situer et un fichier actions/actions.class.php qui doit ressembler à ceci
    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
     
    <?php
     
    require_once dirname(__FILE__).'/../lib/user_adminGeneratorConfiguration.class.php';
    require_once dirname(__FILE__).'/../lib/user_adminGeneratorHelper.class.php';
     
    /**
     * user_admin actions.
     *
     * @package    turlututu
     * @subpackage user_admin
     * @author     Your name here
     * @version    SVN: $Id: actions.class.php 23810 2009-11-12 11:07:44Z Kris.Wallsmith $
     */
    class user_adminActions extends autoUser_adminActions
    {
        // ici je peux rajouter, modifier le comportement par défaut des objets !!!
    }
    "autoUser_adminActions" est le module généré par symfony et est localisé dans le cache "cache/<application>/<environnement>/modules/<nom du modules>/actons/autoUser_adminActions.class.php

    Entre nous, il est très intéressant de se plonger dans ce dossier pour comprendre le fonctionnement des modules d'administration.

    Et d'en déduire qu'on peut réécrire la méthode executeEdit et de l'envoyer sur un template maison, à partir du form maison qui inclurai à ce moment là des embededForm.

    Je pense que c'est une solution qui te permettrait d'utiliser le meilleur des deux mondes.

  3. #3
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2008
    Messages : 186
    Par défaut
    Bonjour,

    Tout d'abord merci d'avoir prit le temps de répondre aussi clairement

    Ensuite entre temps je m'étais lancé dans divers test, dont un presque concluant.
    Dans mon fichier backendJourneeForm.class.php, dans la méthode configure, j'avais voulu faire quelque chose de ce genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    foreach($activites as $acti): {
       $form = new JourneeActivites();
       $form->Journee = $this->getObject();
       $form->Activites = $acti;
       $this->embedForm($acti->getIntitule(), new JourneActivitesForm($form));
    }
    En mettant les unset Journee et Activites dans le JourneeActivitesForm. J'avais bien un champs date qui s'affichait pour chaque activités.

    Seulement ça ne fonctionne pas quand même lors de l'enregistrement ! "Problème lors de l'insertion, il y a deux INSERT INTO"...Le premier lors du choix des activités dans la liste, et le second pour les heures associées. Peut être qu'il faut faire un mixte des deux, redéfinir la liste de sélection des activités.

    Je regarderai ce que tu proposes voir si je trouve quelque chose, là je ne suis pas sur mon ordinateur, je refais de tête.
    Merci

  4. #4
    Expert confirmé
    Avatar de Michel Rotta
    Homme Profil pro
    DPO
    Inscrit en
    Septembre 2005
    Messages
    4 954
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : DPO
    Secteur : Distribution

    Informations forums :
    Inscription : Septembre 2005
    Messages : 4 954
    Par défaut
    Il faut vraiment que je joue avec les embed pour la maitriser... c'est presque 30% des questions ici.

    Il y a une méthode embedRelation() pour les objets sfFormDoctrine qui pourraient permettre de gérer des form liées. Un peu plus d'information dans le "livre" "More with symfony" chapitre "Formulaires avancé"

    Peut-être est-ce là le début de la solution.

  5. #5
    Membre expérimenté

    Profil pro
    Inscrit en
    Mai 2008
    Messages
    186
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Mai 2008
    Messages : 186
    Par défaut
    Bon, je vous propose ma solution, après avoir pris le temps de lire les explications sur les formulaires avancés, et les relire plusieurs fois même, j'ai réussi ce que je voulais faire !

    Donc tout d'abord j'ai créé une classe qui étend un sfForm pour récupérer mes activités et afficher des embedForm pour chacun :

    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
    class CentreActivitesCollectionParJour extends sfForm
    {
        public function configure()
        {
            if (!$jour = $this->getOption('jour'))
            {
                throw new InvalidArgumentException('Objet CentreJour attendu');
            }
     
            // récupère une collection d'objets Activites
            $activites = Doctrine_Core::getTable('CentreActivites')->getChamps(); 
     
            foreach($activites as $i => $acti): {
                $form = new CentreJourComporter();
                $form->CentreActivites = $acti; // id activités
                $form->CentreJour = $jour;  // id du jour
                $formEmbed = new CentreJourComporterForm($form);
                $this->embedForm($acti->getIntitule(), $formEmbed );
     
                // Permet de sélectionner seulement ceux qui ont été choisis
                $this->mergePostValidator(new JourComporterActivitesValidatorSchema());  
     
            }
            endforeach;
     
        }
    }
    Dans la classe JourneeActivitees, qui regroupe l'id du jour, id activités et l'heure, ne pas oublier de passer à unset les id, et mettre le nouveau champs non obligatoire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    public function configure()
      {
          unset(
          $this['jour_id'], $this['acti_id']
        );
     
          $this->validatorSchema['date_ac']->setOption('required', false);
    Ensuite la classe appelée par mergePostValidator
    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
    class JourComporterActivitesValidatorSchema extends sfValidatorSchema
    {
        protected function configure($options = array(), $messages = array())
        {
            //$this->addMessage('date_ac', 'la date est requise');
        }
     
        protected function doClean($values)
        {
            $errorSchema = new sfValidatorErrorSchema($this);
             $i=0;
            foreach($values as $key => $value)
            {
                $errorSchemaLocal = new sfValidatorErrorSchema($this);
     
                // Si le champs date ne contient rien, on l'ignore
                if ( $value['date_ac'] == null )
                {                
                    unset($values[$key]);
                }
     
                // si erreurs...
                if (count($errorSchemaLocal))
                {
                    $errorSchema->addError($errorSchemaLocal, (string) $key);
                }
     
            }
     
            // throws the error for the main form
            if (count($errorSchema))
            {
                throw new sfValidatorErrorSchema($this, $errorSchema);
            }
     
            return $values;
        }
    }
    Pour terminer, la classe JourForm qui affiche le formulaire, doit seulement afficher ses champs et plus la liste à choix multiples qui faisait le lien avec la table Activités.
    Puis il faut appeler la classe CentreActivitesCollectionParJour, pour afficher les imbrications de formulaires, en passant un objet jour en paramètre. On aurait pu mettre directement le code ici, mais comme je vais devoir le réutiliser ailleurs, il était plus judicieux de séparer le code.

    La méthode saveEmbeddedForms est surchargée pour ne pas enregistrer les formulaires vides, sinon vous aurez votre table remplie normalement mais avec un champs vide.

    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
    class CentreJourForm extends BaseCentreJourForm
    {
        public function configure()
        {
            $this->useFields(array('date_j','age'));
            $form = new CentreActivitesCollectionParJour(null, array(
                'jour' => $this->getObject() // Utile pour avoir l'id du jour qui sera créé
              ));
     
            $this->embedForm('activites', $form); // Imbrique les formulaires               
        }
     
        // méthode surchargée
        public function saveEmbeddedForms($con = null, $forms = null)
        {
            if (null === $forms)
            {
                $activites = $this->getValue('activites');
                $forms = $this->embeddedForms;
                foreach ($this->embeddedForms['activites'] as $name => $form)
                {
                    if (!isset($activites [$name]))
                    {
                        unset($forms['activites'][$name]);
                    }
                }
            }
     
            return parent::saveEmbeddedForms($con, $forms);
        }
    Il ne reste plus qu'à modifier la partie édition.

    Je vous conseil de lire le lien que j'ai mis en haut, normalement après ça on a plus de problème avec les formulaires...normalement !

    Si vous avez des commentaires ou des "moi j'aurai fais ça plutôt", je suis preneur

    A+

  6. #6
    Membre actif
    Profil pro
    Inscrit en
    Août 2008
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2008
    Messages : 24
    Par défaut
    J'ai testé un peu ton truc mais rien y fait, je ne peux toujours pas enregistrer dans ma table relation...

    Et qu'est ce que représente CentreJourComporterForm dans ton exemple ?

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 11
    Dernier message: 07/01/2013, 22h45
  2. [AC-2010] Formulaires pour alimenter 2 tables relation plusieurs-plusieurs
    Par florianne dans le forum IHM
    Réponses: 8
    Dernier message: 19/02/2012, 22h31
  3. Formulaire(s) pour relations plusieurs à plusieurs
    Par Kareg dans le forum Modélisation
    Réponses: 7
    Dernier message: 01/09/2007, 14h22
  4. formulaire pour relation plusieurs à plusieurs
    Par Gali dans le forum Access
    Réponses: 4
    Dernier message: 26/04/2006, 10h27
  5. Formulaire pour base XML
    Par Nyx dans le forum XML/XSL et SOAP
    Réponses: 2
    Dernier message: 12/02/2003, 20h51

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