tags:

views:

90

answers:

2

I'm using a function I think that is what you call it, to display my comments and their replies but for some reason I can only display the parent comments and not their replies. can someone help me fix this problem?

Here is my Output NOW.

PARENT COMMENT 1
PARENT COMMENT 2
PARENT COMMENT 3

Here is my DESIRED output.

PARENT COMMENT 1
    child comment 1
    child comment 2
PARENT COMMENT 2
    child comment 1
    child comment 2
    child comment 3
    child comment 4
PARENT COMMENT 3

Here is MySQL comments table.

CREATE TABLE articles_comments (
comment_id INT UNSIGNED NOT NULL AUTO_INCREMENT,
parent_comment_id INT UNSIGNED NOT NULL,
user_id INT UNSIGNED NOT NULL,
article_id INT UNSIGNED NOT NULL,
comment TEXT NOT NULL,
date_created DATETIME NOT NULL,
PRIMARY KEY (comment_id),
);

Here is my PHP & MySQL code.

function make_comments($parent_comment_id = 0, $comment_id = 0) {
global $user_id;

    foreach ($parent_comment_id as $id => $comment) {
        if($comment['user_id'] == $user_id && $comment['parent_comment_id'] == 0){
            echo '<div style="color: orange;">' . $comment['comment'] . '</div><br /><br />';

            if($comment_id  == $comment['parent_comment_id']){ //display replies
                if($comment['user_id'] == $user_id && $comment['parent_comment_id'] >= 1) {
                    echo '<div style="color: purple;">' . $comment['comment'] . '</div><br /><br />';
                } else if($comment['parent_comment_id'] >= 1) {
                    echo '<div style="color: blue;">' . $comment['comment'] . '</div><br /><br />';
                }
            }

        } else if($comment['user_id'] != $user_id && $comment['parent_comment_id'] == 0) {
            echo '<div style="color: brown;">' . $comment['comment'] . '</div><br /><br />';

            if($comment_id  == $comment['parent_comment_id']){ //display replies
                if($comment['user_id'] == $user_id && $comment['parent_comment_id'] >= 1) {
                    echo '<div style="color: purple;">' . $comment['comment'] . '</div><br /><br />';
                } else if($comment['parent_comment_id'] >= 1) {
                    echo '<div style="color: blue;">' . $comment['comment'] . '</div><br /><br />';
                }
            }
        }
    }

}

$dbc = mysqli_query($mysqli, "SELECT articles_comments.comment_id, articles_comments.parent_comment_id, articles_comments.comment, articles_comments.user_id FROM articles_comments LEFT JOIN users ON articles_comments.user_id = users.user_id WHERE article_id = '" . $article_id . "' ORDER BY parent_comment_id ASC");
if (!$dbc) {
    print mysqli_error();
} 

$comment_order = array();

while (list($comment_id, $parent_comment_id, $comment_text, $comment_user, $comment_id) = mysqli_fetch_array($dbc)) {
$comment_order[$parent_comment_id][$comment_id] =  array('parent_comment_id' => $parent_comment_id, 'comment_id' => $comment_id, 'comment' => $comment_text, 'user_id' => $comment_user, 'comment_id' => $comment_id);
}

make_comments($comment_order[0], $comment_id);
+1  A: 

It doesn't look like the make_comments() is actually being called recursively. It's only being called once, from the bottom of the script. With the first level of IF statements in make_comments, you're only checking for comments with parent_comment_id of 0 (which will always only be the parents). It's only INSIDE of those statements that you check for parent_comment_id >=1 (which can never be true at this point).

Without testing this code, this is the general idea about what I would change just to get the children to display. The point is to put the checks for $comment['parent_comment_id'] at the same logic level. If you nest a conditional for $comment['parent_comment_id'] >= 1 inside $comment['parent_comment_id'] == 0, it will never find it true.

if($comment['user_id'] == $user_id) { 
  if(comment['parent_comment_id'] == 0){
    echo "<div style='color: orange;'>" . $comment['comment'] .'</div><br /><br />';
  } else if($id == $comment['parent_comment_id']) {
    //display replies
    if($comment['user_id'] == $user_id && $comment['parent_comment_id'] >= 1) {
      echo '<div style="color: purple;">' . $comment['comment'] .'</div><br /><br />';
    } else if($comment['parent_comment_id'] >= 1) {
      echo "<div style='color: blue;'>" . $comment['comment'] ."</div><br /><br />";
    }
  }
}

And, of course, the same changes would need to be made to the second IF statement in your function (for if($comment['user_id'] != $user_id).

EDIT:

Updated code. I've tested this in an isolated file on my machine and it outputs what you're expecting at the top. Minor adjustments will need to be made to match your table schema, the joins you needed (I was only worried about this one table), and the color-coded output. I didn't include it because I was trying to keep this simple.

And remember that this is a test file, try not to go around connecting to MySQL as root, I'm only doing that for demonstration purposes of the script, here. :)

<?php

/**
 * Recursive function to display comments
 */
function make_comments($comments_list, $parent_id = 0)
{
  if(is_array($comments_list) && count($comments_list))
  {
    foreach($comments_list as $id => $comment)
    {   
      if($comment['parent_id'] == $parent_id)
      {   
        echo "<div id='comment'>Comment: ".$comment['comment']."</div>";
        make_comments($comments_list, $id);
      }   
    }   
  }
}

$article_id = 1;

$conn = mysql_connect("localhost", "root", "") or die("unable to connect.");
mysql_select_db("test") or die("could not select test");


$comments_query = "SELECT c.* from comments c WHERE article_id = $article_id ORDER BY date_created DESC";
$comments_result = mysql_query($comments_query, $conn);

//Sort comments by parent_id
$comments = array();
while($comments_row = mysql_fetch_assoc($comments_result))
  $comments[$comments_row['id']] = $comments_row;

make_comments($comments);
?>

Based on my test data, this script outputted:

Comment: PARENT COMMENT 3
Comment: CHILD COMMENT 1 - PARENT 3
Comment: PARENT COMMENT 2
Comment: CHILD COMMENT 1 - PARENT 2
Comment: PARENT COMMENT 1
Comment: CHILD COMMENT 3 - PARENT 1
Comment: CHILD COMMENT 2 - PARENT 1
Comment: CHILD COMMENT 1 - PARENT 1

With color formatting and indentation, you'll get the results you described above.

Rookz
I can't seem to get this to work:(
NoL
K, give me a few and I'll try to put something together.
Rookz
@NoL, please review EDIT to hopefully resolve your issue.
Rookz
A: 

Your code looks quite convoluted. Why not do something simpler like that:

  1. Get all the comments for a particular article with parent_comment_id=0. These are your 'parent' comments
  2. Cycle through the list of parent comments you've got, doing the following for each of them:
    2.1 Display parent comment
    2.2 Get a list of all child comments, cycle through that list and display each child comment.

When you get that right you can worry about styling the items with the proper color. Like mentioned above, your function is not a recursive one but if you have only 2 levels of comments, you won't need recursion anyway.

Amati
Can you give a simple example code to work with?
NoL