The Hulme Ramblings of a web developer

4Dec/110

Fun with routes

So I haven't looked at my brother's website for a while, and decided with Christmas coming up it is about time I got a move on with the site and got it finished so I can pass it off as his Christmas present!

First thing I did was to get the static pages set up; involving simple controller and view creating which has already been covered.

Next on the list was to set up the news part of the site; which required creating the table, models and views.
While I was at it I created the admin menu page as well.

While creating the admin I came across the need to set up some custom routes. This actually stumped me for 10 mins or so, as all the examples I could find were for older versions of Zend Framework, and it seems that it has changed quite dramatically since then. I did find one website that was quite useful, but only for one of the comments that helped me work out what I need to do.

So for future reference, just like Kohana to add custom routes you need to edit the Bootstrap.php file, but your routes need to go inside a function "protected function _initRoute()". And an example of a custom route is:


$ctrl = Zend_Controller_Front::getInstance();
$router = $ctrl->getRouter();
$router->addRoute(
'addNews',
new Zend_Controller_Router_Route(
'/photo/news/add', array(
'controller' => 'photo',
'action' => 'addnews'
)
)
);

29Oct/110

Model Relationships Part 1

Here is my first tutorial for what I did to get some model relationships working in Zend Framework 1.11.11

Overview

The basic idea I am going to implement here is that I have Albums and Images. An album can have many images, and an image belongs to one album. So before we start, we should make sure that we have set up our tables and DbTable models, as well a controller and a view where we can test our relationships.

How To

Lets start with making sure we have a working controller and view working, by printing out all the albums and images.

For this tutorial I am testing my output in a album view and controller. Here is my index action in my AlbumsController.php:

public function indexAction()    {
       $albums = new Application_Model_DbTable_Albums();
      $this->view->albums = $albums->fetchAll();
      $images = new Application_Model_DbTable_Image(); 
      $this->view->images = $images->fetchAll();    
}

So as we can see, all I do is create a new instance of the Albums DbTable model and run fetchAll and assign it to the view. Same with the Image Image DbTable model. Then in my view I loop through the results and echo them out:

<?php foreach( $this->albums as $album ): ?>
<b>Album:</b> <?php echo $album->title; ?><br />
<?php endforeach; ?>

<b>Images&ltl/b><br />
<?php foreach( $this->images as $image ): ?>
<?php echo $image->title; ?>,
<?php endforeach; ?>

With this in place, we should just be getting a basic output listing the albums and images that we have in our database. Great!

The next thing we will do is edit the Album DbTable model telling it that it has a table that depends on it, and let it know what it's row class is. So at the top of the model, below the "$_name=" line add:

protected $_rowClass = 'Application_Model_Row_Album';
protected $_dependentTables = array('Application_Model_DbTable_Image');

This tells the model that it's row class is the model "Application_Model_Row_Album" (which we will create in a bit) and that the table that it has many to one relationship with is in the class "Application_Model_DbTable_Image" (Because our album has many images).

Next we will edit the image DbTable model to tell it what it's row class is, and what table it has a relationship to. Similarly to the above, underneath the "$_name=" line add:

protected $_rowClass = 'Application_Model_Row_Image';

protected $_referenceMap = array(
'Album' => array(
'columns' => 'album_id', // the column in the 'albums' table which is used for the join
'refTableClass' => 'Application_Model_DbTable_Albums', // the Albums table class
'refColumns' => 'id' // the primary key of the albums table
)
);

Next we need to move on to creating our Row Model classes. If the folder doesn't already exist, create one at "application/models/Row". Inside there create two files "Album.php" and "Image.php".

In Album.php add the following:

class Application_Model_Row_Album extends Zend_Db_Table_Row_Abstract
{
private $images = null;

/**
* @return Model_Row_Image
*/
public function getImages()
{
if (!$this->images) {
$this->images = $this->findDependentRowset('Application_Model_DbTable_Image');
}

return $this->images;
}
}

As we can see, this contains the function to get the images related to this model.

In the Image.php add:

class Application_Model_Row_Image extends Zend_Db_Table_Row_Abstract
{
private $album = null;

/**
* @return Model_Row_Album
*/
public function getAlbum()
{
if (!$this->album) {
$this->album = $this->findParentRow('Application_Model_DbTable_Albums');
}

return $this->album;
}
}

Finally if we update our view file to the below, we should see our relationships getting on fine:

<?php foreach( $this->albums as $album ): ?>
<b>Album:</b> <?php echo $album->title; ?><br />

<b>Images</b><br />
<?php foreach( $album->getImages() as $image ): ?>
<?php echo $image->title; ?>,
<?php endforeach; ?>

<?php endforeach; ?>

<b>Images</b><br />
<?php foreach( $this->images as $image ): ?>
<?php $al = $image->getAlbum(); echo $al->title; ?>,
<?php endforeach; ?>

29Oct/110

Testing My Relationships

Picking up from the other day, I tested echoing out the relationships that I had made, only to find out that I had in fact done it wrong!

After a bit of playing around with the code, it seems my proposed directory structure was the problem. I couldn't reference the general model instead of the DbTable model. The more I worked out as to why this was causing the error the more sense it made to me. So after fixing the references in my Row Models, the relationships were all in good standing.

I would assume there would be a way I could move some of the code around so I could implement my originally desired structure, but that will be something I will look into at a later date when I understand the Zend Framework a lot more.

At this point I am thinking it would be a good time to write my first tutorial on what I have done to get this far to possibly help me understand it a bit better, and who knows, someone out there in the WWW might stumble upon it and find it useful.

27Oct/110

Models, Mappers and fetching

Tonight I decided to have a quick look into getting my head around models and the like.

I have decided in the end to go in format of having a DBTable model which will contain all getter and setter functions and table joins/relationships; and to have a "normal" model (extending the DBTable model) which will be used for all other functions related for that particular model. This probably isn't the right way to be doing it, or the best way. But I'm sure with time and more playing about with Zend Framework I will work it all out.

So for today I started off with making the album table, models, inserting dummy data and getting them to list in a view.

Then I moved on to making the image models and table.

At this point I'm starting to get to like the command line tool. Something Kohana could do with to make it a little bit better. But at this point I am still preferring Kohana.

Next it was trying to work out how to set up relationships in the models. Getting the Album model to have many images, and an image belonging to many albums. Time to dig my nose into the ZF wiki!  ... which ended up not making a lot of sense to me in my current tired state!

I did find to be what seems a godsend to help me understand what I am trying to found out here. Eventually I got my page to stop erroring. Turned out I was missing some row classes that wasn't made clear on the ZF Wiki. This gives me an idea of having a tutorial section explaining how to do this the way I got things working.

 

Conclusion

At the end of tonight I have managed to:

  • Set up Albums and Images Models
  • List all the albums and models in the database in a view
  • Create row models ready for relationship implementation
  • Set up a relationship between the two models

Pages I found useful: