Archive for the ‘Plugins’ Category

Plugins in Zend Framework

Thursday, September 1st, 2011

There is no way you haven’t noticed that the Zend Framework documentation is pure garbage, almost every example they have is useless, there is no context, lacks of more in depth case of use and the quickstart makes you wonder if you really need to use something so complex to create something so simple.

I visit the crappy documentation for a quick reference, then I search for a more detailed explanation on google and 90% of the time there will be a link to a page that clearly explains the functionality I’m searching for and even goes deeper into some subjects.

Ok, enough of my complaints, let’s get to business.

One project I worked recently used the following approach for reusable constructor methods.

It creates a base controller with most common methods and all other controllers inherit from that base controller.

This looks like a good idea. Pretty simple and functional but then I came across this page.

As you can read it encourages others to use the helpers and plugins instead of a base controller. Even though at first it sounds like the base controller approach is justifiable you’ll later realize that helpers or plugins are a better option.

In my case there is a part of the app reserved for logged users so I needed to check the permissions to see if the controller should show something or ask a user to log in.

I read Matthew’s post and decided to go along with this approach. The whole explanation is right there, nevertheless it’s missing a little bit of info regarding the plugins/helpers folder location and how to make them available for your application.

I wanted my app folder schema to be consistent so I decided I’ll have my helpers and plugins folders under the application one.

Next thing to do is make them available; I did this in the bootstrap by adding the following method:

<?php
    protected function _initAutoloader(){
        $moduleLoader = new Zend_Application_Module_Autoloader(array('namespace' => '', 'basePath' => APPLICATION_PATH));
        $moduleLoader->addResourceType('Plugin', 'plugins', 'Plugin');
        $moduleLoader->addResourceType('Helper', 'helpers', 'Helper');
        return $moduleLoader;
    }
?>

Ok, so now both paths are available so every plugin or helper class will be found under those directories.

The following step is to create a plugin and a helper.

My plugin is quite simple: if a session namespace exists it would mean my user is registered and then I would like to set a couple of view variables like the user’s email.

Please note the event I used. This took me to figure out why.

The file is called: registered.php under plugins folder as formerly stated.

<?php
class Plugin_Registered extends Zend_Controller_Plugin_Abstract{
    public static $doNotValidate = false;
    public function postDispatch(Zend_Controller_Request_Abstract $request){
        if(!self::$doNotValidate){
            if(!Zend_Session::namespaceIsset('credentials')){
                //Oops! user isn't logged in, get them somewhere else!
                $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper('redirector');
                $redirector->gotoUrl('/');
            }
            else{
                //Nice! Proceed but set some variables first
                $namespace = new Zend_Session_Namespace('Credentials');
                //Get the view
                $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('viewRenderer');
                if (null === $viewRenderer->view) {
                    $viewRenderer->initView();
                }
                $view = $viewRenderer->view;
                $view->email = $namespace->email;
                //Use the following line when view resource is given in application.ini (resources.view[]...)
                //Zend_Controller_Front::getInstance()->getParam('bootstrap')->getResource('view')->email = $namespace->email;
            }
        }
    }
}
?>

You’ll need to register the plugin and this is really easy.
Again get to the bootstrap. I typed the following code as pointed out by Matthew (it’s within the bootstrap).

<?php
    protected function _initPlugins(){
        $front = Zend_Controller_Front::getInstance();
        //Check if user is logged in
        $front->registerPlugin(new Plugin_Registered());
    }
?>

Now your plugin is registered.
Some static and public available pages won’t need to do this validation, so the controller body would look something like this:

<?php
class IndexController extends Zend_Controller_Action{
    public function preDispatch(){
        Plugin_Registered::$doNotValidate = true;
    }

    public function indexAction(){
        $this->view->headLink()->appendStylesheet($this->view->baseUrl('css/index.css'));
        $this->view->headScript()->appendFile($this->view->baseUrl('js/jquery.js'));
    }

    public function logoutAction(){
        Zend_Session::destroy();
        $this->_redirect('/');
    }
}
?>

The trick here is the preDispatch method. What happens is that it sets the flag before the plugin executes and so the plugin works as expected. If you need a controller to validate a user then you don’t have to set that flag.

Matthew’s post was enlightening. I’m starting to feel more comfortable with ZF now.

Helpers work pretty much the same. I’ll post it later.