Issues

ZF-12350: Function preDispatch called twice in case of module specific bootstrap

Issue Type: Bug Created: 2012-07-27T09:35:25.000+0000 Last Updated: 2012-07-27T16:05:43.000+0000 Status: Resolved Fix version(s): Reporter: Piotr Deszyński (piteer1) Assignee: Ryan Mauger (bittarman) Tags: - Zend_Application

Related issues: Attachments:

Description

This bug occures while using modular ZF1 structure and module specific Bootstrap class. To reproduce this bug:

  1. Create empty ZF1 project (I was using ZF Tool) and make it default modular structure.
  2. Add following settings into application.ini:
<pre class="literal">
resources.frontController.moduleDirectory   = APPLICATION_PATH "/modules"
resources.modules[] =
  1. Add to default module empty boostrap class:
<pre class="literal">
<?php

class Default_Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
}
  1. Create any FrontController Plugin with preDispatch method and add it using application.ini for e.g.:
<pre class="literal">
resources.frontController.plugins.dispatchTest = "Test_Controller_Plugin_DispatchTest"

From now on preDispatch method will be called more than once. This leads to confusion.

To fix this behaviour it's needed to remove module specific Bootstrap.

Expected behaviour:

PreDispatch called only once.

Comments

Posted by Ryan Mauger (bittarman) on 2012-07-27T09:43:59.000+0000

This sounds more like the common problem of not having a favicon.ico, or another missing file which is referenced in the output html (like a link to a stylesheet which is broken).

Could you clarify how you are determining that preDispatch is called twice?

Please also note, that preDispatch will also be called more than once on requests involving the error controller, or any use of _forward in a controller, or if you change the requested controller / action, as all of these methods involve running a second iteration of the dispatch loop.

I'm going to close this issue as preDispatch being called more than once is expected behaviour in many circumstances.

Please provide a clear, reproduce case, and documentation of how you are observing preDispatch being called more than once if you wish to re-open, so that we can rule out all of the legitimate use cases where this is normal behaviour.

Posted by Piotr Deszyński (piteer1) on 2012-07-27T13:45:02.000+0000

I tried this while using curl instead of a browser (so this shouldn't make favicon.ico request). Additionally it's like I wrote: when you remove module specific Bootstrap, everything behaves like it should. There is no _forward call, there is no error either.

I will write again how to reproduce this bug:

  1. Create new empty ZF project (using ZF tool) in zf1-project directory
  2. cd zf1-project
  3. mkdir application/modules/default
  4. mv application/controllers application/modules/default
  5. mv application/views application/modules/default
  6. Create test plugin:
<pre class="literal">
<?php

class Test_Controller_Plugin_Test extends Zend_Controller_Plugin_Abstract {

    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        var_dump('pre dispatch');
    }
}

and put it into file 'library/Test/Controller/Plugin/Test.php'

  1. Add following settings into application.ini:
<pre class="literal">
autoloaderNamespaces.Test = "Test_"
resources.frontController.moduleDirectory   = APPLICATION_PATH "/modules"
resources.modules[] =
resources.frontController.plugins.test = "Test_Controller_Plugin_Test"
  1. Create Bootstrap class for default module:
<pre class="literal">
<?php

class Default_Bootstrap extends Zend_Application_Bootstrap_Bootstrap {
}

and put this code into 'application/modules/default/Bootstrap.php'

  1. Open a browser or use cURL to test (for e.g. localhost/zf1-project/public) the text 'pre dispatch' will be seen twice.

Posted by Piotr Deszyński (piteer1) on 2012-07-27T14:00:11.000+0000

Additionally you can change Plugin class to:

<pre class="literal">
<?php

class Test_Controller_Plugin_Test extends Zend_Controller_Plugin_Abstract {

    private static $_preDispatchCalled = 0;

    public function preDispatch(Zend_Controller_Request_Abstract $request) {
        self::$_preDispatchCalled++;
    }

    public static function getDispatchCalled() {
        return self::$_preDispatchCalled;
    }
}

And run a test:

<pre class="literal">
<?php

class IndexControllerTest extends Zend_Test_PHPUnit_ControllerTestCase
{

    public function setUp()
    {
        $this->bootstrap = new Zend_Application(APPLICATION_ENV, APPLICATION_PATH . '/configs/application.ini');
        parent::setUp();
    }

    public function testPreDispatchOnce() {
        $this->dispatch('/');
        $this->assertTrue(Test_Controller_Plugin_Test::getDispatchCalled() === 1);
    }


}

This test will fail whether it shoulnd't have

Posted by Ryan Mauger (bittarman) on 2012-07-27T14:22:26.000+0000

Given the steps you outlined, there are no controllers in your new 'default' module, so there would have been a controller not found exception, looping the request to the error controller. try creating application/modules/default/controllers/IndexController.php and in it put:

<pre class="highlight">
<?php

class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->getHelper('viewRenderer')->setNeverRender(true);
    }
}

This should make your test pass (it does for me). Also, this is expected behaviour.

Posted by Ryan Mauger (bittarman) on 2012-07-27T14:36:47.000+0000

Additionally, I've just noticed I did one thing different from you when creating the test, I used Zend_Application_Module_Bootstap as the bootstrap for the 'default' module as it is a module bootstrap the way you have used it. Having two or more Zend_Application_Bootstrap_Bootstrap bootstraps will cause unexpected problems also, as this is not its intended use.

You would save yourself some pain by not having a 'default' module in the modules directory, as this really isn't the way that your application will behave anyway.

Posted by Piotr Deszyński (piteer1) on 2012-07-27T16:05:43.000+0000

Yes, thank you. probably that was the cause. Sorry for the problem.

Have you found an issue?

See the Overview section for more details.

Copyright

© 2006-2016 by Zend, a Rogue Wave Company. Made with by awesome contributors.

This website is built using zend-expressive and it runs on PHP 7.

Contacts