Deprecated Behaviour

The inane, sometimes insane, ramblings from the mind of Brenton Alker.

Building a Modular Application in Zend Framework - Part 2

Welcome to part two of the series exploring the modular application structure in Zend Framework. With the basic application set up in part one, we can get down to actually creating our first module. We’re going to refactor the official quickstarts guestbook. This will let us focus on the modular structure without getting bogged down in business logic.

Note, there are still some bugs in Zend_Tool that prevent this working as it should, I will note the bugs and their fixes as we encounter them.

Create the module

From the base path of our application (/WORKING/PATH/aza from the last article), we can issue the command to the Zend_Tool CLI to create our guestbook module.

zf create module guestbook

Then, create the index controller within the guestbook module.

zf create controller index 1 guestbook

The “1” argument tells Zend_Tool that we want to automatically create an index action within the new controller. We can get a help listing like this:

zf create controller ?

Once the new module and controller is created we need to tell the application that we are using modules. We do this by adding two lines to the configs/application.ini. The first activates the modules resource. The second configures the front controller, telling it where the modules are located. These lines should be added to the end of the production section of the .ini file.

resources.modules = ""
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"

To check our module is working, we can navigate to our guestbook at http://aza/guestbook and we should see the default view for the index action.

Bug: Zend_Tool doesn’t prefix the controller names within the module name. The guestbook index controller class IndexController needs to be changed to Guestbook_IndexController. Bug: The default view for the controller is the same as the main page, it shouldn’t be but we don’t really care, we’re going to replace it anyway.

Create module bootstrap

In the same way that the Bootstrap.php set up the environment for our main application (also known as the default module) each module has its own Bootstrap.php that adds anything additional that each module needs. Zend_Tool doesn’t create this bootstrap by default, so we need to create application/modules/guestbook/Bootstrap.php and it should contain.

1
2
3
4
<?php
class Guestbook_Bootstrap extends Zend_Application_Module_Bootstrap
{
}

By creating this file, the application will automatically perform module bootstrap tasks such as adding autoloaders for the default resources; including models, forms and services. Any other module specific bootstrapping tasks can be added as _init*() functions. In our case, we don’t need any further bootstrapping.

Important note: All bootstrap functions for every module are run for every request.

The bootstrap process occurs before routing and dispatch, so during bootstrap there is no way to know which module/controller/action is being requested. Therefore, any setup that should be done only if a particular module is requested should be done in plugins, not bootstrap.

Getting Quickstart

Now we have the module skeleton in place, lets start porting the guestbook code to our module. This turns out to be fairly easy; the majority of the changes involve prefixing class names with the module name.

To make life easy, start by acquiring a copy of the completed quickstart application (it’s on the right hand side in zip or tar.gz form).

Importing Quickstart

Once you have downloaded and extracted the files into a temporary folder, we can start copying in the files we need.

We need to copy the GuestbookController from the Quickstart (making it the IndexController) and all of the Quickstart models, views and forms to the appropriate places within our module.

From (Quickstart)To (Aza)

application/controllers/GuestbookController.php

application/modules/guestbook/controllers/IndexController.php

application/models/* application/modules/guestbook/models/

application/views/scripts/guestbook/* application/modules/guestbook/views/scripts/index/

application/forms/* application/modules/guestbook/forms/

The controller and the views will require overwriting the existing files.

Porting Quickstart

Now we have the files in the right place, we need to update the files to be modular.

We’ll start with the easiest one, the form. It is simple because it is already prefixed for the Default module, all we need to do it change the prefix to Guestbook_. So the class in application/modules/guestbook/forms/Guestbook.php changes from Default_Form_Guestbook to Guestbook_Form_Guestbook.

Now the models. There are many more changes here but they are just as simple because the models (like the form) are already prefixed with “Default”, but the classes also contain references to each other, so we need to change more than just the class names. A simple search and replace of “Default” with “Guestbook_” in the application/modules/guestbook/models/ directory is all we need.

The controller is a little trickier because it isn’t already prefixed (controllers in the default module aren’t), but it’s still not too hard. The name of the class in application/modules/guestbook/controllers/IndexController.php just needs to be changed from GuestbookController to Guestbook_IndexController, as it has changed from the guestbook controller within default module (no prefix) to the index controller within the guestbook module. We also need to update the references to the models and forms, the same search and replace as we used in the models will suffice.

Finally, we get to the view. In our index view (application/modules/guestbook/views/scripts/index/index.phtml) we need to update the parameters passed to the url helper to reference our controller. Adding the module, and changing the controller leaves the first link looking like this:

1
2
3
4
5
6
7
8
<p><a href="<?php echo $this->url(
    array(
        'module'    => 'guestbook',
        'controller' => 'index',
        'action'     => 'sign'
    ), 
    'default', 
    true) ?>">Sign Our Guestbook</a></p>

Done!

Connect the database

I’ll leave the actual creation of the database to you. It is he same as the Quickstart and this post is already particularly long. You will need to create the database, and add the configuration to the application.ini.

Conclusion

We have just ported the Quickstart guestbook application to a Zend Framework Module. Modularizing applications allows for easier code reuse across applications. Hopefully modules will become standardized to the point that there will be a repository of modules that can be added to your application and providing drop in functionality.

Download

For those who had trouble following along, I’ve made the entire application (including database) available via my github repository.