Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Step-by-step conversion to module-based folder structure for zend project

I'm looking for a step-by-step explanation on how to go from the normal folder structure on the left where the application folder contains models,views,controllers, to the module-based folder structure on the right where application contains a modules folder which contains the individual modules with their own models,views,controllers.

I say "conversion" because I don't think zend lets us create projects using the module architecture from the start, but if it did, that would be swell and would remove the need to make these folder structure changes manually.

http://img375.imageshack.us/img375/5582/foldersboth.jpg

Here's my experience so far

  • When I create a module zf create module product, the modules folder is generated and a folder product is generated inside it and the views,controllers,models for that module are also generated.

  • But I also need to move the main views,controllers,models to a modules/default folder of their own. If I create that folder manually and move the main views,models,controllers there, I get a bug when trying to add new controllers to that default module. The bug is that it re-generates the main (now missing) views,controllers,models in application and inserts that new controller in application/controllers/newcont because it doesn't recognize that the default controllers folder has been moved manually to application/modules/default/controllers/.

  • So my solution to that has been to zf create module default then copy the main views,models,controllers there. It ends up looking the same but somehow the zf create module method makes a difference. When I do it this way, new controllers get added correctly into application/modules/default/controllers and not application/controllers

Half the problem solved. But when I try to view the application, I don't see anything from index/index view. I don't get any errors either, but I see nothing. I suspect that it's because the application doesn't know that the index/index view has moved.

  • This used to be located at application/views/scripts/index/index.phtml
  • but is now located at application/modules/default/views/scripts/index/index.phtml

I'm guessing I need to make changes to application.ini or to bootstrap.php or some other location. So what exactly are the steps to get this thing done smoothly and get it working? I'm using the latest ZF 1.10.8. Please start from create a new zend project so there's no confusion on the exact steps.

like image 511
jblue Avatar asked Oct 12 '10 06:10

jblue


2 Answers

Here's what I did to try and follow your example (from scratch):

$ zf create project .
$ zf create module product
$ zf create module default

I then moved controllers, models and views from ./application to ./application/modules.

Next I opened up application.ini, and replaced this line (which tells ZF where to find controllers in a non-modular app):

resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"

with:

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"

which tells ZF where to find modules.

I then manually created an index controller for the product module so I could test that this worked, which it did. I then hit http://localhost/index/index to see if the default module index action still worked, it didn't, instead I got the error:

Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller class ("Default_ErrorController")' in ...

it sounds like this is where you got to.

There are two ways to fix this error, and the documentation is quite misleading (possibly even wrong). It states:

Note that in the default module, controllers do not need a namespace prefix. Thus, in the example above, the controllers in the default module do not need a prefix of 'Default_' -- they are simply dispatched according to their base controller name: 'IndexController' and 'FooController'. A namespace prefix is used in all other modules, however.

but clearly the error above indicates that ZF is looking for an ErrorController class called Default_ErrorController. To fix this you can do one of two things:

  • Change the class names of application/modules/default/controllers/IndexController.php from IndexController to Default_IndexController, and application/modules/default/controllers/ErrorController.php from ErrorController to Default_ErrorController
  • Or remove this line:

    resources.frontController.params.prefixDefaultModule = "1"

from application.ini. This line tells ZF to use the 'Default_' namespace on the default module classes, so without it it will just look for 'IndexController'. I went for the latter option, and http://localhost/index/index then worked as expected.

In your case you said you got a blank page at /index/index, which means either:

  • You have a different problem
  • You have errors disabled in development mode
  • You are running in production mode where errors are disabled by default (most likely)

to check the last option, open application.ini and temporarily change phpSettings.display_errors from 0 to 1 in the production section. If you then get the same error I had above, hopefully you'll be able to get everything working.

I hope this is helpful. All I can say is don't get too reliant on Zend_Tool for management of your app - it can't do everything, and often it's easier to manually move things around than to try and do everything via. the zf command; particularly when restructuring.

like image 159
Tim Fountain Avatar answered Nov 11 '22 21:11

Tim Fountain


Well I dev in Netbeans IDE.

http://i.stack.imgur.com/n9Zjn.jpg

Im a newbie :P ( need 10 points)

Each Bootstrap should have :

<?php 
// Public_Bootstrap replace for Blog_Bootstrap or Administrator_Bootstrap
// well its for me
class Public_Bootstrap extends Zend_Application_Module_Bootstrap {

}

Main Bootstrap:

<?php
    class Bootstrap extends Zend_Application_Bootstrap_Bootstrap {

       protected function _initAutoLoad() {

          $modLoader = new Zend_Application_Module_Autoloader(
                    array(
                        'namespace' => '',
                        'basePath' => APPLICATION_PATH . '/modules/public'
                    )
          );        

          return $modLoader;
       }
       public function _initViewHelpers() {

          $this->bootstrap(array('frontcontroller', 'view'));
          $view = $this->getResource('view');
          $view->doctype('XHTML1_STRICT');
          $view->headMeta()->appendHttpEquiv("Content-Type", "text/html;charset=UTF-8")
            ->appendName("description", "Some description");
     }
  }

application.ini :

[production]
resources.modules[] =
phpSettings.display_startup_errors = 0 
phpSettings.display_errors = 0
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php" 
bootstrap.class = "Bootstrap" 
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts/"

resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.defaultmodule = "public" 
resources.frontController.prefixDefaultModule = true  

resources.view[] = 

resources.db.adapter = PDO_MYSQL
resources.db.isDefaultTableAdapter = true 
resources.db.params.host ="localhost"
resources.db.params.username ="yourUser"
resources.db.params.password ="yourPassword"
resources.db.params.dbname ="DBName"

My bootstrap have more code, including plugings.

like image 31
jd_7 Avatar answered Nov 11 '22 22:11

jd_7