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 :

Problème Symfony ou Doctrine ?


Sujet :

ORM PHP

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 19
    Points : 12
    Points
    12
    Par défaut Problème Symfony ou Doctrine ?
    Voila un moment déjà que je suis sur un projet en symfony, et me voila confronté a un problème que je ne m'explique pas, je vous passe tout le contexte de l'application les seules point à savoir étant que j'ai une variable $prec_lundi qui représente le lundi de la semaine précédente et d'autre part je dispose d'une BDD dans laquelle figure les tables :

    - COURS
    - PLAGE
    - DECLARATION_PLAGE

    avec tous les attributs qui leurs son propres.

    L'objectif est d'obtenir un tableau dans lequel figure les plages déclaré par le formateur entre un jour X et un jour Y ainsi que l'état des-dites plages horaires.

    Pour ce faire j'utilise 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
    14
    15
    16
    17
     
     
    $q1 = Doctrine_Query::create()
    ->select("p.DATEPLAGE AS date, p.HEUREDEBUTPLAGE AS heure, d.IDFORMATEUR AS idFormateur, d.IDETATPLAGEDECLAREE AS etat, c.DUREECOURS AS coursDuree, c.FOR_IDFORMATEUR AS coursIdFormateur")
    ->from("PLAGE p")
    ->leftJoin("p.COURS c ON c.IDPLAGE=p.IDPLAGE")
    ->leftJoin("p.DECLARATION_PLAGE d ON d.IDPLAGE=p.IDPLAGE")
    ->where("d.IDFORMATEUR=".$sf_user->getAttribute('IDFORMATEUR')."")
    ->andWhere("p.DATEPLAGE >= '".date("Y-m-d", $this->prec_lundi)."'")
    ->andWhere("p.DATEPLAGE <= '".date("Y-m-d", $this->prec_lundi+(5*24*3600) )."'")
    ->andWhere("p.HEUREDEBUTPLAGE >= '8:00:00'")
    ->andWhere("p.HEUREDEBUTPLAGE <= '21:00:00'")
    ->orderBy("date, heure");
     
    $coll1 = $q1->execute();
     
    $this->res1 = $coll1->toArray();
    Certes la requête n'est pas des plus courte mais elle est claire, pour vérifier la justesse de ma requête je l'ai testé sur ma BBD en ligne de commande et le retour attendu est bien là au contraire, doctrine me renvoie une collection avec des éléments contenu mais lorsque je souhaite récupérer un tableau à partir de cette collection ma variable $res1 est tous simplement égale a Array()

    Ma question est de savoir pourquoi en Mysql j'obtiens le bon résultat alors qu'avec Doctrine+Symfony je me retrouve avec rien ou pas vraiment puisqu'un tableau vide ce n'est pas rien ...

    Merci de votre aide et de vos réponses.

    A tout hasard j'ai fait un petit symfony cc et j'ai actualisé ma page et la le problème semble "s'éclaircir" par le message d'erreur suivant :
    500 | Internal Server Error | Doctrine_Record_UnknownPropertyException
    Unknown record property / related component "IDPLAGE" on "PLAGE"
    Relation ou propriété inconnu cette erreur me semble des plus incongrue car suite à la récupération de la requete générée avec un
    et le teste de celle-ci dans mon terminal Mysql j'obtiens le tableau que je souhaite ... je me pose la question si Doctrine effectue correctement le mapping de relation à partir d'une BDD existante ... la BDD étant fournie de plus de 100 tables j'ai très peu envie de réécrire toutes les relations à la main .

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Février 2009
    Messages
    66
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 66
    Points : 82
    Points
    82
    Par défaut
    Je ne sais pas vraiment ce que tu veux faire mais pourquoi veux tu absolument obtenir un tableau ?

    Sinon je pense que tu dois pouvoir faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    $this->res1 = Doctrine::getTable('Plage')->createQuery('p')
    ->leftJoin("p.DeclarationPlage dp")
    ->where("dp.IDFORMATEUR = ? ", $this->getUser()->getAttribute('IDFORMATEUR')."")
    ->andWhere("p.DATEPLAGE >= '".date("Y-m-d", $this->prec_lundi)."'")
    ->andWhere("p.DATEPLAGE <= '".date("Y-m-d", $this->prec_lundi+(5*24*3600) )."'")
    ->andWhere("p.HEUREDEBUTPLAGE >= '8:00:00'")
    ->andWhere("p.HEUREDEBUTPLAGE <= '21:00:00'")
    ->orderBy("date, heure")->execute();
    Tu obtiens donc une collection d'objet Plage auxquelles seront automatiquement lié les plages et les DeclarationPlage si tu les as définis dans ton schema.yml

    Ensuite tu récupère dans ton template et tu pourras alors faire :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    <?php foreach ($res1 as $plage) :  ?>
      echo $plage->getCours()->getDate();
    <?php endforeach; ?>
    Voila ne connaissant pas du tout ce que tu veux faire et ton schéma tout ce si n'est qu'hypothétique. Tout dépends des nom que tu as donnés dans ton schema sur les relations.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 19
    Points : 12
    Points
    12
    Par défaut Informations complémentaires
    Merci de ta réponse Muspil, je vais tenté d'utiliser directement la collection au lieu d'utiliser un tableau.

    Ce tableau doit représenté les plages horaires de disponibilité du formateur a savoir qu'une plage a une durée de 30min et que dans ma vue j'affiche un tableau de 6 jours allant de 8h à 21h par jour dans lequel je met en couleur les plages déclarée par le formateur.
    Il me faut également l'état de la plage puisqu'elle en à 3 :
    - Indisponible => je fais une case vide
    - Disponible => je fais une case verte
    - Disponible sous conditions => je fais une case bleue

    Bien entendu le formateur peu mettre a jour ses disponibilité en cliquant sur les cases chaque cases de mon tableau afficher représentant une plage horaire de 30min.

    Voici les tables de mon schéma concerné (le schéma n'est pas au complet les autres tables n'étant pas utiles je ne les ais pas mises)

    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
     
    ETAT_SESSION:
      tableName: ETAT_SESSION
      columns:
        idetatsession:
          type: integer(8)
          primary: true
          autoincrement: true
        libelleetatsession:
          type: string(255)
          notnull: true
        descriptionetatsession: string(2147483647)
     
    FORMATEUR:
      tableName: FORMATEUR
      columns:
        idformateur:
          type: integer(8)
          primary: true
          autoincrement: true
        idtiers:
          type: integer(8)
          notnull: true
        loginutilisateur: string(255)
        descriptionformateur: string(2147483647)
        commentaireformateur: string(2147483647)
      relations:
        TIERS:
          local: IDTIERS
          foreign: IDTIERS
          type: one
        UTILISATEUR:
          local: LOGINUTILISATEUR
          foreign: LOGINUTILISATEUR
          type: one
     
    COURS:
      tableName: COURS
      columns:
        idcours:
          type: integer(8)
          primary: true
          autoincrement: true
        idplage:
          type: integer(8)
          notnull: true
        idsessionsousmodule:
          type: integer(8)
          notnull: true
        dureecours:
          type: integer(4)
          notnull: true
        estactivecours:
          type: integer(1)
          notnull: true
        idformateur: integer(8)
        for_idformateur: integer(8)
        idville: integer(8)
        idsalle: integer(8)
        dateaffectationcours: date(25)
        heureaffectationcours: time(25)
        descriptioncours: string(2147483647)
        adressecours: string(255)
        commentairecours: string(2147483647)
      relations:
        SALLE:
          local: IDSALLE
          foreign: IDSALLE
          type: one
        VILLE:
          local: IDVILLE
          foreign: IDVILLE
          type: one
        PLAGE:
          local: IDPLAGE
          foreign: IDPLAGE
          type: one
        FORMATEUR:
          local: FOR_IDFORMATEUR
          foreign: IDFORMATEUR
          type: one
        SESSION_DE_SOUS_MODULE:
          local: IDSESSIONSOUSMODULE
          foreign: IDSESSIONSOUSMODULE
          type: one
        FORMATEUR_6:
          class: FORMATEUR
          local: IDFORMATEUR
          foreign: IDFORMATEUR
          type: one
     
    DECLARATION_PLAGE:
      tableName: DECLARATION_PLAGE
      columns:
        iddeclarationplage:
          type: integer(8)
          primary: true
          autoincrement: true
        idformateur:
          type: integer(8)
          notnull: true
        idplage:
          type: integer(8)
          notnull: true
        idetatplagedeclaree:
          type: integer(8)
          notnull: true
        datedeclarationplage:
          type: date(25)
          notnull: true
        heuredeclarationplage:
          type: time(25)
          notnull: true
      relations:
        ETAT_PLAGE_DECLAREE:
          local: IDETATPLAGEDECLAREE
          foreign: IDETATPLAGEDECLAREE
          type: one
        PLAGE:
          local: IDPLAGE
          foreign: IDPLAGE
          type: one
        FORMATEUR:
          local: IDFORMATEUR
          foreign: IDFORMATEUR
          type: one
     
    UTILISATEUR:
      tableName: UTILISATEUR
      columns:
        loginutilisateur:
          type: string(255)
          primary: true
        passutilisateur:
          type: string(255)
          notnull: true
        compteutilisateuractif:
          type: integer(1)
          default: '0'
        idclient: integer(8)
        idpartenaire: integer(8)
        idauditeur: integer(8)
        idorganismeaccueil: integer(8)
        idformateur: integer(8)
        commentaireutilisateur: string(2147483647)
      relations:
        AUDITEUR:
          local: IDAUDITEUR
          foreign: IDAUDITEUR
          type: one
        CLIENT:
          local: IDCLIENT
          foreign: IDCLIENT
          type: one
        FORMATEUR:
          local: IDFORMATEUR
          foreign: IDFORMATEUR
          type: one
        ORGANISME_ACCUEIL:
          local: IDORGANISMEACCUEIL
          foreign: IDORGANISMEACCUEIL
          type: one
        PARTENAIRE:
          local: IDPARTENAIRE
          foreign: IDPARTENAIRE
          type: one
     
    PLAGE:
      tableName: PLAGE
      columns:
        idplage:
          type: integer(8)
          primary: true
          autoincrement: true
        dateplage:
          type: date(25)
          notnull: true
        heuredebutplage:
          type: time(25)
          notnull: true
     
    ETAT_PLAGE_DECLAREE:
      tableName: ETAT_PLAGE_DECLAREE
      columns:
        idetatplagedeclaree:
          type: integer(8)
          primary: true
          autoincrement: true
        libelleetatplagedeclaree:
          type: string(255)
          notnull: true
    Voila si cela peut t'aider a comprendre ma question et ce que je veux faire avec ces tables.

    @Muspil : Après avoir essayer ta solution mon affichage fonctionne tant qu'aucune plage n'est déclaré, dès que je tente de visualisé une semaine avec des plages déclarées l'erreur cité dans mon précédent post ...
    500 | Internal Server Error | Doctrine_Record_UnknownPropertyException
    Unknown record property / related component "IDPLAGE" on "PLAGE"
    apparait. La relation de Plage a Declaration_Plage est bien une "hasMany" et une "hasOne" en sens inverse, ma relation est donc bien mappée.

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 117
    Points : 123
    Points
    123
    Par défaut
    Dis moi quand tu vas sur le frontend_dev.php, tu dois avoir les requêtes SQL qui s'affiche? Alors si tu pouvais la mettre pour voir ce que ca te fait exactement.

    Et la table Cours elle te sert à quoi?

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 19
    Points : 12
    Points
    12
    Par défaut Requete SQL génére
    Voici la requete sql généré par Doctrine avec la solution de Muspil :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    SELECT p.idplage AS p__idplage, p.dateplage AS p__dateplage,
    p.heuredebutplage AS p__heuredebutplage, d.iddeclarationplage AS 
    d__iddeclarationplage, d.idformateur AS d__idformateur, d.idplage AS d__idplage, 
    d.idetatplagedeclaree AS d__idetatplagedeclaree, d.datedeclarationplage AS 
    d__datedeclarationplage, d.heuredeclarationplage AS d__heuredeclarationplage 
    FROM PLAGE p 
    LEFT JOIN DECLARATION_PLAGE d ON p.idplage = d.idplage 
    WHERE d.idformateur = ? 
    AND p.dateplage >= '2009-05-04' 
    AND p.dateplage <= '2009-05-09' 
    AND p.heuredebutplage >= '8:00:00' 
    AND p.heuredebutplage <= '21:00:00' 
    ORDER BY p.dateplage, p.heuredebutplage
    Avec ma solution initiale :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    SELECT p.dateplage AS p__0, p.heuredebutplage AS p__1, d.idformateur 
    AS d__2, d.idetatplagedeclaree AS d__3, c.dureecours AS c__4, c.for_idformateur 
    AS c__5 
    FROM PLAGE p 
    LEFT JOIN COURS c ON c.idplage = p.IDPLAGE 
    LEFT JOIN DECLARATION_PLAGE d ON d.idplage = p.IDPLAGE 
    WHERE d.idformateur = 1
    AND p.dateplage >= '2009-05-04'
    AND p.dateplage <= '2009-05-09' 
    AND p.heuredebutplage >= '8:00:00' 
    AND p.heuredebutplage <= '21:00:00' 
    ORDER BY p__0, p__1
    Les résultat obtenu dans ma console mysql correspondent tous les deux a ceux que je recherche à part les champ inutiles séléctionné dans la première requete mais ce n'est pas un problème.

    La table COURS me sert a savoir si le formateur est affecté a un cours auquel cas il ne peut saisir/modifier ses disponibilitées sur les plages horaires utilisées par le cour.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 117
    Points : 123
    Points
    123
    Par défaut
    As tu essayé de faire une requête simple du genre :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    $this->res1 = Doctrine::getTable('Plage')->createQuery('p')
    ->leftJoin("p.DeclarationPlage dp")->execute();
    Est ce que toujours la même erreur?

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 19
    Points : 12
    Points
    12
    Par défaut
    @Malonix : Oui la requête que tu m'a conseillé me donne exactement la même erreur que les autres. Je précise que j'ai généré mon schema.yml à partir d'une BDD existante. Cette erreur à donc à voir avec le mapping de Doctrine qui serai mal effectué ?

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    19
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 19
    Points : 12
    Points
    12
    Par défaut Solution
    Bon après avoir tenté maintes solution en utilisant l'ORM je me suis rabattu sur une autre solution qui fait exactement ce que je souhaite , d'ailleurs depuis que je l'ai trouvée j'ai eu la nécessité de l'utiliser plusieurs fois .

    Le truc consiste a envoyer directement la requête au SGBD en ignorant l'ORM généré par nôtre cher Doctrine , voici le code de ma solution à vous de l'adapter si vous passez par ce problème

    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
     
    public function getPlanningDispo($prec_lundi)
    	{
    		$connexion = Doctrine_Manager::getInstance()->getCurrentConnection();
     
    		$query = "SELECT p.IDPLAGE AS idPlage,  p.DATEPLAGE AS date, p.HEUREDEBUTPLAGE AS heure, d.IDFORMATEUR AS idFormateur, d.IDETATPLAGEDECLAREE AS etat, c.DUREECOURS AS coursDuree, c.IDFORMATEUR AS coursIdFormateur, c.ESTACTIFCOURS AS estActif
    		FROM PLAGE p LEFT JOIN DECLARATION_PLAGE d ON p.IDPLAGE=d.IDPLAGE LEFT JOIN COURS c ON c.IDPLAGE=p.IDPLAGE LEFT JOIN FORMATEUR f ON f.IDFORMATEUR = d.IDFORMATEUR
    		WHERE p.DATEPLAGE >= '".date("Y-m-d", $prec_lundi)."' AND p.DATEPLAGE <= '".date("Y-m-d", $prec_lundi+(5*24*3600) )."' 
    		AND p.HEUREDEBUTPLAGE >= '8:00:00' AND p.HEUREDEBUTPLAGE <= '21:00:00' ORDER BY date,heure";
     
    		$statement = $connexion->prepare($query);
    		$statement->execute();
     
    		$res1 = array();
     
    		while ($resultset = $statement->fetch(PDO::FETCH_ASSOC))
    		{
    			$res1[] = array(
    								'date'				=> $resultset['date'] ,
    								'heure'				=> $resultset['heure'] ,
    								'idFormateur'		=> $resultset['idFormateur'] ,
    								'etat'				=> $resultset['etat'],
    								'coursDuree'		=> $resultset['coursDuree'],
    								'coursIdFormateur'	=> $resultset['coursIdFormateur'],
    								'estActif'			=> $resultset['estActif'],
    								'idPlage'			=> $resultset['idPlage']
    							);				
    		}
     
    		return $res1;
    	}

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Janvier 2009
    Messages
    117
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2009
    Messages : 117
    Points : 123
    Points
    123
    Par défaut
    Je pense que comme ce n'est pas toi qui a fait la base de données, je me demande si ca ne viendrait pas de la.

  10. #10
    Expert confirmé
    Avatar de emmanuel.remy
    Inscrit en
    Novembre 2005
    Messages
    2 855
    Détails du profil
    Informations personnelles :
    Âge : 56

    Informations forums :
    Inscription : Novembre 2005
    Messages : 2 855
    Points : 4 045
    Points
    4 045
    Par défaut
    SAlut,

    C'est peut-être un peu tard mais si cela peut servir:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    $tableau = Doctrine_Query::create()
    ->from("Plage p")
    ->leftJoin("p.DeclarationPlage dp")
    ->where("dp.IDFORMATEUR = ? ", $this->getUser()->getAttribute('IDFORMATEUR')."")
    ->andWhere("p.DATEPLAGE >= '".date("Y-m-d", $this->prec_lundi)."'")
    ->andWhere("p.DATEPLAGE <= '".date("Y-m-d", $this->prec_lundi+(5*24*3600) )."'")
    ->andWhere("p.HEUREDEBUTPLAGE >= '8:00:00'")
    ->andWhere("p.HEUREDEBUTPLAGE <= '21:00:00'")
    ->orderBy("date, heure")
    ->fetchArray();	
    Quand on appelle la méthode toArray() sur un record, il ne renverra que les liaisons pour lesquelles un accès en lecture/écriture a déjà été fait.
    Pour forcer et avoir les liaisons (références) , on peut appeler la méthode $obj->refreshRelated();
    Inversement pour les supprimer on peut appeler $obj->clearRelated();


    ERE

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

Discussions similaires

  1. [Doctrine] problème de création de base mysql avec Symfony et Doctrine
    Par maarek dans le forum ORM
    Réponses: 1
    Dernier message: 15/12/2011, 10h23
  2. Réponses: 4
    Dernier message: 07/01/2011, 16h35
  3. Outils pour symfony et doctrine
    Par JPminM dans le forum ORM
    Réponses: 3
    Dernier message: 27/10/2009, 17h52
  4. [1.x] Problème symfony (rafraichissement de page)
    Par PPAPP dans le forum Symfony
    Réponses: 3
    Dernier message: 04/02/2009, 10h09

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