Système de commentaire avec réponse

Par lakamark, il y a 11 ans


Bonjour,
J'ai mis en place un sistème de commentaire et je veux mettre un système de réponse. Je suis bloqué sur comment je peut réupéré les commentaires parent

dans le exemple suivant :

'Comment' => array( 'id' => '3', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'content' => 'Je fait un autre teste TESTE', 'ref' => 'song', 'ref_id' => '8', 'ip' => '192.168.56.1', 'created' => '2014-11-14 22:58:09', 'url' => 'http://local.dev/MusicalityMaker/song/teste-6-1', 'parent_id' => '0', 'user_id' => '1', 'spam' => '0' ),

a un commentaire parent :

Comment' => array( 'id' => '14', 'username' => 'musicality', 'mail' => 'm.a.l.musique@gmail.com', 'content' => 'Pourquoi tu fait un TESTE?', 'ref' => 'song', 'ref_id' => '8', 'ip' => '192.168.56.1', 'created' => '2014-12-16 21:59:55', 'url' => 'http://local.dev/MusicalityMaker/private/song/teste-6-1', 'parent_id' => '3', 'user_id' => '7', 'spam' => '0' ),

Comment je peut faire pour que sa resseble à ceci :

Comment' => array( 'id' => '3', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'content' => 'Je fait un autre teste TESTE', 'ref' => 'song', 'ref_id' => '8', 'ip' => '192.168.56.1', 'created' => '2014-11-14 22:58:09', 'url' => 'http://local.dev/MusicalityMaker/song/teste-6-1', 'parent_id' => '0', 'user_id' => '1', 'spam' => '0 ), answers = array( // J'ai tout les commentaires parent qui appartient au commentaire #3. )

Merci de votre aide.

15 réponses

Azorgh, il y a 11 ans

Salut !

Alors tu peut utiliser les relations entres tes models. Ce qu'il te faut ici c'est une relation hasMany.

Commentaire hasMany Commentaires. (Un commentaire a plusieurs commentaires).
Et lors de ta requete, tu peux ne récuperer que ce qui ont un parent = 0, ce qui te sortira un tableau a peu près comme ça :

'Comment' => array( 'id' => '3', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'content' => 'Je fait un autre teste TESTE', 'ref' => 'song', 'ref_id' => '8', 'ip' => '192.168.56.1', 'created' => '2014-11-14 22:58:09', 'url' => 'http://local.dev/MusicalityMaker/song/teste-6-1', 'parent_id' => '0', 'user_id' => '1', 'spam' => '0' ), Comments = array( 0 => array( 'id' => '4' /* Le reste ici */ ) ) )

Voilà pour moi, il se peut (surement vu l'heure) que je me suis mal exprimé. Si c'est le cas, re-regarde peut être cette vidéo : http://www.grafikart.fr/formations/cakephp/associations-model

lakamark, il y a 11 ans

Ok j'ai réussit, mais le petit problème est que dans mon tableau 'ChildComment'
je n'est pas un tableau User qui vient avec.

/app/Controller/PostsController.php (line 77) array( (int) 0 => array( 'Comment' => array( 'id' => '1', 'username' => 'musicality', 'mail' => 'm.a.l.musique@gmail.com', 'content' => 'Je fait un teste', 'ref' => 'Post', 'ref_id' => '3', 'ip' => '192.168.56.1', 'created' => '2014-12-17 16:27:05', 'url' => 'http://local.dev/MusicalityMaker/blog/music', 'parent_id' => '0', 'user_id' => '7', 'spam' => '0' ), 'User' => array( 'id' => '7', 'username' => 'musicality', 'thumb' => null, 'mail' => 'm.a.l.musique@gmail.com', 'profilPage' => 'http://local.dev/MusicalityMaker/profil/musicality', 'avatar' => '' ), 'ChildComment' => array( (int) 0 => array( 'id' => '2', 'username' => 'musicality', 'mail' => 'm.a.l.musique@gmail.com', 'content' => 'Je suis l'enfant de ce commentaire là.', 'ref' => 'Post', 'ref_id' => '3', 'ip' => '192.168.56.1', 'created' => '2014-12-17 16:31:12', 'url' => 'http://local.dev/MusicalityMaker/blog/music', 'parent_id' => '1', 'user_id' => '7', 'spam' => '0' ), (int) 1 => array( 'id' => '6', 'username' => 'musicality', 'mail' => 'm.a.l.musique@gmail.com', 'content' => 'Teste 2 Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.', 'ref' => 'Post', 'ref_id' => '3', 'ip' => '192.168.56.1', 'created' => '2014-12-17 17:02:39', 'url' => 'http://local.dev/MusicalityMaker/blog/music', 'parent_id' => '1', 'user_id' => '7', 'spam' => '0' ) ) ) )
amethyste, il y a 11 ans

Tu peux utiliser le Containable behavior pour affiner tes requêtes

Inspirat, il y a 11 ans

Bonsoir, il faut que tu modifies le niveau de récursivité juste avant ton find():

// app/Model/Comment.php public $hasMany = array('Comment'); public $belongsTo = array('User'); // app/Controller/PostsController.php $this->loadModel('Comment'); $this->Comment->recursive = 2; $comments = $this->Comment->find('first', array( 'conditions' => array('Comment.ref_id' => $ref_if), 'contain' => array( 'User', 'Comment' => array( 'User' ) ) ));
lakamark, il y a 11 ans

Le résuive = 2 est déconseillé. Car il demande énormément de ressouce à Mysql.

Inspirat, il y a 11 ans

C'est juste pour ce cas qu'il est utilisé, c'est juste qu'il est inutile dans le cas où on souhaite seulement récupérer le modèle courant et pas les enfants de ce-dernier.

lakamark, il y a 11 ans

J'utilise ce-ci :

$this->Comment->contain(array( 'User' => array(), 'ChildComment' => array() ));

et

$comments = $this->Paginate('Comment',array('Comment.ref'=>'Post','Comment.ref_id'=>$post['Post']['id'],'Comment.parent_id' => 0));

Je ne voit pas le tableau user dans les enfants même si j'utilise ceci

$this->Comment->recursive = 2;

Dans mon model Comment.php j'ai ce-ci :

public $belongsTo = array( 'User' => array( 'className' => 'User', 'foreignKey' => 'user_id', 'conditions' => '', 'fields' => '', 'order' => '' ), 'ParentComment' => array( 'className' => 'Comment', 'foreignKey' => 'parent_id', ) ); public $hasMany = array( 'ChildComment' => array( 'className' => 'Comment', 'foreignKey' => 'parent_id', ), );
lakamark, il y a 11 ans

J'ai mis le rursive = 2 et je ne voit pas dans les enfants du commentaire parent n'ont pas de tableau user.
Dans mon model j'ai ceci :

public $belongsTo = array( 'User' => array( 'className' => 'User', 'foreignKey' => 'user_id', 'conditions' => '', 'fields' => '', 'order' => '' ), 'ParentComment' => array( 'className' => 'Comment', 'foreignKey' => 'parent_id', ) ); public $hasMany = array( 'ChildComment' => array( 'className' => 'Comment', 'foreignKey' => 'parent_id', ), );

Dans mes controllers j'utilise ce-ci :

$comments = $this->Paginate('Comment',array('Comment.ref'=>'Post','Comment.ref_id'=>$post['Post']['id'],'Comment.parent_id' => 0));

Je pense que je me suis planter dans mes associations entre modele.

Inspirat, il y a 11 ans

Utilise mon modèle, ça fonctionne à merveille ;)
Pas besoin de se compliquer à renommer les modèles etc...
Avec la pagination ça donne ça:

// app/Model/Comment.php public $hasMany = array( 'Comment' => array( 'foreignKey' => 'parent_id' ) ); public $belongsTo = array('User'); // app/Controller/PostsController.php $this->loadModel('Comment'); $this->Comment->recursive = 2; $this->paginate['Comment'] = array( 'conditions' => array( 'Comment.ref_id' => $post['Post']['id'], 'Comment.ref' => 'post', 'Comment.parent_id' => 0 ), 'contain' => array( 'User', 'Comment' => array( 'User' ) ) ); $comments = $this->paginate('Comment');
lakamark, il y a 11 ans

Ok dans ma vue je récupère les comment

Ok ça me sort un tableau très propre, ce qui me gène est comment je réupère les donners dans ma vue?

'Comment' => array( 'id' => '1', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'content' => 'Je suis le premier commentaire', 'ref' => 'Post', 'ref_id' => '1', 'ip' => '192.168.56.1', 'created' => '2014-12-17 20:32:53', 'url' => 'http://local.dev/MusicalityMaker/blog/mon-premier-article', 'parent_id' => '0', 'user_id' => '1', 'spam' => '0', (int) 0 => array( 'id' => '2', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'content' => 'Une réponse', 'ref' => 'Post', 'ref_id' => '1', 'ip' => '192.168.56.1', 'created' => '2014-12-17 20:33:07', 'url' => 'http://local.dev/MusicalityMaker/blog/mon-premier-article', 'parent_id' => '1', 'user_id' => '1', 'spam' => '0', 'User' => array( 'id' => '1', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'thumb' => '/img/uploads/users/avatars/1/1.png' ) ),

Il y a un (int) 0 => array() dans le tableau Comment

Je fait ça dans ma vue :
Jr fait ça pour réupéré les commentaire

<?php foreach($comments as $comment): ?> <?php foreach($comments as $comment): ?> Pour répéré les commentaire enfant : <?php foreach($comment['Comment'] as $children): ?> <?php endforeach; ?>

Il me retourne une erreur :
Illegal string offet suivie du nom du champ.

lakamark, il y a 11 ans

J'ai acroché le bouton valider le sujet. Comment tu arrfiche les enfant des commentaires?
Je parcourre le tableau $comments

<?php foreach($comments as $comment): ?> <?php endforeach; ?>

Ensuite j'essai d'affichier les enfants des commentaire parent :

<?php foreach($comment[0] as $children): ?> <?php endforeach; ?>

Il me retourne une erreur
illegal string 0

Inspirat, il y a 11 ans

Je t'invite sur ta vue à debug ta variable, de cette façon tu verra comme est formé ta variable:

// app/View/Posts/view.ctp <?= debug($comments); ?> // Ce qui va donner quelque chose du type si je ne me trompe pas. array( 0 => array( 'Comment' => array( '...' => '...', 'Comment' => array( 0 => array( '...' => '...' 'User' => array(...) ), 1 => array(...) ) ), 'User' => array(...) ) 1 => array(...) )
lakamark, il y a 11 ans

j'ai ce tableau :

array( (int) 0 => array( 'Comment' => array( 'id' => '1', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'content' => 'Je suis le premier commentaire', 'ref' => 'Post', 'ref_id' => '1', 'ip' => '192.168.56.1', 'created' => '2014-12-17 20:32:53', 'url' => 'http://local.dev/MusicalityMaker/blog/mon-premier-article', 'parent_id' => '0', 'user_id' => '1', 'spam' => '0', (int) 0 => array( 'id' => '2', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'content' => 'Une réponse', 'ref' => 'Post', 'ref_id' => '1', 'ip' => '192.168.56.1', 'created' => '2014-12-17 20:33:07', 'url' => 'http://local.dev/MusicalityMaker/blog/mon-premier-article', 'parent_id' => '1', 'user_id' => '1', 'spam' => '0', 'User' => array( 'id' => '1', 'username' => 'MusicalityMaker', 'mail' => 'marc@mail.com', 'thumb' => '/img/uploads/users/avatars/1/1.png' )
Inspirat, il y a 11 ans

Effectivement dans ce cas il sera nécessaire de donner un nom différent à l'association au sein du modèle Comment de la sorte:

// app/Model/Comment.php public $hasMany = array( 'Child' => array( 'foreignKey' => 'parent_id', 'className' => 'Comment' ) ); // app/View/Posts/view.ctp foreach ($comments as $comment) { echo $comment['Comment']['content']; // Contenu du commentaire parent echo $comment['User']['username']; // Auteur du commentaire parent if($comment['Child']){ foreach ($comment['Child'] as $child) { echo $child['content']; // Contenu du commentaire enfant echo $child['User']['username']; // Auteur du commentaire enfant } } }
lakamark, il y a 11 ans

@Inspirat
Mercu beaucoup de ton aide.