Issues

ZF-6545: Zend_Application_Module_Bootstrap doesn't work

Description

I think, that problem lies in constructor where is never calling parent class (Zend_Application_Bootstrap_Bootstrap) for initializing front controller. When I insert to constructor on first line calling parent class, modules then works fine.

Comments

I'm reading this request not as it doesn't work, but as a feature request to have Zend_Application_Module_Bootstrap extend Zend_Application_Bootstrap_Bootstrap instead of Zend_Application_Bootstrap_BootstrapAbstract.

Ooops -- it already does, and is simply missing the call to parent::__construct(), as you note in your comment. Fixing.

Patched in trunk and 1.8 release branch.

After this patch, my app doesn't work. No error trapped neither blank screen, only the message from firefox "can't found the page".

I have the standard modular structure:

application Bootstrap.php ----Configs --------application.ini modules --------default --------------controllers --------------models --------------views --------module1 --------------Bootstrap.php --------------controllers --------------models --------------views --------module2 --------------Bootstrap.php --------------controllers --------------models --------------views library public

The main bootstrap.php extends Zend_Application_Bootstrap_Bootstrap (only one method to _initLogger), and the bootstrap module's extends Zend_Application_Module_Bootstrap without any method.

And application ini, contains this settings:

phpSettings.display_startup_errors = 0 phpSettings.display_errors = 0

bootstrap.path = APPLICATION_PATH "/Bootstrap.php" bootstrap.class = "Bootstrap"

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" resources.frontController.plugins.debug = "Scienta_Controller_Plugin_Debug"

resources.modules[] =

autoLoaderNameSpaces.0 = "Scienta"

I'm reading the tests for this issue, but don't understand what's the real problem. If I include this revision the application can't run, but if revert to previous everything works.

Thanks in advance. PS: a posibility to show how to configure a modular application with Zend_application and autoad resources?

First, change your autoloaderNamespaces entry to read:


autoloaderNamespaces[] = "Scienta"

IIRC, numeric keys are not allowed in Zend_Config.

Second, the reason you're not seeing any error messages is because you've told PHP not to display them. Change your display_*errors settings:


phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1

and this will give you a hint as to any issues you're having.

Third, make sure your error_reporting is as strict as possible. You can do this by adding the following to your config:


phpSettings.error_reporting = 8191

Do all of the above, and you should get some indicators as to what's occurring.

Sorry about showing you only the "production" section of my application.ini. "Development" it's the running section that inherits "production" and add this settings:

phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
phpSettings.error_reporting = 8191

Replaced numeric keys with array notation:

autoloaderNamespaces[] = "Scienta"

The result is the same: the server shutdown without any clue about it (neither apache logs, nor php logs). If I revert the commit everything work again.

Thanks

ok, I've found that this error only happens when I have this setting in the ini file:

 
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"

If I reduce the memory_limit from my php.ini, I get the "memory exhausted" error in Zend/Loader/Autoloader/Resource.php on line 257

that's the unique error I can see, otherwise the server crash.

I can't say I've run into this issue myself, nor heard of any similar reports. Is it possible that you don't have any directories under modules? or that there's a recursive symlink in there?

First all, thanks for your attention.

I've tried with several environments (including windows OS and Linux) and checked symlinks already. It's a very, very little app without any other logic than test modules autoloader and Zend_Application. If you want to look into, this is the link.

http://bit.ly/10GaXw

Thanks in advance

hi,

You can find more information in the mailing list: [http://nabble.com/Adding-Zend_Application_Module_B…]

I am running into this as well (rev 15472).

When using multiple controller directories and Zend_Application_Module_Bootstrap bootstraps it recurses through...

{main}( ) ../index.php:0 Zend_Application_Bootstrap_BootstrapAbstract->bootstrap( ) ../index.php:49 Zend_Application_Bootstrap_BootstrapAbstract->_bootstrap( ) ../BootstrapAbstract.php:518 Zend_Application_Bootstrap_BootstrapAbstract->_executeResource( ) ../BootstrapAbstract.php:558 Zend_Application_Resource_Modules->init( ) ../BootstrapAbstract.php:615 Zend_Application_Bootstrap_BootstrapAbstract->bootstrap( ) ../Modules.php:84 Zend_Application_Bootstrap_BootstrapAbstract->_bootstrap( ) ../BootstrapAbstract.php:518 Zend_Application_Bootstrap_BootstrapAbstract->_executeResource( ) ../BootstrapAbstract.php:558 Zend_Application_Resource_Modules->init( ) ../BootstrapAbstract.php:615 Zend_Application_Bootstrap_BootstrapAbstract->bootstrap( ) ../Modules.php:84 Zend_Application_Bootstrap_BootstrapAbstract->_bootstrap( ) ../BootstrapAbstract.php:518 Zend_Application_Bootstrap_BootstrapAbstract->_executeResource( ) ../BootstrapAbstract.php:558 Zend_Application_Resource_Modules->init( )

...and so on until reaching Fatal error: Maximum function nesting level of '100' reached, aborting!

Jorge, Chris -- that gives me more information. I'm not sure the diagnosis of the issue is correct, but it at least gives me somewhere to start looking. I'll have this resolved for 1.8.1.

This issue is still present in the rev. 15476

With config of:

[bootstrap] autoloadernamespaces[] = "Zend_" autoloadernamespaces[] = "SF_"

phpsettings.display_errors = 0 phpsettings.error_reporting = 8191 phpsettings.date.timezone = "Europe/London"

bootstrap.path = APPLICATION_PATH"/bootstrap/Bootstrap.php"

resources.frontcontroller.moduledirectory = APPLICATION_PATH"/modules" resources.frontcontroller.defaultmodule = "storefront" resources.frontcontroller.throwexceptions = false resources.frontcontroller.params.prefixDefaultModule = true resources.frontcontroller.plugins.action = "SF_Plugin_Action" resources.frontcontroller.plugins.admin = "SF_Plugin_AdminContext"

resources.db.adapter = "PDO_MYSQL" resources.db.isdefaulttableadapter = true resources.db.params.dbname = "storefront" resources.db.params.username = "root" resources.db.params.password = "root" resources.db.params.hostname = "localhost" resources.db.params.driver_options.1002 = "SET NAMES UTF8;"

resources.modules[] =

global.autoloadersupresswarnings = true

[production : bootstrap]

[development : bootstrap] phpsettings.display_errors = 1 resources.frontcontroller.throwexceptions = true global.autoloadersupresswarnings = false

[test : bootstrap]

I get recursive loop, this is due to the addition of the call to the parent constructor in the module bootstrap in rev. 15357 this now means that all options are passed back re-adding the resource modules option and causing the loop.

The quick fix is to revert the changes from rev.15357, however I think what actually needs to happen is for the modules option to be removed before it is passed back to the parent.

This issue was previously fixed for ZF-6183 in rev. 14738

I had a quick hack at this by adding this to Zend_Application_Bootstrap_BootstrapAbstract:

 
    public function removeModulesOption()
    {
        if ($this->hasOption('resources')) {
            unset($this->_options['resources']['modules']);
            $this->unregisterPluginResource('modules');
        }
    }
} 

And then in the module bootstrap:

 
$application->removeModulesOption();
parent::__construct($application);

This however seemed to break my FC plugin that uses the Action Stack???

Hope this helps track this issue down.

I was never able to reproduce the recursion, but I've added in a call to remove the 'Modules' resource within module bootloaders if it is detected.

I have the same problem. Recursive loop is still present in rev. 15522.

Here it's solved with r15506 (ZF-6545: merge r15505 to 1.8 release branch)

Dmitry -- I have yet to be able to reproduce the recursion based on any of the information available here or via the referenced mailing lists. I have added logic in the base module bootloader to remove the "Modules" resource during initialization if found, as this was identified by somebody else as the issue.

Please, re-open this issue only if you can post a complete setup that reliably reproduces the issue with current trunk.

Jorge, don't you really have this problem now? Well, I see the following fixed code in Zend_Application_Module_Bootstrap:

// ZF-6545: prevent recursive registration of modules if ($this->hasPluginResource('Modules')) { $this->unregisterPluginResource('Modules'); } but I still get the recursive loop. If its works fine for you it means I do something wrong...

Dmitry -- is it possible that your module bootstraps are not extending Zend_Application_Module_Bootstrap?

Incidentally, is it efficient that every Module's Bootstrap constructs Zend_Application_Bootstrap_Bootstrap as parent with the same instance of the application and makes the same resources in them? In this case I supporse the Delegation is better than the Inheritance. Because * Module's Bootstrap should be an inner bootstrap of global bootstrap ,isn't it? * In the case of the Inheritance, The system having many modules should have too many instances of bootstrap.
* If the global bootstrap have resources customized by -- _initFoo -- , they conflict with module's resources.

The Delegation's example,


interface Zend_Application_Bootstrap_ModuleBootstrapper
 extends Zend_Application_Bootstrap_Bootstrapper
{
    public function setBootstrap(Zend_Application_Bootstrap_Bootstrapper $bootstrap);
}

And it must provide properties of the resources with the delegation to the master bootstrap.

@Tomoaki: The application bootstrap could potentially be a module bootstrap instance. As such, having a setBootstrap() instances doesn't make sense -- there is no parent bootstrap.

Second, there will be no conflicts with "global" resources. Each bootstrap is responsible for running its own resources. You can pass these in by prefixing them with the module name, or have your bootstrap grab its own configuration. Any given bootstrap can be responsible for as much or as little bootstrapping as they need.

Third, I don't know what you mean by "too many instances of bootstrap" -- there is one, and then references to that one. (Actually, there will be one for each module, but that's only if the module has a bootstrap, and each module bootstrap is responsible for its own configuration -- which brings us back to the question of what "too many instances" means...)

Confirmed that this issue is fixed in the trunk now :)

However I have one more issue after the parent::__construct() was added, now my FC plugins are being called twice per request??

My setup is available here:

http://code.google.com/p/zendframeworkstorefront/

I have a basic FC plugin which uses the ActionStack this now fails for some reason, and if I echo some text in it in gets called twice instead of once like it should be. If I un-reg the frontcontroller resource everything works as normal:


        // ZF-6545: prevent recursive registration of modules
        if ($this->hasPluginResource('Modules')) {
            $this->unregisterPluginResource('Modules');
            $this->unregisterPluginResource('Frontcontroller');
        }

I will not reopen this issue but if you could check it out that would be cool :)

Thanks,

@Matthew In case the module having its bootstrap class and the application having no extra options for the module,the module's bootstrap and the application's bootstrap are as independent bootstrap and they have the same options. Thus Resource_Modules exec the module's bootstrap->bootstrap(). This causes unfortunately conflicts.

For example: This is a scraping of the sequence.


// application Bootstrap 
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap{
 protected function _initView(){
$view = new Zend_View_Smarty;
// customized code using options 
// and 
// set view to viewRenderer
 return $view;
}
}
// Foo Module's Bootstrap
class Foo_Bootstrap extends Zend_Application_Module_Bootstrap{
protected function _initBar(){} //  initializing some.
}


    $application = new Zend_Application(
        $env,
        array(
            'bootstrap' => '/path/to/Bootstrap.php',
            'resources' => array(
                 'modules' => array(), // to call module bootstrap
                 'view' => array(), // some settings
            ),
        )
    );

// Zend_Application exec below
$bootstrap = new Bootstrap($application);

// Resource_Modules exec below
$module = 'Foo';
$bootstrapClass = 'Foo_Bootstrap';
$moduleBootstrap = new $bootstrapClass($bootstrap);
$moduleBootstrap->bootstrap();
$bootstraps[$module] = $moduleBootstrap;

In this case, setting the view and the viewRenderer by class method - Bootstrap::_initView - . But the module Foo_Bootstrap breaks them unfortunately by a plugin resource so called Zend_Application_Resource_View .-- it creates new view instance and new viewRenderer and push it--. This is the sample of conflicts.

Global resources or static objects have a similar problem. For instance, FrontController resource.

BTW I said "too many instances". In some case the module bootstrap needs the application's resources they have already set. I think that it should be solved by injecting The Application Bootstrap to the module bootstrap. Not by creating new bootstrap instance and making the same resources with the same options.

If the module bootstrap only needs frontController resource , how about this one?


// Module_Bootstrap::__construct
if ($application instanceof Zend_Application_Bootstrap_Bootstrap) {
 $this->frontController = $application->getResource('FrontController');
}

This might be more appropriate as a separate bug, but in case recent changes are related...

Module recursion is fixed, but I am now seeing custom Application Resources being called twice: (r15545)


class Main_Bootstrap_Resource_View extends Zend_Application_Resource_ResourceAbstract
{
    /**
     * @var Zend_View_Interface
     */
    protected $_view;

    /**
     * Defined by Zend_Application_Resource_Resource
     *
     * @return void
     */
    public function init()
    {
        // Return view so bootstrap will store it in the registry
        return $this->getView();
    }

    /**
     * Retrieve view object
     * 
     * @return Zend_View
     */
    public function getView()
    {
        if (null === $this->_view) {
            $options = $this->getOptions();
            $title   = '';
            if (array_key_exists('title', $options)) {
                $title = $options['title'];
                unset($options['title']);
            }

            $view = new Zend_View($options);
            print("

FOO!

"); // Prints twice $viewRenderer = Zend_Controller_Action_HelperBroker::getStaticHelper('ViewRenderer'); $viewRenderer->setView($view); if (isset($options['viewbasepathspec'])) { $viewRenderer->setViewBasePathSpec($options['viewbasepathspec']); } $this->_view = $view; } return $this->_view; } }

./app/lib/Main/Bootstrap.phpMain_Bootstrap./app/lib/Main/Bootstrap/Resource1./app/lib/Test/Controller./app/lib/Main/Controllermain1UTF-8:moduleDir/View./app/lib/Main/View/Helper./app/lib/Main/View/Helper/Navigation

@Chris Martin: I think what you are seeing is related to what @Tomoaki is indicating -- that the module bootstrap is running the same plugin resources as the application bootstrap. I'm going to get this resolved for 1.8.1 today.

@Tomoaki -- I've updated the code to (a) no longer call parent::__construct() (@Chris, @Keith -- this was the culprit behind duplicate resource initialization), and also to ensure the front controller resource is registered (which ensures a module bootstrap can run standalone if necessary).