I was trying to create a commenting system like that uses facebook. I use php and jquery. My code works perfect. All I want is just to add a reply system in it. Any idea how to do this?
This is my main page: wall.php
<script>
$(document).ready(function(){
$("#comment_process").click(function(){
if($("#comment_text").val() != ""){
$.post("comments.php?action=post", { comment: $("#comment_text").val() }, function(data) {
$(".comments").html(data);
$("#comment_text").val("");
});
}
});
});
</script>
<div class="comment_container">
<div class="comment_form">
<textarea id="comment_text" ></textarea>
<input type="button" id="comment_process" value="Post"/>
</div>
</div>
<div class="comments"> <?php include_once("comments.php");?> </div>
?>
and this is comments.php
<?php
function getComments(){
$comments = "";
// use desc order by date in order to display comments by date
$sql = mysql_query("SELECT * FROM comments ORDER BY comment_date DESC ") or die (mysql_error());
if(mysql_num_rows($sql) == 0){
$comments = " <div class='each_comment'> There are no comments ...</div> ";
}else{
while ($row= mysql_fetch_assoc($sql)){
$comments .= "Says : <div class='each_comment'> <small><em> ".$row['comment_date']." </em></small><br />".$row['comment']."</div> </br>";
}
}
return $comments;
}
function postComments($comment){
$comment = mysql_real_escape_string(strip_tags($comment));
$sql = mysql_query(" INSERT INTO `comments` (comment, comment_date) VALUES ('".$comment."', now()) ");
return true;
}
if((isset($_GET['action'])) && ($_GET['action'] == "post")) {
postComments($_POST['comment']);
}
echo getComments();
?>
Orbling has it right. Let me show you what I did for my blog site that I am working on in ASP.NET MVC and maybe it will others in the future.
I have two classes named Article and Comment and they would have the following properties in php from what I remember. A little rusty on my php
class Article {
public $article_id;
public $user_id;
public $article_date;
//... more properties, ctors, methods
}
class Comment {
public $comment_id;
public $article_id;
public $isRoot;
public $parent_id;
public $comment_date;
public $content;
//... more properties, ctors, methods
}
Then I would user similar to what you constructed:
function getComments($article_id){
$str = "";
// This should put all the comment in order by date but we still have to separate the //comments from the replies so we will add an additional nest foreach loop following an if //statement inside the main foreach loop. What will happen is the newest/oldest comment //will be the first one appended to the string and then it will go to the inner foreach //loop to see if the $parent_id = $comment_id and if it does it will append to string.
//I have a different div class for replies so they are indented. This may not be the most //practical way, but considering that most articles are going to have less that a 1000 //comments if your lucky this wont be too bad.
$q = $this->db->query("SELECT * FROM comments WHERE article_id = $article_id ORDER BY comment_date DESC") or die (mysql_error());
if($q->num_rows() > 0):
foreach($q->result() as $row):
if($row->isRoot && $row->ParentId = null):
// here you will append to the $str where you will create a div container //for each comment which is a root comment. I included a user avatar, user link, date //create, content, and on the bottom of my div I have an <span>expand replies</span> and a //<span>reply<span> where I use JQuery to toggle the replies on and off etc.
// Now I do the same thing here as I will cycle through $q to find the //comments with the parent_id equal to the comment_id of this $row
//they will already be ordered by date. Cool thing is you could create an array of the reply and change the order so maybe you want newest comments on top but oldest replies on //top or I should say below the parent comment
foreach($q->result() as $row2):
if($row->comment_id = $row2->parent_id)
// do the same thing except html format for reply (eg: indent div)
endif;
endforeach;
endforeach;
}
else:
$str = "<div class='each_comment'> There are no comments ...</div> ";
endif;
echo htmlentities($str);
}
Then you will have to use some JQuery/Javascript as Orbling suggests: show(); hide(); replies and use a function such as slideDown(parent_id); once the reply button is hit where a <div> container appears below its parent comment.
Related
In my 'magnums' table I have the following data:
What I want is to display the producer as a title and then the corresponding rows under that heading underneath that. My desired output:
I'm very new to PHP and mysql so I'm not sure how to go about this but this is what I have so far:
Model:
class Magnum_model extends CI_Model {
public function get_magnum_wines() {
$query = $this->db->query('SELECT * FROM magnums');
return $query->result();
}
}
Controller:
public function index() {
$data['magnums']= $this->Magnum_model->get_magnum_wines();
$this->load->view('magnums.php',$data);
}
View:
<h3>Domaine Vincent Rapet</h3>
<?php foreach($magnums as $magnum): ?>
<div id="magnum-img">
<div class="gallery">
<img src="/BurgundyDirect/gallery/<?php echo $magnum->Image; ?>">
</div><!-- gallery ends -->
<div class="desc">
<div id="wine-name">
<h5><?php echo $magnum->Name_of_wine; ?></h5>
</div>
<h6><?php echo $magnum->Producer; ?><h6>
<h4><?php echo $magnum->Magnum_price; ?></h4>
</div>
</div>
<?php endforeach; ?>
The output of the above code:
I don't know how to sort it to my desired output. Any help would be much appreciated and thank you in advance :)
If you need to show groups of products, you can get list of producers of producers and related products in controller.
In your producers model, create method, that get all producers (select * from producers).
Get producers in controller $producers = $this->Producer_model->get_producers();
Then create array with producer's name and products.
sample code:
$producerWithProducts = array();
foreach($producers as $producer) {
$producerId = $producer->Id;
$producerWithProducts[$producerId]['producerName'] = $producer->Name;
$producerWithProducts[$producerId]['products'] = $this->Magnum_model->get_magnum_wines_by_producer_id($producerId);
}
Then pass $producerWithProducts in template and iterate it.
I had the same thing but with wine categories / colours so this is what I did:
First make a new table called producers with 2 columns: id and name.
In the wine table make a new column with the name producer_id.
The value of this column is corresponds with the id in the producers table.
Then you can iterate through it like this:
function extractWines() {
$producers = mysqli_query("SELECT id FROM producers");
foreach($producers as $key => $value) {
$query = mysqli_query("SELECT * FROM wines WHERE producer_id = " . $value . "");
$rowname = mysqli_fetch_assoc($query);
$html = <<<HTML
<h1>{$rowname['producer']}</h1>
HTML;
echo $html;
while($row = mysqli_fetch_assoc($query)) {
$html = <<<HTML
(html code of the item with styling)
HTML;
echo $html;
}
}
}
This should help you with your problem.
I would like to hide the article from the sidebar if it is already open, but I don't know how it can be done. I'm a newbie, sorry about that.
I am using MySqli select random to show 8 articles in a sidebar.
The articles are saved in a variable and then I echo them on a different page.
Can anyone help me out or tell me how should I do this. What kind of code to use. Thank You.
Here is the article code.
case'article':
$get_article = mysqli_query($conn, "SELECT title,link,excerpt,description_1,description_2,description_3,description_4,description_5,description_6,description_7,description_8,description_9,description_10,description_11,description_12 from `articles_".LANG."` where link = '".$_GET['article']."'") or die(mysqli_error($conn));
if(mysqli_num_rows($get_article) != 1){
header("Status: 404 Not Found");
$page = '404';
}
else{
$row = mysqli_fetch_assoc($get_article);
$title = $row['title'];
$description = $row['excerpt'];
$content_url= 'http://www.example.com/'.$_GET['lang'].'/'.$row['link'].'/';
$meta_img = 'http://www.sub.example.com/'.$_GET['lang'].'/'.$row['link'] .'/1.jpg';
$files = glob('/home/site/sub.example.com/'.$_GET['lang'].'/'.$row['link'].'/*.{jpg,jpeg,png,gif}', GLOB_BRACE);
$total = count($files);
for($i = 1;$i <= $total; $i++){
if(is_file('/home/site/sub.example.com/'.$_GET['lang'].'/'.$row['link'].'/'.$i.'.jpg')){
$picture = $i.'.jpg';
}
elseif(is_file('/home/site/sub.site.com/'.$_GET['lang'].'/'.$row['link'].'/'.$i.'.jpeg')){
$picture = $i.'.jpeg';
}
$pictures .= '<div class="article_box"><h3 class="top_img_description">'.$row['description_'.$i]. '</h3>'.'<div class="single_img_container"><img src="http://sub.example.com/'.$_GET['lang'].'/'.$row['link'].'/'.$picture.'"/></div></div>';
}
Here is the sidebar code.
$article_sidebar = mysqli_query($conn, "SELECT title,link from `articles_".LANG."`ORDER BY RAND() LIMIT 8") or die(mysqli_error($conn));
while($row2 = mysqli_fetch_array($article_sidebar)){
if(is_file('/home/site/sub.example.com/'.$_GET['lang'].'/'.$row2['link'].'/1.jpg')) {
$file='http://sub.example.com/'.$_GET['lang'].'/'.$row2['link'].'/1.jpg';
}
$sidebar_articles .= '<div class="article">
<div class="article_thumb">'.'<img src="'.$file.'"/>
</div>
<h3 class="feed_title">
'.$row2['title'].'
</h3>
</div>';
}
And here is the a screenshot of what I want.
"SELECT title,link from `articles_".LANG."`WHERE id <> ".$currentid." ORDER BY RAND() LIMIT 8"
Exclude the id of the current displayed element in your query. This is done for example by using <>. And don't forget to check the values before you put them in a mysql-query!
You can do this with javascript if want to be able to switch through articles at some point without the page reloading. Add a unique class to all articles on the right and the main article on the page (a unique ID perhaps) and compare this to the main section. If the two match then apply apply a hidden class or change it's display property to none.
If you want to do this server side and switching between articles causes the page to refresh, you should apply a similar approach to the above. Store some reference to the current 'main' article and wrap the sidebar articles in a foreach.
In this foreach, wrap each addition to the sidebar html in an if statement which compares the the current value with that of the main article.
eg.
if ( $currentArticleId !== $mainArticleId )
{
$sidebar_articles .= '<div class="article">
<div class="article_thumb">'.'<img src="'.$file.'"/>
</div>
<h3 class="feed_title">
'.$row2['title'].'
</h3>
</div>';
...
I have a blog page "plugin" in my own little cms and it's displayed with return() on the index.php.
Part of the index.php:
$id = (isset($_GET['m_id'])) ? $_GET['m_id'] : 1; //menu id
$sql = "SELECT m_cim, m_tartalom, m_plugin
FROM menu
WHERE m_s_id = (SELECT s_id FROM statusz WHERE s_nev='aktiv')
AND m_id = ".$id;
$eredmeny = mysql_query($sql);
if (#mysql_num_rows($eredmeny) == 0) {
$tartalom = "<h1>404!</h1>\n";
}
else {
$sor = mysql_fetch_assoc($eredmeny);
$tartalom = "<h2>{$sor['m_cim']}</h2>
<span class=\"tart\">{$sor['m_tartalom']}</span>\n";
if(!empty($sor['m_plugin'])){
$tartalom.=include("./modul/{$sor['m_plugin']}");
}
}
<section id="content">
<?php print $tartalom; ?>
</section>
The posts come from a database and the news.php is included in the index.php.
This is the "plugin" news.php
$aktiv="(SELECT s_id FROM statusz WHERE s_nev='aktiv')";
$sql = "SELECT hir_id, hir_cim, hir_tartalom, hir_ido
FROM hirek
WHERE hir_s_id=".$aktiv."
ORDER BY hir_id DESC";
$eredmeny = mysql_query($sql);
$kimenet = "";
while ($sor = mysql_fetch_assoc($eredmeny)) {
$kimenet.= "<article class=\"hirek\">
<h3>{$sor['hir_cim']}</h3>
<span class=\"hido\">{$sor['hir_ido']}</span>
<p class=\"htart\">".substr(strip_tags($sor['hir_tartalom']),0,200)."</p>
Tovább...
</article>\n";
}
return $kimenet;
If I use a php pagination, I only saw, that the page number is posted via the ‘GET’ method, but in that case, I use the GET method for the menu id, and when I want to post something else with get, the result will be the menu item with the actual id. Is it possible to use $_GET method for this?
I think this technique can solve my problem, but I don't know if it's outdated/not-so-good/do-not-use-it or not.
When I find somewhere a solution for my actual problem, somebody always says that "do not use it, because..." "it's not the best idea, because..." "this is not the best solution,because.."
Can I trust in this?
I am new to both PHP and the Codeigniter(v2.0) framework. Hoping you can help me find my way through my first webapp. Details below, and thank you in advance!
Goal/Issue Summary: I would like to display within my view all blog_Comments that are attached to each paticular blog_Post.
Details: My blog_Posts table contains all original blog posts [id(int), title, entry, author (all varchar), and date(timestamp)]. My blog_Comments table[id(int), entry_id(int), author, comment(varchar)] contains all comments; they are associated with the original blog_Post via the *entry_id* attribute.
Controller:
$query1 = $this->blog_model->get_posts();
$query2 = $this->blog_model->get_comments();
$data = array();
$data['posts'] = $query1;
$data['comments'] = $query2;
Model:
function get_posts() {
$query = this->db->get('blog_Posts');
return $query->result;
}
function get_comments() {
$query = this->db->get('blog_Comments');
return $query->result;}
View:
<?php if(isset($posts)) : foreach($posts as $posts=>$row) : ?>
<?php $row->title; ?>
<?php $row->author; ?>
<?php $row->entry; ?>
<?php foreach($comments as $comments=>$com) : ?>
<?php if($com->entry_id == $row->id) : ?>
<p>author: <?php echo $com->author; ?></p>
<p>comment: <?php echo $com->comment; ?></p>
<?php endif; ?>
<?php endforeach; ?>
<?php endforeach; ?>
<?php else : ?> <p>no blog_Posts found</p>
<?php endif; ?>
Edit/Update:
My attempt to display the comments is pasted into the view code block above, I've also listed the two issues it is giving me. Right now I have 2 sample original blog posts, and comments associated with each.
Issues:
the first blog entry (first time through the loop) it is displaying ALL comments, including those associated with other entry_id s.
The second blog entry (second time through loop), it throws the following error: "Invalid argument supplied for foreach()", and points to the line in my view containing the foreach for $comments.
In short, I'm trying to loo through only those comments with the entry_id that matches the original posts "id."
Thanks again for your assistance and time.
-AJ
Well since you do not need to display all comments at once, you could just alter your get_comments function like below to return comments for each post and of course display them in your way, order by date created, last entry etc:
So for the model part:
function get_comments($post_id){
$query = $this->db->query("select * from `blog_Comments` where `entry_id` = $post_id ORDER BY `created_on` DESC");
if($query->num_rows() != 0){
return $query->result();
}else{
return false;
}
}
And in your view file:
foreach($posts as $row){
echo 'Title: ' . $row->title .
'Author: ' . $row->author .
'Entry:' . $row->entry;
$comments = $this->blog_model->get_comments($row->id);
if(!$comments){
echo 'No comments';
}else{
foreach($comments as $com){
echo $com->comments . '<br/>' . $com->user . '<br/>' . etc etc
}
}
}
I'm too lazy to test, but i think you are trying to use $row, but you are outside the foreach where its defined. you introduce $row here
<?php if(isset($posts)) : foreach($posts as $posts=>$row) : ?>
and then you close the foreach -- so $row is no longer available down here:
<?php if($com->entry_id == $row->id); ?>
so yeah. but really you should be doing as much logic and checking as you can in the controller and model. verify your data objects - like Posts - THEN the controller determines the correct view. so then if there aren't any posts to show -- you dont have messy 'what if there are no posts' conditionals in your view. you just call the no posts view file.
I have a simple page which contains some products in the database. What I want is to create some sort of an updater, if the user add a product then that specific div in the page will display the latest product added automatically.
I tried to view this link but it doesnt help at all we have different problem.
Anyway heres the function i have in php.
function recentlyAddeditems() {
echo '<h3>Recently Added Products</h3> <hr/>';
echo '<div id="main_section_widget">';
$sql = mysql_query("SELECT * FROM products ORDER BY id DESC LIMIT 20") or die(mysql_error());
if ($sql) {
while ($row = mysql_fetch_array($sql)) {
$name = $row['name'];
$id = $row['id'];
$category = $row['category'];
echo "$name | $category<br/>
<hr/>
";
}
echo '</div>';
echo '
<p><br/>More items...</p>
';
}
}
and the in html page
<div id="main_section_widget_cover" class="dates">
<?php recentlyAddedItems(); ?>
</div>
Is there a simpler way how to do this? I tried to read about ajax in jquery but still having confused without a concrete example.
Please help wizards of stack!!!
IF you want an example of a ajax in jquery here is a really simple example
<div id="main_section_widget_cover" class="dates"><div>
<script>
$('#main_section_widget_cover').load('recentitems.php');
</script>
in recentitems.php
<?php recentlyAddedItems(); ?>
Thats it, thats all you need to do to do a basic ajax call