Welcome Guest, Not a member yet? Register   Sign In
noob: trying to build on "blog tutorial"
#11

[eluser]cirox![/eluser]
Managed to get everything working.

The reason why the load helper command was spitting out the helper function as text was because (to my embarassment) I hadn't enclosed the function in <?php ?> tags.

Also, the final function is slightly different:
a) It needed a where clause for it to return what I wanted. Duh!
b) It was giving me Fatal error: Using $this when not in object context which I'm not sure what to make of.
However, I tried to pass the object from the view as a parameter, like so:

Code:
get_comments_no($row->id, $this)

to the comment_helper.php:

Code:
<?php

function get_comments_no($id, $obj)
{
    $obj->db->where('entry_id',$id);
    $q = $obj->db->get('comments');
    
    return $q->num_rows();
}

?>

and this worked fine.

I also managed to get it to work without the helper, which was what I was initially trying to achieve.
I had originally defined get_comments_no() inside the controller, but when I tried viewing the page it was throwing a
Fatal error: Call to undefined function get_comments_no() ...
The reason, I figured out, was because I'd defined the function outside the index() function, and that way, the view didn't know about it.

I've got so much to learn!

This is the final code [for other newbies' benefit] ;-P

blog.php
Code:
<?php

class Blog extends Controller {

    function Blog()
    {
        parent::Controller();
        
        $this->load->helper('url');
        $this->load->helper('form');
    }

    function index()
    {

        function get_comments_no($id, $obj)
        {
            $obj->db->where('entry_id',$id);
            $q = $obj->db->get('comments');
    
            return $q->num_rows();
        }

        $data['title'] = "My Blog Title";
        $data['heading'] = "My Blog Heading";
        $data['query'] = $this->db->get('entries');
        
        $this->load->view('blog_view', $data);
    }
    
    function comments()
    {
        $data['title'] = "My Comment Title";
        $data['heading'] = "My Coment Heading";
        $this->db->where('entry_id',$this->uri->segment(3));
        $data['query'] = $this->db->get('comments');
        $this->load->view('comment_view', $data);
    }

    function comment_insert()
    {
        $this->db->insert('comments',$_POST);
        redirect('blog/comments/'.$_POST['entry_id']);
    }

}

?>

blog_view.php
Code:
<html>
<head>
<title><?php echo $title; ?></title>
</head>
<body>
<h1>&lt;?php echo $title; ?&gt;</h1>

&lt;?php foreach($query->result() as $row): ?&gt;
    <h3>&lt;?php echo $row->title ?&gt;</h3>
    <p>&lt;?php echo $row->body ?&gt;</p>
    <p>&lt;?php echo anchor('blog/comments/'.$row->id,'Comments ('.get_comments_no($row->id, $this).')'); ?&gt;</p>
    <hr />
&lt;?php endforeach; ?&gt;

&lt;/body&gt;
&lt;/html&gt;
#12

[eluser]Jamie Rumbelow[/eluser]
Well done!

Just one quick note: Defining a function inside another function, particularly one of a controller, is about as far from MVC coding standards as you could hope. Try to adhere; that's what helpers and libraries are for in the first place!

Thanks,

Jamie
#13

[eluser]ajrowland[/eluser]
Hello. For efficiency you could use a left join on your query to obtain the number of comments for each entry. Then you would not need to run an extra query on each entry just to pull out the number of comments.

For example change your index method to:

Code:
function index()
{
    $data['title'] = "My Blog Title";
    $data['heading'] = "My Blog Heading";
        
    $this->db->select('entry.id, entry.title, entry.body, COUNT(comment.entry_id) AS num_comments', FALSE);
    $this->db->from('entries entry');
    $this->db->join('comments comment', 'entry.id = comment.entry_id', 'left');
    $this->db->group_by('entry.id, entry.title, entry.body');

    $data['query'] = $this->db->get();

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

Therefore your view would be something like:

Code:
&lt;html&gt;
&lt;head&gt;
    &lt;title&gt;&lt;?php echo $title; ?&gt;&lt;/title&gt;
&lt;/head&gt;
&lt;body&gt;

<h1>&lt;?php echo $title; ?&gt;</h1>

&lt;?php foreach($query->result() as $row): ?&gt;
    <h3>&lt;?php echo $row->title ?&gt;</h3>

    <p>&lt;?php echo $row->body ?&gt;</p>

    <p>&lt;?php echo anchor('blog/comments/'.$row->id,'Comments ('.$row->num_comments.')'); ?&gt;</p>

    <hr />
&lt;?php endforeach; ?&gt;

&lt;/body&gt;
&lt;/html&gt;

It may seem minor, but now your rendered page only requires one database query no matter how many entries, and therefore scales better.
#14

[eluser]cirox![/eluser]
@andy that's a good tip, cheers mate! I will definitely use it when I next need to do something similar.

I really like this syntax
Code:
$this->db->select
$this->db->from
$this->db->join
$this->db->group_by
very SQL like and easy to pick up, if you're accustomed to sql that is.
#15

[eluser]EzS[/eluser]
2ajrowland

Thanks a lot for your solution!




Theme © iAndrew 2016 - Forum software by © MyBB