Que se passe-t-il lorsque vous devez écrire un backend avec un nombre conséquent de contrôleurs dont l’affichage des résultats est paginé? Plusieurs possibilités:

  • Vous dupliquez votre code dans chaque contrôlleur, que ce soit via l’attribut $paginate du contrôleur, ou directement dans l’action
  • Ou bien vous paramétrez votre attribut $paginate directement dans l’AppController

La première solution ressemblera à ceci:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class postsController extends AppController {

    public $paginate = array(
        'limit' => 25,
        'order' => array( 'id' => 'asc' )
    );

    // la suite du code...
}

class commentsController extends AppController {

    public $paginate = array(
        'limit' => 25,
        'order' => array( 'id' => 'asc' )
    );

    // la suite du code...
}

Solution pas vraiment élégante, car si le client décide de changer le nombre de résultats par page, on est bon pour modifier tous les contrôleurs utilisant la pagination dans leurs résultats.

Une petite remarque en passant… Si la requête SQL exécutée par CakePHP est un tant soit peu complexe, vous aurez droit à une exception lancée par votre gestionnaire de DB car votre champ “id” ne sera pas nommé assez spécifiquement (par exemple lors d’une jointure entre deux tables possédant toutes les deux un champ “id”).

Pour régler ce problème, il suffit d’utiliser le nom du modèle dans vos conditions:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class PostsController extends AppController {

    public $paginate = array(
        'limit' => 25,
        'order' => array( 'Post.id' => 'asc' )
    );

    // la suite du code...
}

class CommentsController extends AppController {

    public $paginate = array(
        'limit' => 25,
        'order' => array( 'Comment.id' => 'asc' )
    );

    // la suite du code...
}

Au moins votre code dupliqué aura moins de chance de planter !

La deuxième solution est évidemment meilleure, mais encore faut-il s’y prendre convenablement! Je viens juste de vous expliquer qu’il valait mieux ajouter le nom du model utilisé dans les conditions. Aucun problème lorsque vous vous trouvez dans un contrôleur tel que PostsControlleur ou CommentsController, vous connaissez le nom du domaine à utiliser.

Mais dans le cas de l’AppControlleur, les choses sont différentes! En effet, vous ne connaissez pas le nom du modèle utilisé, car celui-ci dépend du contrôleur en cours d’exécution. Heureusement, les développeurs de CakePHP sont des gens extrêmement intelligents, et ils ont pensé à ce cas de figure: chaque contrôleur possède un attribut appelé modelClass contenant le nom du modèle associé par défaut au contrôleur. Au lieu de dupliquer notre code dans les deux contrôleurs PostsController et CommentsControler, nous pouvons maintenant aisément le déplacer dans l’AppController de la manière suivante:

1
2
3
4
5
6
7
8
9
class AppController {

    public $paginate = array(
        'limit' => 25,
        'order' => array( $this->modelClass . '.id' => 'asc' )
    );

    // la suite du code...
}

Quelques nouvelles

Bien…. Ca fait plus de 5 mois que je n’ai plus rien posté sur ce blog, la honte! Pourtant les idées se bousculent au portillon…## Ce qu …… Continuer la lecture