Archive for the “Zend Framework” Category

Zend Framework Action Helpers and Namespaces

In my current Zend Framework project, I am using PHP 5.3’s namespaces for all my library code (It makes sense considering I’m using Doctrine 2 and will attempt to upgrade to ZF 2 when it’s released). I have come across a few compatibility issues when trying to use namespaces, mostly with Zend’s PluginLoader and Phing. Below is how I have my action helpers setup:

site/
  library/
    Cob/
      Controller/
        Action/
          HelperBroker.php
          Helper/
            Myhelper.php
            HelperAbstract.php

HelperBroker.php

<?php

namespace Cob\Controller\Action;

use \Zend_Controller_Action_HelperBroker;

/**
 * Custom implementation of the HelperBroker to provide namespace support
 *
 * @author Andrew Cobby
 */

class HelperBroker extends Zend_Controller_Action_HelperBroker {

    /**
     * Add a namespace prefix (works the same as Zend_Helper_BrokerBroker::addPrefix()
     *
     * @param string $prefix Namespace prefix
     */
    static public function addNamespacePrefix($prefix)
    {
        $prefix = rtrim($prefix, '\\') . '\\';
        $path = str_replace('\\', DIRECTORY_SEPARATOR, $prefix);
        $path = rtrim($path, '/');
        self::getPluginLoader()->addPrefixPath($prefix, $path);
    }

    /**
     * Adds an array of helpers
     *
     * @param array $helpers Helpers
     */
    static public function addHelpers(array $helpers)
    {
        foreach($helpers as $helper){
            parent::addHelper($helper);
        }
    }

}

HelperAbstract.php

<?php

namespace Cob\Controller\Action\Helper;

use \Zend_Controller_Action_Helper_Abstract;

/**
 * Abstract helper for namespaced action helpers
 *
 * @author Andrew Cobby
 */

class HelperAbstract extends Zend_Controller_Action_Helper_Abstract
{

    /**
     * Fix to get the correct helper name (Overrides Zend_Controller_Action_HelperAbstract::getName)
     *
     * @return string
     */
    public function getName()
    {
        $className = get_class($this);
        if(strpos($className, '\\') !== false){
            $helperName = strrchr($className, '\\');
            return ltrim($helperName, '\\');
        }elseif(strpos($className, '_') !== false){
            $helperName = strrchr($className, '_');
            return ltrim($className, '_');
        }else{
            return $className;
        }
    }

}

Myhelper.php

<?php

namespace Cob\Controller\Action\Helper;

/**
 * Example helper that uses namespaces
 *
 * @author Andrew Cobby
 */

class Myhelper extends HelperAbstract
{

    public function direct()
    {
        return 'Namespaces are cool!!';
    }

}

Before you starting using this, you will need to add your namespace prefix in our new HelperBroker:

<?php

namespace Cob\Controller;

use \Zend_Controller_Action;
use \Cob\Controller\Action\HelperBroker as HelperBroker;

class Action extends Zend_Controller_Action
{

    public function preDispatch()
    {
        HelperBroker::addNamespacePrefix('Cob\Controller\Action\Helper\\'); // remember 2 trailing slashes to fix the escaping
        $coolio = $this->_helper->Myhelper(); // calling a helper is still the same
    }
}

As you can see, the only real part of the compatibility issue is overriding HelperAbstract::getName(), the methods in HelperBroker are more just for convenience.
Hope this helps!

May 22, 2010 Posted Under: Zend Framework   Read More