Howto make pages controller like in CakePhp with Zend_Action_Controller
CakePhp framework comes with controller class extension called PagesController , this extension serves very productive propose , it checks what actions was called and renders view template with same name .
For example if user accesses url http://micrub.info/pages/examples/ , the controller should search for view template in PagesController views directory , like app/views/pages/examples.ctp , if page isn’t found 404 headers should be returned to the browser .
This approach is very MVC oriented , person which is responsible to add new static content to a view layer doesn’t depends on programmer , he simple adds or removes a new pages without any need to have access to the businesses logic layer , working with which demands much deeper understanding of the web development field .
One of the first things that I have done when started to work with Zend Framework was to create same future within Zend Framework based project template .
In order to provide such a future , Zend_Controller_Action class was extended , magic php function __call() was overwritten in order to create proxy method which checks for existing view template and handle exceptions like :
- template is not found , return HTTP 404
- other application exception , return HTTP 500
Why is __call() function was overwritten ?
When Zend_Controller_Action extended class is dispatched and action function isn’t defined in it , php’s magic function __call() is called . Its default implementation throws Zend_controller_Action exceptions and if front controller bootstrapped not to throw exceptions )( $front->throwExceptions(false); ), ErrorController is set , a proper HTTP statuses can be returned to the browser for PagesController exceptions .
require_once 'Zend/Controller/Action.php'; class PagesController extends Zend_Controller_Action { /** * Checks if view template file is found in one of script paths for this controller . */ protected function checkScript($name) { $paths = $this->view->getScriptPaths(); foreach ($paths as $dir) { $path2script = $dir . str_ireplace('/',DIRECTORY_SEPARATOR,$name); <strong>// for some reason , without this one action name isn't compatible on winXP </strong> if (is_readable($path2script)) { return true; } } return false; } /** * Proxy for undefined methods. Default behavior is to throw an * exception on undefined methods, however this function was * overridden to provide run-time dispatching. * * @param string $methodName * @param array $args */ public function __call($methodName, $args) { if ('Action' == substr($methodName, -6)) { // Zend_Controller_actions methods name must be formatted like this "exampleAction". $action = substr($methodName, 0, strlen($methodName) - 6); $script = $this->getViewScript($action); if(!$this->checkScript($script)){ throw new Zend_Controller_Action_Exception(sprintf('Pages Action script "%s" does not exist and was not trapped in __call()', $script), 404); } }else{ throw new Zend_Controller_Action_Exception(sprintf('Illegal action name "%s" was called and not trapped in __call()', $action), 500); } } }
Comments
Leave a Reply