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

ORM PHP Discussion :

Doctrine, schema.yml et contrainte d'unicité


Sujet :

ORM PHP

  1. #1
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut Doctrine, schema.yml et contrainte d'unicité
    Bonjour à tous,

    Alors pour une rapide présentation, je suis actuellement en train d'apprendre à utiliser symfony. Pour cela, j'ai rapidement lu et réaliser une partie du tutoriel 'Jobeet'. Je réalise maintenant un projet personelle.
    J'ai donc élaborer un modèle, j'ai ensuite générer automatiquement le schema.yml mais comme les clés étrangères n'étaient pas prise en compte, j'ai repris à la main ce fichier.
    Cependant, et c'est la que les ennuis commencent, j'ai un problême au niveau des contraintes de deux tables liées entre elles par une clé étrangère.

    Pour le SGBDR, j'utilise PostGreSql.

    Voici le code:
    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
     
    El_Candidats:
      connection: doctrine
      tableName: el_candidats
      columns:
        cotisant_id: { type: integer(4) , primary: true }
        poste_id: { type: integer(4), primary: true }
        description: { type: integer(4), notnull: true }
      relations:
        Co_Cotisants: { onDelete: CASCADE, onUpdate: CASCADE, local: cotisant_id, foreign: id, type: one, foreignType: many }
        El_Postes: { onDelete: CASCADE, onUpdate: CASCADE, local: poste_id, foreign: id, type: one, foreignType: many }
     
    El_Postes:
      connection: doctrine
      tableName: el_postes
      columns:
        id: { type: integer(4), primary: true }
        description: { type: string(), notnull: true }
     
    El_Votes:
      connection: doctrine
      tableName: el_votes
      columns:
        poste_id: { type: integer(4), primary: true }
        cotisant_id: { type: integer(4), primary: true }
        candidat_id: { type: integer(4), primary: true }
      relations:
        Co_Cotisants: { onDelete: CASCADE, onUpdate: CASCADE, local: cotisant_id, foreign: id, type: one, foreignType: many }
        El_Postes: { onDelete: CASCADE, onUpdate: CASCADE, local: poste_id, foreign: id, type: one, foreignType: many }
        El_Candidats: { onDelete: CASCADE, onUpdate: CASCADE, local: candidat_id, foreign: cotisant_id, type: one, foreignType: many }
    Et voici le SQL généré par la commande 'symfony doctrine:build --all':
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    CREATE TABLE el_candidats (poste_id SERIAL, cotisant_id INT, description INT NOT NULL, PRIMARY KEY(poste_id, cotisant_id));
    CREATE TABLE el_postes (id SERIAL, description TEXT NOT NULL, PRIMARY KEY(id));
    CREATE TABLE el_votes (poste_id SERIAL, cotisant_id SERIAL, candidat_id INT, PRIMARY KEY(poste_id, cotisant_id, candidat_id));
    ALTER TABLE el_candidats ADD CONSTRAINT el_candidats_poste_id_el_postes_id FOREIGN KEY (poste_id) REFERENCES el_postes(id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE;
    ALTER TABLE el_candidats ADD CONSTRAINT el_candidats_cotisant_id_el_votes_candidat_id FOREIGN KEY (cotisant_id) REFERENCES el_votes(candidat_id) NOT DEFERRABLE INITIALLY IMMEDIATE;
    ALTER TABLE el_candidats ADD CONSTRAINT el_candidats_cotisant_id_co_cotisants_id FOREIGN KEY (cotisant_id) REFERENCES co_cotisants(id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE;
    ALTER TABLE el_votes ADD CONSTRAINT el_votes_poste_id_el_postes_id FOREIGN KEY (poste_id) REFERENCES el_postes(id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE;
    ALTER TABLE el_votes ADD CONSTRAINT el_votes_cotisant_id_co_cotisants_id FOREIGN KEY (cotisant_id) REFERENCES co_cotisants(id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE;
    ALTER TABLE el_votes ADD CONSTRAINT el_votes_candidat_id_el_candidats_cotisant_id FOREIGN KEY (candidat_id) REFERENCES el_candidats(cotisant_id) ON UPDATE CASCADE ON DELETE CASCADE NOT DEFERRABLE INITIALLY IMMEDIATE;
    J'ai alors plusieurs questions :
    1. Pourquoi la commande SQL suivante est généré
      Code : Sélectionner tout - Visualiser dans une fenêtre à part
      ALTER TABLE el_candidats ADD CONSTRAINT el_candidats_cotisant_id_el_votes_candidat_id FOREIGN KEY (cotisant_id) REFERENCES el_votes(candidat_id) NOT DEFERRABLE INITIALLY IMMEDIATE;
      alors que nul part dans mon schema.yml, il y a une contrainte de clé étrangère de el_candidats vers el_votes ...
    2. Je voulais savoir si il était possible que les deux colonnes concerné soit de type différent (INT et SERIAL dans mon cas)


    De plus lorsque j'essaye d'éxecuter ce code, j'obtient l'erreur suivante :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    SQLSTATE[42830]: Invalid foreign key: 7 ERREUR:  il n'existe aucune contrainte unique correspondant aux clés données pour la table « el_votes » référencée.
    Failing Query: "ALTER TABLE el_candidats ADD CONSTRAINT el_candidats_cotisant_id_el_votes_candidat_id FOREIGN KEY (cotisant_id) REFERENCES el_votes(candidat_id) NOT DEFERRABLE INITIALLY IMMEDIATE".
    Si vous voulez me poser des questions supplémentaires, n'hésitez pas.
    Inarius

  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
    Je ne connais pas postgre si ce n'est de nom.

    Par contre, je connait relativement bien doctrine, et je pense que c'est là que ce trouve ta solution.

    Par contre, il semble manquer une table dans ton schema : Co_Cotisants


    Question 3
    Ton schema n'est pas réellement simple, doctrine 1.2 n'aime pas vraiment les clefs multiples. De plus (pas simple avec l'absence supposée de la table Co_Cotisants) mais j'ai l'impression qu'une des liaisons entre vote et poste ou entre candidat et poste est en trop, suivant ce que tu veux faire.

    L'erreur pourait être là

    Question 2
    non (ça c'est des réponses simple) même type.

    Question 1
    Je propose de régler d'abord le schéma pour qu'il s'implémente correctement, il est possible que cette contrainte soit une conséquence de la question 3.


    Pourrais-tu mettre le code de la table qui semble manquante.

    Dans les conseils supplémentaires :
    • Évite les préfixe sur les nom des objets (le nom de la table peut-être différent du nom de l'objet.
    • Évite de mettre les nom des tables au pluriels et le nom des objets. Le schema va généré plus que les tables, il va générer le modèle, les form et les filter. Avec ton schéma un objet vote apparaîtra sous la forme de ElVotes ce qui ne laisse pas de place à une collection des votes qui devrait alors s'appeler ElVotess ce qui est peu lisible.

  3. #3
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    Pour ce qui est de la table manquante, c'est juste que je ne l'ai pas poster mais elle existe bien et est bien dans le schéma (Pour clarifier le tout, j'ai mis une représentation du modèle en pièce jointe)

    Ensuite pour le suffixe, je désire le garder car il y a environ 18 tables, nombre qui est ammené à augmenter. Et chaque table est plus ou moins lié à d'autres tables, mais comme elles ne sont pas toutes dans la même catégorie (sp_photos, ga_photos, ) c'est beaucoup plus simple à gérer. De même pour le nom des objets

    Ensuite, je ne vois pas vraiment ou est la liason en trop :s J'espère que la modélisation que j'ai mis en pièce jointe pourra t'aider à m'aider

    Et enfin pour les 's' à la fin des objets, je m'en vais les retirer de suite

  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
    Soit pour les préfixes, c'est une bonne méthode de travail, je suis sans doutes plus confus.

    On va juste discuter, pour commencer sur le schéma, et sur la partie qui t'intéresse avec le préfixe EL.

    Si je comprends bien.

    On a des cotisants qui peuvent ce porter candidat à un poste.
    On a des cotisants qui peuvent voter pour un candidat à un poste

    Il me semblerait logique qu'un cotisants ne puisse voter que pour une candidature (un cotisant pour un poste). Hors dans ton schéma, un cotisant peut lui même choisir le candidat (a condition qu'il se soit présenté à un poste) et le poste qui peut être différent de celui auquel le candidat prétend du fait de la liaison entre la table poste et la table vote. C'est là que je vois le liens de trop. Il me semblerait plus logique que la clef (poste) de vote soit en liaison avec la clef (poste) de candidat.

    De plus il semblerait manquer un attribut à la table vote permettant de préciser le vote.

    Je pense qu'il serait plus simple de créer une clef unique sur la table candidature pour gérer la liaison, Doctrine n'aime pas les clefs composées.

    De plus, en passant très vite sur ton schéma je suis tombé sur la table sp_sports, c'est le champs Belfort qui a attiré mon regard, on est presque voisin. Dans cette table, il semblerait qu'il y ait, en dur des lieux, ce qui n'est pas conforme aux formes normal et rendrait très compliqué tout ajout d'un nouveau lieu.

    Autre choses, tu as deux tables photos identiques... m'est avis qu'elle auraient intérêt à être regroupées avec un code qui indiquerait le rattachement de la photo. Un seul système de gestion des téléchargement et une consultations centralisée possible.

    C'est les principaux points du schéma qui ont attiré mon œil, mais je pense qu'il y a d'autres choses qui pourrait être discutées, mais ceci n'était pas l'objectif du message.

    Réfléchi à ces liens dans la partie élection, il doit y avoir quelque chose qui cloche.

  5. #5
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    Alors pour répondre à ta question de nom des villes dans la table sport, en fait il s'agit du future site du Bureau de Sports de l'UTBM ^^ Donc comme les sports se déroulent soit à Sevenans soit à Belfort soit à MontBélliard soit deux ou même les trois, et que l'UTBM ne s'implémente dans une autre ville, on a le temps

    Ensuite pour les tables 'sp_photos' et 'ga_photos', j'avais déjà penser à centraliser les photos dans une seul et même table cependant je préfère ne pas mettre de table centralisé pour toutes les photos pour permettre de pouvoir supprimé des parties de code facilement sans surchargé la bdd ni rien, donc je trouve personnelement que ce sera plus rangé comme ca

    Et finalement pour les votes, j'ai complétement simplifier le tout

    Donc voila ce que ca devient :
    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
     
    El_Candidat:
      connection: doctrine
      tableName: el_candidats
      columns:
        cotisant_id: { type: integer(4) , primary: true }
        poste_id: { type: integer(4), primary: true }
        description: { type: integer(4), notnull: true }
        nb_vote: { type: integer(4), notnull: true }
      relations:
        Co_Cotisant: { onDelete: CASCADE, onUpdate: CASCADE, local: cotisant_id, foreign: id, type: one, foreignType: many }
        El_Poste: { onDelete: CASCADE, onUpdate: CASCADE, local: poste_id, foreign: id, type: one, foreignType: many }
     
    El_Poste:
      connection: doctrine
      tableName: el_postes
      columns:
        id: { type: integer(4), primary: true, autoincrement: true }
        description: { type: string(), notnull: true }
    Donc maintenant les votes sont complétements anonymes (ce qui n'est pas plus mal ) et ensuite ca marche

    Mais merci beaucoup de ton aide et dsl mais j'ai pas tout compris a ce que tu as dis
    Il me semblerait logique qu'un cotisants ne puisse voter que pour une candidature (un cotisant pour un poste). Hors dans ton schéma, un cotisant peut lui même choisir le candidat (a condition qu'il se soit présenté à un poste) et le poste qui peut être différent de celui auquel le candidat prétend du fait de la liaison entre la table poste et la table vote. C'est là que je vois le liens de trop. Il me semblerait plus logique que la clef (poste) de vote soit en liaison avec la clef (poste) de candidat.

    De plus il semblerait manquer un attribut à la table vote permettant de préciser le vote.

  6. #6
    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
    Citation Envoyé par Inarius Voir le message
    Alors pour répondre à ta question de nom des villes dans la table sport, en fait il s'agit du future site du Bureau de Sports de l'UTBM ^^ Donc comme les sports se déroulent soit à Sevenans soit à Belfort soit à MontBélliard soit deux ou même les trois, et que l'UTBM ne s'implémente dans une autre ville, on a le temps
    C'est probable effectivement que cela ne soit jamais le cas, mais, niveau analyse ce n'est pas "satisfaisant", même étant sur qu'il n'y a aucune chance que... Suivant la loi de l'emmerdement maximal, ça va arriver, soit une autre salle, soit dans un quartier qui devra être nommé,...

    Citation Envoyé par Inarius Voir le message
    Ensuite pour les tables 'sp_photos' et 'ga_photos', j'avais déjà penser à centraliser les photos dans une seul et même table cependant je préfère ne pas mettre de table centralisé pour toutes les photos pour permettre de pouvoir supprimé des parties de code facilement sans surchargé la bdd ni rien, donc je trouve personnelement que ce sera plus rangé comme ca
    C'est une manière de voir les choses. Mais je continue de penser que si le système est bien conçu, tu aurais juste un module "photo" en plus. Soit plus d'indépendance et surtout pas de redondance du code. Avec ta solution, si tu veux changer un traitement sur les photos, tu vas être bon pour vérifier les deux codes... Bien conçu, tu n'auras ni surcharge de la BD, ni duplication de code. Mais c'est toi qui code.

    Citation Envoyé par Inarius Voir le message
    Mais merci beaucoup de ton aide et dsl mais j'ai pas tout compris a ce que tu as dis
    Hélas, parfois je ne suis pas clair, et un bon dessins aurait été meilleur, mais en dessin aussi, je ne suis pas fort.

    Tes modifications ont supprimé toutes mes remarques.

    J'en rajoute une sur tes modification. L'avantage est que tu ne sais pas qui a voter pour qui et que ce n'est plus traçable, ce qui correspond à un vote secret, et est un mieux. D'un autre côté, tu ne sais pas qui a voté, et que tu risques de saisir deux fois un même vote.

    Et une dernière, où gères-tu la composition du bureau, une fois les élections terminées ?

  7. #7
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    Alors voila j'ai suivi ce que tu m'as dit et voila ce que j'obtient comme modèle (voir pièce jointe)

    Donc j'ai réglé le problême de la loi de "l'emmerdement maximal" en rajoutant une table sp_salles et c'est vrai que du coup on peut en fait réglé plus finement les endroits ou se dérouleront les sports

    Ensuite par la même technique j'ai changer la table co_cotisants pour la gestion des objets qui lui sont associé, et j'ai rajouter la partie matos.

    Et enfin j'ai corrigé le potentiel problême de double vote en remettant la table el_votes mais en supprimant la clé étrangère qui posait problême

    J'espère avoir pu corriger tous les défauts de mon modèle

    Si tu trouve quelquechose à redire n'hésite pas
    Images attachées Images attachées  

  8. #8
    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
    Encore quelques remarques :

    Table co_cotisant :
    Il n'y a aucun champs pour l'adresse, ni pour le téléphone (les téléphones aujourd'hui).
    Il n'est pas possible de mettre un co_cotisant maître d'autre fiches (par exemple dans le cas d'une famille, les enfants ayant dans la table un lien bouclant sur la fiche du père, en cas de demande des cotisations, tu peux ne faire qu'un mail, par exemple...
    Tu gères dans la même table le cotisant et la cotisation. Hors le cotisant est "fixe" alors que la cotisation peut évoluer d'une année sur l'autre.

    Table ph_photo
    Tu comptes stocker les photos dans la table ?
    Ceci me semble particulièrement lourd a gérer y compris niveau affichage. A ta place, je gèrerais les photos dans trois dossiers mini, moyen et grand. Ensuite tu y stockes la photo avec en nom leur Id. Et si tu ne veux pas qu'on puisse les retrouver facilement, tu les stocks avec un nom aléatoire généré avec un random et un md5.
    Fait attention au droit à l'image...
    Pourquoi ne pas avoir une liaison entre co_cotisant et ph_photo pour pouvoir avoir la photo du cotisant ?

    Dans la partie sport sp
    Tu as une liaison n-n entre sp_sports et sp_salles, doctrine gère très bien ce type de données si la déclaration est correctement mise en œuvre dans le schéma.
    Même remarque entre sport et cotisants
    Sauf que...
    Je pense que les liaisons entre sport et salle devrait passer par sp_horaire. En effet un créneau d'entraînement ce passe dans une salle hors il n'y a pas de liens entre les horaires et les salles.
    Même chose entre sp_sport et co-cotisant, tu as une notions de responsable que j'intégrerais dans la table sp_participants. Après tous, il est possible qu'il y ait un jour besoins de plusieurs responsables, où d'un responsable et d'un nettoyeur... donc je casserais la table sp_participant pour y rajouter un type et une table des types. Une liaison en moins, mais une table en plus.

    Dans la partie droits
    Si c'est bien ce que je pense, c'est ici que tu gères les droits sur les différentes parties de l'application. A ta place, j'utiliserais plutôt le plugins sfDoctrineGuard, pourquoi réinventer la roue ?

    Dans la partie élection.
    Ben c'est bon, mais il va falloir être très, très précis dans le programme de gestion des votes pour assurer l'impossibilité de double vote et qu'il ne soit pas possible de tricher, même par erreur.

    Dans la partie News
    Peut-être voir s'il n'y a pas un plugin qui gère les blogs. Il y en a un qui gère les cms et un autre un wiki.
    Tu y gères des photos qui ne sont pas en liaison avec sp_photo.

    Dans la partie Matériel pret
    Rien a dire.

    Dans la partie Grande activité
    Pourquoi pas simplement activité ?
    J'ai l'impression que la table ga_photo sert à une liaison n-n avec photo. Il y a des règles strictes pour utiliser les n-n dans doctrine, notamment la table de liaison ne doit comporter que les deux clefs primaires de chacune des tables liées.
    J'aurais mis un lien avec les news, qui permettraient d'avoir des informations reliés aux activités.


    Voilà mes quelques remarques.

    J'ai un projet plus généraliste qui ressemble au tiens, mais sans les élections, sans le prêt et avec la gestion comptable en plus...

    Bonne chance.

  9. #9
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    Pour la table co_cotisants :
    Pour l'adresse et le téléphone, le bureau n'a pas désiré stocké ces infos donc j'ai pas trop le choix ^^ de plus dans notre ecole, les mails sont le moyen de communication principale Et pour les liens de parenté, il ne sont pas pris en comtpe déjà parce que rare sont les étudiants déjà parent (avec des enfants dans la même université) donc je ne pense pas que ce soit utile. Et enfin pour la cotisation, elle n'a quand même pas bouger depuis X années (et encore, ce sera une "revolution" le fait de stocker le certificat medical de manière électronnique xD )

    Pour la table ph_photos:
    Oui les photos seront stocké dans la base de donnée, pour différentes raisons:
    - déjà c'est beaucoup plus simple pour les sauvegardes
    - comme le site sera hébergé sur un des serveurs de l'uni, je n'ai aucun pouvoir sur les droits d'utilisateur, et notre CRI (Centre des Ressources Info) n'est pas du genre très coopératif donc c'est encore la plus simple de stocker dans la bdd
    - et c'est pas pour les 50ène de personne par jour qui vont voir le site qu'il y aura de gros problêmes de performances

    Pour la partie sport:
    Je ne suis pas très familier avec le SQL en général, j'ai déjà fait quelques trucs mais rien de bien transcendant. J'ai donc un peu du mal avec les tables n:n (je m'en vais me documenter de suite )
    Et ta remarque sur le fait de réunir la table sp_sprt et la sp_salles par la table sp_horaires me parait des plus judicieuses.

    Pour la partie droit:
    je n'avait pas vu le plugin sfDoctrineGuard et vu tout le bien que j'ai pu en lire, je crois que je vais abandonner mon système perso ^^

    Pour les elections, j'ai changer la table el_votes, c'est maintenant impossible q'un cotisant vote plusieurs fois pour le même poste.

    Et enfin pour les news, vu la simplicité de la chose, je pense je vais plutôt developper mon propre système. Ca me fera apprendre et si j'y arrive vraiment pas, bah je me rabatterai sur quelquechose qui existe déjà.

    Et pour les grandes activites, j'ai bien renommé GdeActivite en Activite (toujours moins de problemes )

    En tout cas je te remercie grandement pour l'intérêt que tu porte à mon projet

    Inarius

    EDIT: En pièce jointe le nouveau modèle
    EDIT2: j'avais une autre question, plus technique et qui touche à symfony
    J'aimerais récupérer le nombre de photo et le nombre de participants à une grande activite. Donc j'utilise un objet Doctrine_Query et j'ai le code suivant:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    $this->gdes_activites = Doctrine_Query::create()
                    ->select('
                        g.nom,
                        g.presentation,
                        g.date_debut,
                        g.date_fin,
                        ( SELECT COUNT(*) as nb_participant FROM gaParticipant g2 WHERE g2.activite_id = g.id ) AS nb_participant,
                        ( SELECT COUNT(*) as nb_photo FROM gaPhoto g3 WHERE g3.activite_id = g.id ) AS nb_photo')
                    ->from('gaActivite g')
                    ->where('g.actif')
                    ->orderBy('g.date_debut ASC')
                    ->execute();
    Donc j'obtient le code SQL suivant :
    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
     
    SELECT 
    	g.id AS g__id, 
    	g.nom AS g__nom, 
    	g.presentation AS g__presentation, 
    	g.date_debut AS g__date_debut, 
    	g.date_fin AS g__date_fin, 
    	(
    		SELECT COUNT(*) AS g2__0 
    		FROM ga_participants g2 
    		WHERE (g2.activite_id = g.id)
    	) AS g__0, 
    	(
    		SELECT COUNT(*) AS g3__0 
    		FROM ga_photos g3 
    		WHERE (g3.activite_id = g.id)
    	) AS g__1 
    FROM 	ga_activites g 
    WHERE 	(g.actif) 
    ORDER BY g.date_debut ASC
    Mais comment je récupère le résultat du SELECT COUNT parce que le g__0, on l'affiche comment dans le template ?
    Images attachées Images attachées  

  10. #10
    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
    Je n'avais pas saisi que c'était un club de sport rattaché à une université ! Effectivement, même avec l'allongement des études, les liens de parentés entre les membres sont peu probables et ne méritent aucun traitement

    Pour les photos, le problème de stockage n'est pas tant de les stocker dans un fichier que de les récupérer. En effet, dans le code xhtml tu vas afficher avec une balise <img> qui a besoins d'un fichier, que tu ne vas pas avoir. Théoriquement tu peux faire une route et une action sous symfony qui va intercepter la demande d'une image en jpg et retourner le fichier, mais je ne suis pas sur que je me lancerais dans un tel montage, mais c'est réalisable avec symfony. Note que dans ce cas, je ne vois plus l'intérêt de stocker l'image en trois tailles, vu qu'elle doit être manipulée à chaque sortie en local sur le serveur, tu dois pouvoir la réduire suivant la demande, à chaque fois, sans que le temps de traitement ne soit trop important. Après, avec le système de cache de symfony, on devrait pouvoir facilement traiter les multiples demandes.

    Pour sfGuard, oui, c'est un bon plugin, mais fait toi un essai dans une application de test avant d'appliquer, il faudra rajouter un champs user_id à la table cotisant pour gérer le liens avec les tables des users.

    Pour la question 2, je ne savais pas que l'on pouvait faire ce type de manipulation avec doctrine. Disons qu'elle soit contre nature (pour doctrine).

    Mais je pense qu'il faut dans un premier temps entrer ton schéma, tester la création des tables pas symfony, et faire un gros fichier de fixtures pour alimenter la base de tests.

    Ensuite, regarde bien la documentation de doctrine, tu vas voir qu'il y a des notion de leftjoin qui permettent de lier les tables et des méthodes magiques, pour récupérer un nombre d'enregistrement, y compris dans des tables dépendantes.

    Tu auras peut-être physiquement trois requêtes au lieu d'une, mais je ne pense pas qu'au niveau performance ce soit mieux que celle créer qui, en fait, est constituée elle aussi de trois requête.

    Stabilise ta base, alimente la avec des fixatures et passe à la suite doucement.

    Jette un œil attentif aux plugins, il y a beaucoup de chose qui existent déjà et réinventer la roue n'est pas nécessairement une bonne idée.

  11. #11
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    En parlant des fixtures, j'ai suivi tes conseils et j'ai commencé un faire un fichier fixtures.yml pour peupler la bdd. Mais j'ai maintenant des problêmes sur la rédaction de ce fichier.
    J'ai commencer par écrire ca:
    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
     
    <?php for ( $i = 1 ; $i <= 1000 ; $i++ ) : ?>
    phPhoto:
      photo_<?php echo $i ?>: { id: <?php echo $i ?>, grand: A2, content_type: image/jpeg, date: now() }
    <?php endfor ?>
     
    <?php for ( $i = 1 ; $i <= 100 ; $i++ ) : ?>
    coCotisant:
      cotisant_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        photo_id: <?php echo rand( 1, 1000 )."\n" ?>
        nom: <?php echo "nom$i\n" ?>
        prenom: <?php echo "prenom$i\n" ?>
        email: <?php echo "nom$i"."prenom$i" ?>@utbm.fr
        sexe: <?php echo rand( 0, 1 )."\n" ?>
        branche: TC
        semestre: <?php echo rand( 0, 5 )."\n" ?>
        semestre_fin_cotisation: P10
        duree_cotisation: <?php echo rand( 1, 2 )."\n" ?>
        date_certificat: now()
        certificat: A
        certificat_content_type: image/png
    <?php endfor ?>
     
    <?php for ( $i = 1 ; $i <= 5 ; $i++ ) : ?>
    neCategory:
      category_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        nom: category_<?php echo $i."\n" ?>
        description: description_<?php echo $i."\n" ?>
        image: A
        image_content_type: image/jpeg
    <?php endfor ?>
     
    <?php for ( $i = 1 ; $i <= 10 ; $i++) : ?>
    neNew:
      news_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        cotisant_id: <?php echo rand( 1, 100 )."\n" ?>
        categorie_id: <?php echo rand( 1, 5 )."\n" ?>
        titre: titre_<?php echo $i."\n" ?>
        contenu: contenu_<?php echo $i."\n" ?>
        valide: <?php echo ( rand( 0, 1 ) === 1 ? 'true' : 'false' )."\n" ?>
        date_creation: now()
    <?php endfor ?>
     
    <?php for ( $i = 1 ; $i <= 20 ; $i++ ) : ?>
    gaActivite:
      gde_activite_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        responsable_id: <?php echo rand( 1, 100 )."\n" ?>
        nom: gde_activite_<?php echo $i."\n" ?>
        presentation: contenu_<?php echo $i."\n" ?>
        date_debut: now()
        date_fin: <?php echo date( 'Y-m-d', time() + 60 * 60 * 24 * 365 * 5 ) ?>
        actif: <?php echo ( rand( 0, 1 ) === 1 ? 'true' : 'false' )."\n" ?>
    <?php endfor ?>
    mais quand j'éxécute, il y a une erreur au niveau de PostGres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    SQLSTATE[23503]: Foreign key violation: 7 ERREUR:  une instruction insert ou update sur la table « co_cotisants » viole la contrainte de clé  
      étrangère « co_cotisants_photo_id_ph_photos_id »                                                                                             
      DETAIL:  La clé (photo_id)=(793) n'est pas présente dans la table « ph_photos ».
    En gros, les cotisants sont introduits dans la bdd avant les photos alors que les photos sont avant les cotisants dans le fixtures.yml
    En fait lorsque je regarde dans la bdd, il n'y a que l'enregistrement 1000 mais pas le reste...

    Pour Doctrine, la manipulation ne marche pas donc c'est que c'est vraiment pas bon Donc je vais me documenter et apprendre du SQL et du DQL et jvais essayer tout seul

    EDIT: J'ai trouver la solution à mon erreur qui était très... bête ...
    J'ai mis le nom de la table à remplir DANS la boucle ...
    Donc suffit de le mettre en dehors comme ca:
    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
     
    coCotisant:
    <?php for ( $i = 1 ; $i <= 100 ; $i++ ) : ?>
      cotisant_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        photo_id: <?php echo rand( 1, 1000 )."\n" ?>
        nom: <?php echo "nom$i\n" ?>
        prenom: <?php echo "prenom$i\n" ?>
        email: <?php echo "nom$i"."prenom$i" ?>@utbm.fr
        sexe: <?php echo rand( 0, 1 )."\n" ?>
        branche: TC
        semestre: <?php echo rand( 0, 5 )."\n" ?>
        semestre_fin_cotisation: P10
        duree_cotisation: <?php echo rand( 1, 2 )."\n" ?>
        date_certificat: now()
        certificat: A
        certificat_content_type: image/png
    <?php endfor ?>
    et ca marche tout seul ...

  12. #12
    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
    Avec la solution c'est beaucoup moins drôle !

    J'aurais perso commencé par un ou deu enregistrement à la mano pour m'assurer que tout passe avant de lancer la "production de masse" mais manifestement, bruler les étapes peut parfois fonctionner aussi !

  13. #13
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    en fait j'avais deja un ou deux enregistrements à la mano, mais comme dit c'est pas beaucoup et j'avais pas remplit toutes les tables, donc autant faire tout bien c'est plus rapide pour la suite

  14. #14
    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
    Cela permet surtout deux choses :

    de reprendre tes tests de dév à chaque scéance de dev avec la même base, juste en la reconstruisant régulièrement avec un doctrine:build --all --and-load.

    d'avoir une base fixe et standard pour tes tests que tu ne manqueras pas de mettre en œuvre. En cela, la notion de random dans la génération du fixature n'est peut-être pas une bonne idée.

  15. #15
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    C'est pas bête ce que tu dit. Ce que je vais faire, c'est finir avec les random la, et une fois que j'ai un fixture complet (pour toutes les tables), je creer un fixture.yml fixe (sans aucun php).

  16. #16
    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
    Tu peux créer des fixtures avec du code php. Si non, il va être monstrueux.

    La difficulté, vient juste des liaisons aléatoire des photos. Si tu lies les 500 premières photos aux 500 premiers cotisant, tu peux vérifier dans les tests que tel cotisant à bien sa photo.

  17. #17
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    J'ai belle et bien mis du php dans mon fixture :
    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
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
     
    <?php
      define('NB_PHOTOS', 500);
      define('NB_COTISANTS', 200);
      define('NB_GDES_ACTIVITES', 10);
      define('NB_OBJETS', 10);
      define('NB_NEWS', 25);
      define('NB_NEWS_CATEGORIES', 5);
      define('NB_NEWS_COMMENTAIRES', 250);
      define('NB_MATOS_STATUTS', 3);
      define('NB_MATOS', 50);
      define('NB_MATOS_PRET', 150);
      define('NB_SPORTS', 30);
      define('NB_SPORTS_PARTICIPANTS_TYPES', 5);
      define('NB_SPORTS_SALLES', 5);
     
      function rand_branche() {
        $branches = array ('TC', 'GI', 'GESC', 'MC', 'EDIM', 'IMAP');
        return $branches[rand( 0, 5 )];
      }
    ?>
     
    phPhoto:
    <?php for ( $i = 1 ; $i <= NB_PHOTOS ; $i++ ) : ?>
      photo_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        grand: A2
        content_type: image/jpeg
        date: now()
    <?php endfor ?>
     
    coCotisant:
    <?php for ( $i = 1 ; $i <= NB_COTISANTS ; $i++ ) : ?>
      cotisant_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        photo_id: <?php echo rand( 1, NB_PHOTOS )."\n" ?>
        nom: <?php echo "nom$i\n" ?>
        prenom: <?php echo "prenom$i\n" ?>
        email: <?php echo "prenom$i".".nom$i" ?>@utbm.fr
        sexe: <?php echo rand( 0, 1 )."\n" ?>
        branche: <?php echo rand_branche()."\n" ?>
        semestre: <?php echo rand( 1, 6 )."\n" ?>
        semestre_fin_cotisation: P10
        duree_cotisation: <?php echo rand( 1, 2 )."\n" ?>
        date_certificat: now()
        certificat: A
        certificat_content_type: image/png
    <?php endfor ?>
     
    coObjet:
    <?php for ( $i = 1 ; $i <= NB_OBJETS  ; $i++ ) : ?>
      objet_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        description: objet_<?php echo $i."\n" ?>
        quantite_initial: <?php echo rand( 20, 250 )."\n" ?>
    <?php endfor ?>
     
    coObjetDonne:
    <?php for ( $i = 1 ; $i <= NB_COTISANTS ; $i++ ) : ?>
      objet_<?php echo $i ?>:
        cotisant_id: <?php echo $i."\n" ?>
        objet_id: <?php echo rand( 1, NB_OBJETS )."\n" ?>
    <?php endfor ?>
     
    neCategory:
    <?php for ( $i = 1 ; $i <= NB_NEWS_CATEGORIES ; $i++ ) : ?>
      category_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        nom: category_<?php echo $i."\n" ?>
        description: description_<?php echo $i."\n" ?>
        image: A
        image_content_type: image/jpeg
    <?php endfor ?>
     
    neNew:
    <?php for ( $i = 1 ; $i <= NB_NEWS ; $i++) : ?>
      news_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        cotisant_id: <?php echo rand( 1, NB_COTISANTS )."\n" ?>
        categorie_id: <?php echo rand( 1, NB_NEWS_CATEGORIES )."\n" ?>
        titre: titre_<?php echo $i."\n" ?>
        contenu: contenu_<?php echo $i."\n" ?>
        valide: <?php echo ( rand( 0, 1 ) === 1 ? 'true' : 'false' )."\n" ?>
        date_creation: now()
    <?php endfor ?>
     
    neCommentaire:
    <?php for ( $i = 1 ; $i <= NB_NEWS_COMMENTAIRES ; $i++ ) : ?>
      commentaire_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        news_id: <?php echo rand( 1, NB_NEWS )."\n" ?>
        cotisant_id: <?php echo rand( 1, NB_COTISANTS )."\n" ?>
        message: message_<?php echo $i."\n" ?>
        date: now()
        edit: <?php echo ( rand( 0, 1 ) === 1 ? 'true' : 'false' )."\n" ?>
    <?php endfor ?>
     
    gaActivite:
    <?php for ( $i = 1 ; $i <= NB_GDES_ACTIVITES ; $i++ ) : ?>
      gde_activite_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        responsable_id: <?php echo rand( 1, NB_COTISANTS )."\n" ?>
        nom: gde_activite_<?php echo $i."\n" ?>
        presentation: contenu_<?php echo $i."\n" ?>
        date_debut: now()
        date_fin: <?php echo date( 'r', time() + 60 * 60 * 24 * 365 * 5 )."\n" ?>
        actif: <?php echo ( rand( 0, 1 ) === 1 ? 'true' : 'false' )."\n" ?>
    <?php endfor ?>
     
    gaParticipant:
    <?php for ( $i = 1 ; $i <= NB_COTISANTS ; $i++ ) : ?>
      participant_<?php echo $i ?>:
        cotisant_id: <?php echo $i."\n" ?>
        activite_id: <?php echo rand( 1, NB_GDES_ACTIVITES )."\n" ?>
    <?php endfor ?>
     
    gaPhoto:
    <?php for ( $i = 1 ; $i <= NB_PHOTOS ; $i++ ) : ?>
    <?php   if ( rand( 0, 2 ) === 1 ) : ?>
      photo_<?php echo $i ?>:
        activite_id: <?php echo rand( 1, NB_GDES_ACTIVITES )."\n" ?>
        photo_id: <?php echo $i."\n" ?>
    <?php   endif ?>
    <?php endfor ?>
     
    maStatut:
    <?php for ( $i = 1 ; $i <= NB_MATOS_STATUTS ; $i++ ) : ?>
      statut_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        description: description_<?php echo $i."\n" ?>
    <?php endfor ?>
     
    maMateriel:
    <?php for ( $i = 1 ; $i <= NB_MATOS ; $i++ ) : ?>
      matos_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        photo_id: <?php echo ( rand( 0, 5 ) === 5 ) ? rand( 1, NB_PHOTOS )."\n" : "\n"; ?>
        statut_id: <?php echo rand( 1, NB_MATOS_STATUTS )."\n" ?>
        nom: nom_<?php echo $i."\n" ?>
        description: descritpion_<?php echo $i."\n" ?>
    <?php endfor ?>
     
    maPret:
    <?php for ( $i = 1 ; $i <= NB_MATOS_PRET ; $i++ ) : ?>
    <?php $time = time() + 60 * 60 * 24 * rand( -120, 30 ) ?>
      pret_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        materiel_id: <?php echo rand( 1, NB_MATOS )."\n" ?>
        cotisant_id: <?php echo rand( 1, NB_COTISANTS )."\n" ?>
        date_debut: <?php echo date( 'r', $time )."\n" ?>
        date_fin: <?php echo date( 'r', $time + 60 * 60 * 60 * 24 * rand( 1, 15 ) )."\n" ?>
        actif: <?php echo ( rand( 0, 1 ) === 1 ? 'true' : 'false' )."\n" ?>
    <?php endfor ?>
     
    spSport:
    <?php for ( $i = 1 ; $i <= NB_SPORTS ; $i++ ) : ?>
      sport_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        nom: nom_<?php echo $i."\n" ?>
        description: description_<?php echo $i."\n" ?>
        matos: matos_<?php echo $i."\n" ?>
        actif: <?php echo ( rand( 0, 1 ) === 1 ? 'true' : 'false' )."\n" ?>
    <?php endfor ?>
     
    spPhoto:
    <?php for ( $i = 1 ; $i <= NB_PHOTOS ; $i++ ) : ?>
    <?php   if ( rand( 0, 2 ) === 1 ) : ?>
      photo_<?php echo $i ?>:
        sport_id: <?php echo rand( 1, NB_SPORTS )."\n" ?>
        photo_id: <?php echo $i."\n" ?>
    <?php   endif ?>
    <?php endfor ?>
     
    spParticipantType:
    <?php for ( $i = 1 ; $i <= NB_SPORTS_PARTICIPANTS_TYPES ; $i++ ) : ?>
      type_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        description: description_<?php echo $i."\n" ?>
    <?php endfor ?>
     
    spParticipant:
    <?php for ( $i = 1 ; $i <= NB_COTISANTS ; $i++ ) : ?>
    <?php $rand = rand( 0, 2 ) ?>
    <?php   if ( $rand === 1 || $rand === 2 ) : ?>
      photo_<?php echo $i ?>:
        cotisant_id: <?php echo $i."\n" ?>
        sport_id: <?php echo rand( 1, NB_SPORTS )."\n" ?>
        cotisant_type_id: <?php echo rand( 1, NB_SPORTS_PARTICIPANTS_TYPES )."\n" ?>
    <?php   endif ?>
    <?php endfor ?>
     
    spSalle:
    <?php for ( $i = 1 ; $i <= NB_SPORTS_SALLES ; $i++ ) : ?>
      salle_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        nom: nom_<?php echo $i."\n" ?>
        adresse: adresse_<?php echo $i."\n" ?>
    <?php endfor ?>
     
    spHoraire:
    <?php for ( $i = 1 ; $i <= NB_SPORTS * 2 ; $i++ ) : ?>
    <?php   $time_debut = time() + rand( 0, 7) * 24 * 60 * 60 ?>
      horaire_<?php echo $i ?>:
        id: <?php echo $i."\n" ?>
        sport_id: <?php echo rand( 1, NB_SPORTS )."\n" ?>
        salle_id: <?php echo rand( 1, NB_SPORTS_SALLES )."\n" ?>
        debut_jour: <?php echo date('r', $time_debut )."\n" ?>
        debut_heure: <?php echo date('r', $time_debut )."\n" ?>
        fin_jour: <?php echo date('r', $time_debut )."\n" ?>
        fin_heure: <?php echo date('r', $time_debut + rand ( 1, 2 ) * 60 * 60 )."\n" ?>
    <?php endfor ?>
    Sinon c'est vrai que 500 photos, 200 cotisants, ... à la main . Nan en fait je disait que je pouvais utiliser la console linux pour creer un fichier dynamiquement sans aucun code PHP comme ca c'est stable entre les différentes évolutions du modèle.

    Et pour les cotisants, les photos sont prises au hasard, mais chaque cotisant aura forcement une photo.

  18. #18
    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
    Comme dirait l'autre, il n'y a plus qu'a coder tous ça...

    Reviens par ici si tu as des problèmes avec les liaisons n-n qui sont un peu particulières.

  19. #19
    Membre confirmé
    Homme Profil pro
    Étudiant
    Inscrit en
    Octobre 2009
    Messages
    100
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 33
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2009
    Messages : 100
    Par défaut
    Alors aujourd'hui j'ai pas mal taffer et j'ai réalisé la page qui présente un sport (sports/show)
    Donc je suis arriver à tirer toutes les informations des tables suivantes : sp_sports, sp_participants, co_cotisants, sp_participants_types, sp_photos, sp_horaires et sp_salles.
    Mais j'arrive à un code certe assez propre et sans trop de requête SQL ( 4 au total) mais quand même assez long.

    Voila mon code:
    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
     
    public function getCompleteSport($id) {
        if ( empty($id) || $id === null )
            return false;
     
        $q = new Doctrine_RawSql();
     
        $sport_infos = $q->select('
                    {s.nom},
                    {s.description},
                    {s.matos},
                    {s.actif},
                    {h.salle_id},
                    {h.jour},
                    {h.heure_debut},
                    {h.heure_fin},
                    {pa.cotisant_type_id}')
                ->from('
                    sp_sports s
                    LEFT JOIN sp_participants pa ON s.id = pa.sport_id
                    LEFT JOIN sp_photos po ON s.id = po.sport_id
                    LEFT JOIN sp_horaires h ON s.id = h.sport_id')
                ->where('s.id = ?', $id)
                ->addComponent('s', 'spSport s')
                ->addComponent('pa', 's.sp_participants pa')
                ->addComponent('po', 's.sp_photos po')
                ->addComponent('h', 's.sp_horaires h')
                ->execute(array(), Doctrine::HYDRATE_ARRAY);
     
        if(empty($sport_infos))
            return false;
     
        if (!empty($sport_infos[0]['sp_participants'])) {
            foreach ( $sport_infos[0]['sp_participants'] as $participant ) {
                $participants_id[] = $participant['cotisant_id'];
                $participants_statuts[] = $participant['cotisant_type_id'];
            }
     
            $q = new Doctrine_RawSql();
            $cotisants_infos = $q->select('
                    {c.nom},
                    {c.prenom},
                    {c.photo_id}')
                    ->from('co_cotisants c')
                    ->where('c.id IN (' . implode( ',', $participants_id ) . ')')
                    ->addComponent('c', 'coCotisant c')
                    ->execute(array(), Doctrine::HYDRATE_ARRAY);
     
            $q = new Doctrine_RawSql();
            $statuts_infos = $q->select('{st.description}')
                    ->from('sp_participants_types st')
                    ->where("st.id IN (" . implode(',', $participants_statuts) . ')')
                    ->addComponent('st', 'spParticipantType st')
                    ->execute(array(), Doctrine::HYDRATE_ARRAY);
            ;
        }
     
        if (!empty($sport_infos[0]['sp_horaires'])) {
            foreach ( $sport_infos[0]['sp_horaires'] as $horaire )
                $horaires_salle_id[] = $horaire['salle_id'];
     
            $q = new Doctrine_RawSql();
            $salles_infos = $q->select('{sa.adresse},{sa.nom}')
                    ->from('sp_salles sa')
                    ->where('sa.id IN (' . implode( ',', $horaires_salle_id ) . ')' )
                    ->addComponent('sa', 'spSalle sa')
                    ->execute(array(), Doctrine::HYDRATE_ARRAY);
        }
     
        if (isset($salles_infos)) {
            foreach ( $salles_infos as $salle )
                $salles["{$salle['id']}"] = array(
                        'id' => $salle['id'],
                        'nom' => $salle['nom'],
                        'adresse' => $salle['adresse']
                );
     
            foreach ( $sport_infos[0]['sp_horaires'] as $horaire )
                $horaires["{$horaire['id']}"] = array(
                        'id' => $horaire['id'],
                        'salle' => $salles[$horaire['salle_id']],
                        'jour' => $horaire['jour'],
                        'heure' => array('debut' => $horaire['heure_debut'], 'fin' => $horaire['heure_fin'])
                );
        }
     
        if ( isset($cotisants_infos) && isset($statuts_infos) ) {
            foreach ( $cotisants_infos as $cotisant )
                $cotisants["{$cotisant['id']}"] = array(
                        'nom' => $cotisant['nom'],
                        'prenom' => $cotisant['prenom'],
                        'photo_id' => $cotisant['photo_id']
                );
     
            foreach ( $statuts_infos as $statut )
                $statuts["{$statut['id']}"] = array('description' => $statut['description']);
     
            foreach ( $sport_infos[0]['sp_participants'] as $participant )
                $participants["{$participant['cotisant_id']}"] = array(
                        'id' => $participant['cotisant_id'],
                        'nom' => $cotisants["{$participant['cotisant_id']}"]['nom'],
                        'prenom' => $cotisants["{$participant['cotisant_id']}"]['prenom'],
                        'photo_id' => $cotisants["{$participant['cotisant_id']}"]['photo_id'],
                        'statut' => $statuts["{$participant['cotisant_type_id']}"]['description']
                );
        }
     
        if ( !empty( $sport_infos[0]['sp_photos'] ) )
            foreach ( $sport_infos[0]['sp_photos'] as $photo)
                $photos[] = $photo['photo_id'];
     
        $sport = array(
                'nom' => $sport_infos[0]['nom'],
                'description' => $sport_infos[0]['description'],
                'matos' => $sport_infos[0]['matos'],
                'actif' => $sport_infos[0]['actif'],
                'horaires' => isset( $horaires ) ? $horaires : false,
                'participants' => isset( $participants ) ? $participants : false,
                'photos' => isset( $photos ) ? $photos : false
        );
     
        return ( empty($sport['nom']) || empty($sport['description']) || empty($sport['matos']) ) ? false : $sport;
    }
    et j'arrive à sortir des tableaux imbriqués propre et sans informations superflues :
    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
    142
    143
    144
    145
     
    Array
    (
        [nom] => nom_18
        [description] => description_18
        [matos] => matos_18
        [actif] => 1
        [horaires] => Array
            (
                [1] => Array
                    (
                        [id] => 1
                        [salle] => Array
                            (
                                [id] => 3
                                [nom] => nom_3
                                [adresse] => adresse_3
                            )
     
                        [jour] => Friday
                        [heure] => Array
                            (
                                [debut] => 2010-06-04 16:52:59
                                [fin] => 2010-06-04 17:52:59
                            )
     
                    )
     
                [4] => Array
                    (
                        [id] => 4
                        [salle] => Array
                            (
                                [id] => 4
                                [nom] => nom_4
                                [adresse] => adresse_4
                            )
     
                        [jour] => Friday
                        [heure] => Array
                            (
                                [debut] => 2010-06-04 16:52:59
                                [fin] => 2010-06-04 18:52:59
                            )
     
                    )
     
                [24] => Array
                    (
                        [id] => 24
                        [salle] => Array
                            (
                                [id] => 3
                                [nom] => nom_3
                                [adresse] => adresse_3
                            )
     
                        [jour] => Monday
                        [heure] => Array
                            (
                                [debut] => 2010-05-31 16:52:59
                                [fin] => 2010-05-31 17:52:59
                            )
     
                    )
     
                [50] => Array
                    (
                        [id] => 50
                        [salle] => Array
                            (
                                [id] => 3
                                [nom] => nom_3
                                [adresse] => adresse_3
                            )
     
                        [jour] => Sunday
                        [heure] => Array
                            (
                                [debut] => 2010-06-06 16:52:59
                                [fin] => 2010-06-06 17:52:59
                            )
     
                    )
     
            )
     
        [participants] => Array
            (
                [125] => Array
                    (
                        [id] => 125
                        [nom] => nom125
                        [prenom] => prenom125
                        [photo_id] => 131
                        [statut] => description_3
                    )
     
                [114] => Array
                    (
                        [id] => 114
                        [nom] => nom114
                        [prenom] => prenom114
                        [photo_id] => 231
                        [statut] => description_1
                    )
     
                [97] => Array
                    (
                        [id] => 97
                        [nom] => nom97
                        [prenom] => prenom97
                        [photo_id] => 95
                        [statut] => description_5
                    )
     
                [61] => Array
                    (
                        [id] => 61
                        [nom] => nom61
                        [prenom] => prenom61
                        [photo_id] => 497
                        [statut] => description_1
                    )
     
                [8] => Array
                    (
                        [id] => 8
                        [nom] => nom8
                        [prenom] => prenom8
                        [photo_id] => 145
                        [statut] => description_1
                    )
     
            )
     
        [photos] => Array
            (
                [0] => 88
                [1] => 231
                [2] => 390
                [3] => 393
            )
     
    )
    Ce qui me permet d'avoir un code dans le template simple et propre:
    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
     
    <?php if ( $sport['actif'] === false ) : ?>
    <h3>Ce sport est inactif ce semestre</h3><br/><br/>
    <?php endif ?>
     
    <table class="table">
        <tr>
            <td>Nom</td>
            <td><?php echo $sport['nom'] ?></td>
        </tr>
        <tr>
            <td>Presentation</td>
            <td><?php echo $sport['description'] ?></td>
        </tr>
        <tr>
            <td>Matériel mis à disposition</td>
            <td><?php echo $sport['matos'] ?></td>
        </tr>
        <tr>
            <td>Horaires</td>
            <td>
                <?php if ($sport['horaires'] !== false ) : ?>
                <table class="table">
                    <tr>
                        <td>Salle et adresse</td>
                        <td>Horaires</td>
                    </tr>
                        <?php foreach ( $sport['horaires'] as $horaire ) : ?>
                    <tr>
                        <td><?php echo $horaire['salle']['nom'] ?><br/><?php echo $horaire['salle']['adresse'] ?></td>
                        <td><?php echo "{$horaire['jour']}, de " . date('H:i', strtotime( $horaire['heure']['debut'] ) ) . ' à ' . date('H:i', strtotime( $horaire['heure']['fin'] ) ) ?></td>
                    </tr>
                        <?php endforeach ?>
                </table>
                <?php else : ?>
                Aucun horaire pour ce sport
                <?php endif ?>
            </td>
        </tr>
        <tr>
            <td>Nombre de photos</td>
            <td><?php echo count( $sport['photos'] ) ?></td>
        </tr>
        <tr>
            <td>Nombre de participants</td>
            <td><?php echo count( $sport['participants'] ) ?></td>
        </tr>
    </table>
    <br/>
    <h2>Participants</h2>
    <br/>
    <?php if ( $sport['participants'] !== false ) : ?>
    <?php foreach ( $sport['participants'] as $participant ) : ?>
        <?php echo "{$participant['nom']} {$participant['prenom']}" ?><br/>
        <?php echo "{$participant['statut']} {$participant['photo_id']}" ?><br/><br/>
    <?php endforeach ?>
    <?php else : ?>
        Aucun participant à ce sport
    <?php endif ?>
    <br/>
    <br/>
    <h2>Photos</h2>
    <br/>
    <?php foreach ( $sport['photos'] as $photo ) : ?>
        <?php echo $photo ?>&nbsp;&nbsp;&nbsp;
    <?php endforeach ?>
    Et tout ca s'execute relativment rapidement : environ 100ms et 8000k de mémoire (avec APC bien sur)

    Mais j'aurais voulu savoir, n'y a t'il pas plus simple? Parcque c'est assez propre, et le fait de changer un peu le modèle ne dérange pas trop et les modifications rapides. Mais quand même 119 lignes ...

  20. #20
    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
    Pour la fonction : getCompleteSport je ne sais pas où tu l'as mise contrôleur où modèle ?

    J'ai l'impression que tu hydrates des données déjà traiter et que tu fais le traitement que fais doctrine à la base.

    Ta requête n'est pas bonne, la première. Tes relations sont définie dans le modèle, il ne sert à rien de les redéfinir. Utilise la méthoe InnerJoin() de docrtine et ne définit pas les relations toi même. Si tu changes ton modèle ou ta base, doctrine saura adapter le code.

    Je ne sais pas où tu as mis ta fonction, mais je lui aurait bien vu faire des foward404 à la place des return false.

    J'ai rapidement (trop) lu ton code, mais j'ai eu beaucoup de mal à trouver les commentaires (à ben oui, bien sur !).


    Bon, faut clarifier, ce code. J'ai un peu l'impression que tu commences à construire la maison en débutant sur une tours de 40 étages par le 20ème alors que tu ne sais pas vraiment où mettre les fondations, ni comment les couler !

    Ca me rappel un adage qui dit que sa première application, on l'écrit pour son ennemis, la deuxième pour son amis et la troisième pour soi. C'est la première non


    A priori, une requête bien faîte devrait arriver au même résultat, quoique... Faut voir.


    Le template j'aime mieux. Juste mettre des <th> au lieu de <tr> pour les lignes de titre, cela simplifiera la rédaction des CSS, voir même rajouter des thead et tbody dans les tableau, toujours pour les CSS.

    Envisage de passer par des partiels, il est possible que certaines parties puisse reservir dans d'autre template.

    Pourquoi la liste des participants ne bénéficie t'elle pas d'un tableau ?

    Pourquoi ne pas mettre un lien sur un participant pour afficher sa fiche directement ?


    Pour les prochains bout de code, précise où il sont placé dans le MVC et dans quel fichiers symfony. Et pense à mettre des, heu, commentaire ...

    Tu es sur le bon chemin, je testerais l'application avec plaisir.

+ Répondre à la discussion
Cette discussion est résolue.
Page 1 sur 2 12 DernièreDernière

Discussions similaires

  1. [Doctrine] Relation entre deux tables dans schema.yml sans contrainte
    Par ninorotto dans le forum ORM
    Réponses: 8
    Dernier message: 24/08/2011, 10h26
  2. [doctrine]problème avec syntaxe du schema.yml
    Par flora806 dans le forum ORM
    Réponses: 3
    Dernier message: 15/03/2011, 10h19
  3. schema.yml pour relation n-n Doctrine
    Par psgman113 dans le forum ORM
    Réponses: 3
    Dernier message: 22/03/2010, 19h59
  4. [Doctrine] 2 schema.yml
    Par zoukkev dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 15/04/2009, 11h54

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