Integrate Propel with Zend the Easy Way
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 entity referenced by the request is known explicitly by my application only when the requested action code is about to be executed.
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.
Use case
Let’s say I want to apply business logic that involves one more additional models(or should I say entity in the model?) before the controller’s action is called. Then I would need to know the controller(thus the model) mentinoed in the request URL before the 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 is 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:
public function routeStartup(Zend_Controller_Request_Abstract $request)
{
//$this->getResponse()->appendBody("<p>routeStartup() called</p>\n");
}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);
}
}
public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
{
//$this->getResponse()->appendBody("dispatchLoopStartup() called\n");
}
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
//$this->getResponse()->appendBody("preDispatch() called\n");
}
public function postDispatch(Zend_Controller_Request_Abstract $request)
{
//$this->getResponse()->appendBody("postDispatch() called\n");
}
public function dispatchLoopShutdown()
{
//$this->getResponse()->appendBody("dispatchLoopShutdown() called\n");
}
}
Tags: PHP, Propel, Zend Framework
You can comment below, or link to this permanent URL from your own site.