API Documentation for PHP 5.3

If you are like me, then you’ve probably just gone to run your latest library code through phpDocumentor, only to get a bunch of problems all to do with namespaces. But fear not! After a round of tedious searching I finally found a solution, PHPDoctor. Well, it’s actually a fork version I found on GitHub. It operates pretty much identically to phpDocumentor but all your configurations are stored in an INI file and it has no web interface.

The only bad thing about PHPDoctor is it’s output. I found the default output to be a little boring, so I’ve gone through and copied a few elements from one of the phpDocumentor’s frames templates. PHPDoctor doesn’t have modular templates like phpDocumentor, and having to modify PHPDoctors code was a chore – it’s source code is disgusting… The other thing it is missing is the JavaScript TreeMenu.

Enough blabbering, here is my custom version of PHPDoctor with namespace support. Included is a basic Phing task as well, because I am such a nice fellow.
Cobby’s PHPDoctor

If anyone is interested, I would be keen on making a new API doc generator in PHP 5.3 with some actual coding standards.

May 22, 2010 Posted Under: PHP   Read More

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