Salut à vous !

Dans mes différents projets, j'ai souvent besoin d'utiliser plusieurs controller depuis la même page, et à chaque fois je bricole un truc qui fonctionne, mais sans jamais être sûr que ma méthode est la plus propre.

Comment faites-vous ? Y'a t'il un moyen conventionnel de procéder ?

Merci pour vos réponses :)

14 réponses


Bonjour,

il y a plusieurs reponses possibles par rapport a ton reel besoin. Lequel est-ce ?
1) J'ai une page qui charge un Controller, mais j'ai besoin de charger des widgets sur cette meme page : Tu vas avoir besoin d'utiliser JavaScript et de faire des appels AJAX.
2) J'ai une page avec un Controller, mais avant de lancer un rendu, j'ai besoin de travailler avec plusieurs Controllers.
si tu as besoin de plusieurs controllers c'est que tu ne decoupes pas ton application correctement. Tu utilises le MVC j'imagine (Model-View-Controller), et donc tu places ta logique dans le Controller. Il te faut rajouter un nouvel element, Service (ou Repository suivant les framework). Le Service n'est pas lie a un Controller ou un Model, il va se charger de recuperer des donnees, les traiter et renvoyer le resultat. Tu peux utiliser plusieurs Services pour une action.

Salut à tous,
Le sujet m'intéresse, si cela peut nous permettre d'avancer, voici un exemple concret :

Je souhaite sur une même vue afficher mes posts (article avec titre, texte, date...), ainsi que les posts les plus lus, et pour finir la liste des catégories. D'arpès ce que j'ai compris sur le fonctionnement de CakePhp, il faudrait créer un controller PostsController avec l'action qui permet de récupérer et envoyer à la vue les posts, une autre action permettant de trier les posts les plus lus, et enfin un autre controller CategoriesController avec une action permettant de récupérer et envoyer à la vue la liste des catégories.

Selon vous quelle est la méthode la plus adaptée ?

Par avance merci.

Dans ce cas il s'agit de la reponse 2. Tu vas donc avoir un PostRepository et un CategoryRepository.

class PostRepository {
    public function getPosts() {}
    public function getPopularPosts(){}
}

class CategoryRepository {
    public function getCategories();
}

et ensuite pour les injecter dans vos controllers :

class PostsController {
    protected $postRepository;
    protected $categoryRepository

    function __construct(PostRepository $postRepository, CategoryRepository categoryRepository)  {
        $this->postRepository = $postRepository;
        $this->categoryRepository = $categoryRepository;
    }

    func index() {
        $posts = $this->postRepository->getPosts();
        $popular = $this->postRepository->getPopularPosts();
        //...
    }
}

PS : Je n'ai pas fait de CakePHP depuis tres longtemps. Je ne sais pas s'il est possible d'overrider le constructeur ou s'il faut utiliser un autre moyen pour l'injection de dependences.

slt,
selon moi si une catégorie peut avoir plusieurs post, alors cela signifie qu'il ya une relation entre post et catégories
ce qui te donne la possibilité d'avoir access à tout tes model depuis un même controleur à cause de leur relation et du coup moi j'utiliserai des 'elements' de vues pour afficher les données

Bonjour.
@prbaron : S'il ne s'est pas trompé de forum en postant son sujet, sa question concerne CakePHP, je ne vois donc pas pourquoi tu lui propose du code externe à CakePHP.

Si lorsque tu dis que tu as souvent besoin d'utiliser plusieurs controller depuis la même page, tu veux dire que tu as besoin d'avoir des informations de différentes tables de ta base de données, tu as deux solutions :

  1. Les tables sont reliées entre elles et tu utilises les associations définies
  2. Les tables ne sont pas reliées entre-elles, dans ce cas là, tu peux utiliser $this->loadModel('leNomDuModel');.

@Latark, parce que ma reponse lui suggere d'utiliser une bonne pratique, a savoir de decouper proprement son application. C'est a mon sens plus interessant que de proposer une solution CakePHP only. De memoire CakePHP utilise du PHP donc le langage natif peut etre utilise :).

@Lartak : Effectivement, concrètement j'ai besoin de différentes données via différents models, t'as solution pourrait donc répondre à certaines de mes problématiques. Néanmois le principe "d'action" dans les controlleurs n'est pas clair pour moi :

J'ai tendance à assimiler ces "actions" par des méthodes que l'on pourrait retrouver dans une class PHP object classique. Or, ce n'est pas vraiment le cas. Pour reprendre l'exemple des posts et des catégories, si je souhaite afficher une page avec plusieurs traitements (ex : afficher les posts au centre, afficher les posts les plus lus sur le coté ainsi que le nom de la catégories courante), je suis contraint d'écrire le code au sein d'une même action (les relations des models me permettrons d'accéder à toutes les données utiles), ce qui n'est pas forcement idéal, non ?

bonjour, une action est un point d'entrée par quelqu'un d'extérieur (navigateur, client natif,...).
le Repository sert à réaliser la logique de ton application de manière plus modulable. les deux remplissent donc deux fonctions différentes.

Merci pour tes conseils @prbaron. Néanmoins, comme son nom l'indique l'utilisation d'un framwork nous propose un cadre de travail, je souhaiterais donc, dans la mesure du possible respecter le plus possible les principes de CakePhp et surtout bien assimiler son fonctionnement.

Voila un bon article pour implementer le Repository pattern avec CakePHP : http://www.endyourif.com/implementing-the-repository-pattern-with-cakephp/.

le Repository pattern n'est pas lie a un framework, c'est une bonne pratique, tu vas le trouver dans tous les frameworks.

2 solutions :

Dans la même action (point d'entrée), tu fais 3 requêtes

public function homepage()
{
    $posts = $this->paginate($this->Posts); // liste classique de tes posts, paginée
    $categories = $this->Posts->Categories->find('list');
    $recentPosts = $this->Posts->find('all')->order(['Posts.nombredevues' => 'DESC'])->limit(5);
    $this->set(compact('posts','categories','recentPosts));
}

Ou alors, je suppose que tu vas réutiliser ces "blocs" que sont "categories" et "posts populaires" et du coup les View Cells sont plus appropriées

Merci @prbaron et @amethyste, petit à petit les choses sont plus claires. Cela ne pose donc pas de problèmes de faire appel à plusieurs models et faire plusieurs traitements de données dans une même action ?

Aucun souci si les modeles sont liés (comme ici categories et posts). S'ils ne sont pas liés, ca ne pose toujours aucun problème mais il ne faut pas en abuser. Après tout est question d'optimisation de perf, dans ton cas je choisirais les view cells avec mise en cache car il y a de grande chances que l'on retrouve les modules "liste des categories" et "articles populaires" sur plusieurs pages/actions.

@amethyste : Merci pour tes conseils. Effectivement les liaisons entre mes models me permettent de traiter toutes mes données à l'intérieure d'un controller. Donc pour m'a part vous avez répondu à mes interrogations.

Pour ne pas trop me compliquer la tâche, je regarderai le fonctionnement des view cells et plus généralement de l'optimisation du code une fois le développement fonctionnel terminé.