threaded comments in codeigniter easy way.
In this tutorial, you will learn about how to build threaded comments or nested comments without any library or hard coding . I provide a simple and easy way to do this task with clean code .
Brief intro
As you know Threaded comments is a most popular functionality which widely used in many projects like social Facebook, twitter, and google plus, etc. to let people communicate with the site and each other in the same time
There are many ways to do this task some is simple as some are complicated- we also choose the simple in Webeasystep - but the important note to keep in your mind that all of these ways back to Storing Hierarchical Data in a Database structures
There were most popular ways like:
- Adjacency List (the "parent_id" one almost everyone uses)
- Nested Sets
- Path Enumeration
- Closure Table (aka Adjacency Relation)
Every one of this list has its pros and cons, but we choose the first one because it was easy to implement and understand, also it is most popular to many developers.
It is matter also to know that hierarchal data has many variety usages not just threaded comments but you can use the drop down menus, and nested product categories.
How To Do
Step one:
create database schema : comment table
ne_id means = post id or news id
parent_id means = the parent comment_id
if someone called x add a comment and someone called z reply on x comment ,the comment_id of x would be saved to z parent_id field.
--
-- Table structure for table `comment`
--
CREATE TABLE `comment` (
`comment_id` int(11) NOT NULL,
`ne_id` int(11) NOT NULL,
`parent_id` int(11) NOT NULL,
`comment_name` varchar(100) NOT NULL,
`comment_email` varchar(100) NOT NULL,
`comment_body` text NOT NULL,
`comment_state` tinyint(1) NOT NULL DEFAULT '0',
`comment_created` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Step two :
Create News.php controller file
/** @property news_model $news_model *
* @property comment_model $comment_model
*/
class News extends Front_end
{
function __construct()
{
parent::__construct();
$this->load->model('news_model');
$this->load->model('comment_model');
$this->load->library('form_validation');
}
// this function to handle getting all news
function index()
{
$data['news'] = $this->news_model->get_all();
$this->view('content/news_list', $data);
}
/* this function to handle getting
news details and its comments based on news id */
function show_one($ne_id)
{
// get a post news based on news id
$data['news'] = $this->news_model->get_one($ne_id);
// get a post COMMENTS based on news id and send it to view
$data['comments'] = $this->show_tree($ne_id);
$this->view('content/show_one', $data);
}
// this function to handle add comments form on the news
function add_comment($ne_id)
{
// get a post id based on news id
$data['news'] = $this->news_model->get_one($ne_id);
//set validation rules
$this->form_validation->set_rules('comment_name', 'Name', 'required|trim|htmlspecialchars');
$this->form_validation->set_rules('comment_email', 'Email', 'required|valid_email|trim|htmlspecialchars');
$this->form_validation->set_rules('comment_body', 'comment_body', 'required|trim|htmlspecialchars');
if ($this->form_validation->run() == FALSE) {
// if not valid load comments
$this->session->set_flashdata('error_msg', validation_errors());
redirect("news/show_one/$ne_id");
} else {
//if valid send comment to admin to tak approve
$this->comment_model->add_new_comment();
$this->session->set_flashdata('error_msg', 'Your comment is awaiting moderation.');
redirect("news/show_one/$ne_id");
}
}
function show_tree($ne_id)
{
// create array to store all comments ids
$store_all_id = array();
// get all parent comments ids by using news id
$id_result = $this->comment_model->tree_all($ne_id);
// loop through all comments to save parent ids $store_all_id array
foreach ($id_result as $comment_id) {
array_push($store_all_id, $comment_id['parent_id']);
}
// return all hierarchical tree data from in_parent by sending
// initiate parameters 0 is the main parent,news id, all parent ids
return $this->in_parent(0,$ne_id, $store_all_id);
}
/* recursive function to loop
through all comments and retrieve it
*/
function in_parent($in_parent,$ne_id,$store_all_id) {
// this variable to save all concatenated html
$html = "";
// build hierarchy html structure based on ul li (parent-child) nodes
if (in_array($in_parent,$store_all_id)) {
$result = $this->comment_model->tree_by_parent($ne_id,$in_parent);
$html .= $in_parent == 0 ? "<ul class='tree'>" : "<ul>";
foreach ($result as $re) {
$html .= " <li class='comment_box'>
<div class='aut'>".$re['comment_name']."</div>
<div class='aut'>".$re['comment_email']."</div>
<div class='comment-body'>".$re['comment_body']."</div>
<div class='timestamp'>".date("F j, Y", $re['comment_created'])."</div>
<a href='#comment_form' class='reply' id='" . $re['comment_id'] . "'>Replay </a>";
$html .=$this->in_parent($re['comment_id'],$ne_id, $store_all_id);
$html .= "</li>";
}
$html .= "</ul>";
}
return $html;
}
}
/* End of file news.php */
/* Location: ./application/controllers/news.php */
Step three:
Create news_model.php file and put these functions
class News_model extends CI_Model
{
// get all news
function get_all()
{
$query = $this->db->get('ci_news');
return $query->result_array();
}
// get one news article by its id
function get_one($ne_id)
{
$this->db->get_where('ci_news', array('ne_id' => $ne_id));
$query = $this->db->get('ci_news');
return $query->row();
}
}
/* End of file news_model.php */
/* Location: ./application/models/news_model.php */
Create comment_model.php file and put these functions
class Comment_model extends CI_Model
{
// get full tree comments based on news id
function tree_all($ne_id) {
$result = $this->db->query("SELECT * FROM comment where ne_id = $ne_id")->result_array();
foreach ($result as $row) {
$data[] = $row;
}
return $data;
}
// to get child comments by entry id and parent id and news id
function tree_by_parent($ne_id,$in_parent) {
$result = $this->db->query("SELECT * FROM comment where parent_id = $in_parent AND ne_id = $ne_id")->result_array();
foreach ($result as $row) {
$data[] = $row;
}
return $data;
}
// to insert comments
function add_new_comment()
{
$this->db->set("ne_id", $this->input->post('ne_id'));
$this->db->set("parent_id", $this->input->post('parent_id'));
$this->db->set("comment_name", $this->input->post('comment_name'));
$this->db->set("comment_email", $this->input->post('comment_email'));
$this->db->set("comment_body", $this->input->post('comment_body'));
$this->db->set("comment_created", time());
$this->db->insert('comment');
return $this->input->post('parent_id');
}
}
/* End of file comment_model.php */
Step five:
Create show_one.php file and put in the views
<script type='text/javascript'>
$(function () {
$("a.reply").click(function () {
var id = $(this).attr("id");
$("#parent_id").attr("value", id);
$("#name").focus();
});
});
</script>
<style type='text/css'>
a, a:visited {
outline: none;
color: #7d5f1e;
}
.clear {
clear: both;
}
#wrapper {
width: 480px;
margin: 0 auto 0 4px;
padding: 15px 0px;
}
.comment_box {
padding: 5px;
border: 2px solid #7d5f1e;
margin-top: 15px;
list-style: none;
}
.aut {
font-weight: bold;
}
.timestamp {
font-size: 85%;
float: right;
}
#comment_body {
display: block;
width: 100%;
height: 150px;
}
</style>
<div class="container">
<div class="starter-template">
<h1><?= $news->ne_title ?></h1>
<p class="lead"><?= $news->ne_desc ?></p>
<p><img src="<?php echo base_url(); ?>global/uploads/<?= $news->ne_img ?>"/></p>
<p> </p>
</div>
<div class="contact-form">
<?php echo $comments ?>
<h3 class="comment-reply-title">
Leave a Reply
</h3>
<p class="notice error"><?= $this->session->flashdata('error_msg') ?></p><br/>
<form id="comment_form" action="<?= base_url() ?>news/add_comment/<?= $news->ne_id ?>" method='post'>
<div class="form-group">
<label for="comment_name">Name:</label>
<input class="form-control" type="text" required name="comment_name" id='name' value="<?= set_value("comment_name") ?>"/>
</div>
<div class="form-group">
<label for="email">E-mail :</label>
<input class="form-control" type="text" name="comment_email" value="<?= set_value("comment_email") ?>" id='email'/>
</div>
<div class="form-group">
<label for="comment">Comment :</label>
<textarea class="form-control" name="comment_body" value="<?= set_value("comment_body") ?>" id='comment'></textarea>
</div>
<input type='hidden' name='parent_id' value="0" id='parent_id' />
<input type='hidden' name='ne_id' value="<?= set_value("ne_id", $news->ne_id) ?>" id='parent_id'/>
<div id='submit_button'>
<input class="btn btn-success" type="submit" name="submit" value="add comment"/>
</div>
</form>
</div>
</div><!-- /.container -->
-
vinodhGood One.... Thanks for sharing.... i'm implementing your code in my website... i have some doubt on this part.. could you help me please...Reply
-
Ysunnykimysunnykim01@gmail.comthank youReply
-
-
adminyou are welcome , what is your question about ?Reply
-
vinodhvinojmca@hotmail.comI am new to CI. Now i am try to develop the comment system with reply option. So far i have developed the insert comment . But i don't know how to insert reply on comments and how to fetch reply comments under the main comment. Please help me. my code: views:Reply
-
admininfo@webeasystep.complease follow this tutorial and if you face any problem i can help youReply
-
-
-
Excellent Web WorldDoing great job keep it up. and any one need any help ?Reply
-
admininfo@webeasystep.comthanks man , i hope to be :)Reply
-
-
Nihar DaveThere is no function in model $this->article_model->add_new_comment(); Please provide code for that. I am trying to implement this type of functionality.Reply
-
admininfo@webeasystep.comi updated the code with this function,also i will put the full code as soon as possibleReply
-
-
Raj ThakkarNice Sharing! This blog is very nice,must be readable post. i really appreciated to blogger. Thank you so much for sharing this kind of info, love it hire laravel developerReply
-
admininfo@webeasystep.comyou are welcome MR / Raj Thakkar i am so happy for this comment, if you need any help i am hereReply
-
-
pradeepsir can u send me the full codeReply
-
admininfo@webeasystep.comhi pradeep until now i try to update all old tutorials with the full code example and the demo , so have patient and you will links soonReply
-
-
JamesCould you do a tutorial using codeigniter to build a reddit page with up vote and down vote and links with comments. Thanks please reply backReply
-
Alvin Nguyentieucaca102@gmail.comThanks you so much for sharing this. I'm done. it working fine. (like)Reply
-
-
rezathanx for your tutorial, but after download your source code, i did not find database *.sql fileReply
-
admininfo@webeasystep.comif you go to this path you will see the sql files threaded-comments-codeigniter / application / tables / you are welcomeReply
-
-
NMVNice comment system!Reply
-
Pragya DagaWaoo. Great. Thank you so much for sharing this. This is very informative information about threads in Codeigniter Development framework. Keep sharing.Reply
-
admininfo@webeasystep.comyou are welcome Pragya Daga, i am glade to hear thatReply
-
-
Zain QureshiIf comment against any aticle is not already stored in database then it show error of undefined data variable in comment model tree all function.So help me how i solve this problemReply
-
adminhow come man ? it is must to store articles and comments in the database because it has a relation by idReply
-
ClintonNice script... Do you have a File for this one?Reply
-
barvevishal0105barve@gmail.comsuperb......Reply
-
-
Rashmi SahuThank you for sharing this article its very helpful for me.Reply
-
Zeeshan Ahmedthank you for the code. Mine project is some what familiar and i am using Ci for my project 1st time and i had my head in the ground on discussion/ comment section on its really helped me.Reply
-
Shakir KhanHi, I have implemented this code, one table is missing, it shows "Table 'abc_db.ci_news' doesn't exist" .Reply
-
huongok thanks somuch for this tutorialReply
-
Big MakGood tutorial.Reply
-
Miley CyrusThanks for sharing these tips! I am sure your tips really helpful!Reply
-
HamzehHi How do you send parent_id and add comment reply? I couldn't find this part. just I see validation...Reply
-
christoper stalinThanks for this nice article!!!Reply