Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to integrate ezComponents with magento

in a 'native' Zend Framework application I would enable the use of ezComponents by adding the autoloader of ezComponents to Zends autoloader:

$autoLoader = Zend_Loader_Autoloader::getInstance();
require_once('../library/EZComponents/Base/src/base.php');
$autoLoader->pushAutoloader(array('ezcBase', 'autoload'), 'ezc'); 

Now, I'm wondering how I could do the same with Magento. Is there a way to extend Varien_Autoload (magentos autoloader) to enable easy integration of ezComponents? OR: Is there a way to use Zends autoloader beside the one from Magento without interfering each other?

edit:

Well, I implemented a workaround, by adding the following to function autoload() in Varien_Autoload:

if(substr($class, 0, 3) == 'ezc'){
        require_once('EZComponents/Base/src/base.php');
        return ezcBase::autoload($class);

    }

I consider this as a very bad hack though, because it will be overwritten, when upgrading Magento. Does anyone has a better idea?

like image 714
volka Avatar asked Nov 03 '10 10:11

volka


1 Answers

My basic approach here would be to create a custom module with an observer for the

controller_front_init_before

event. In the event observer, you'd be able to setup your autoloader however you want. There's a Magento Wiki article on Setting up Event Observers. The controller_front_init_before event is one of the first non-generic events to fire in Magento. That's why we're using it.

The big problem we need to solve is this: Magento's autoloader is on the stack first, and if it doesn't find a file (which will be the case with the EZComponent classes), its include will raise a error that will halt execution.

So, what we need to do in our event observer above is to

  1. Remove the Varien_Autoloader from the spl_autoload stack

  2. Register our own autoloader (we'll use Zend_Autoloader, since it ships with Magento and you seem familiar with it)

  3. Re-add the Varien_Autoloader to the stack

There'll be a little extra jiggery-pokery we'll need to do since loading of the classes in the Zend namespace is normally handled by the autoloader we'll be removing. See comments for more details

//we need to manually include Zend_Loader, or else our zend autoloader
//will try to use it, won't find it, and then try to use Zend_Loader to
//load Zend_Loader
require_once('lib/Zend/Loader.php');


//instantiate a zend autoloader first, since we 
//won't be able to do it in an unautoloader universe
$autoLoader = Zend_Loader_Autoloader::getInstance();        

//get a list of call the registered autoloader callbacks
//and pull out the Varien_Autoload.  It's unlikely there
//are others, but famous last words and all that
$autoloader_callbacks = spl_autoload_functions();
$original_autoload=null;
foreach($autoloader_callbacks as $callback)
{
    if(is_array($callback) && $callback[0] instanceof Varien_Autoload)
    {
        $original_autoload = $callback;
    }
}

//remove the Varien_Autoloader from the stack
spl_autoload_unregister($original_autoload);

//register our autoloader, which gets on the stack first
require_once('library/EZComponents/Base/src/base.php');
$autoLoader->pushAutoloader(array('ezcBase', 'autoload'), 'ezc');           

//lets just make sure we can instantiate an EZ class
#$test = new ezcBaseFile();
#var_dump(get_class($test));

//IMPORANT: add the Varien_Autoloader back to the stack
spl_autoload_register($original_autoload);      

Put the above code in an observer method and you should be good to go.

The other approach you could take, one that would fit in more with Magento patterns, would be to create a custom module that implemented an EZComponent loader.

$o = Mypackage_Mymodule_Loader::getModel('ezcBaseFile');

You'd then implement autoloader style require code in your static getModel method, and use it whenever you wanted an ezcBaseFile class. You'd probably want methods for loading a class without instantiating an object in case you wanted to call a static method on an ezcBaseFile base class.

$o = Mypackage_Mymodule_Loader::getLoadclass('ezcBaseFile');
like image 62
Alan Storm Avatar answered Nov 15 '22 11:11

Alan Storm