Building a Threaded News System With PHP - Adding Comments (comment.php) (Page 3 of 4 ) This script will allow comments to be posted. See the commenting in the code for more information: <?php // we need db operations require('db_connect.php'); ?> <html> <head> <title>Add Comment</title> </head> <body> <h2>Add your comment</h2> <?php
if(isset($_POST['submit'])) {
// if form has been submitted // check id and rid are present in query string // and that they're numbers. if(!isset($_GET['id']) | !isset($_GET['rid']) | !is_numeric($_GET['id']) | !is_numeric($_GET['rid'])) { die('Missing or invalid input'); }
// check they filled in all the fields if(!$_POST['author'] | !$_POST['title'] | !$_POST['comment']) { die('Please fill in all the fields.'); }
// get rid of tags $_POST['author'] = htmlspecialchars($_POST['author']); $_POST['title'] = htmlspecialchars($_POST['title']); $_POST['comment'] = htmlspecialchars($_POST['comment']);
// text new lines to HTML new lines. $_POST['comment'] = str_replace("\ ", '<br>', $_POST['comment']);
/* if 'rid' is zero it means they're at the top level if it isn't, we need to increment the 'replies' field of the commenting they're replying to. */ if($_GET['rid'] != 0) { $inc_replies = $db->query("UPDATE comments SET replies = (replies + 1) WHERE id = '".$_GET['rid']."'"); if(DB::IsError($inc_replies)) { die($inc_replies->getDebugInfo()); } }
// now insert the data $insert = $db->query("INSERT INTO comments (news_id, rel_id, replies, author, title, comment) VALUES ('".addslashes($_GET['id'])."', '".addslashes($_GET['rid'])."', '0', '".addslashes($_POST['author'])."', '".addslashes($_POST['title'])."', '".addslashes($_POST['comment'])."')"); if(DB::IsError($insert)) { die($insert->getDebugInfo()); }
// echo out a thanks echo '<p>Cheers '.$_POST['author'].', your comment has been added, click <a href=" /comments.php?id='.$_GET['id'].'&rid='.$_GET['rid'].'">here</a> to view it.</p>'; } else { // if form hasn't been submitted...
// echo it out echo '<form action="'.$_SERVER['PHP_SELF'].'?id='.$_GET['id'].'& rid='.$_GET['rid'].'" method="post">'; echo '<input type="text" name="author" maxlength="40"><br>'; echo '<input type="text" name="title" maxlength="40"><br>'; echo '<textarea name="comment" rows="20" cols="60"></textarea><br>'; echo '<input type="submit" name="submit" value="Post it"><br>'; echo '</form>'; } ?> </body> </html> The Function To create the threading we need to use a recursive function that prints out each comment, checking if it has replies, and if it does it then prints out the replies in an indented layout: function thread($news_id, $rel_id) { GLOBAL $db; // retrieve comments associated with top-level comments' 'id' fields. $comments = $db->query("SELECT * FROM comments WHERE news_id = '$news_id' AND rel_id = '$rel_id'"); echo '<ul>'; // go through them while($c = $comments->fetchRow()) { if($c->id == $_GET['rid']) { // if this comment is currently being viewed // echo text not link echo '<li><strong>'.stripslashes($c->title).'</strong> </li>'; } else { // else echo link echo '<li><a href="/comments.php?id='.$news_id.'& rid='.$c->id.'"> '.stripslashes($c->title).'</a> by '.stripslashes($c->author).' </li>'; } if($c->replies > 0) { /* if the comment just echoed has replies call function again and pass it the 'id' of the comment just echoed, creating the threading */ thread($news_id, $c->id); } } echo '</ul>'; /* Note: each time the function repeats another <ul> tag is opened this is what creates the threading effect */ } Listing Comments (comments.php) Here's the script that will list the comments and use the function that you just saw above to show the comments in a threaded style: <?php require('db_connect.php');
// include out function function thread($news_id, $rel_id) { GLOBAL $db; // retrieve comments $comments = $db->query("SELECT * FROM comments WHERE news_id = '$news_id' AND rel_id = '$rel_id'"); echo '<ul>'; // go thru comments while($c = $comments->fetchRow()) { if($c->id == $_GET['rid']) { // if this comment is currently being viewed // echo text not link echo '<li><strong>'.stripslashes($c->title).'</strong> </li>'; } else { // else echo link echo '<li><a href="/comments.php?id='.$news_id.'& rid='.$c->id.'"> '.stripslashes($c->title).'</a> by '.stripslashes($c->author).' </li>'; } if($c->replies > 0) { /* if the comment just echoed has replies call function again and pass it the 'id' of the comment just echoed */ thread($news_id, $c->id); } } echo '</ul>'; /* Note: each time the function repeats another <ul> tag is opened this is what creates the threading effect */ } ?> <html> <head> <title>Comments</title> </head> <body> <h2>Comments for...</h2> <?php // echo out the news post these comments belong to. $n_a = $db->query("SELECT * FROM news WHERE id = '".$_GET['id']."'"); $a = $n_a->fetchRow(); echo '<h4>'.stripslashes($a->title).' by '.stripslashes($a->author).'</h4>'; echo '<p>'.stripslashes($a->announcement).'</p>'; echo '<p><a href="/comment.php?id='.$_GET['id'].'& rid='.$_GET['rid'].'">reply to this</a> | <a href="/index.php">back to news</a></p>'; // if 'rid' is not equal to zero, we have a comment to show if($_GET['rid'] != 0) { // retrieve comments with the 'id' that matches 'rid' $select = $db->query("SELECT * FROM comments WHERE id = '".$_GET['rid']."'"); $com = $select->fetchRow(); // and echo it out... echo '<blockquote>'; echo '<h4>Comment '.stripslashes($com->title).' by '.stripslashes($com->author).' </h4>'; echo '<p>'.stripslashes($com->comment).'</p>'; echo '<p><a href="/comment.php?id='.$_GET['id'].'& rid='.$com->id.'">reply to this comment</a></p>'; echo '</blockquote>'; }
// now to list the comments. echo '<h2>Comments...</h2>';
// comments with a 'rel_id' value of zero are top-level comments // we need to list these... $comments = $db->query("SELECT * FROM comments WHERE news_id = '".$_GET['id']."' AND rel_id = '0'");
// if no comments... $numc = $comments->numRows(); if($numc == 0) { // echo out so... echo '<p>No one has contributed any comments, yet.</p>'; } else { // or else... echo '<ul>'; // go through the comments.. while($cs = $comments->fetchRow()) { if($cs->id == $_GET['rid']) { // if comment is being viewed dont echo link. echo '<li><strong>'.stripslashes($cs->title).' by '.stripslashes($cs->author).' </strong></li>'; } else { echo '<li><a href="/comments.php?id='.$_GET['id'].'& rid='.$cs->id.' ">'.stripslashes($cs->title).'</a> by '.stripslashes($cs->author).'</li>'; } if($cs->replies > 0) { /* if replies for this comment exist call our function passing it the 'id' of this comment the function will then echo out any comments with a 'rel_id' field matching this comment's 'id' field. Any any comments that are a reply to that, and any that are a reply to that, etc etc */ thread($_GET['id'], $cs->id); } } } echo '</ul>'; ?> </body> </html> There we have it. It's the recursive function that makes everything come together and work seamlessly. Without the thread method we'd never be able to list comments that are replies to other comments. I think that the code is sufficiently commented to help you get started. Security I seriously don't recommend using these scripts on your website unless you improve them. The data checking leaves a lot to be desired, however I just wanted to show you a basic structure so that you could see how it works, modify it, and implement it into your own web site. If you want a threaded comment system then the code in this article a good base to build on. Next: Conclusion >>
More MySQL Articles More By Free2Code Team |