Ordonner les resultats Doctrine avec une table de composition

Posted on 01/06/2010 · Posted in Doctrine

Prenons le schéma ci-dessus.
Au niveau de la définition, nous avons deux entités : Bureau ( rooms ) et Utilisateur ( users ). Ces deux entités sont liées par une relation manyToMany car un utilisateur peut avoir plusieurs bureaux, et un bureau peut avoir plusieurs utilisateurs.
Pour pouvoir intégrer l’ordonnancement des utilisateurs au sein d’une pièce, nous avons ajouté le champs “index” sur la table de liaison.

Grâce à cette définition, nous pouvons avoir les cas suivants :
– Robert est à la place #2 dans le bureau d’accueil
– Robert est à la place #1 dans le bureau du président
– Annie est à la place #1 dans le bureau du président

Définition des Domain Model Object

doctrine
Nous allons maintenant définir les liaisons Doctrine entre ces objets.
Je n’utiliserai pas la définition YAML.

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
abstract class Model_Base_Room extends Model_Base
{
    public function setTableDefinition()
    {
        $this->setTableName('rooms');
        $this->hasColumn('id_room as idRoom', 'integer', 4, array(
             'type' => 'integer',
             'fixed' => 0,
             'unsigned' => false,
             'primary' => true,
             'autoincrement' => true,
             'length' => '4',
             ));
        $this->hasColumn('title', 'string', 80, array(
             'type' => 'string',
             'fixed' => 0,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             'length' => '80',
             ));
    }
   
    public function setUp()
    {
        parent::setUp();
        $this->hasMany('Model_User as users', array(
             'refClass' => 'Model_CompoRoomsUsers',
             'local' => 'id_room',
             'foreign' => 'id_user'));
    }
}

abstract class Model_Base_User extends Model_Base
{
    public function setTableDefinition()
    {
        $this->setTableName('users');
        $this->hasColumn('id_user as idUser', 'integer', 4, array(
             'type' => 'integer',
             'fixed' => 0,
             'unsigned' => false,
             'primary' => true,
             'autoincrement' => true,
             'length' => '4',
             ));
        $this->hasColumn('firstname', 'string', 80, array(
             'type' => 'string',
             'fixed' => 0,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             'length' => '80',
             ));
    }
   
    public function setUp()
    {
        parent::setUp();
        $this->hasMany('Model_Room as rooms', array(
             'refClass' => 'Model_CompoRoomsUsers',
             'local' => 'id_user',
             'foreign' => 'id_room'));
    }
}

abstract class Model_Base_CompoRoomsUsers extends Model_Base
{
    public function setTableDefinition()
    {
        $this->setTableName('compo_rooms_users');
        $this->hasColumn('id_room as idRoom', 'integer', 4, array(
             'type' => 'integer',
             'fixed' => 0,
             'unsigned' => false,
             'primary' => true,
             'autoincrement' => false,
             'length' => '4',
             ));
        $this->hasColumn('id_user as idUser', 'integer', 4, array(
             'type' => 'integer',
             'fixed' => 0,
             'unsigned' => false,
             'primary' => true,
             'autoincrement' => false,
             'length' => '4',
             ));
        $this->hasColumn('index', 'integer', 4, array(
             'type' => 'integer',
             'fixed' => 0,
             'unsigned' => false,
             'primary' => false,
             'notnull' => true,
             'autoincrement' => false,
             'length' => '4',
             ));
    }

    public function setUp()
    {
        $this->hasOne('Model_User as user', array(
             'local' => 'id_user',
             'foreign' => 'id_user'));

        $this->hasOne('Model_Room as room', array(
             'local' => 'id_room',
             'foreign' => 'id_room'));
    }
}

Ordonner avec DQL

Après cette longue définition, nous pouvons passer au code DQL qui permettra d’ordonner les résultats en fonction de l’index de notre table de liaison.

1
2
3
4
5
$query  = Doctrine_Query::create ()
    ->select ("room.*, users.*")
    ->from ("Model_Room room")
    ->leftJoin ("room.users users")
    ->orderBy ("room.id_room, users.Model_CompoRoomsUsers.index ASC");

Prenez note du fait que nous trions dans un premier temps par identifiant de bureau et ensuite par index. Si nous n’utilisions qu’un tri par index, l’ordre des bureaux serai incohérent.

Pour aller plus loin

Nous avons décrit le fonctionnement pour ordonner des résultats à partir d’une table de liaison.
Mais vous pouvez aussi utiliser cette méthode pour conditionner le résultat.