Whatsup codeigniters!
I want to display total comments of my blog that I am building with codeigniter.
In my controller I have:
function index() {
$data['query'] = $this->blog_model->get_all_entries();
$this->load->view('blog/index',$data);
}
Function index() gets all posts.
and I have
public function post($id) {
$data['query'] = $this->blog_model->get_post($id);
$data['comments'] = $this->blog_model->get_post_comment($id);
$data['post_id'] = $id;
$data['total_comments'] = $this->blog_model->total_comments($id);
$this->load->view('blog/index',$data,TRUE);
$this->load->helper('form');
$this->load->library(array('form_validation','session'));
//validation rules for post function
$this->form_validation->set_rules('commentor','Name','required');
$this->form_validation->set_rules('email','Your email','required|valid_email');
$this->form_validation->set_rules('comment','Comment','required');
if($this->blog_model->get_post($id))
{
foreach($this->blog_model->get_post($id) as $row)
{
//set page title
$data['title'] = $row->entry_name;
}
if($this->form_validation->run() == FALSE)
{
//if validation runs FALSE
$this->load->view('blog/post',$data);
}
else
{
//if valid
$name = $this->input->post('commentor');
$email = strtolower($this->input->post('email'));
$comment = $this->input->post('comment');
$post_id = $id;
$this->blog_model->add_new_comment($post_id,$name,$email,$comment);
$this->session->set_flashdata('message', '1 new comment added!');
redirect('blog/post/'.$id);
}
}
else
show_404();
}
Basically, post($id) gets a post with id (single post) and display comments. I can print total comments number in single post. But how do i print total comments number in index() function where all posts are listed. Thank you!
Use this active record
$this->db->select("post_id , count(comment) as total_comments");
$this->db->group_by('post_id');
$query = $this->db->get('comments');
This generate this sql query
SELECT
post_id,
count(comment) as total_comments
FROM comments
GROUP BY post_id
Means this selects posts , count of posts for each comment and seperate them by post. For understanding Here is the table Structure
Comments
id count(comment) post_id
Now the query will first fetch all the comments then it will use group by to seperate posts giving you total comments for each post.
Try to do something like this
in Model
public function fetch_all_comment()
{
$query = $this->db->get('comments');
return $query->result();
}
In Controller
$data['all_comments'] = $this->model_name->fetch_all_comment();
$this->load->view('viewname',$data);
In View
For this you have to call model in your view. for example if you want to display post name.
Load Model in view
foreach ($all_comments as $row)
{
echo $row->post;
echo $total_no_post = $this->model_name->fetch_total_no_of_comment_in_post($row->postid);
}
Count no of comment in this function fetch_total_no_of_comment_in_post
Related
(sorry for my bad English)
I'm creating a website where users can post something and other users can leave a comment on that post.
I learned from a video from HowCode (youtube) that if you want to display the comments on multiple pages, it is usefull to create 1 page that selects the comments and on all the other pages I can 'include' those comments.
The problem is that it now only displays one comment while I have multiple comments on some posts.
Does anyone know how to solve this?
On the page where I select the comments:
class Comment {
public static function displayComments($postId) {
$comments = DB::query('SELECT * FROM table WHERE post_id = $postId');
foreach($comments as $comment) {
$commentDisplay = $comment['comment'].' ~ by a user';
return $commentDisplay;
}
}
}
On the page where I display the comments:
$showComments = Comment::displayComments($_GET['postid']);
echo $showComments;
Yes, this is happening because you are returning on the first iteration of the foreach.
When you return it immediately exists the method displayComments() and therefore only displays the first one.
What you want to do is return all the comments by adding them to an array and turning the array:
class Comment {
public static function displayComments($postId) {
$comments = DB::query('SELECT * FROM table WHERE post_id = $postId');
foreach($comments as $comment) {
$commentDisplay[] = $comment['comment'].' ~ by a user';
}
return commentDisplay;
}
}
Then when you call it:
$showComments = Comment::displayComments($_GET['postid']); // this is an array
echo array_values($showComments);
Or use foreach on $showComments if you want to print it in a different way
Instead of returning a single comment, you should push all comments related to the post in an array and return it.
class Comment {
public static function displayComments($postId) {
$comments = DB::query('SELECT * FROM table WHERE post_id = $postId');
$commentDisplay = array();
foreach($comments as $comment) {
$commentDisplay[] = $comment['comment'].' ~ by a user';
}
return $commentDisplay;
}
}
And then loop through the returned array to display all comments.
$showComments = Comment::displayComments($_GET['postid']);
foreach($showComments as $comment){
// display comment
// echo $comment . '<br />';
}
Sidenote: Learn about prepared statement because right now your query is susceptible to SQL injection attack. Also see how you can prevent SQL injection in PHP.
You can do it with dependency injection...you should as below more flex more elastic,also data mapping support to user class
class Comment {
public function displayComments($postId) {
$data = DB::query('SELECT * FROM table WHERE post_id = $postId')->fetch(PDO::FETCH_ASSOC)
return $data;
}
}
class User
{
private $comment;
private $name;
private $id;
function __construct(Comment $comment,int $postid)
{
$this->comment=$comment;
$this->id=$postid;
}
function comment()
{
return $this->comment->displayComments($this->id)['comment'];
function name()
{
$this->comment->displayComments($this->id)['name'];
}
}
$comment=new Comment ();
$user=new User($comment,$postid);
echo $user->comment() .':'.$user->name();
I have to table article and table comment. In the home page I want to see how many comment for earch article.
Model
function show_latest_article($start,$display,$cate)
{
$query= $this->db->get_where('news_news', array('News_Cate_ID'=>$cate),$start,$display);
if($cate==0)
{
$query= $this->db->get_where('news_news',$start,$display);
}
return $query->result();
}
function count_comment($id)
{
$query = $this->db->get_where('comment',array('comment_article_id'=>$id) );
return $query->num_rows();
}
Controller
function index() {
$this->load->model('article');
$data=array('article'=>$this->article->show_latest_article(0,8,1),
'sidebar'=>$this->article->side_bar(9),
'count_comment'=> $this->article->count_comment($id),
);
$this->load->view('page/index',$data);
}
In the view I have this
foreach($article as $art)
{
echo $art->title."<br>";
$id= $art->id;
// I want to echo number of comment here.
// Or I want to call function count_comment($id)
}
$this->load->model('article');
$data['article'] = $this->article->show_latest_article(0, 8, 1);
$data['sidebar'] => $this->article->side_bar(9);
$data['count_comment'] => $this->article->count_comment($id);
$this->load->view('page/index', $data);
And it should work.
It's not so clear, where the $id variable come from, but I suggest to join the comments table to your article. It's not a best practice to make queries within loops.
In your model:
public function show_latest_article($ids = array())
{
return $this->db
->select('articles.*, COUNT(comments.id) as comment_count')
->where_in('articles.id', $ids) // You can skip this
->join('comments', 'comments.article_id = articles.id', 'left')
->group_by('articles.id')
->get('articles')
->result();
}
In your controller:
public function index()
{
$data['articles'] = $this->article->show_latest_article(array(0, 8, 1));
$this->load->view('page/index', $data);
}
Just change the field name according to database columns. Also you can skip the where_in condition. (I'm not sure what the three number stands for).
Then in your view, you can simply access the field:
$art->comment_count
EDIT: According to your comment:
$this->db
->select('a.*, (SELECT COUNT(*) FROM comment c WHERE c.comment_article_id = a.News_News_ID ) as counta')
->get('news_news')
->result();
I am writing this answer as you provided code. It could be more simpler if you give more database details. Try below code
function index() {
$this->load->model('article');
$articles = $this->article->show_latest_article(0,8,1);
foreach($articles as $article)
{
$article->comment_count = $this->article->count_comment($article->id);
$all_article[] = $article;
}
$data=array('article'=>$all_article,
'sidebar'=>$this->article->side_bar(9)
);
$this->load->view('page/index',$data);
}
On view
foreach($article as $art)
{
echo $art->title."<br>";
$id= $art->id;
echo $art->comment_count;
}
Controller :
function index() {
$this->load->model('article');
$articles = $this->article->show_latest_article(0,8,1);
$count_comments = Array();
for($i=0;$i<count($articles);$i++){
$count_comments[$i] = $this->article->count_comment($articles->$id);
}
$count_comments =
$data=array('article'=>$articles,
'sidebar'=>$this->article->side_bar(9),
'count_comment'=> $count_comments);
$this->load->view('page/index',$data);
}
In the View :
$i=0;
foreach($article as $art)
{
echo $art->title."<br>";
$id= $art->id;
echo $count_comment[$i];
$i++;
}
Data is passed from the controller to the view by way of an array or an object in the second parameter of the view loading function. Here is an example using an array:
$data = array(
'title' => 'My Title',
'heading' => 'My Heading',
'message' => 'My Message'
);
$this->load->view('blogview', $data);
Also below is the example for object
$data = new Someclass();
$this->load->view('blogview', $data);
PLEASE NOTE: Note: If you use an object, the class variables will be turned into array elements.
You can find out more from below ref URL
Ref: https://ellislab.com/codeigniter/user-guide/general/views.html
First of all in your controller you get count_comment only for specific article ID and not for all articles so you cant do foreach to display comment count of each article.
You need to setup you model better and in model function show_latest_article to use JOIN comments table and do count comment in query.
I will help you with query if you provide me more info about database table of article and comments.
SELECT
article.*,
COUNT(comment.id),0) AS numberOfCommments
FROM article
LEFT JOIN comment
ON comment.article_id = article.id
GROUP BY article.id
i want show my products name in url
now i get my product with id and my url display like that.
www.mydomain.com/home/single/1
i want to show my product url with product name Like.
www.mydomain.com/home/single/New-Dell-Laptop
Here is my code that's get post with it's id number.
Controller
//get all products
public function index()
{
$data['products'] = $this->front->get_products();
$this->load->view('index',$data);
}
//get single product
public function single($id)
{
$data['product']=$this->front->get_product($id);
$this->load->view('product',$data);
}
Model
//get all products
public function get_products()
{
$this->db->select()
->from('vendor_products')
->where('DESC','date_added');
$data = $this->db->get();
return $data->result_array();
}
//get single product
public function get_product($id)
{
$this->db->select()
->from('vendor_products')
->where('prod_id',$id);
$data = $this->db->get();
return $data->first_row('array');
}
Views
//show all products index.php
<?php foreach($products as $one) : ?>
//create link for single product
<a href="<?=base_url();?>home/single/<?=$one['prod_id'];?>">
<?=$one['product_name'];?>
</a>
<p><?=$one['product_price'];?></p>
//show single product (product.php)
<p><?=$product['product_name'];?></p>
<p><?=$product['product_price'];?></p>
<p><?=$product['product_description'];?></p>
The string you`re humanizing, will be in a field, right?
www.mydomain.com/home/single/New-Dell-Laptop
So, if you select in database for "New Dell Laptop"
It will return 1 record, right? If so, you can configure something like this on Routes in config.
$route['single/{product}'] = 'productController/{product}';
Then when you load productController/New-Dell-Laptop
You can use $this->uri->segment(3) to get the value, and search in Database, retrieve page, and show to user.
You should use something like this:
www.mydomain.com/home/single/34/New-Dell-Laptop
Where 34 will be the id to the page and will be easy to you locate on database, but you should not get troubles to find if you search for "New Dell Laptop"
You can use routes.
In your config/routes.php
require_once( BASEPATH .'database/DB'. EXT );
$db =& DB();
$query = $db->get('vendor_products');
$result = $query->result();
foreach( $result as $row )
{
$route["home/single/" . $row->product_name] = "home/single/" . $row->prod_id;
}
And then in your view, change
<a href="<?=base_url();?>home/single/<?=$one['prod_id'];?>">`
by
<a href="<?=base_url();?>home/single/<?=$one['product_name'];?>">`
I'm trying to get records and let users of the application edit details of records and update new details. But when I print_r ($row->emp_name) it returns: John Smith and ($row->emp_type) returns Cachier which are correct values. But why those data are not passed into the 'emp_name' and 'emp_type' inputs in the view?
Second question:
I also want to know how to define a value for a dropdown, to be selected on load. Note that the dropdown values has to be from a database and should be retrieved in a similar way described above.
View:
<?php
$js = 'id="emp_name"';
echo form_input('emp_name', $emp_name, set_value('emp_name'), $js);
?>
Controller:
function index() {
$this->load->model('edit/default_price_model');
//$data['query'] = $this->default_price_model->get_employees_table();
$this_employee['emp_name'] = $this->default_price_model->current_cmployees();
//$temp_array=array_merge($data, $this_employee);
$this->load->view('/edit/employees', $this_employee);
}
function form_validation() {
if($this->input->post('this_employee') == "View") {
$this->populate_form();
}
else {
$this->load->library('form_validation');
$this->form_validation->set_rules('emp_name','Employee Name', 'required|min_length[3]|max_length[60]');
$this->form_validation->set_rules('emp_type','Employee Name', 'required');
$this->form_validation->set_rules('emp_description','Optional Description', 'max_length[500]');
if ($this->form_validation->run() == FALSE ) {
$this->index();
}
else {
$this->update_table();
}
}
}
function populate_form() {
$this->load->model('edit/default_price_model');
$selection = $this->input->post('select_employee');
$data['emp_name'] = $this->default_price_model->get_employees_table($selection);
$this->index();
}
Model:
function get_employees_table($selection) {
$query = $this->db->query(" SELECT emp_name, emp_type, emp_description
FROM employees
WHERE emp_name='$selection'
ORDER BY emp_name ASC
LIMIT 1");
if($query->num_rows()>0) {
foreach($query->result() as $row) {
$row->emp_name;
$row->emp_type;
$row->emp_description;
}
}
}
Your form input is just has the form values if set in set_value not your database values it should look like this
<?php
$js = 'id="emp_name"';
echo form_input('emp_name', $emp_name,
set_value('emp_name', isset($emp_name[0]->emp_name) ? $emp_name[0]->emp_name : '')
, $js);
?>
$emp_name is what you have from the controller and has the db values
$data['emp_name'] = $this->default_price_model->get_employees_table($selection);
One thing i have notice you haven't returned any results from the query in your model and also the foreach loop is doing nothing
function get_employees_table($selection) {
$query = $this->db->query(" SELECT emp_name, emp_type, emp_description
FROM employees
WHERE emp_name='$selection'
ORDER BY emp_name ASC
LIMIT 1");
if($query->num_rows()>0) {
return $query->result();
}else{
return 0;
}
}
Hope it helps you
I am trying to implement a commenting system on my website that is only two levels deep for example you will have the main comment and replies to that comment but it does not go any further:
main comment 1
(sub_comment1)
(sub_comment2)
main comment 2
(sub_comment1)
(sub_comment2)
(sub_comment2)
etc...
Make sense?
I am creating the site in codeigniter but i think a basic php solution will do.
each row in my database table has an id and a parent_id, if the parent id is 0 then its a main comment and if its a sub-comment it will have the id of its parent comment in parent_id.
how to I feed a two dimensional array with the parent and child comments in the right order.
My current code is like so: The controller:
function status_comments($id){
$this->load->model('status_model');//load the status model
$this->load->model('comment_model');//load the comment model
$status = $this->status_model->get_entry_and_category($id);
$comments = $this->comment_model->get_comments($id);
if($status !== false) {
if($comments !== false) {
foreach($comments as $comment){
if($comment->reply_id == 0){
$comment =
}
}
$content_data['comments'] = $comments;
}
$content_data['status'] = $status;
$data['content'] = $this->load->view('status_view', $content_data, TRUE);
$data['title'] = $status->title.' - High Value Status';
$data['page_title'] = $status->title;//The page H1 tag
$this->load->view('home', $data);
}
else
{
$this->session->set_flashdata('invalid', '<p class="rejectionalert"><span>The status you tried to view does not exist.</span></p>');
redirect('home');
}
}
The model function:
//Gets comments associated with an individual status
function get_comments($status_id, $offset=null, $limit=null)
{
$this->db->select('id, comment, nickname, created, reply_id');
$this->db->from('comments');
$this->db->where('active', 1);
$this->db->where('status_id', $status_id);
$query = $this->db->get();
if ($query->num_rows() > 0) {
return $query->result();
}
return false;
}
This works but its using more than one query, the model:
function get_comments($status_id, $limit=NULL, $offset=NULL)
{
$this->db->where(array('status_id' => $status_id, 'reply_id' => 0));
$query = $this->db->get('comments', $limit, $offset);
$parents = $query->result_array();
$comments = array();
foreach($parents as $key => $comment)
{
array_push($comments, $comment);
$this->db->order_by('created', 'ASC');
$this->db->where(array('status_id' => $status_id, 'reply_id' => $comment['id']));
$comments = array_merge($comments, $this->db->get('comments')->result_array());
}
return $comments;
}
I thought it would be more efficent to make one query of all comments, index them into an array by their id, and iterate over them again to find their children. I still dont know how to implement that?