0
votes

Hey guys I'm trying to learn codeigniter, but once again I'm STUCK and I seek help (as usual :P )

What I need to do?
-> I need to get the data related to a article from the database along with other stuff like the tags for the article and all the comments. I'm thinking of keeping single level nested comments for the article.

Well I'm done with the tag part [link to the answer which helped me with the same : Returning and using multidimensional array of records from database in CodeIgniter 2.0 ] but the comment part is driving me nuts.
Well to get started here is my comments table

Comments
+---------------+-------------+
| Field         | Type        |
+---------------+-------------+
| commentId     | int(10)     |
| PostId        | int(10)     |
| author        | varchar(30) |
| email         | varchar(30) |
| url           | varchar(50) |
| date          | datetime    |
| comment       | text        |
| parent        | int(10)     | 
+---------------+-------------+

I'm using the parent field to keep a track of the parent for a nested child comment. By default the value is 0 which means it the parent. Child comment will have the commentid of its parent comment

    public function getPost($postName = NULL , $year = NULL, $month = NULL ){
        if($postName != NULL && $year != NULL && $month != NULL){
            //single post
            $this->load->model('comment_model');
            $this->db->where('postName',$postName);
            $this->db->where('year(date)',$year);
            $this->db->where('month(date)',$month);
            $q = $this->db->get('mstack_Post'); 
            if($q->num_rows()>0){
                $post = $q->result();
                foreach ($post as &$p) {
                    $p->tags = $this->getAllTags($p->postId);   

                      /* getting the comments */
                    $com = $this->comment_model->getComments($p->postId); 

                    /*echo count($com).' is the total count'; output= 4 */
                    foreach ($com as &$c) {
                                      /* trying to filter the comment. but all I get is 1 comment as the output*/
                        if($c->parent==0){
                            $p->comments->parentComment = $c;
                        }elseif($c->commentId==$c->parent){
                            $p->comments->childComment = $c;
                        }
                    }
                }
                return $post;
            }else{
                return array();
            }
        }
    }

Any help will surely be appreciated. If you have any other technique /idea to display multi level comments then do let me know. :)

1
One thing: write if($c->parent == '0'), I think without quotes you're evaluating it to false, then using always the elseif. Please correct me if I'm wrong on this. - Damien Pirsy
okay I'll try it out and let you know if it works - Charanraj Golla
$c->commentId == $c->parent?? maybe it should be $p->postId. put a simple else and print_r($c) to see which records satisfy neither conditions. - Kinjal Dixit
@kinjal You are right there is something wrong in that part of the code.I added a else part and tried printing the array it printed me all the child comments (which had a value different from 0 in the parent field). The first block of if ($c->parent==0) print only one comment no matter what I do. - Charanraj Golla
@charanraj, just change the elseif part to a simple else... if the parentid is not 0, then it is a child comment, and it will be a comment from this postid because of the way the query is written. your next problem is that $p->comments->childComment = $c will hold only one comment. it should be an array for it to hold multiple comments. - Kinjal Dixit

1 Answers

1
votes

Here is the solution that might be helpfull:

First you need 2 helper recursive function:

// Building comments.
function buildComments($list, $parent = 0)
{
    // Creating result array.
    $result = array();

    //looping...
    foreach ($list as $item)
    {
        //iteration starts with 0 as default.
        if ($item->parent == $parent)
        {
            // add to the result
            $result[$item->commentId] = array(
                'author' => $item->author,
                // ... other definitions
                'child' => buildComments($list, $item->commentId) //execute this function for child.
            );
        }
    }
    return $result;
}

function printComments($arg, $depth = 1)
{
    foreach ($arg as $item)
    {
        // Printing comment...
        echo str_repeat('&nbsp; ', $depth) . $item['author'] . "<br />\r\n";
        // extra echoes...

        // if it has a child comment...
        if (count($item['child'] > 0))
        {
            printComments($item['child'], $depth + 1);
        }
    }
}

A little explaining:

The buildComments() function will starts with rows that parents has 0. Then it will execute itself for child. if child as a child, it will add it. In the end, result will be like this:

$result = array(
    1 => array(
        'author' => 'John',
        'child' => array(
            8 => array(
                'author' => 'Jane',
                'child' => array(
                    3 => array(
                        'author' => 'Jamie',
                        'child => array()
                    )
                )
            ),
            6 => array(
                'author' => 'Jackie',
                'child => array()
            ),
            9 => array(
                'author' => 'Harry',
                'child => array()
            )

        )
    ),
    4 => array(
        'author' => 'Jack',
        'child' => array()
    ),
    10 => array(
        'author' => 'Clark',
        'child' => array(
            11 => array(
                'author => 'Lois',
                'child' => array()
            )
        )
    ),
    12 => array(
        'author' => 'Luthor',
        'child' => array()
    )
);

In the printComments() function we are printing results recursive. for each child, function repeats itself. You will get result like this:

  John
    Jane
      Jamie
    Jackie
    Harry
  Jack
  Clark
    Lois
  Luthor

For more information about recursive functions Look this answer

USAGE

$this->db->where('postName',$postName);
$this->db->where('year(date)',$year);
$this->db->where('month(date)',$month);
$this->db->order_by('parent', 'asc');
$query = $this->db->get('comments');

$comments = buildComments($query->result());

printComments($comments);

that'is that simple...