Welcome Guest, Not a member yet? Register   Sign In
can i pass data from view to controller?
#11

[eluser]gRoberts[/eluser]
Hi Brian,

Apologies, I was meant to reply but got caught up in other work and unfortunately never got around to.

The "Comments" column as it were, is not a column in your table, but one that is added by code within your controller.

In my initial post, the code created an $Comments array against each Post that then contained all of the comments related to that post.

I've corrected your code and inserted some comments.

Code:
<?

function index()
{
  // 1. Get an array of "Posts"
  $Posts = $this->main_mod->getPosts();
  
  // 2. Get the list of ID's within $Posts
  $postIds = array();
  foreach ($Posts as $p)
  {
   $postIds[] = $p->id;
  }
  reset($Posts);

  // 3. Get all of the comments related
  // to the Posts above.
  $Comments = $this->main_mod->getComments($postIds);

  // 4. Loop through each of the Posts
  // and attach the related comments
  // to the post.
  foreach ($Posts as $index => $p)
  {
   // Create an empty array
   $p->Comments = array();
   // Loop through the comments
   foreach($Comments as $c)
   {
    // If the comment belonds to the
    // post, attach it.
    if($c->postId == $p->id)
    {
     $p->Comments[$c->id] = $c;
    }
   }
   // Update the $Posts array to include
   // the comments
   $Posts[$index] = $p;
  }
  unset($Comments);
  // 5. Pass the array of Posts and comments
  // to the view
  var_dump($Posts);
  /*
   array
   (
    0 => object // with comments
    {
     'id' => 1,
     'Comments' => array
     (
      1 => object
      {
       'id' => 1,
       'postId' => 1,
       'comment' => 'this is your comment text'
      }
     )
    },
    1 => object // without comments
    {
     'id' => 2,
     'Comments' => array()
    }
   )
  */
  $data['posts'] = $Posts;

  // views
  if($this->session->userdata('logged_in') === true)
  {
   $this->load->view('header_logged_in', $data);
   $this->load->view('home', $data);
   $this->load->view('footer');
  }
  else
  {
   $this->load->view('header', $data);
   $this->load->view('home', $data);
   $this->load->view('footer');
  }
} // end

?>
#12

[eluser]brian88[/eluser]
Thanks a lot. I got the comments connected with their posts...

However it is limiting only 1 comment per post. When I post a new comment it just replaces the old comment. But the old comments are still saved in the database. So the view is always showing the latest comment. I want to show all the comments for a post.

I think the problem is in this logic.

Code:
//get all comments
  $allComments = $this->main_mod->getComments($postIds);

  var_dump($allComments); // this returns ALL my comments

  // attach comments to their posts
  foreach ($data['posts'] as $index => $p) {
   $p->comments = array();
    foreach($allComments as $c){
     echo $index;
    if($c->postId == $p->id){
     $p->comments[$c->id] = $c;
    }
   }
   $data['posts'][$index] = $p;
  }
  unset($allComments);

  var_dump($data['posts']); // returns only 1 comment per post.

There are lots of comments in the database. But they are not showing up. It's only showing the newest comment for a post.
#13

[eluser]gRoberts[/eluser]
If you do

Code:
var_dump($allComments)

Is the `id` column the same for every comment?

As a test, remove the `$c->id` from the line

Code:
$p->comments[$c->id] = $c;

This should fix it until you find out why the wrong Comment ID is being returned against `$c->id`
#14

[eluser]CroNiX[/eluser]
Each loop you are overwriting your array so it will only hold the last one in the loop.
First, check to see if $p->comments is already set before creating it.

Code:
if ( ! isset($p->comments))
{
  $p->comments = array();
}
#15

[eluser]gRoberts[/eluser]
[quote author="CroNiX" date="1335810778"]Each loop you are overwriting your array so it will only hold the last one in the loop.
First, check to see if $p->comments is already set before creating it.

Code:
if ( ! isset($p->comments))
{
  $p->comments = array();
}
[/quote]

Unfortunately not my friend. If you look at the foreach statement that loops through the $posts or $data['posts'] variable, you'll notice that the $p->comments = array() is only set when looping through each post and not through each comment.

As a result, $p->comments = array() will only ever be called once and never overwritten.
#16

[eluser]brian88[/eluser]
Thanks a ton gRoberts! I got it to work.

The id was not the same for every post. But I removed `$c->id` from the line and it worked.

Are the reset() and unset() good practice? Because I took them out and it still worked fine.
#17

[eluser]cPage[/eluser]
The question was :
can i pass data from view to controller ?

Code:
$viewPlusData = $this->load->view('theview',$data,TRUE);
#18

[eluser]brian88[/eluser]
Right cPage. But that returns the whole view's html. I wanted just an single id in that view. if theres someway to get that out that would be great.

I have another question gRoberts.
I got the comments to pop up. But I want to throw in the user name who posted it too. When I post then sign in as another user the comment says its from whoever created the post.
So... when Chris makes a post. and David signs in and comments. The comment still says its Chris even though david is logged in and he posted it.

controller
Code:
function index() {
  // header data
  $data['title'] = 'title of home page';
   $data['desc'] = 'desc of home page';

  // model data
  $data['posts'] = $this->main_mod->getPosts();
  if($this->session->userdata('userInfo') != null){
   $data['userInfo'] = $this->user_mod->getUserById($this->session->userdata('userInfo')->id);
  }

  // views
  if( !empty($data['posts']) ) {

   $postIds = array(); // empty array
   foreach ($data['posts'] as $p) { // foreach post
    $postIds[] = $p->id; // store the post id in array
   }
   reset($data['posts']);

   //get all comments
   $allComments = $this->main_mod->getComments($postIds);

   // attach comments to their posts
   foreach ($data['posts'] as $index => $p) {
    $p->comments = array(); // create empty array
     foreach($allComments as $c){ // loop through all the comments
     if($c->postId == $p->id){ // If the comment belongs to the post...
      $p->comments[] = $c; // attach it
     }
    }
    // update the $posts array to include the comments
    $data['posts'][$index] = $p;
   }
   unset($allComments);

   if($this->session->userdata('logged_in') === true) {
    $this->load->view('header_logged_in', $data);
    $this->load->view('home', $data);
    $this->load->view('footer');
   }else{
    $this->load->view('header', $data);
    $this->load->view('home', $data);
    $this->load->view('footer');
   }
  }else{ // empty post data
   if($this->session->userdata('logged_in') === true) {
    $this->load->view('header_logged_in', $data);
    $this->load->view('home_error', $data);
    $this->load->view('footer');
   }else{
    $this->load->view('header', $data);
    $this->load->view('home_error', $data);
    $this->load->view('footer');
   }
  }

} // end function
model
Code:
// get all posts
function getComments($postIds) {

  $this->db->select('comments.comment, comments.postId, comments.date, posts.userId, users.name, users.picture');
  $this->db->join('posts', 'posts.id = comments.postId', 'left');
  $this->db->join('users', 'users.id = posts.userId', 'left');
  $this->db->where_in('posts.id', $postIds);
  $q = $this->db->get('comments');
  
  if($q->num_rows() > 0){
   foreach($q->result() as $row){
    $data[] = $row;
   }
   return $data;
  }
} // end function

view
Code:
<?php foreach($posts as $p): ?>

   <!-- ////////////////// Start Post ////////////////// -->

   <!-- Post Body -->
   <div class="feedPost cfix">
    <img src="&lt;?php echo base_url('assets/uploads/user/images') . '/' . $p-&gt;picture; ?&gt;" width="50" alt="&lt;?php echo $p-&gt;name; ?&gt;">
    <div class="postContainerRight">
     <div class="postBody">
      <span><a href="&lt;?php echo base_url('user/profile') . '/' . $p-&gt;userId . '/' . $p-&gt;name; ?&gt;">
      <strong>&lt;?php echo $p->name; ?&gt;</strong></a> <br />
      &lt;?php echo $p->date; ?&gt;</span>
     &lt;?php if( str_word_count($p->body) > 50): ?&gt;
      
      <p>&lt;?php echo word_limiter(auto_link($p->body, 'url', true), 50, "..."); ?&gt;<a href="&lt;?php echo site_url(">id . '/'. url_title($p->name, 'dash', true)); ?&gt;">Read more</a></p>
     &lt;?php else: ?&gt;

      <p>&lt;?php echo auto_link($p->body, 'url', true); ?&gt;</p>
     &lt;?php endif; ?&gt;
     </div>
     &lt;!-- End Post Body --&gt;
    &lt;?php if( !empty($p->comments) ): ?&gt;

     &lt;!-- Comments --&gt;
     <div class="comments">
      
    &lt;?php foreach($p->comments as $c): ?&gt;

      <div class="comment cfix">
       <img src="&lt;?php echo base_url('assets/uploads/user/images') . '/' . $c-&gt;picture; ?&gt;" width="40" alt="&lt;?php echo $c-&gt;name; ?&gt;">
       <span><a href="&lt;?php echo base_url('user/profile') . '/' . $p-&gt;userId . '/' . $p-&gt;name; ?&gt;"><strong>&lt;?php echo $c->name; ?&gt;</strong></a> <br />&lt;?php echo $c->date; ?&gt;</span>
       <p>&lt;?php echo $c->comment; ?&gt;</p>
      </div>&lt;!-- End Comment --&gt;
    &lt;?php endforeach; ?&gt;

     </div>
     &lt;!-- End Comments --&gt;

    &lt;?php endif; ?&gt;

     &lt;!-- Post Comment --&gt;
     <div class="postComment">
      &lt;form action="&lt;?php echo base_url('main/add_comment_db'); ?&gt;" method="post" accept-charset="utf-8"&gt;
      <ul>
       <li>&lt;textarea class="blank" name="comment"&gt;Comment...&lt;/textarea&gt;&lt;/li>
       <li>&lt;input type="hidden" name="postId" value="&lt;?php echo $p-&gt;id; ?&gt;"&gt;&lt;/li>
       <li>&lt;input class="submit" type="submit" name="submit" value="Post"&gt;&lt;/li>
      </ul>
      &lt;/form&gt;
     </div>
     &lt;!-- End Post Comment --&gt;

     <hr />
    </div>&lt;!-- /postContainerRight --&gt;
   </div>&lt;!-- /feedPost --&gt;
   &lt;!-- ////////////////// End Post ////////////////// --&gt;

  &lt;?php endforeach; ?&gt;

in my database the comments are correct with the right userIds.

http://dl.dropbox.com/u/9883217/work/db.png


when i
Code:
var_dump($allComments);
all the comments are when the wrong userIds. Because every commenter is automatically the userId of the poster. As I said above.

http://dl.dropbox.com/u/9883217/work/comments.png
#19

[eluser]GrahamDj28[/eluser]
Is it just me, or is this thread a little confusing?

If I'm reading this right, it comes down to this.

You have executed a query that gives you all the available posts, right?
So why should you use a where in, if the post ids are already known and you have the function getComments?

This is how it can be done

Change the function getComments() to this:
Code:
public function getComments($postId) {
    $comments = array();
    $this->db->where('postId',$postId);
    if($q = $this->db->get('comments')) {
        $comments = $q->result(); // All the comments should be here
    }

    return $comments;
}

You then call it like so:
Code:
foreach($posts as $key => $post) {
    $posts[$key]['comments'] = $this->your_model->getComments($post->id);
}

Doing it this way does cause the system to execute an extra query for every post. So if you have 10 post results the total number of executed queries will be 11. That can cause some problems if the number of posts gets higher and higher.

Solution:
Change your getPosts() function so it will also get the comments with 1 query.

Code:
$query = "SELECT post.*, comment.*
          FROM posts as post
          LEFT JOIN comments as comment ON comment.postId = post.id";

All the data you need will now be returned with this simple query

As a complete function:
Code:
public function getPosts() {
    $sql = "SELECT post.*, comment.*
            FROM posts as post
            LEFT JOIN comments as comment ON comment.postId = post.id";
    $query = $this->db->query($sql);
    if($query->num_rows() > 0) {
        $results = $query->result();
    }

    /* For every comment of a post, the post will be in the results.
    So if a post has 4 comments, the post will be in the results 4 times.
    Once for each comment.
    We will need to filter this. */
    $posts = array();
    foreach($results as $post) {
        if( ! array_key_exists($post->id, $posts) ) {
            $posts[$post->id]['post'] = $post; //Collect the posts
        }
        $posts[$post->id]['comments'][]  = $post;
    }

    return $posts;
}



With both my solutions there will be a turning point where the one is better than the other.
When the number of records gets very high, the second method could slow things down again. The database will sub query every result to find the comments, and a large data array can eat up memory and there is alot of overhead information being sent.
So in some situations, more small queries is more friendly.

And to anwser the original question:
You can, by posting a form with the id in it. You will post the form with Javascript once the page is done loading. But you have multiple posts with multiple comments and posting forms. And you will generate alot of extra unwanted traffic. So you can, but you should not do it like that.
#20

[eluser]brian88[/eluser]
Thanks for a response. Im trying your way also.

I my first error is...
Fatal error: Cannot use object of type stdClass as array in C:\Program Files (x86)\wamp\www\cms\application\controllers\main.php on line 26
Code:
$data['posts'] = $this->main_mod->getPosts();
foreach($data['posts'] as $key => $post) {
    $data['posts'][$key]['comments'] = $this->main_mod->getComments($post->id);
   }
// line 26 main

I added in your other code also. But got many errors. Maybe once we fix this one it will work better.




Theme © iAndrew 2016 - Forum software by © MyBB