I'm working with multi-modules CMS in Zend Framework. I want to create a structure like this:
testsite/
index.php
library/
zend/
test/
application/
configs/
application.ini
modules/
users/
controllers/
models/
....
frontend/
controllers/
models/
....
backend/
controllers/
models/
...
bootstrap.php
I have created the following code:
//in application.ini
resources.frontController.defaultModule = "frontend"
resources.frontController.defaultControllerName = "index"
resources.frontController.defaultAction = "index"
resources.frontController.plugins.init = "Test_Controller_Plugin_Initializer"
//in bootstrap.php
protected function _initControllers()
{
$this->bootstrap('frontController');
$this->_front = $this->getResource('frontController');
$this->_front->addControllerDirectory(APPLICATION_PATH . '/backend/controllers', 'backend');
$this->_front->addControllerDirectory(APPLICATION_PATH . '/frontend/controllers', 'frontend');
}
//in Test/controllers/plugin/initializer.php
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
$front = Zend_Controller_Front::getInstance();
$request = $front->getRequest();
$request->setModuleName('frontend');
$request->setControllerName('index');
$request->setActionName('index');
}
It does not work when I go to my base URL .../testsite. Can you please let me know where I went wrong?
Have you tried putting your modules in the modules directory?
ie:
testsite/
index.php
library/
zend/
test/
application/
configs/
application.ini
modules/
users/
controllers/
models/
....
frontend/
controllers/
models/
....
backend/
controllers/
models/
...
bootstrap.php
Wich is typically where zf expects to find its modules. You might have to adjust you rapplication.ini settings to reflect this.
To make this work how you want it to refer to Zend_Application_Resource_Frontcontroller
specifically you need to pass an array of 'module' => 'controller' directory pairs to resources.frontController.controllerDirectory.
controllerDirectory: either a string value specifying a single
controller directory, or an array of module to controller directory
pairs.
I doubt this will solve all the problems but it should head you in the right direction.
Related
I am writing my own log class in zendframework based application. I was wondering as it's my own lib class where to keep it in application. I decided to keep this class parallel to "Zend" folder inside /library folder
-library
- Zend
- Helper [ custom lib classes]
In bootstrap.php I have _initAutoload function where in I have added following
$autoloader=new Zend_Loader_Autoloader_Resource(array(
'basePath' => dirname(__FILE__),
'namespace' => 'Demo',
));
$autoloader->addResourceType('model', 'models/', 'Model');
$autoloader->addResourceType('helper', APPLICATION_PATH.'/library/Helper', 'Helper');
but I get error Demo_Helper_Logger class not found.
Whats could be wrong here? Any idea?
Thanks
If you are using ZF 1.9+ you can handle this inside your application.ini
Put your custom "library" into:
../library/Helper/Log.php
Name your class like:
class Helper_Log {}
Add
autoloadernamespaces.1 = "Helper_"
to your application.ini
$log = new Helper_Log();
I have a very strange case where my Module is working but my Module's boostrap is not being loaded.
Here is the segment in my application.ini for module autoloading:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules[] = ""
Here is the bootstrapper:
protected function _initAutoload()
{
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'User_',
'basePath' => APPLICATION_PATH .'/modules/user',
'resourceTypes' => array (
'model' => array(
'path' => 'models',
'namespace' => 'Model',
)
)
));
}
Structure of my modules
Application
--modules
----user
------config/
------controllers/
------models/
------views/
------Bootstrap.php
----admin
The problem here is that User_Bootstrap is not being loaded.
<?php
class User_Bootstrap extends Zend_Application_Module_Bootstrap
{
protected function _initAutoload()
{
Zend_Registry::set('debug', 'haha');
}
}
By doing a Zend_Registry::get('debug') on any controller, it doesn't recognize that the key was set in the module bootstrap. In fact any syntax error in the User_Bootstrap does not work.
I don't know why User_Bootstrap is not being autoloaded. This is driving me crazy because I've been researching for 5 hours and can't even get a blog post close to covering this case...
Speaking of which, my models and controller classes are being autoloaded fine.
Try the following...
Change your application.ini file to use
; lose the quotes
resources.modules[] =
See http://framework.zend.com/manual/en/zend.application.available-resources.html#zend.application.available-resources.modules
Remove the _initAutoload() method from your Application Bootstrap class. You don't need this as the module bootstrap will automatically create a resource loader for your User_ classes
Not sure but it might as simple as improper case.
--Modules is in your structure but you keep referring to it as /modules. These should match case.
I hope it's that simple.
Don't duplicate the function names of your main bootstrap in your module bootstrap, as far as I know in ZF 1.x all of the boostraps get processed every call and I think your _initAutoload in the main boostrap is overriding the module bootstrap.
try calling your function some different like _initModuleAutoload.
At least worth a shot :)
Have you tried disabling frontController directory in application.ini config file? Try commenting/deleting this line:
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
My zend app is created, everything seems to be in order but every time I try to do something like:
$accProducts = new Application_Models_AccProductsMapper();
Only get:
Warning: include_once(Application/Models/AccProductsMapper.php): failed to open stream: No such file or directory in /home/blah/blah/blah/Loader.php on line 148
however, the AccProductsMapper.php file do exist in such directory, directories within the zend app are all lowercase tough.
I've spend a lot of time looking for something to solve this issue with no good results at all.
Bootstrap.php
<?php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initDoctype()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('XHTML1_STRICT');
}
protected function _initAutoload()
{
$moduleLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH));
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->registerNamespace(array('App','My_'));
return $moduleLoader;
}
}
The standard Zend_Loader_Autoloader_Resource class added to each module looks for models with the class prefix <ModuleNamespace>_Model_ in <module-directory>/models.
For the default module, the namespace is defined in your config's appnamespace property (defaults to Application). The directory is typically application.
To summarize, create your default module model classes in application/models with class prefix Application_Model_, eg
<?php
// application/models/AccProductsMapper.php
class Application_Model_AccProductsMapper
{
// etc
As for your _initAutoload() method, I can't tell what you're doing with that module loader and would advise you don't need it at all. You can register PEAR style namespaces in your config file, eg
autoloadernamespaces.App = "App_"
autoloadernamespaces.My = "My_"
I have a Zend project with the following directory structure:
/myApp
/application
Bootstrap.php
/configs
application.ini
/layouts
/modules
/default
/controllers
MessageController.php
ErrorController.php
IndexController.php
/models
/DbTable
Message.php
Message.php
MessageMapper.php
/views
Bootstrap.php
/login
/controllers
/forms
/library/login
/models
/plugins
/views
Bootstrap.php
/data/db
/library/zend
/public
http://localhost/ - works fine but i can not get the login module and the message inside the Default module to work. I get the following error:
Fatal error: Class 'Application_Module_Default_Model_MessageMapper' not found in /Library/WebServer/Documents/myApp/application/modules/default/controllers/MessageController.php on line 14
I am sure i am not initialising something i need to. Here is what my code looks like..
application.ini
autoloaderNamespaces[] ="Message_"
autoloaderNamespaces[] ="Login_"
autoloadernamespaces.0 = "Zend_"
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.moduleControllerDirectoryName = "controllers"
resources.frontController.defaultControllerName = "index"
resources.frontController.defaultActionName = "index"
resources.frontController.params.displayExceptions = 0
resources.frontController.defaultModule = "default"
resources.frontController.params.prefixDefaultModule = "1"
resources.frontController.plugins[] = "Login_Plugin_SecurityCheck"
resources.modules = ""
/application/bootstrap.php
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
protected function _initDoctype()
{
$this->bootstrap('view');
$view = $this->getResource('view');
$view->doctype('HTML5');
}
}
/public/index.php
set_include_path(implode(PATH_SEPARATOR, array(
realpath(APPLICATION_PATH . '/../library'),
get_include_path(),
)));
require_once 'Zend/Application.php';
require_once('Zend/Loader/Autoloader.php');
$autoloader = Zend_Loader_Autoloader::getInstance();
/module/default/controllers/MessageController.php
$message = new Application_Module_Default_Model_MessageMapper();
$this->view->entries = $message->fetchAll();
Let me know if any more details would help. Any help would be much appreciated.
Have you tried:
$message = new Default_Model_MessageMapper();
Also, are you autoloading your module in the module Bootstrap.php file? I'm not sure how much it has changed since I used ZF, but I had to include this:
$loader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Default_',
'basePath' => '/path/to/modules/default'
));
me too had the same issue, but my cause was very simple
i had a form Form_Template_Add & a controller TemplateController.
From the controller i called the form - new Form_Template_Add();
My form resides in a folder template.
Issue was with the folder name, see the 't' in template is small caps, while 'T' for controller & class name is caps.
I changes folder name to Template & it worked... hooya
Make sure you have created a Bootstrap.php in each module directory, which looks like:
class Admin_Bootstrap extends Zend_Application_Module_Bootstrap
{}
In which Admin is the name of the module. Also, make sure there is actually a file Login.php inside directory modules/admin/forms with a class Admin_Form_Login
[Zend_Form][1.11.1] Error Message Fatal error: Class 'Admin_Form_Login' not found in ...\modules\default\controllers\IndexController.php
Is there a way to have models for each module? I have 3 modules, one is a "contacts" module.
I created a model for it in modules/contacts/models/Codes.php
Codes Controller
class Contacts_CodesController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
$this->view->messages = $this->_helper->flashMessenger->getMessages();
}
public function indexAction()
{
$codesTable = new Contacts_Model_Codes();
}
Codes Model:
class Contacts_Model_Codes extends Zend_Db_Table
{
protected $_name = 'codes';
}
The error I get:
Fatal error: Class 'Contacts_Model_Codes' not found in /Applications/MAMP/htdocs/zf_site/application/modules/contacts/controllers/CodesController.php on line 26
thanks
I found the problem. I forgot to put a bootstrap file in with my contacts module.
Now it all works and I can have my modules use their own models.
class Contacts_Bootstrap extends Zend_Application_Module_Bootstrap
{
}
I've found the solution, I guess! :)
It's a problem when you add the next Resource in the application.ini file
resources.frontController.defaultModule = "Default"
and also you use some kind of parameters. I think that is a Bug.
The correct way to implement Modules is:
1 - Create your desired modules and the 'Default' Module with zf tool
2 - In apllication.ini tell ZF where the modules are and where the controllers of those modules are, with
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.moduleControllerDirectoryName = "controllers"
Use the known
resources.modules = ""
And set:
resources.frontController.params.prefixDefaultModule = ""
It's important because zf tool set it to "1". Here is the bug. :)
And remember DO NOT PUT WHAT THE DEFAULT MODULE IS!!
3 - Create the bootstrap file for each module and put:
If my module is 'Evacol':
<?php
class Evacol_Bootstrap extends Zend_Application_Module_Bootstrap
{
}
Save it to /modules/Evacol/ obviously
Take note of Evacol_... and ..._Module_Bootstr... THE NAME OF MY MODULE EXTENDING THE CORRECT CLASS.
Don't use the default value of bootstrap file created with zf tool. I did it :)
DON'T MODIFY ANYTHING ELSE. IT IS NOT NECESARY.
And voila! Trust me. It works!
It was Zend Framework 1.10.8
You have to register the 'Contacts_' namespace with the auto loader. You can use Zend_Application_Module_Autoloader for this.
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Contacts_',
'basePath' => dirname(__FILE__) . '/modules/cotacts',
));
This will create the following mappings for your module inside the basePath you provide.
api/ => Api
forms/ => Form
models/ => Model
DbTable/ => Model_DbTable
plugins/ => Plugin
If you are using Zend_Application to boostrap your application and it' modules you should not need this because the docs say that:
When using module bootstraps with Zend_Application, an instance of Zend_Application_Module_Autoloader will be created by default for each discrete module, allowing you to autoload module resources.
add
resources.modules[] =
To your config ini
I'm using version 1.9.
This is part of my bootstrap:
protected function _initAutoload() {
$modelLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH.'/modules/default')
);
}
protected function _initAutoloaders()
{
$this->getApplication()->setAutoloaderNamespaces(array('Eric_'));
return $this;
}
protected function _initPlugins()
{
$this->bootstrap('autoloaders');
$this->bootstrap('frontController');
// register the plugin for setting layouts per module
$plugin = new Eric_Plugin_Modularlayout();
$this->frontController->registerPlugin($plugin);
return $modelLoader;
}
The plugin Eric_Plugin_Modularlayout sets the correct layout for each module.
I have 3 modules: default, ez, contacts.
The funny thing is, In a contacts action I can call the models in the ez/models dir. without a problem.