Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to pass the result of recursive function to view

Tags:

codeigniter

I am using only controller and view.
using following code i am displaying post and post having reply.
i used the following controller and View to display post and reply.

By using query 1 i am selecting post for the topic id.(eg.topic id=34) from post table and using this get post id 30 and 31 .

By using query 2 i am selecting reply for each post id from reply table.
say post id 30 having reply id 1 and
post id 31 having reply id 2.

by using 2nd for loop i am selecting if any reply have anothr reply using parent_id column from Reply table.(use recursive call to showreply() function)

I am stuck in how i pass result from recursive function showreply() in view.

By using my code i disply:

Post 30
---first reply for post 30
post 31
---reply for post 31

but i want to show like.

Post 30
---first reply for post 30
---reply to first reply
post 31
--- first reply for post 31
---reply to first reply

i have used the recursive function call to get the reply for reply using parent id but i am not getting how can i pass this to view.

Controller:

   <?php
public function viewpost()
    {  
        //Query 1

        $topicid = trim($this->input->get('topicid'));
        $q =$this->db->select(array(
            'fp.id as id',
            'fp.postdata',
            'fp.topicid'))
            ->from('forum_post AS fp')
            ->where('fp.topicid',$topicid)
            ->order_by('fp.id DESC')->limit(0,10)->get();

        $resultq1 = $q->result_array();
        $data['resultq1'] = $resultq1;

        //$data['resultq1'] = $res;
        $resultq2 = array();
        foreach ($resultq1 as $rec)
        {
            //Query 2

            $postid = $rec['id'];
             $q1 =$this->db->select(array(
                'fr.id as id',
                'fr.reply_data'))
                ->from('forum_reply AS fr')
                ->where('fr.postid',$postid)
                ->order_by('fr.id ')->get();

            $resultq2[$postid] = $q1->result_array();
            $data["resultq2"][$postid] = $resultq2[$postid];

            foreach($q1->result_array() as $row1)
            {

                //second for loop

                  $reply_id = $row1['id'];
                  $resultq3[$reply_id] = $this->showreply($reply_id); // call to function
                  $data["resultq3"] = $resultq3[$reply_id];


            }//inner for loop
        } //outer for loop

        $this->load->view('viewpost',$data);
    }

    public function showreply($reply_id)
    {

                    $reply_id1 = $reply_id;
                     $q1 =$this->db->select(array(
                        'fr.id as id',
                        'fr.reply_data',
                        'fr.parent_id'))
                        ->from('forum_reply AS fr')
                        ->where('fr.parent_id',$reply_id1)
                        ->order_by('fr.id ')->get();

                        //print $this->db->last_query();
                         $resultq4[$reply_id1] = $q1->result_array();
                         $data["resultq4"]= $resultq4[$reply_id1];

                        $i=0;
                        foreach($q1->result_array() as $row4)
                         { 
                                print_r($q1->result_array());
                                echo "id".$id = $row4['id'];
                                $parent_id = $row4['parent_id'];
                                if($parent_id!=0)
                                {  
                                    //$data['nested'][$i] = $q1->result_array();
                                    $this->showreply($id);  //recursive call to function                        
                                    $i++;
                                }
                         }

            return  $resultq4;
    }
?>

Table Structure for reply Table:

Rep_id    rep_text                       post_id     Parent_ID
-------------------------------------------------------------------------
  1         Reply for post 30              30           null
  2         Reply for post 31              31           null
  3         reply to Rep_id 1              null           1
  4         Rep_id 3 have Rep_id 4         null           3
  5         Reply for post 31              null           2
  6         Reply for Rep_id 5             null           5

----------------------------------------------------------------------------

Post Table:

post_id  topic id   post_title   post_desc 
-----------------------------------------
  30       34         xyz         sssss
  31       34         pqr         tyyyu

----------------------------------------

*View:*

<div>
    <?php foreach($resultq1 as $row)
    {  ?> 
       <ul>
            <li></li>      // used to display post
      </ul>
    <?php foreach($resultq2 as $rows)
    {
        foreach($rows as $row1)
        {
            if($row['id']==$row1['postid'])
            {   ?>
            <ul>
              <li></li>      // used to display reyly for post 
            </ul>
           <?php foreach($resultq3 as $rows)
            {
                foreach($rows as $row2)
                { 
                  if($row1['id']==$row2['parent_id'])
                {   ?>
                    <ul>
                       <li></li>   // used to display reply for reply
                    </ul>
                 <?php     
                 }//if 
                } //inner for  $row2
            } // outr for $resultq3 
          } //if
        } //inner for of $row1
      }//outer for $resultq2
    } ?>
    </div>
like image 984
Kango Avatar asked Oct 05 '22 15:10

Kango


2 Answers

i'm sorry but this is a very bad code :(. i would suggest rewrite the whole thing..

example

table posts:

ID    type    title    content  parent_id    post_id
1    post      xyx      asd       Null        1
2    comment    asd     DEMO      1           1
2    comment    com     DEMO2     2           1

now that is what i would suggest,

all posts should be in 1 table

with column Type (enum field [post,comment])

a parent_id column that would specify its position in the tree.

and a post_id table that glue all of them together.

now all you have to do is

$post = $this->db->select('*')->where('post_id',$post_id)->get('posts');

now $post will contain all your posts with its comments and subcomments and everything..

in a single db query, all you have to do now is to organize them in an assoc array

$post = $this->db->select('*')->where('post_id',$post_id)->get('posts');

if($post->num_rows==0)return false;//end if there is no post found

//step 1 find main post
$main_post=FALSE;
foreach($post as $fp){
if($fp->type=='post')$main_post=array ('id'=>$fp->id,'title'=>$fp->title,'content'=>$fp->content);
}

if($main_post==false)return false;///THERE WAS NO MAIN POST FOUND !!!

//step 2 get comments on post

$comments=array();

foreach($post as $fp){
if($fp->type=='comment' && $fp->parent_id==$main_post['id']){
$comment[$fp->id]=array('title'=>$fp->title,'content'=>$fp->content,'child'=>array());
}
}

//step 3 comments of a comment

//IF comment is not on parent so its on another comment right :) !
foreach($post as $fp){
if($fp->type=='comment' && $fp->parent_id != $main_post['id']){
$comment[$fp->parent_id]['child'][]=array('title'=>$fp->title,'content'=>$fp->content);
}
}

now you have all your comments and comments on comment inisde $comment var, very easy to loop and the main post inside $main_post :) a simple view will be

<h2><?=$main_post['title']?></h2>
<div class='fp_post'>
<?=$main_post['post']?>
</div>
<ul class='comments'>

<?
foreach($comment as $c){
echo "<li> $c['title'] : $c['content']";

if(!empty($c['comment'])){
//there is a comments on this comment :)
echo "<ul>";
foreach($c['comment'] as $coc){echo "<li> $coc['title']: $coc['content']</li>";}
echo "</ul>";//end of comment of comments
}
echo "</li>"//end of a comment and its comments

}

?>
</ul>

i hope that this simple code help you out solving your problem, this is simple yet effective way to do it, and im sure you can use some debug-ing try_catch instead of returning false on error, also you can add some verification yet this is not our case now.

hope this answer is good enough for you :)

cheerz

like image 99
Zalaboza Avatar answered Oct 10 '22 02:10

Zalaboza


This is my answer:

First

Consider using MVC aproach, separate your db query in model part of your application.

Second

You should always check wether there is result on your query or not. This can prevent your code from fatal error when there is no result in your query and you try to foreach them.:

<?php
public function viewpost()
{  
     //Query 1

     $topicid = trim($this->input->get('topicid'));
     $q =$this->db->select(array(
          'fp.id as id',
          'fp.postdata',
          'fp.topicid'))
           ->from('forum_post AS fp')
           ->where('fp.topicid',$topicid)
           ->order_by('fp.id DESC')->limit(0,10)->get();
     //$data['resultq1'] = $res;
     $resultq2 = array();
     if($q->num_rows() > 0) 
     {
            $resultq1 = $q->result_array();
            foreach ($resultq1 as $rec)
            {
                //Query 2

                $postid = $rec['id'];
                $q1 =$this->db->select(array(
                    'fr.id as id',
                    'fr.reply_data'))
                    ->from('forum_reply AS fr')
                    ->where('fr.postid',$postid)
                    ->order_by('fr.id ')->get();

            // the rest of your code

     }

     // the rest of your code

Third

I assume that you will display your first level reply in same as your second level reply (instead of nested):

Post

-- reply to post

-- reply to reply

Post

-- reply to post

-- reply to reply

<div>
<?php
if($resultq1) 
{
   echo '<ul>';
   foreach($resultq1 as $row)
   { 
      echo '<li>';      
      echo $row;// used to display post
      if(resultq2)
      { 
         echo '<ul>';
         foreach($resultq2 as $rows)
         {
             echo '<li>';
             echo $rows; // display reply to post
             echo '</li>';
             if($resultq3)
             {
                foreach($resultq3 as $row1)
                {
                    echo '<li>';
                    echo $row1; // display reply to reply
                    echo '</li>';
                }
             }
          }
          echo '</ul>';
       }
       echo '</li>';
    }
    echo '</ul>';
  }
  </div>

So far, this is my answer, I hope this help you too.

like image 22
Seto Avatar answered Oct 10 '22 03:10

Seto