ZF-6458: Zend_Application_Resource_Frontcontroller overwrites multiple controller directories

Description

This is in reference to ticket ZF-6244, which I believe was misunderstood. Because Zend_Controller_Front::setControllerDirectory() clears any existing controller directories every time that it is invoked, using the foreach loop in Zend_Application_Resource_Frontcontroller:54, only the last directory in the array of controller directories will remain set, regardless of the uniqueness of the module => directory pairs you pass in. The solution that I see for this issue is to remove the foreach loop in the front controller resource, and just pass in the array (setControllerDirectory() accepts an array by default). I am using revision 15243 (1.8.0dev)

Comments

This is a patch removes the condition check for if $value is a string and just passes $value to Zend_Controller_Front::setControllerDirectory().

What's odd is that setControllerDirectory() is not written such that it should overwrite -- and yet I just verified that it does.

As a workaround until this is fixed, I'd recommend keeping your modules under a common directory, and using the moduleDirectory configuration key instead of controllerDirectory.

I was mistaken when I first made the report. It's not in Zend_Controller_Front::setControllerDirectory(). It's actually in Zend_Controller_Dispatcher_Standard::setControllerDirectory(). It's the first line of the method, and it assigns an empty array to $this->_controllerDirectory. Apologies for the confusion. :)

IMHO this is a very high priority bug: for existing ZF based applications with multiple modules it's nearly impossible to upgrade to the 1.8 release.

To make the problem even more clear: using the new Zend_Application, if you create an .ini file with these lines:

{{[production]}} {{includePaths.library = APPLICATION_PATH "/../library"}} {{bootstrap.path = APPLICATION_PATH "/Bootstrap.php"}} {{bootstrap.class = "Bootstrap"}} {{resources.frontController.controllerDirectory.default = APPLICATION_PATH "/default/controllers"}} {{resources.frontController.controllerDirectory.module1 = APPLICATION_PATH "/module1/controllers"}}

than the Application_Resource_Frontcontroller invokes the Frontcontroller's setControllerDirectory which in turn invokes the Dispatcher method setControllerDirectory which resets the internal __controllerDirectory_ array each time it's called.

The solution is really simple: Application_Resource_Frontcontroller should use addControllerDirectory in stead of setControllerDirectory. For your convenience I've attached a patch file.

Fixed in trunk and 1.8 release branch.