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 :

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