Using a Plugin to Integrate Propel with Zend

Background

In his article
“Integrating propel with the Zend Framework” , Ralph Eggert explains how one could integrate propel to his Zend application. It’s interesting to see how an _autoload php function can be used to automatically load needed classes (propel,or Zend classes) and thus avoid having to explicitly include the propel files in every controller that would need access to the model.

From there

One area that the article did not mention was, how does the app know which model will be used? I mean, let’s say a client clicks on the link “controller/action”, do I have to wait for the front controller to dispatch the request to the controller before knowing that it was called? That is, the model is known explicitly by my app only when I’m in the requested action.

Before going further we have to make some assumption about our application. We will assume that each controller relates to one entity in our model. For example, the “apple” controller is the “apple” model’s controller.

A use case

Let’s say I want to apply business logic that involves one or more additional entity in the model before the controller’s action is called. Then I would need to know the controller(thus the model) mentinoned in the request URL before the action is actually dispatched.

Using A Plugin

The Zend Framework plugin system provides a solution to this problem. The solution involves writting a plugin and registering it. The Zend Framework documentation says it better than me:

The controller architecture includes a plugin system that allows user code to be called when certain events occur in the controller process lifetime. The front controller uses a plugin broker as a registry for user plugins, and the plugin broker ensures that event methods are called on each plugin registered with the front controller.

The event I’m looking for is the routeShutdown event. It means that the router has done parsing the request URL and has populated the Request object with the controller name and action name. At this point I can use this code $controllerName = $this->getRequest()->getControllerName(); to get the controller name.

From there on, the logic really depends on what you want to achieve and the naming convention of your model classes, among others. In my case, I renamed the ORM generated classes so that they have the same name as the controllers, only that they are camel cased. In fact I use the propel generated model classes as the abstraction layer to the database. The business logic, I will call the model service. This is what is done to the data that propel will give me from the database.Hence I could have controller ‘user’ ,model ‘User’, and model service ‘UserService’ . Here is the code for my plugin:

class ModelPlugin extends Zend_Controller_Plugin_Abstract
{
public function routeShutdown(Zend_Controller_Request_Abstract $request)
{
$controllerName = $this->getRequest()->getControllerName();
$modelClass = ucwords($controllerName).'.php';
$modelServiceClass = ucwords($controllerName).'Service.php';

if (file_exists('path/to/your/app/propel/generated/files/modelClass'))
{
require_once($modelClass);
}

if (file_exists('path/to/your/app/modelServiceClass'))
{
require_once($modelServiceClass);
}
}
//don't forget to add the remaining functions of
//Zend_Controller_Plugin_Abstract. Empty function
//stubs will do.
}

Conclusion

Integrating Propel to the Zend Framework has its advantages. For example oyu do not have to write all the base code to access the data base. The relations between the entities of your model is enforced by Propel. It is easy to add wanted behaviour from there. Using third party software can be made easy with ZF plugin system. Actually I use a plugin for the View also.