Decorating Zend Developer Zone

September 28th, 2006

If you’re in the mood for design patterns, my article, Decorating with External Data has just been published on Zend Developer Zone and runs through an example of using the Decorator.

I’m really interested to see it get a bit of a kicking from those who really know their design patterns, so if you’re one of those people please let me know of anything I should or should not do in the comments here or at DevZone.

Diving into WordPress

September 27th, 2006

Yes, I know the title is a little cheesy, but it does introduce some of the recent projects we have been working on.

One of the things that is often requested is a means for businesses to update their own content and this generally requires some kind of content management system. For previous larger projects like underwater.com.au, the requirements have been specific enough to require a custom system to be developed. For smaller projects, however, a custom solution is often overkill. In this article I’m going to run through some of the thoughts that went into developing a couple of sites using WordPress.

Yongala Dive

Yongala Dive website screenshotYongala Dive is a small dive resort based in the Great Barrier Reef Marine Park which primarily runs trips to the famous S.S. Yongala Wreck.

Their previous static site was difficult to update and maintain and was also in need of search engine optimisation. We started by looking at their statistics to get an indication of how the site was being used and from that came up with the following overview:

  1. First users looked for information about the S.S. Yongala wreck.
  2. Then they wanted to know about the people providing the service.
  3. Then about the service they provide.
  4. Then they looked at images in the gallery.
  5. At this point they seemed ready to contact them.

These were some of the findings that were used in the development of the site and influenced decisions, such as, what order pages appeared in the site navigation.

I initially started looking at using a pared down version of our own content management system but decided that in this case it would have been the wrong choice. Instead, the advantages of using a solution like WordPress include:

  • You can spend more time solving business problems than on the inevitable tweaking of your in-house engine.
  • It is free, used all over the place, many hosts actually have it as a package.
  • It is well documented.
  • Finding someone in the future to develop for it will be many times easier than finding someone to develop for an in-house custom solution.
  • You will be able to take advantage of the many available plugins like gallery, calendar, weather, etc. Plus, of course, you can also build plugins.

Bear in mind that many of the above benefits apply not only to your involvement in the project, but also in the case of you no longer working on the site. If, for example, your client employs an in-house developer it will be to your benefit to have allowed for that.

WordPress Plugins Used

Australian Divemaster Academy

Australian Divemaster Academy website screenshotThe Australian Divemaster Academy is an initiative of Byron Bay Dive Centre, taking students from beginner to Divemaster in 10 weeks of training.

The main requirement for this site, aside from introducing the course, was to provide a means for the non-technical staff to update news and the program calendar. The relative simplicity of WordPress’ “Write Post” process was really the key reason to use it.

We also added the WP-iCal plugin to publish the calendar posts to an .ics format so that calendar applications like iCal, Sunbird and the upcoming Outlook 2007, can subscribe and be kept up to date with program availability.

WordPress Plugins Used

Conclusion

WordPress is not a panacea and I have to admit that moving from developing object-oriented, MVC-architected, design-pattern-influenced, ok-I-sound-like-a-wanker, code to WordPress and many of its plugins feels like a step back in time. Articles recommending what not to do when developing modern PHP applications could find examples in WordPress and its plugins.

Just to mention a few: Functions are often huge and on occasion perform everything from querying the database to outputting the HTML. The API seems geared mainly towards retrieving HTML output when often you’d like to set or retrieve more basic data like an array or an integer. Many plugins would benefit greatly from updating the indexing of the database columns but make no such recommendation.

One example is a plugin that had database queries nested in two levels of loops. Having first retrieved some data, it used it to loop through another query and in turn, used that to loop through a further query. In a small test it had already run over 100 queries and would have increased in line with the number of posts. A reworking of the code reduced the total queries down to 2. (Note: I did do what you’re supposed to do with open-source code you see needing some work; fix it and send its developer the reworked solution. I’ve intentionally not named the plugin as a mark of gratitude to anyone who gives their time to helping others out.)

However, before I go on and on, getting all precious and code nazi, I have to admit that it is fun to hack away at WordPress. If your client makes a request the first thing you can do is Google for a plugin. Often there are a selection that almost meet the mark which can then be used as a prototype to show the client. If not immediately appropriate, most can be adapted to the needs of the business.

In short while you still need to be vigilant there is a real sense of liberation in being able to focus on finding solutions to your clients needs rather than getting overly (and the danger being unnecessarily) precious about the code itself.

Rob Allen’s Zend Framework Tutorial

August 18th, 2006

Anyone looking for a good comprehensive run through of a Zend Framework application should read Rob Allen’s My Take on a Zend Framework Tutorial.

As it’s a PDF, you might like to read it using this trick from Jon Udell: Vertical PowerBook as ebook reader. He uses a Mac but I’m sure you can achieve much the same on other OS’s.

Customers who purchased X also purchased Y

August 4th, 2006

Coming home to the Cowboy book coverThis recommendation by Amazon, that just arrived in my email inbox, is either one of those smug moments when you kid yourself into thinking “ha, see, even the big guys get it wrong” or Amazon knowing more about me than I realise…

“Dear Amazon.com Customer,

We’ve noticed that customers who have purchased Head First HTML with CSS & XHTML (Head First) by Elisabeth Freeman also purchased books by Patricia Thayer. For this reason, you might like to know that Patricia Thayer’s Coming Home To The Cowboy (Silhouette Romance) will be released soon.”

I like the “people who purchased X also purchased Y” feature when it works but this is a not the best example of it in action.

Similarly, if you’ve ever bought anything from iTunes, you may have noticed a “Just for you” section appears with tunes you may be interested in based on your past purchases. All is well until you buy a tune by “The Veronicas” for your daughters (honest!) and from then on you’re doomed. Just for you: “Hilary Duff”, Just for you: “The Pussycat Dolls”, Just for you: “High School Musical”, etc., until you Just switch it off. What they need is the “I like/don’t like it” feature that Pandora has.

Anyway, I have a cowboy waiting for me, The Veronicas playing in my head and an excited anticipation of the kind of traffic the keywords in this article will pull in!

RewriteRouter and Zend_Config play together

July 18th, 2006

While getting the hang of the Zend_Controller_RewriteRouter, which is now included in Zend Framework 0.1.5, I was adding the routes in my index.php (bootstrap) file and wondered if there was any way of storing them elsewhere. It is possible to loop over Zend_Controller_RewriteRouter::addRoutes() but the method I will describe here is based on some recent updates to Zend_Controller_RewriteRouter by its author Michael Minicki.

The point of RewriteRouter is to map urls, like ingredients.com.au/recipe/tomato_sambal, to whatever controller, action and parameters needed without having to use external (and often painful!) methods like mod_rewrite.

For the sake of this article I’ll use a relatively simple URL…

ingredients.com.au/articles/cooking/

First setup some routes in a config file “routes.php”. Note that this does require the latest version of the RewriteRouter which needs to be checked out from the subversion repository

$config['routes']['articles'] = 
new Zend_Controller_Router_Route('articles/:category', 
array('category' => 'all', 
       'controller' => 'articles', 
       'action'      => 'index' ), 
       array('category' => '[a-z_]+') );

This establishes a route called “articles” that will respond to any url of the form “/articles/whatever” with the colon in :category indicating that it is an url variable that can be recovered through Zend_Controller_Action::_getParam( ‘category’ ). The controller and action indexes make the action “indexAction” in the controller file “ArticlesController.php” the final target. To cover cases where there is no category specified the default setting “all” is given. For extra assurance :category has to be a string containing only lower case letters and underscores as indicated by the final requirements array.

Next load them into the bootstrap file using Zend_Config_Array:

$routes = new Zend_Config( 
        Zend_Config_Array::load( 
       '../application/configuration/routes.php', 'routes' ) );

Then create the RewriteRouter object and pass it the $routes…

$router = new Zend_Controller_RewriteRouter;
$router->addRoutes( $routes );

All that is needed now is to pass the $router to the front controller…

$controller = Zend_Controller_Front::getInstance();
$controller->setRouter( $router );

That’s it, now the routes are nicely stored outside of the bootstrap file and with the rest of the domain files.

Further Reading

Aside from the manual pages mentioned I can’t close without pointing to an actual recipe for tomato sambal !!

Endnote

I should also mention that it’s well worth getting involved with the development of the framework even if you can only do so in a small way. After a relatively short discussion via the issue tracker about having some means to load routes in one hit, Michael Minicki had implemented one (thanks Michael).

Mr Dizzy, Getters/Setters and Constructors

July 17th, 2006

Mr Dizzy“Mr Dizzy was to be quite honest, not very clever.”

One day, while refactoring a web application from procedural to object oriented code, Mr Dizzy decided to use constructors in a way that anyone in Cleverland would have pointed out was really not very clever.

While Mr Dizzy was building his user class he decided that it would be useful to have getPermissions() and getOrganisations() methods. These methods needed to make a query or more to the database to get the information they needed.

Mr Dizzy thought it might be a good idea to have the setters for these methods in a constructor so that when he needed a User object it would have gathered all the necessary information and was ready to go, so, he added setPermissions() and setOrganisations() methods.

“Great”, thought Mr Dizzy, and he proceeded to use his new user object. His idea seemed to be working well so he decided to use the same idea in his Organisation class so it could also get its own permissions on call. “Even better”, thought Mr Dizzy, “I can’t wait to show this to the other programmers in Cleverland”.

Before taking a trip to Cleverland, Mr Dizzy decided to finish off some code to allow him to show a list of users. This list included using many instances of his newly built user class.

Can you guess what happened?

Of course, every time a new user object was created so too was a new organisation object and so too was a new permissions object and all of these objects made database queries. Before long hundreds of queries had been made to the database, all hidden away nicely in constructors.

Luckily for Mr Dizzy he had done his usual trick of missing the last bus to Cleverland and had also recently installed the Zend_Db_Profiler which showed just how silly he had been before anyone else could see.

From that day on Mr Dizzy knew to be very careful when deciding what to do within constructors.

Obvious, but necessary disclaimer

Surprised as you may be, Roger Hargreaves, the original author of the excellent Mr Men series of children’s books, did not in fact author any of the above. Nor, unfortunately, was it narrated by Arthur Lowe, but I’d recommend that if you know his voice then you imagine him doing so.

Mr Dizzy is obviously copyright and I probably shouldn’t be messing with the classics, so if there are any copyright objections then I’m happy to alter this tribute. I do recommend that even if you don’t have kids you should own at least one Mr Men or Little Miss book if only for the great graphics!

Finally, I, of course, would never do something as silly as Mr Dizzy!