Create a business object class for a blog post.

Here is the minimal code.

application/models/Post.php

  class Post extends BusinessObject
  {
      private $_id;
 
      public function __construct($id = null)
      {
          $this->_id = $id;
      }
 
      public function load()
      {
          $sql = "select * from posts where post_id = ? limit 1";
 
          $data = Zend_Registry::get('db')->getRows($sql, array($this->_id));
          return $data[0];
      }
  }

All business object classes must extend the “BusinessObject” class.

Instantiating a business object class does not query the database. All it really does is assign an ID. The load() method is called if data is requested by code that looks like $post→title.

Create a business object class for containing a list of blog posts.

Here is the minimal code.

application/models/Post/All.php

  class Post_All extends BusinessObject
  {
      public function getPosts()
      {
          $sql =  "select post_id from posts";
          $this->_hint('Post');
          return Zend_Registry::get('db')->getCol($sql);
      }
  }

Class organization and naming must adhere to the PEAR and Zend conventions for the autoloader to find it. That is, the Post_All class is in the file All.php in the “Post” folder.

There is no load() method needed in this class. The getPosts() method is called by code that looks like $posts→posts.

To create a list of business objects, only the ID's of the objects are needed. Querying for an array of ID's (or otherwise suitable primary key) is all that's needed for the framework to generate the rest of the objects. This keeps the code pertaining to Post business object out of the class pertaining to the container for Post business objects. There is no need to query for, for example, the title or body or whatever. This also makes the query faster and more query cache-able.

The _hint() method is required when generating a collection to tell the framework what the collection is a collection of.

Create a controller to display the blog posts (model) in a page (view).

Here is the minimal code:

application/controllers/BlogController.php

  class BlogController extends Controller
  {
      public function index()
      {
          $posts = Zend_Registry::get('factory')->get('Post_All');
 
          $this->view->posts = $posts->posts;
          $this->view->title = 'My Blog';
          $this->view->display('blog/posts.tpl');
      }
  }

All controllers must extend the Controller class and have a classname matching a pattern of *Controller.

The controller action name corresponds to the URL. So the index action can be called by requesting the URL http://localhost/blog/index. Since index is the default action, you can also request the URL http://localhost/blog.

All objects are instantiated using the framework factory, i.e. the new keyword should never be used to instantiate a business object.

The list of posts is generated by the statement $posts→posts. This calls the getPosts() class method, unless the data is already cached.

$this→view represents the Smarty template. Template variables can be assigned, and templates can be displayed like always.

Create the view (Smarty template).

Here is the minimal code:

application/views/blog/posts.tpl

  <html>
  <body>
      <h1>{$title}</h1>
      <table border="1">
              <tr><th>ID</th><th>Title</th><th>Created</th></tr>
 
          {foreach from=$posts item=post}
              <tr><td>{$post->post_id}</td><td><a href="/blog/view/{$post->post_id}">{$post->title}</a></td><td>{$post->create_dt_tm}</td></tr>
 
          {/foreach}
      </table>
  </body>
  </html>

The $posts Smarty variable is assigned by the PHP line $this→view→posts = $posts→posts.

The $post→post_id field must match the name of the table column.

Load the page by requesting the URL http://localhost/blog. Here is a screenshot of what I get. (Note that clicking on the title hyperlink will result in a 404. We'll get to that link in a bit.)

Let's make the date look a little nicer.

The best way to do this is to return a timestamp from the database, and then let the template writer format the date in any way he wants, using Smarty modifiers. First, we need to return a timestamp. Given a statement like “$post→time”, the framework will first look for the field as a table column, then look for a getter method for that field. So, for “$post→time” to work, we need to add a getter method for a time field, where we can return anything we need. Here is the method.

  public function getTime()
  {
      return strtotime($this->_data['create_dt_tm']);
  }

The framework will look for any requested fields in the following locations in the following order:

1. looks in ''$this->data'', a hash of all the fields for this object.
2. looks at table columns, loaded by the ''_load()'' method.
3. looks for a special ''get*'' method matching the field name.   

Since we called $post→time and time is not a table column, it will look for and call the getTime() method, which will return our data, and set the value for $this→_data['time'] for future requests to use.

Then, in our view, we can use this newly available time field.

application/views/blog/posts.tpl

  <html>
  <body>
      <h1>{$title}</h1>
 
      <table border="1">
              <tr><th>ID</th><th>Title</th><th>Created</th></tr>
 
          {foreach from=$posts item=post}
              <tr><td>{$post->post_id}</td><td><a href="/blog/view/{$post->post_id}">{$post->title}</a></td><td>{$post->time|date_format:"%A %b. %e %Y %l:%M %p"}</td></tr>
 
          {/foreach}
      </table>
  </body>
  </html>

And now my screenshot looks like this.

That's it. Now, let's implement that title link so that we can View a single blog post.

pox-php/view_all_blog_posts.txt · Last modified: 2010/05/09 20:48 by gerard
 
 
© 2010 Straylightrun.net under Creative Commons Attribution
Green hosting by Dreamhost.com | Powered by DokuWiki