Adapting The Actions and Views
There are two changes we need to introduce. First we want our actions and views to use the models we created in the last step. Second we should move all data retrieval code to the place where it belongs - in the Action. Let's start with the Post.Show Action.
As our Post.IndexAction should respond to GET - Request, we'll need to adapt executeRead() that contains our data retrieval logic. Using the Posts_PostManagerModel [app/modules/Posts/models/PostManager.class.php] we created in the last step this is very little work:
<?php
class Posts_IndexAction extends BlogPostsBaseAction
{
/**
* Serves Read (GET) requests
*
* @param AgaviRequestDataHolder the incoming request data
*
* @return mixed <ul>
* <li>A string containing the view name associated
* with this action; or</li>
* <li>An array with two indices: the parent module
* of the view to be executed and the view to be
* executed.</li>
* </ul>
*/
public function executeRead(AgaviRequestDataHolder $rd)
{
$manager = $this->getContext()->getModel('PostManager', 'Posts');
$this->setAttribute('posts', $manager->retrieveLatest(10));
return 'Success';
}
/**
* Returns the default view if the action does not serve the request
* method used.
*
* @return mixed <ul>
* <li>A string containing the view name associated
* with this action; or</li>
* <li>An array with two indices: the parent module
* of the view to be executed and the view to be
* executed.</li>
* </ul>
*/
public function getDefaultViewName()
{
return 'Success';
}
}
?>
Now we need to adapt the view accordingly:
<?php
class Posts_IndexSuccessView extends BlogPostsBaseView
{
public function executeHtml(AgaviRequestDataHolder $rd)
{
$this->setupHtml($rd);
$ro = $this->getContext()->getRouting();
$posts = array();
foreach($this->getAttribute('posts') as $p)
{
$post = $p->toArray();
$post['url'] = $ro->gen('posts.post.show', array('post' => $p->getId()));
$posts[] = $post;
}
$this->setAttribute('posts', $posts);
$this->setAttribute('_title', 'Latest Posts');
}
}
?>
Note how we transform the objects we retrieved from our PostManager to arrays. While it may seem easier to pass objects to the template it removes a lot of flexibilty. Some template engines don't handle objects gracefully. There is little added overhead and little code we had to add for that as we need to add some information anyways - in our case the url to the post detail page. We could have added the url in the PostModels toArray() method but that would be bad practice - the url is probably only required in this specific context and would be useless clutter in all other occasions.
Let's just go over our Post.Show action and adapt that, using our models it will be a breeze:
class Posts_Post_ShowAction extends BlogPostsBaseAction
{
public function executeRead(AgaviRequestDataHolder $rd)
{
$manager = $this->getContext()->getModel('PostManager', 'Posts');
$this->setAttribute('post', $manager->retrieveById($rd->getParameter('post')));
return 'Success';
}
public function getDefaultViewName()
{
return 'Success';
}
}
class Posts_Post_ShowSuccessView extends BlogPostsBaseView
{
public function executeHtml(AgaviRequestDataHolder $rd)
{
$this->setupHtml($rd);
$post = $this->getAttribute('post')->toArray();
$this->setAttribute('post', $post);
$this->setAttribute('_title', $post['title']);
}
}
And that's it. Now our actions and views are completely decoupled from the data retrieval, they don't care about whether data is loaded from a flatfile, retrieved from a database, from a webserver or just faked with a static array like we do. You can bet that this will come in handy at some later point.

