views:

1275

answers:

2

I've setup my application with Zend_Application. I have an _initAutoload() method in my Bootstrap.php wich looks like this:

 public function _initAutoload(){
     $this->bootstrap("frontController");
     $front = $this->frontController;

     $autoloader = Zend_Loader_Autoloader::getInstance();

     $autoloader->registerNamespace('Client_');
     $autoloader->registerNamespace('Frontend_');
     $autoloader->registerNamespace('Global_');
     $autoloader->registerNamespace('Global_Helper_');
     $autoloader->setFallbackAutoloader(true);

     $modules = $front->getControllerDirectory();
     $default = $front->getDefaultModule();

     foreach (array_keys($modules) as $module) {
         if ($module === $default) {
             continue;
         }

         $autoloader->pushAutoloader(new Zend_Application_Module_Autoloader(array(  
             "namespace" => ucwords($module),
             "basePath" => $front->getModuleDirectory($module),
         )));

     }

     return $autoloader;  
 }

I have setup FrontController to prefix the default module also (seems more logical to me) $front->setParam("prefixDefaultModule", true)

I think I have the usual directory structure.

The problem:

I've set up subdomains for every module that I have. Everything works fine in the main main domain (www). The main module is frontend. If frontend is the default module then stuff works :). Ok. Now. For every subdomain, I have the same index.php but theres changed the env value. For client subdomain the env value is client etc. Each env value corresponds to my application.xml section. Each application.xml subdomain section (client, api, etc) extend the main section which is called defaults (currently theres a testing section also which enables errors etc, so every subdomain extends testing and testing extends defaults).

Each subdomain section of the application.xml changes the default module name. So for section defaults its frontend, for section client its client, etc.

Now
When I access domain.com/client or domain.com/api - its fine. Both API & Client use Client_Model_NameOfTheModel and like it supposed to - it's located application/modules/client/models/NameOfTheModel.php and the DbTable/NameOfTheModel.php WORKS

BUT When I access the the module from its respective subdomain (client.domain.com, api.domain.com, etc) and the default module has been changed from frontend to its respective subdomain module name - it ends working. It even doesn't output that "stack trace".

Warning: include(Client/Model/ContactLists.php) [function.include]: failed to open stream: No such file or directory in [heres-my-path-to-root]/library/Zend/Loader.php on line 136

Warning: include() [function.include]: Failed opening 'Client/Model/ContactLists.php' for inclusion (include_path='[heres-my-path-to-root]/library:.:/usr/lib/php:/usr/local/lib/php') in [heres-my-path-to-root]/library/Zend/Loader.php on line 136

Fatal error: Class 'Client_Model_ContactLists' not found in [heres-my-path-to-root]/application/modules/client/controllers/ContactListsController.php on line 4

I've tried 2 days to get it working. It just doesn't. It just works under the default domain and doesn't when the application.xml changes its default module to its subdomain name. Like that. This point is very very crucial currently because I can't continue and this app needs to be out of sandbox (in early beta) by the end of this week.

Thanks for anyone for some advice.
PS. Sorry for the poor English. It isn't my native tongue

A: 

This is just a cursory guess, but it looks like it might be working on default because of these lines:

 $autoloader->setFallbackAutoloader(true);

 $modules = $front->getControllerDirectory();
 $default = $front->getDefaultModule();

 foreach (array_keys($modules) as $module) {
     if ($module === $default) {
         continue;
     }

Essentially, if your module is the default module it skips it, which means it falls back to the fallback autoloader i would assume, and if the default autoloader cant find your models, well theres the issue. Is the concat of the root path in the error and the path of the class its trying to load correct?

Also, this looks like it might be wrong

         "namespace" => ucwords($module),

I would think it would need to be

         "namespace" => ucwords($module) . "_",

Like your other namespaces.

devians
Okay! It gets now weirder. I've commented out the following /* if($module === $default) { continue; } */ Now thats funny! Really funny actually. Bootstrap.php can access any model. I've set up this little check in _initAutoloader's end: $check = $autoloader->autoload("Client_Model_ContactLists"); var_dump($check);exit; //Outputs boolean | So im now in subdomain client.domain.com and run this with the lines that were mentioned commented out and the return is **TRUE**. If those lines were uncommented then the return is **FALSE** also under domain.com thats also **TRUE** (w. module === default)
DJRayon
Oh and autoloader seems to add the ."_" by itself. Atleast when I var_dump that.This is my current _initAutoloader(): http://pastie.org/private/6meikpb05jv7csowbhxhgq. This is the var_dump of the current autoloader when it works in bootstrap (new modelname()), but gives an error in controller Fatal: no modelname() found: http://pastie.org/private/aqvq2hsxdyieheges5b6qg
DJRayon
So the current round up is that: without those lines (module === default) Bootstrap.php itself can load any model in any subdomain (that means that what ever the default module is set: client, api, frontend, etc) but when it reaches to a controller and controller tries to reach a model - it fails.
DJRayon
Oh and I removed all the namespaces. Left just one **Global_**. That also maybe caused some problems. I just merged those libraries and namespaces.
DJRayon
A: 

Which version of ZF are you using?

Are you using a later 1.8 - 1.10 version?

If so, you should be using the resource in Zend_Application for a module. It sets up autoloading for forms, models, helpers, etc under your modules.

If you are using an application.ini you should have a line like this for each module :

resources.modules.module_name = "enabled"

http://framework.zend.com/manual/en/zend.application.available-resources.html#zend.application.available-resources.modules

Travis
Using 1.9.7. The Zend_Application_Module_Autoloader should setup autoloading for module. I give a module path to frontController. FrontController reads that path and determines what modules are available. Then it I request the front and ask what modules did it found from the directory. I then foreach them to autoloader with Zend_Application_Module_Autoloader wich sets up autoloading for forms, models, etc under $key module.
DJRayon