Bonsoir à tous,

je me joins à vous pour que vous m'aidiez à trouver une solution
pour le problème dont je rame à trouver la solution.

Pour commencer j'utilise une version 2.x de cakephp,
je vous explique en quelques phrases ce que je veux faire :

j'aimerai paginer un nombre donné d'article, mais qui appartient
à une catégorie particulière caractérisée par son slug.

Mon code ressemble donc à :

$this->paginate = array('limit' => 5,
                                'order' => array('Post.id' => 'asc'),
                                'conditions' => array('Post.online' => 1,),
                                'contain' => array('Category' =>array('fields'=>array('Category.name','Category.slug','Category.description'),),
                                                      'Image',),);

Seul problème je ne vois pas où mettre ma condition 'Category.slug' => $slug;

Sachez que j'ai essayé plusieurs solutions et effectué plusieurs recherches sur google
avant de venir vous posez la question.

Je reste entièrement à votre disposition pour tous renseignements.

Cordialement,
ccvf2s.

5 réponses


ccvf2s
Auteur
Réponse acceptée

Solution trouvée, et cela n'était pas très difficile il fallait juste le voir.

Peu importe ou se trouve la pagination, dans le controller des articles ou de
la catégorie.
Pour des raisons qui sont miennes et de logique, je l'ai remis dans
le controller CategoriesController.

<u>Exemple de code:</u>

$category = $this->Category->findBySlug($slug);
 //Si la catégorie n'existe pas
if(empty($category))
{
    throw new NotFoundException('Désolé aucune catégorie ne correspond à cette url.');
}
//On récupère l'id de la catégorie
$category_id = $category'Category']'id'];
//On charge la table de liaison
$this->loadModel('CategoriesPost');
//On configure notre pagination avec en contain les articles et les elements de la catégorie
$this->paginate = array( 
            'limit' => 5,
            'contain' => array('Post' => array('Image'),'Category'),
            'conditions' => array('CategoriesPost.category_id' => $category_id),);
 //Pagination des différents posts par catégorie caractérisée par id.
 $d'posts'] = $this->paginate('CategoriesPost');
//On envoie à la vue
$this->set($d);

En espérant que sa aide une autre personne.

Superbement,
ccvf2s.

Bonsoir.

$this->paginate = array('limit' => 5,
                        'order' => array('Post.id ASC'),
                        'conditions' => array('Post.online' => 1,),
                        'contain' => array(
                            'Category' => array(
                                'fields' => array('Category.name','Category.slug','Category.description'), 
                                'conditions' => array('Category.slug' => $slug)
                                ), 
                            'Image'));

Par contre, là ça ne fait que te retourner les catégories par rapport au slug, si tu veux limiter également les articles par rapport au slug de la catégorie, il vaut mieux que tu le fasse depuis le controller Categories en faisant l'inverse, c'est à dire récupérer les catégories par rapport au slug transmis et faire un contain des posts.
Enfin, je veux plutôt dire, que vu que tu veux faire un paginate des posts, dans ce cas là tu es obligé de le faire en deux requêtes.
La première qui retrouve la catégorie qui correspond au slug avec un find('first'), et avec le retour de celle-ci, tu récupères l'ID de la catégorie en question et tu fais un paginate avec comme condition le category_id.
Quelque chose comme ça :

$category_id = $this->Post->Category->findBySlug($slug);
$posts = $this->paginate = array('limit' => 5,
                        'order' => array('Post.id ASC'),
                        'conditions' => array('Post.online' => 1, 'Post.category_id' => $category_id),
                        'contain' => array('Image'));
ccvf2s
Auteur

Bonsoir Lartak11,

merci pour cette réponse très bonne qui aidera sans doute
plusieurs utilisateurs de cakephp.

J'ai oublié de spécifier que la relation entre Category
et Post était de type HABTM et non (HasOne & HasMany).

Alors ta solution est surement bonne mais pas pour
un type de relation comme celle que j'ai avec mes
tables.

Merci encore pour cette solution mais si t'en a
une autre, je suis preneur.

Pour la première solution que tu spécifies, je
l'avais fait dans CategoriesController mais j'ai
du l'enlever pour la raison suivante : <u>La pagination de mes posts</u>.

Superbement,
ccvf2S.

Je vais peut être dire une bêtise, mais à mon sens, tu t'y prends mal.

A ce que j'ai compris dans ce que tu cherches à faire c'est d'avoir dans ton controller posts une action qui te permettrai d'afficher un listing paginé de tes posts, mais en affichant uniquement les posts qui appartiennent à une catégorie donnée.

Peu importe que la relation soit du HABTM à mon sens.

Si je devais poser ça niveau structure en bossant depuis le controller Posts, je dirai qu'il faut :

  • lister les catégories qui ont au moins un article (donc faire un loadModel pour passer en categorie puis faire un find avec une condition HAVING COUNT)

  • passer le listing des catégories à la vue, avec le slug et l'id de la catégorie (puisque j'imagine que sur ta table de liaison, tu fonctionne en post_id <-> categorie_id)

  • préparer une route qui peut accueillir le slug de la catégorie pour préparer le listing des posts et qui récupère également l'id de la catégorie

  • sur l'action de listing des posts, on récupère le categorie_id depuis l'url (query params) et on l'utilise comme argument dans la fonction

  • la fonction fait un bête find avec le categorie_id en paramètre, ce qui permettra de chopper les articles qui appartiennent au moins à cette catégorie et ensuite on fait un paginate pour harmoniser tout ça

C'est peut-être un peu confus, mais en gros, on sépare le listing des catégories de la vrai logique controller de l'action du listing des posts.

Ca demande un peu de boulot. Je t'avoue que sans la structure précise de tes models c'est un peu plus compliqué, donc ça pourrait nous aider. Mais je pense que la piste la plus propre est dans cette direction.

ccvf2s
Auteur

Merci pour ta réponse Pakito, mais je pense pas faire autant de choses pour aboutir à une pagination avec cette condition.
Au pire je chercherai une alternative voir construire une requête sql complète pour y arriver.

Je reste quand même à l'écoute de toutes propositions.
Superbement,
ccvf2s.

<u>P.S</u>: Tu as bien compris la structure de mes models

Post HABTM Category ,
Post HasMany CategoriesPost
Category HABTM Post
Category HasMany CategoriesPost

Dans ce cas, plus besoin de faire un loadModel, et justement au lieu
de travailler avec l'id de la catégorie je travaille avec le slug
qui est tout aussi unique.