1
votes

I am trying to create a module for an admin interface but am having trouble getting it to respond at all - What I've done so far is this: I've modified my main application's bootstrap file to load the modules directory:

$modules = PROJECT_DIR . '/library/PHPLib/ZF/Modules';
define('MODULES_DIR', $modules);
$frontController->addModuleDirectory(MODULES_DIR);

The module is contained inside my external PHP library that I re-use for every project, ZendFramework based or not. This is the first time I am adding a module, but previously I had used the library to contain helper classes and plugins with no issues. The structure of the module is contained inside the PHPLib/ZF/Modules and looks like the following:

ModAdmin/
  controller/
    IndexController.php
  model/
  view/
    includes/
    layouts/
    scripts/
      index/
        index.phtml

The IndexController.php class is defined as "ModAdmin_IndexController" as I was instructed in some of the ZF resources I own. The script is present and the layout hasnt been created yet. I am not sure if I am going to use one or not.

So, when I try to request the index of the ModAdmin module in the browser, I get 404. The URL I am using is:

http://hostname/ModAdmin/

Am I missing something? According to some books such as "ZendFramework In Action" and "ProPHP" they say that this is all that is required. When I read that they say it was this simple I almost could not stop from laughing - nothing in ZendFramework is ever ever "that" simple - I like ZF, ALOT, but its not simple. The complexity is there because it is so flexible and powerful.

Anyway - any ideas?

EDIT

I think I should add that I started using ZF long before there was a Zend_Application or Zend_Tool classes - this was before ZF got wise and started emulating RoR style MVC - and in any case - my project does not have any of this because until I started researching about modules I was not even aware of their existence. That being said - I do not have the time to mount the learning curve involved with those and I am quite content manually creating my bootstrap.

Actually - to be honest - I had created a 'deployment tool' called "padmin" which is a CLI run php script that does a lot of what Zend_Tool does - and I use it in conjunction with "phing" which is like "ant" for php - anyway - I got around it, like most people do.

EDIT2

I found this resource that appears to address the adding of modules without the use of Zend_Tool and despite following through with all of the requirements it lays out, I still get a 404 code when requesting the module in the manner described:

http://hostname/modulename/index or http://hostname/modulename/

EDIT3

Well folks - I cant express how frustrating this is. Every resource on the web is either referencing the creation of modules with Zend_Tool/Application or what I end up with only discusses modules in a very specific aspect. I need something that will help me debug why it is that the dispatch / route stage of the FrontController is not finding the module. I have set the modules directory in my bootstrap. The module has a controller and a view script. That is it - it shouldn't need anything more than that. What else does it possibly require? I've tried to add the module's controller directory individually (instead of adding it via 'addModuleDirectory') and still no dice. There is some documentation I mentioned earlier which says:

The rules for matching specify that a module will only be matched if a key of the same name exists in the controller directory array passed to the front controller and dispatcher.

Well - folks - I did just that:

    $defaultControllerDir  = PROJECT_DIR . '/application/controller';
    $modadminControllerDir = PROJECT_DIR . '/library/PHPLib/ZF/Modules/ModAdmin/controller';
$frontController->setControllerDirectory(array(
                                         'default'  => $defaultControllerDir,
                                         'modadmin' => $modadminControllerDir
                                        ));

Yet - no dice. The browser kicks back with 404. It would be nice if the front controller had some kind of internal auditing/logging capacity that I could flip on and watch exactly whats happening (and I suppose I could do that if I wanted to dig into the source and put some print statements, but that's getting ridiculous).

This is absolutely mind-numbing. This happened to me a long time ago when I was first learning ZF - and as documented as it is - when something goes wrong - its very difficult to understand why. Well I am here once again with another issue - I have followed every conceivable instruction (that I found pre-dating zend_tool) and yet nothing is working.

The only thing I havent done is to set up my directory structure like this:

modules/
  default/
    controllers/
    models/
    views/
  custom1/
    controllers/
    models/
    views/

but doing that would completely defeat the purpose of a module right? If I cannot keep my modular module code in a library (i.e. not in the application directory but in an external library) then what the hell is the point of creating the module!? I need to be able to put my module code in my library: '/library/PHPLib/ZF/Modules/ModAdmin' - what gives!

EDIT - In response to Selected Answer

So interestingly enough - after changing the Directory settings of Apache to AllowOverride All then I get your plugin's response to the request for mod-admin instead of a 404 (array(3) { ["module"]=> string(9) "mod-admin" ["controller"]=> string(5) "index" ["action"]=> string(5) "index" }) then if I disable the plugin I get this error:

Fatal error: Uncaught exception 'Zend_Controller_Dispatcher_Exception' with message 'Invalid controller specified (index)' in /home/nevertap/work/nevertap/library/Zend/Controller/Dispatcher/Standard.php:248 Stack trace: #0 /home/nevertap/work/nevertap/library/Zend/Controller/Front.php(954): Zend_Controller_Dispatcher_Standard->dispatch(Object(Zend_Controller_Request_Http), Object(Zend_Controller_Response_Http)) #1 /home/nevertap/work/nevertap/application/configuration/bootstrap.php(100): Zend_Controller_Front->dispatch() #2 /home/nevertap/work/nevertap/application/configuration/bootstrap.php(110): Bootstrap->configureFrontController() #3 /home/nevertap/www/nevertap/index.php(19): Bootstrap->runApp() #4 {main} thrown in /home/nevertap/work/nevertap/library/Zend/Controller/Dispatcher/Standard.php on line 248

which is very strange because .../Modules/mod-admin/controller/IndexController.php exists as does .../Modules/mod-admin/view/scripts/index/index.phtml - not to mention the IndexController class is appropriately prefixed as "ModAdmin_IndexController"

FINAL EDIT

OK I Finally got it - looks like by loading the module directory it looked for the default controller directory which is always patterned as "controllers" and mine was "controller" so instead of loading the Module with addModuleDir i used another:

$modadminControllerDir = PROJECT_DIR . '/library/PHPLib/ZF/Modules/mod-admin/controller';
$frontController->addControllerDirectory($modadminControllerDir, 'mod-admin');
2
From what I understand the idea of modules in ZF 1.x is that they are like mini applications. The intent is for each module to mirror a complete application as much as possible. Usually the default module would be the original folders like global module. Then added modules would be in a module folder below application. I think you can probably make this work the way you want but you may have to almost completely reconfigure the autoloader. Your module structure doesn't conform to the default autoloader so you might to look into that.RockyFord
Rocky - your last observation became an issue over the course of my effort here. When you are adding a module its more important to pay attention to the default auto-loader's standards as the changes made in the bootstrap may only be applied to the main / default application.user124626
so it all came down to an 's', wow! we were all over thinking this.RockyFord
But isn't it always like that? Bugs are usually small things that are overlooked - just like actual bugs :)user124626

2 Answers

0
votes

looks like you still need to initialize the modules, I do it in application.ini with
resources.modules[] = ""
I'm sure you can translate that to bootstrap code.
What you already have is equivalent to
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules" if that gives a clue.

[EDIT] In case it hasn't been mentioned each of your modules should have it's own bootstrap the extends Zend_Application_Module_Bootstrap.

P.S. I just recently worked my through Pro Zend Framework Techniques, I found it has a lot of useful info, but was outdated as far current configuration was concerned and in the some tools are currently used in ZF. Rob Allen maintains an excellent tutorial on ZF that he keeps up to date for current versions at Akrabat.com and Padrig Brady has a great free online book that is fairly current, It's not 100 % complete but is very good at what it covers, find it at Survive the Deepend

0
votes

rename your module directory to "mod-admin"

mod-admin/
  controller/
    IndexController.php
  model/
  view/
   ...

your controller class should remain ModAdmin_IndexController, and you access it by http://hostname/mod-admin/

P.S. and of course still do this

$modules = PROJECT_DIR . '/library/PHPLib/ZF/Modules';
define('MODULES_DIR', $modules);
$frontController->addModuleDirectory(MODULES_DIR);

P.P.S

to see what's going on with your request you can register a plugin and override the routeshutdown method to var_dump the params like this, (your Bootstrap file should look something like)

<?php

class TestPlugin extends Zend_Controller_Plugin_Abstract {

    public function routeShutdown(Zend_Controller_Request_Abstract $request) {
        var_dump($request->getParams());
        die();
    }

}

class Bootstrap extends Zend_Application_Bootstrap_Bootstrap { ...

    protected function _initDebugingRequest() {
       $front = Zend_Controller_Front::getInstance();
       $front->registerPlugin(new TestPlugin());
    }
...

P.P.P.S

make sure you have rewrite enabled with sudo a2enmod rewrite and also in /etc/apache2/sites-available/default file you have something like

<Directory /var/www/>
...
AllowOverride All
...
</Directory>