📜 ⬆️ ⬇️

Lazy load modules bootstrap

Many, like me, use the Modules resource, which allows using separate Bootstrap files for each module. But this resource has one drawback - it always loads all Bootstrap files regardless of the kind of modules we use in a particular request. I decided to provide a solution to this problem.

To begin, slightly change 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;
}
}

The code is simple to ugliness. 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 $ options
** /
public function __construct ($ options = null ) {
if ($ options! == null ) {
$ this -> setOptions ($ options);
}
}

/ **
* Implement configurable object pattern
* param array $ 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 function _getFront ()
{
return Zend_Controller_Front :: getInstance ();
}
/ **
* Return is module run
* param string $ module
* return bool
* /
public function isBootsraped ($ module)
{
return isset ($ this -> _ bootstrapedModules [$ module]);
}


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

/ **
* Format a module name prefix
*
* param string $ name
* return string
* /
protected function _formatModuleName ($ name)
{
$ name = strtolower ($ name);
$ name = str_replace (array ( '-' , '.' ), '' , $ name);
$ name = ucwords ($ 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 plugin, we handle the preDispatch event, in which we load and run Bootstrap for the current module, if it was not loaded before.

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



Enjoy using

Source: https://habr.com/ru/post/76975/


All Articles