Nesting Comments Yii2

Multi tool use
Nesting Comments Yii2
I have a comment table, like below:
+-----------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-----------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| user_id | int(11) | NO | | NULL | |
| parent_id | int(11) | NO | | 0 | |
| post_id | int(11) | NO | | NULL | |
| body | text | NO | | NULL | |
| date | datetime | NO | | NULL | |
| status | tinyint(1) | NO | | 0 | |
+-----------+--------------+------+-----+---------+----------------+
Comment parent_id by defautl is 0, if comment is answered, parent id insert in parent_id column.
And make a relation with User Table with below code:
public function getPosts()
{
return $this->hasMany(Post::className(), ['category_id' => 'id']);
}
How can i show nesting?
there is no limit, a wirete a comment, b replay to a, c replay to b and ..., i need a recursive function to show the all comment.
– Masoud92m
Jul 1 at 6:29
1 Answer
1
First, you need to define the relation inside your Comment model class:
public function getChildComments()
{
return $this->hasMany(self::className(), ['parent_id' => 'id']);
}
That defines the entity relationship to itself. I think it is always good to always keep related logic or handlers into helper/callable methods in the same class in a way that doesn't require you to load them all at once from database. What comes next should answer the question:
How can i show nesting?
Simply override fields()
inside Comment class to always output child comments:
fields()
public function fields()
{
$fields = parent::fields();
$fields['childs'] = 'childComments';
return $fields;
}
That's it. yiirestSerializer should take care of the recursive representation and you'll get something similar to this when outputting a list of comments:
There is probably many ways to achieve it. The easiest and cleanest way I could think of is to tie on the template engine that Yii is already using to re-render the view holding child comments in a recursive way. As a working example, add something like what follows to your index.php file:
<?php
use yiihelpersHtml;
use yiiwidgetsListView;
use yiidataActiveDataProvider;
use appmodelsComment;
?>
<?= ListView::widget([
'dataProvider' => new ActiveDataProvider([
'query' => Comment::find(),
]),
'itemView' => '_comment',
'itemOptions' => ['style' => 'padding: 10px 50px; border: 1px solid red'],
]); ?>
Then create that _comment.php file:
<?php
use yiihelpersHtml;
use yiiwidgetsListView;
use yiidataActiveDataProvider;
?>
id) ?>
name) ?>
<?php
if ($model->getChildComments()->count()) {
echo ListView::widget([
'dataProvider' => new ActiveDataProvider([
'query' => $model->getChildComments(),
]),
'itemView' => '_comment',
'itemOptions' => ['style' => 'padding: 10px 0 10px 50px; border: 1px dotted blue'],
]);
}
?>
The template will create a new instance of itself each time it finds childComments
linked to the represented one. With that bit of CSS paddings to show the nesting, that code should output this:
childComments
I did not understand, i wrote a function to get childeren like getChildComments(), it to level one works and don't work in recursive function, how can i use it in a recursive function?
– Masoud92m
Jul 1 at 6:33
@Masoud92m what about now?
– Salem Ouerdani
Jul 2 at 4:46
thanks a lot, works very well.
– Masoud92m
Jul 2 at 14:30
Thanks. Glad it helped
– Salem Ouerdani
Jul 2 at 14:33
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
what is the max level of the hierarchy, or let's say you are using The Adjacency List Model, how many self-joins will be required to retrieve a single path for any top-level comment?
– Muhammad Omer Aslam
Jun 30 at 23:16