Précédent   Forum des professionnels en informatique > PHP > PHP & SGBD > ORM > Doctrine
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 28/01/2011, 03h29   #1
rib
Membre à l'essai
 
Inscription : janvier 2005
Messages : 70
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 70
Points : 23
Points : 23
Par défaut Doctrine_Collection & Foreign_key

bonjours j'ai deux tables mysql reliées par une foreign_key, j'ai générer mes modèles avec doctrine:
Artists.php:
Code :
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
 
<?php
// Connection Component Binding
Doctrine_Manager::getInstance()->bindComponent('App_Models_Artists', 'doctrine');
 
/**
 * App_Models_Base_Artists
 * 
 * This class has been auto-generated by the Doctrine ORM Framework
 * 
 * @property integer $id_artist
 * @property string $nom
 * @property string $id_facebook
 * @property string $bio
 * @property integer $ordre
 * @property Doctrine_Collection $ArtistsHaveLinks
 * 
 * @package    ##PACKAGE##
 * @subpackage ##SUBPACKAGE##
 * @author     ##NAME## <##EMAIL##>
 * @version    SVN: $Id: Builder.php 7490 2010-03-29 19:53:27Z jwage $
 */
abstract class App_Models_Base_Artists extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->setTableName('artists');
        $this->hasColumn('id_artist', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'fixed' => false,
             'unsigned' => false,
             'primary' => true,
             'autoincrement' => true,
             ));
        $this->hasColumn('nom', 'string', 20, array(
             'type' => 'string',
             'length' => 20,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('id_facebook', 'string', 30, array(
             'type' => 'string',
             'length' => 30,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('bio', 'string', 5000, array(
             'type' => 'string',
             'length' => 5000,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('ordre', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
    }
 
    public function setUp()
    {
        parent::setUp();
        $this->hasMany('App_Models_ArtistsHaveLinks as ArtistsHaveLinks', array(
             'local' => 'id_artist',
             'foreign' => 'id_artist'));
    }
}
et ArtistsHaveLinks.php:
Code :
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
 
<?php
// Connection Component Binding
Doctrine_Manager::getInstance()->bindComponent('App_Models_ArtistsHaveLinks', 'doctrine');
 
/**
 * App_Models_Base_ArtistsHaveLinks
 * 
 * This class has been auto-generated by the Doctrine ORM Framework
 * 
 * @property integer $id_link
 * @property integer $id_artist
 * @property string $img_link_artist
 * @property string $url_link_artist
 * @property integer $ordre
 * @property App_Models_Artists $Artists
 * 
 * @package    ##PACKAGE##
 * @subpackage ##SUBPACKAGE##
 * @author     ##NAME## <##EMAIL##>
 * @version    SVN: $Id: Builder.php 7490 2010-03-29 19:53:27Z jwage $
 */
abstract class App_Models_Base_ArtistsHaveLinks extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->setTableName('artists_have_links');
        $this->hasColumn('id_link', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'fixed' => false,
             'unsigned' => false,
             'primary' => true,
             'autoincrement' => true,
             ));
        $this->hasColumn('id_artist', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('img_link_artist', 'string', 50, array(
             'type' => 'string',
             'length' => 50,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('url_link_artist', 'string', 100, array(
             'type' => 'string',
             'length' => 100,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('ordre', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
    }
 
    public function setUp()
    {
        parent::setUp();
        $this->hasOne('App_Models_Artists as Artists', array(
             'local' => 'id_artist',
             'foreign' => 'id_artist'));
    }
}
ma classe artist a bien une Doctrine_Collection $ArtistsHaveLinks

je comprend pas comment faire pour la peupler,
se peuple elle automatiquement lors d'un select * sur la table artists dans ce cas comment accéder a la collection

je souhaiterais récupérer un objet avec un vecteur pour les liens mais je c pas comment faire.
Merci d'avance.
rib est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2011, 10h20   #2
rib
Membre à l'essai
 
Inscription : janvier 2005
Messages : 70
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 70
Points : 23
Points : 23
bon j'ai trouvé une solution:

j'ai modifier ma classe App_Models_Artists comme ceci:
Code :
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 App_Models_Artists extends App_Models_Base_Artists
{
	private $link;
 
	/**
	 * @param $link
	 */
	public function setLink() {
		$vue = Doctrine_Core::getTable('App_Models_ArtistsHaveLinks');
		$listeLinks = $vue->fetchAll('id_artist= '.$this->id_artist,'ordre ASC',null,null);
		$this->link = $listeLinks;
	}
 
	public function haveLink() {
		if (count($this->link)>0){
			return true;
		}else{
		return false;
		}
	}
 
	public function getLink() {
		return $this->link;
	}
 
}
la classe App_Models_ArtistsHaveLinksTable:
Code :
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
 
class App_Models_ArtistsHaveLinksTable extends Doctrine_Table
{
    /**
     * Returns an instance of this class.
     *
     * @return object App_Models_ArtistsHaveLinksTable
     */
    public static function getInstance()
    {
        return Doctrine_Core::getTable('App_Models_ArtistsHaveLinks');
    }
 
	public function fetchAll($where=null, $order=null, $limit=null, $offset=null)
	{
		$select = Doctrine_Query::create()
			->select('*')
			//dans le from on met le nom de la classe
			//Doctrine s'occupe du reste
			->from('App_Models_ArtistsHaveLinks');
 
		if(isset($where)){ $select->where($where); }
		if(isset($order)){ $select->orderBy($order); }
		if(isset($limit)){ $select->limit($limit); }
		if(isset($offset)){ $select->offset($offset); }
 
		return $select->execute();
	}
}
voici mon controleur ki genere la liste de mes artists avec leur liens:
Code :
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
 
class Artists_ListController extends Zend_Controller_Action {
 
	public function indexAction() {
		//on récupère la classe table de App_Models_Artists
		$table = Doctrine_Core::getTable('App_Models_Artists');
		//on liste tout le monde
		$listeArtists = $table->fetchAll(null,'ordre ASC',null,null);
		//on traite le résultat
 
		foreach($listeArtists as $artist){
 
			$artist->setLink();
		}
 
 
 
		$nbArtists = COUNT($MalisteArtists);
		if ($nbArtists % 2 != 0){
			$nombre_de_lignes = (int)($nbArtists/2)+1;
		}else{
			$nombre_de_lignes = $nbArtists/2;
		}
		$height_conteneur =  $nombre_de_lignes * 235;
 
 
		$this->view->nbartists = $nbArtists;
		$this->view->height_conteneur = $height_conteneur;
		$this->view->artists = $listeArtists;	
	}
}
com sa dans ma vue je recupere bien mes artists avec le ArrayObject contenant leur liens respectif.

si quelqu'un connait quelquechose de plus simple pour obtenir le meme resultat je suis preneur.
Merci d'avance
rib est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 29/01/2011, 18h49   #3
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
Je peux de conseiller sur des modèles écris en yaml. Par contre, sur ceux écris directement, je n'ai pas d'expérience.
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/01/2011, 03h28   #4
rib
Membre à l'essai
 
Inscription : janvier 2005
Messages : 70
Détails du profil
Informations forums :
Inscription : janvier 2005
Messages : 70
Points : 23
Points : 23
voila le yaml generé par doctrine grace a ma base de donnée:
Code :
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
Artists:
  connection: doctrine
  tableName: artists
  columns:
    id_artist:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    nom:
      type: string(20)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    id_facebook:
      type: string(30)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    bio:
      type: string(5000)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    ordre:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
  relations:
    ArtistsHaveLinks:
      local: id_artist
      foreign: id_artist
      type: many
ArtistsHaveLinks:
  connection: doctrine
  tableName: artists_have_links
  columns:
    id_link:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: true
      autoincrement: true
    id_artist:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    img_link_artist:
      type: string(50)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    url_link_artist:
      type: string(100)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
    ordre:
      type: integer(4)
      fixed: false
      unsigned: false
      primary: false
      notnull: true
      autoincrement: false
  relations:
    Artists:
      local: id_artist
      foreign: id_artist
      type: one
la classe artist generée par doctrine a une Doctrine_Collection $ArtistsHaveLinks

je vien de me rendre compte que je pouvait i aceder et qu'elle se peuplait automatiquement avec un select * sur la table.
apparement doctrine rempli une Doctrine_Collection contenant les enregistrements liés par les Foreighn_key

du coup voici ma classe App_Models_Artists:
Code :
1
2
3
4
5
6
7
8
9
10
11
 
class App_Models_Artists extends App_Models_Base_Artists
{
	public function haveLink() {
		if (count($this->ArtistsHaveLinks)>0){
			return true;
		}else{
		return false;
		}
	}
}
voici la App_Models_Base_Artists:
Code :
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
 
abstract class App_Models_Base_Artists extends Doctrine_Record
{
    public function setTableDefinition()
    {
        $this->setTableName('artists');
        $this->hasColumn('id_artist', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'fixed' => false,
             'unsigned' => false,
             'primary' => true,
             'autoincrement' => true,
             ));
        $this->hasColumn('nom', 'string', 20, array(
             'type' => 'string',
             'length' => 20,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('id_facebook', 'string', 30, array(
             'type' => 'string',
             'length' => 30,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('bio', 'string', 5000, array(
             'type' => 'string',
             'length' => 5000,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
        $this->hasColumn('ordre', 'integer', 4, array(
             'type' => 'integer',
             'length' => 4,
             'fixed' => false,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             ));
    }
 
    public function setUp()
    {
        parent::setUp();
        $this->hasMany('App_Models_ArtistsHaveLinks as ArtistsHaveLinks', array(
             'local' => 'id_artist',
             'foreign' => 'id_artist'));
    }
}
voici la App_Models_ArtistsTable:
Code :
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 App_Models_ArtistsTable extends Doctrine_Table
{
    /**
     * Returns an instance of this class.
     *
     * @return object App_Models_ArtistsTable
     */
    public static function getInstance()
    {
        return Doctrine_Core::getTable('App_Models_Artists');
    }
 
	/**
     * Select de base
     * 
     * @param string $where
     * @param string $order
     * @param int $limit
     * @param int $offset
     * @return Collection
     */
	public function fetchAll($where=null, $order=null, $limit=null, $offset=null)
	{
		$select = Doctrine_Query::create()
			->select('*')
			//dans le from on met le nom de la classe
			//Doctrine s'occupe du reste
			->from('App_Models_Artists');
 
		if(isset($where)){ $select->where($where); }
		if(isset($order)){ $select->orderBy($order); }
		if(isset($limit)){ $select->limit($limit); }
		if(isset($offset)){ $select->offset($offset); }
 
		return $select->execute();
	}
}
mon controlleur:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
 
class Artists_ListController extends Zend_Controller_Action {
 
	public function indexAction() {
		//on récupère la classe table de App_Models_Artists
		$table = Doctrine_Core::getTable('App_Models_Artists');
		//on liste tout le monde
		$listeArtists = $table->fetchAll(null,'ordre ASC',null,null);
		//on traite le résultat
 
		$nbArtists = COUNT($listeArtists);
		if ($nbArtists % 2 != 0){
			$nombre_de_lignes = (int)($nbArtists/2)+1;
		}else{
			$nombre_de_lignes = $nbArtists/2;
		}
		$height_conteneur =  $nombre_de_lignes * 235;
 
 
		$this->view->nbartists = $nbArtists;
		$this->view->height_conteneur = $height_conteneur;
		$this->view->artists = $listeArtists;	
	}
}
j'accede au liens de cette facon maintenant:
Code :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
<?php foreach($this->artists as $unartist) : ?>
<?php if($unartist->haveLink()):?>
			<span class="link_titre_liste_artists">
			<img src="<?php echo $this->baseUrl(); ?>/images/artists/bouton_links_normal.png" />
			</span>
 
			<div class="boite_link_liste_artists">
				<?php foreach($unartist->ArtistsHaveLinks as $link):?>
					<span class="link_liste_artists">
					<a href="http://<?php echo $link->url_link_artist; ?>" class="fade_img" target="_blank" ><img src="<?php echo $this->baseUrl(); ?>/images/artists/liens/<?php echo $link->img_link_artist; ?>" border="0" /></a>
					</span>
				<?php endforeach;?>
			</div>
 
			<?php endif;?>
<?php endforeach;?>
en fait se que j'avait fait avant, repeupler un vecteur liens dans la classe artists ne servait a rien car doctrine le faisait deja.
rib est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 30/01/2011, 15h15   #5
Modérateur
 
Avatar de Michel Rotta
 
Homme Michel Rotta
Responsable d'exploitation informatique
Inscription : septembre 2005
Messages : 4 913
Détails du profil
Informations personnelles :
Nom : Homme Michel Rotta
Âge : 49
Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

Informations professionnelles :
Activité : Responsable d'exploitation informatique
Secteur : Distribution

Informations forums :
Inscription : septembre 2005
Messages : 4 913
Points : 7 505
Points : 7 505
Voici la manière par la quel j'aurais écris le shema.yml pour une de mes applications

Code :
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
 
Artist:
  connection: doctrine
  tableName: artists
  columns:
    nom:
      type: string(20)
      notnull: true
    id_facebook:
      type: string(30)
      notnull: true
    bio:
      type: string(5000)
      notnull: true
    ordre:
      type: integer(4)
      notnull: true
 
ArtistsHaveLink:
  connection: doctrine
  tableName: artists_have_links
  columns:
    artist_id:
      type: integer
      notnull: true
    img_link_artist:
      type: string(50)
      notnull: true
    url_link_artist:
      type: string(100)
      notnull: true
    ordre:
      type: integer(4)
      notnull: true
  relations:
    Artist:
      foreignAlias: ArtistsHaveLinks
  • Le nom des entité toujours au singulier, l'objet généré représente un "artiste" et pas une collection d'"artistes".
  • doctrine considère que la clef primaire est Id en integer auto-incrémenté. Si rien n'est défini, il va la créer automatiquement.
  • Le nom d'une clef est <nomDeLEntite>_id ce qui permet de laisser doctrine comprendre ce que l'on fait.
  • Pour le confort de la lecture, j'ai supprimé les informations qui correspondent à la valeur par défaut des arguments et que le système automatique génère systématiquement.
  • "id_artist" est devenu artist_id (voir ci dessus) et est passé en integer pour coller a sa clef autogénéré sur le table "artist".
  • Le lien est définit sur une seul des deux entité (en yaml), celle qui est du côté N de la relation. Seul l'argument foreignAlias est nécessaire, les autres sont les valeurs par défauts. Les arguments en entier seraient :
    • foreignAlias: ArtistsHaveLinks. Celui-ci est nécessaire, il permet de donner le nom du lien de l'autre côté de la relation. Un $artist va connaître ces liens par $artist->getArtistsHaveLinks() ce qui retourne une Doctrine_Collection et explique le "s" à la fin du nom de la liaison.
    • local: artist_id (défaut). Le champ de l'entité où la liaison est défini et qui sera en relation.
    • foreign: Id (défaut). Le champ de l'entité de l'autre côté de la relation et qui sera en relation.
    • class: artist (default). Le nom de la classe a utilisé de l'autre côté de la relation, le défault est le nom de la relation définie.
    • type: many (default). Le type de relation de ce côté de la relation. Par défault Doctrine utilise des relations 1-n.
    • foreignType: one (default). Le type de la relation sur l'autre côté de la relation.
    Il y a d'autre paramètres, mais il ne sont pas utilisés dans une relation 1-1 ou 1-n.

Je te propose de générer a partir de ce schéma et de regarder ce que tu obtiens. Je ne suis pas entièrement sur du résultat ainsi, mais ce type de schéma fonctionne bien. L'autre solution est de garder le schéma en YAML et de continuer a travailler ainsi.

Le schéma déclaré dans doctrine (par YAML ou en écrivant les entités directement) est très important et dois primer à chaque fois que cela est possible sur une écriture de la base avec un outils style phpMyAdmin où autre et une importation de la structure. En effet, dans le schéma sont stockés des informations nécessaire à un bon usage des entités Doctrine qui ne peuvent être récupérés par une simple importation.

Pour le reste du code, je ne vais pas pouvoir aider, je travail sur symfony et je connais pas suffisamment le zend framework pour avoir un avis pertinent. Il y a un bon forum dédié au zend sur le forum tu y trouvera des personnes largement plus connaisseuses que moi !
__________________
Si tu donnes un poisson à un homme, il mangera un jour. Si tu lui apprends à pêcher, il mangera toujours (Lao Tseu).
  • Pensez à valoriser les réponses pertinantes, cliquez sur le bouton vert +1 pour indiquer votre accord avec la solution proposée.
  • Pensez à utiliser la balise [code] pour afficher du code, elle est cachée sous le bouton [#] dans l'éditeur.
  • Une discussion est terminée ? Alors le bouton est votre ami !
Michel Rotta est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 03h40.


 
 
 
 
Partenaires

Hébergement Web