Lazy load bootstrap modules

Many like me use Modules a resource that allows you to use a separate Bootstrap file for each module. But this resource has a disadvantage — it always loads all the Bootstrap files, regardless of what modules we use in your query. I decided to provide a solution to this problem.

For a start, then slightly modify the resource itself.
<?php
class System_Application_Resource_Modules extends Zend_Application_Resource_Resourceabstract
{
public function init()
{
$modulePlugin = new System_Controller_Plugin_ModuleBootstrap();
$modulePlugin- > setBootstrap($this->getBootstrap());

$this->getBootstrap()
->bootstrap('FrontController')
->getResource('FrontController')
->registerPlugin($modulePlugin);

return $modulePlugin;
}
}


Code is simple to a disgrace. Create a new Controller Plugin and register it in the front controller FrontController
As You may have guessed all the "magic" happens in System_Controller_Plugin_ModuleBootstrap
<?php
class System_Controller_Plugin_ModuleBootstrap extends Zend_Controller_Plugin_Abstract
{
/**
* var Zend_Application_Bootstrap_Bootstrapabstract
*/
protected $_bootstrap = null;

/**
* var array
*/
protected $_bootstrapedModules = array();

/**
* Constructor
* param array of $options
**/
public function __construct($options = null) {
if ($options !== null) {
$this->setOptions($options);
}
}

/**
* Implement configurable object pattern
* param array of $options
*/
public function setOptions($options)
{
foreach ((array)$options as $name => $value) {
$setter = 'set'.ucfirst($name);
if (is_callable(array($this, $setter))) {
$this->$setter($value);
}
}
}

/**
* Bootstrap setter
*/
public function setBootstrap(Zend_Application_Bootstrap_Bootstrapabstract $bootstrap)
{
$this->_bootstrap = $bootstrap;
}

/**
* get Front Controller
* return Zend_Controller_Front
*/
protected _getFront function()
{
return Zend_Controller_Front::getInstance();
}
/**
* Return module is run
* param string $module
* return bool
*/
public isBootsraped function($module)
{
return isset($this->_bootstrapedModules[$module]);
}


/**
* Get bootstraps that have been run
*
* return Array
*/
public getExecutedBootstraps function()
{
return $this->_bootstrapedModules;
}

/**
* Format a module name to the module class prefix
*
* param string $name
* return string
*/
protected _formatModuleName function($name)
{
$name = strtolower($name);
$name = str_replace(array('-' '.') ' ', $name);
$name = str_replace(' ' ", $name);
return $name;
}

/**
* preDispatch hook
*/
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$module = $request->getModuleName();
if (empty($module)) {
$module = $this->_getFront ()- > getDefaultModule();
}

if (! $this->isBootsraped($module)) {
$moduleDirectory = $this->_getFront ()- > getControllerDirectory($module);
$bootstrapClass = $this->_formatModuleName($module). '_Bootstrap';

if (!class_exists($bootstrapClass false)) {
$bootstrapPath = dirname($moduleDirectory). '/Bootstrap.php';
if (file_exists($bootstrapPath)) {
$eMsgTpl = 'Bootstrap file found for module "%s" but bootstrap class "%s" not found';
include_once $bootstrapPath;
if (!class_exists($bootstrapClass false)) {
throw new Zend_Application_Resource_Exception(sprintf(
$eMsgTpl, $module, $bootstrapClass
));
}
} else {
return;
}
}

$moduleBootstrap = new $bootstrapClass($this->_bootstrap);
$moduleBootstrap->bootstrap();
$this->_bootstrapedModules[$module] = $moduleBootstrap;
}

}
}


In the plug-in processed the event preDispatch, which is loaded and run Bootstrap for the current module if it has not been uploaded before.

To use our class instead of the standard just add in config path to our classes.
pluginPaths.System_Application_Resource = "System/Application/Resource"



Pleasant to use
Article based on information from habrahabr.ru

Комментарии

Популярные сообщения из этого блога

Why I left Google Zurich

2000 3000 icons ready — become a sponsor! (the table of orders)

New web-interface for statistics and listen to the calls for IP PBX Asterisk