Details
-
Type:
Bug
-
Status:
Resolved
-
Priority:
Major
-
Resolution: Won't Fix
-
Affects Version/s: 1.8.3
-
Fix Version/s: None
-
Component/s: Zend_Application
-
Labels:None
Description
Behaviour:
In Zend_Application_Resource_Modules::init(), all Bootstrap classes for all modules are loaded, regardless of what module was requested.
Effect:
This has the following side-effect: config ini keys that are set for each module are overwritten by each module when its bootstrap() method is called. The (unwanted) result is that the key is set for the last module encountered, not for the module requested.
Example:
setting layout resource in the config ini:
resources.layout.layout = "default" resources.modules[] = extranet.resources.layout.layout = "extranet" intranet.resources.layout.layout = "intranet"
Also the module paths are not set explicitly, but by only setting
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
That means modules are registered in the order they are encountered when iterating through the modules directory.
Result:
the layout is set to 'intranet', even if the default or extranet module were requested.
Suggested solution:
Zend_Application_Resource_Modules::init() should check for the requested module and only instantiate that bootstrap class.
The problem is that the request is not yet set in the frontcontroller when this is run. Is there a workaround?
If the request was set, it could be something like this:
the foreach starting on line 65:
foreach (array_keys($modules) as $module) {
if ($module === $default) {
continue;
}
...
}
should be changed to:
$current = $front->getRequest()->getModuleName();
foreach (array_keys($modules) as $module) {
if ($module === $default) {
continue;
}
if ($module === $current) {
continue;
}
...
}
Issue Links
| This issue is related to: | ||||
| ZF-7095 | Zend_Application_Resource_Modules Example is wrong |
|
|
|
That's indeed a bit unclear how the modules resource is tied to the actual application modules.
A solution could be to delegate the role of bootstrapping the modules to a plugin on routeShutdown.
This can be done by replacing the following line in Zend_Application_Resource_Modules
by this one
and creating a Zend_Controller_Plugin_ModulesBootstrapper plugin as follows:
class Zend_Controller_Plugin_ModulesBootstrapper extends Zend_Controller_Plugin_Abstract { public function routeShutdown(Zend_Controller_Request_Abstract $request) { $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap'); $bootstraps = $bootstrap->getResource('modules'); $module = $request->getModuleName(); if (isset($bootstraps[$module])) { $bootstraps[$module]->bootstrap(); } } }Although the side effects of this method need to be evaluated.
class Zend_Controller_Plugin_ModulesBootstrapper extends Zend_Controller_Plugin_Abstract { public function routeShutdown(Zend_Controller_Request_Abstract $request) { $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap'); $bootstraps = $bootstrap->getResource('modules'); $module = $request->getModuleName(); if (isset($bootstraps[$module])) { $bootstraps[$module]->bootstrap(); } } }