hey,

this is how i tried to solve this:

i set the directories the same way you did. created an
application/controllers/IndexController.php with IndexController class that
represents the route for '/'.
then i created an application/controllers/admin/IndexController.php with
Admin_IndexController class that represents the correct routes for '/admin'.

so when you call for /, it should use the IndexController/indexAction and
when you call for /admin, it should use the
Admin_IndexController/indexAction.

for assurance, i made application/controllers/ArticlesController.php with
ArticlesController class that would represent the route for /articles.

the first two routes worked, while the last one didnt.
i was using the stable 0.7.0 release and i realized it was time for an
update. so i checked out the latest files from the svn repository and took a
look at the new files and documentation. after a while, i revised my
index.php with the following:

Zend::loadClass( 'Zend_Controller_ModuleRouter' );
Zend::loadClass( 'Zend_Controller_ModuleDispatcher' );

...

$frontController->setControllerDirectory( array( 'default' =>
'./application/controllers',
                                                'admin'   =>
'./application/controllers/admin' ) );
$frontController->setRouter( new Zend_Controller_ModuleRouter() );
$frontController->setDispatcher( new Zend_Controller_ModuleDispatcher() );

at this point, routes for '/admin' AND '/articles' worked as expected. BUT
the route for '/' got me a weird error of not being able to FIND
IndexController.php file:

*Fatal error*: Uncaught exception 'Zend_Exception' with message 'File "
IndexController.php" was not found.

after some looking, i figured out that the pretty easy way to solve this for
good would be to modify the set_include_path, so it would include a
directory to default module controllers:

set_include_path( '.' . PATH_SEPARATOR . '../ZendFramework/library'
               . PATH_SEPARATOR . './application/controller/'
               . PATH_SEPARATOR . get_include_path() );

but i somehow felt this wasnt very pragmatic so i kept diggin in the core
files and classes and finally came to an interesting conclusion (at least
for me):

In the dispatch() method of the Zend_Controller_Dispatcher class, $className
for the '/' route is obviously empty, so the _getDefaultControllerName()
method is called, which is actually overriden in
Zend_Controller_ModuleDispatcher, where it ends up with Null
dispatcherdirectory array (_curDirectory) due to invalid moduleName (which
is actually valid only in the case of '/admin' route, as the 'default'
module is clearly considered invalid).
as the dispatcher-directory array is null, the following call to loadClass
method in Zend_Controller_Dispatcher's dispatch() method fails with the
above-mentioned error.

i even found this easy to fix, by changing a small piece of code in
ModuleDispatcher.php:

change this (around line 287):

       } elseif ($useGlobalDefault && $validModule) {
           $dirs = $this->getControllerDirectory();
           $this->_curDirectory = $dirs['default'];
       }

to this:

       } else { //if ($useGlobalDefault && $validModule) {
           $dirs = $this->getControllerDirectory();
           $this->_curDirectory = $dirs['default'];
       }

and now the whole thing works as originally expected.
im not sure if this fix is actually the correct one, so ill stick with the
set_include_path solution for now.


good luck
SHY

2007/1/23, Philip Iezzi <[EMAIL PROTECTED]>:

some additions...
Even after Matthew's corrections in revision 2958, the new named module
support doesn't seem to work as it is supposed to (in my opinion).

$controller = Zend_Controller_Front::getInstance();
$controller->setParam('useModules', true);
$controller->setControllerDirectory('../application/controllers');
$controller->addControllerDirectory('../application/controllers/Admin',
'admin');

If I call any of the following: "/" or "/index" or "/index/index" or even
IndexControllers in my modules, e.g. "/admin/" or "/admin/index", I always
get the following exception:

Fatal error: Uncaught exception 'Zend_Exception' with message 'File "
IndexController.php" was not found.' in
D:\frameworks\zend\library\Zend.php:175
Stack trace:
#0 D:\frameworks\zend\library\Zend.php(103):
Zend::loadFile('IndexController...', Array, true)
#1 D:\frameworks\zend\library\Zend\Controller\Dispatcher.php(585):
Zend::loadClass('IndexController', NULL)
#2 D:\frameworks\zend\library\Zend\Controller\Front.php(731):
Zend_Controller_Dispatcher->dispatch(Object(Zend_Controller_Request_Http),
Object(Zend_Controller_Response_Http))
#3 D:\vhosts\projects\airpane\htdocs\index.php(82):
Zend_Controller_Front->dispatch()
#4 {main}
  thrown in D:\frameworks\zend\library\Zend.php on line 175

It will find all other controllers, so e.g. "/index/customers" is fine and
calls the CustomersController in
"../application/controllers/CustomersController.php".
Another sample: "/admin/mailing" will correctly call the
Admin_MailingController in
"../application/controllers/Admin/MailingController.php".
I tried to add a "Default_|Index_" prefix to all non-modular controller
class names - no success!!

If I reactivate my manually defined router, everything works fine!...

$mainRoute = new
Zend_Controller_Router_Route(':module/:controller/:action/*', array('module'
=> 'index', 'controller' => 'index', 'action' => 'index'));
$router = new Zend_Controller_RewriteRouter();
$router->addRoute('mainroute', $mainRoute);
$controller->setRouter($router);

Before your change last night, I was able to use module support with the
default route by just specifying $controller->setParam('useModules', true);
And besides, with my own router it works though, but it's a bit annoying
to call "/index/index/action" instead of "/index/action" ("index" was never
defined as a module and is not found in a module directory. Anything that
doesn't match a named module should be found in the default controller
directory set in
$controller->setControllerDirectory('../application/controllers'); and
treated as a controller.
Correct me if I'm wrong.

take care
Philip


Reply via email to