Building a nested comment reply system

Quite often, we face the challenge to display comment replies in a proper way. Showing them chronologically does not fit our need sometimes. We may require showing them in such a way that the reply for each comment is below the actual comment itself. In other words, we can say we need a nested comment reply system or threaded comments. We want to build something similar to the following screenshot:

We can follow the same steps we did in the nested category section. However, this time, we will have some UI elements to give it a more realistic look. Let's assume that we have a table named comments with the following data and columns. For simplicity, we are not going into multiple table relationships. We are assuming that the usernames are stored in the same table with the comments:

Id

comments

username

Datetime

parentID

postID

1

First comment

Mizan

2016-10-01 15:10:20

0

1

2

First reply

Adiyan

2016-10-02 04:09:10

1

1

3

Reply of first reply

Mikhael

2016-10-03 11:10:47

2

1

4

Reply of reply of first reply

Arshad

2016-10-04 21:22:45

3

1

5

Reply of reply of reply of first reply

Anam

2016-10-05 12:01:29

4

1

6

Second comment

Keith

2016-10-01 15:10:20

0

1

7

First comment of second post

Milon

2016-10-02 04:09:10

0

2

8

Third comment

Ikrum

2016-10-03 11:10:47

0

1

9

Second comment of second post

Ahmed

2016-10-04 21:22:45

0

2

10

Reply of second comment of second post

Afsar

2016-10-18 05:18:24

9

2

Let's now write a prepared statement to fetch all the comments from a post. Then, we can construct an array similar to the nested category one:

$sql = "Select * from comments where postID = :postID order by parentID asc, datetime asc"; 
$stmt = $dbh->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$stmt->setFetchMode(PDO::FETCH_OBJ);
$stmt->execute(array(':postID' => 1));
$result = $stmt->fetchAll();

$comments = [];

foreach ($result as $row) {
$comments[$row->parentID][] = $row;
}

Now, we have the array and all required data in it; we can now write a function that will call recursively to display the comment with proper indentations:

 

function displayComment(Array $comments, int $n) { 
if (isset($comments[$n])) {
$str = "<ul>";
foreach ($comments[$n] as $comment) {
$str .= "<li><div class='comment'><span class='pic'>
{$comment->username}</span>";
$str .= "<span class='datetime'>{$comment->datetime}</span>";
$str .= "<span class='commenttext'>" . $comment->comment . "
</span></div>";

$str .= displayComment($comments, $comment->id);
$str .= "</li>";
}

$str .= "</ul>";

return $str;
}
return "";
}

echo displayComment($comments, 0);

 

Since we have added some HTML elements in the PHP code, we need some basic CSS to make it work. Here is the CSS code we have written to make it a clean design. Nothing fancy, but pure CSS to create the cascading effects and some basic styling for each section of the comment:

 

  ul { 
list-style: none;
clear: both;
}

li ul {
margin: 0px 0px 0px 50px;
}

.pic {
display: block;
width: 50px;
height: 50px;
float: left;
color: #000;
background: #ADDFEE;
padding: 15px 10px;
text-align: center;
margin-right: 20px;
}

.comment {
float: left;
clear: both;
margin: 20px;
width: 500px;
}

.datetime {
clear: right;
width: 400px;
margin-bottom: 10px;
float: left;
}

As mentioned earlier, we are not trying to make something complex here, just responsive, device friendly, and so on. We are assuming that you can integrate the logic in different parts of your application without any problem.

Here is the output from the data and the preceding code:

From the preceding two examples, we can see that it is very easy to create nested contents without having multiple queries or having a limitation of join statements for nesting. We do not even require a self-join to generate the nested data.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset