Tag Archives: zend framework

Default Error Handling in Zend Framework

Zend_Controller_Action_Exception

There’s a cool feature in Zend Framework when a controller or action doesn’t exists. That’s really useful, because you simply write an ErrorController.php in you default module and every action’s exception sends the user to this controller/action and the job is done for you. What is important here is to show the error message at least on the development stage. Actually the request stores it as a parameter. Here’s some source:

<?php
 
class ErrorController extends Zend_Controller_Action
{
    public function errorAction()
    {
        $errorHandler = $this->getRequest()->getParam('error_handler');
        /* @var $error Zend_Controller_Action_Exception */
        $error = $errorHandler->exception;
        echo $error->getMessage();
    }
}

Zend Framework: Simple Acl Front Controller Plugin

access with Zend_Acl

Almost every web site need some abstraction over the access control list (ACL) to grant access of its users. As usual Zend Framework has quite good mechanism to deal with this – Zend_Acl.

Out in the web there are a lot of resources about Zend_Acl’s usage, so I ain’t going to cover it one more time, but simply copy/paste a very small front controller plugin implementing the basic usage of Zend_Acl.

Note that instead of defining the __construct() here is called preDispatch where the request is passed as a parameter. However only by copy pasting not every answer will be given. That’s why I’m going to write more about Zend_Acl in my future posts, for now only the source code:

<?php
 
class AclInit extends Zend_Controller_Plugin_Abstract
{
    public function preDispatch(Zend_Controller_Request_Abstract $request)
    {
        // create new acl object
        $acl = new Zend_Acl();
 
        // define resources. typically there are
        // only four resources from the CRUD functionality
        // but there can be added more resources
        $acl->add(new Zend_Acl_Resource('index'))
            ->add(new Zend_Acl_Resource('create'))
            ->add(new Zend_Acl_Resource('read'))
            ->add(new Zend_Acl_Resource('update'))
            ->add(new Zend_Acl_Resource('delete'));
 
        // define roles
        $acl->addRole(new Zend_Acl_Role('guest'))
            ->addRole(new Zend_Acl_Role('admin'));
 
        // define privileges
        $acl->allow('guest', array('index', 'read'))
            ->allow('admin');
 
        // setup acl in the registry for more
        Zend_Registry::set('acl', $acl);
 
        // check permissions
        if (!$acl->isAllowed('guest', $request->getActionName())) {
            $request->setControllerName('error');
            $request->setActionName('error');
        }
    }
}

Bind Zend Action with Non-Default View – Part 2

Typical Setup

Typically Zend Framework is setup to bind every controller’s action to a specific view. The names of the action and the view script must be the same, or at least must be similar – following the ZF’s convention.

Thus if you name an action, let’s say, indexAction(), you’ve to create an index.phtml file into the views/scripts/index/ folder. Let me remind you that this is what is called a typical setup, but this may vary from one installation to another.

Thus everything’s fine and the MVC does its best. After the user requests a specific uri, the framework parses it and finds the controller, than the action and than the view script – and there is a view script for every single action.

typical zend framework setup

When there are two or more actions – there are two or more .phtml (view scripts) files.

typical zend framework setup for two or more actions

Some Exceptions

Sometimes you have very similar logic, but very different markup between two actions. As the logic goes to the controller/action and the markup into the view, the question is can you simply have one action in the controller, but with two different .phtml file as a view scripts? Of course switching between those two (or more) with some conditionals.

Solution No. 1

However once I posted a simple, and working, solution. There you have again two actions and two scripts:

<?php
 
class IndexController extends Zend_Controller_Action
{	
	public function firstAction()
	{
		// place all the logic you need here
		// and every view placeholder assignment
		$this->view->title = "My Title";
 
		// if the logic requires a different markup
		// simply redirect to another view
		if (some_expression) {
			$this->_forward('second');	
		}	
	}
 
	public function secondAction()
	{}
}
 
// in the application/views/scripts/index
// 1. first.phtml
<h1><?php echo $this->title ?></h1>
 
// 2. second.phtml
<h2><?php echo $this->title ?></h2>

As you can see in the second action there’s no logic – it’s only serving the role of a bridge between the views. Everything is setup into the first action, but the second action is doing the relation with the second.phtml view script.

Solution No. 2

However there’s another solution with only one action and two scripts which makes something like that shown on the diagram bellow:

zend framework one action multiple=

The only thing to do is to add some code to your action:

<?php
 
class IndexController extends Zend_Controller_Action
{	
	public function firstAction()
	{
		// place all the logic you need here
		// and every view placeholder assignment
		$this->view->title = "My Title";
 
		// if the logic requires a different markup
		// simply redirect to another view
		if (some_expression) {
			echo $this->view->render('index/second.phtml');
			$this->_helper->viewRenderer->setNoRender(true);
		}	
	}
}
 
// in the application/views/scripts/index
// 1. first.phtml
<h1><?php echo $this->title ?></h1>
 
// 2. second.phtml
<h2><?php echo $this->title ?></h2>

Note that you’ve to setNoRender on the view renderer once you render the other script!

Zend Examples: GET Parameters Default Value

PHP Style

As you may know in PHP you can access everything in the request uri by accessing the global $_GET array. If there is something like that in the browser’s address field: www.example.com/index.php?controller=index&action=test, you can simply get the values by that:

echo $_GET['controller']; // this will print "index"
echo $_GET['action'];     // this will print "test"

Zend Framework, Uri & Request Params

If you code with Zend Framework, you should know already, and that’s perhaps the first thing you’ve learned about Zend, that $_GET params can be accessed by calling the requrest’s getParam() method. But first of all the request uri will be different. The Zend’s convetion is to place after the domain name first the module name (which is omited when there’s only one module), than the controller’s name followed by the action and the key value pairs of all parameters. In that scheme the request uri above will look like that:

http://www.example.com/index/test

Here the keywords “controller” and “action” are omitted. This is cool – it’s more user friendly and it definitely helps the SEO.

Get the $_GET

Once the uri is setup like so – /index/test you can access it via the Zend way:

echo $this->getRequest()->getParam('controller'); // this will print "index"

The cool thing is that in the first case you don’t have any prevention of a missing value, while in the second case there is a second parameter or the getParam() method that does this job. What if the uri is www.example.com/index.php?controller=&action=test than by printing the $_GET[‘controller’] you’ll get nothing. In other hand even this:

echo $this->getRequest()->getParam('action');

won’t return “test” if the uri is http://www.example.com/index/

Note: actually here the default “index” action will be referenced!

That’s where the power of the framework comes. In the first case the solution is:

echo (empty($_GET['controller']) ? 'default': $_GET['controller']);

while in Zend there’s more elegant solution:

echo $this->getRequest()->getParam('action', 'test');

Thus when the action param is missing the “test” value is considered as default! Very useful!

Joomla! – Old Code or Bad Code?

Recently I started managing a small system based on Joomla 1.0.15. I know there is a most recent version of the popular CMS, but this one wasn’t based on it. Actually once upon a time I was working with Joomla as basic CMS for my web projects, but now after two+ years with Zend Framework and MVC I was amazed to see how bad the Joomla 1.0.15 was written.

Indeed it is really strange to see all SQL, HTML and PHP all in one file?! This is like end of ’90s! That’s for sure a bad approach.

I’ll download the 1.5 version with the hope the code there will be better!