My zend application was originally set up like this:
application
- controller
- model
- view
Now I want to set it up to use modules structures, so I changed it like this:
application
- modules
- default
- controller
- model
- view
- test
- controller
- model
- view
Beside moving all the files to the right structure, I just add the following lines to the config file:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules[] = ""
and add the Bootstrap file for each module.
Since I moved all the current controllers to the default module, I'm able run the application fine. However, I cannot access any new controller in the new test module. Am I missing something? Do I have to change anything in config or bootstrap?
For example, I created a new controller in the test module called TestController, and when I go to localhost/test/test, I'm getting error: "EXCEPTION_NO_CONTROLLER".
maybe check your module bootstrap routes
class Transfer_Bootstrap extends Zend_Application_Module_Bootstrap
{
public function _initModuleRoutes()
{
$this->bootstrap('FrontController');
$frontController = $this->getResource('FrontController');
$router = $frontController->getRouter();
$route = new Zend_Controller_Router_Route(
'modulename/:action/*',
array(
'module' => 'modulename',
'controller' => 'modulecontroller',
'action' => 'index'
)
);
$router->addRoute('routename', $route);
return $router;
}
Related
After creating a modular structure for a single module would prevent the url appears the name of the controller.
everything works with the defaul
site.con/foo/index/action/
I wish I could write as
site.com/foo/action/
being IndexController the only controller that module.
I have tested several solutions but do not work. Being the first app with ZF I do not quite clear the steps to be taken.
You need Zend Routes.
Define routes in your
bootstrap.php
Open your bootstrap.php and put the following:
function _initRoutes() {
$front_controller = Zend_Controller_Front::getInstance();
$router = $front_controller->getRouter();
$router->addRoute('foo-action', new Zend_Controller_Router_Route(
'<foo module name>/<action name>', array('module' => 'foo', 'controller' => 'index', 'action' => '<action-name>')
));
}
PS:Worked / Didn't work?
Mention in comments and if didn't work, give proper names of module, controller and action.
EDIT:
How to set default controller / module in application.ini
routes.index.type = "Zend_Controller_Router_Route"
routes.index.route = "/"
routes.index.defaults.module = "<module name>"
routes.index.defaults.controller = "index"
routes.index.defaults.action = "index"
Solves it?
I have a module-based arhitecture in Zend Framework 1.11 (site.com/module/controller/action).
I've setup my site to have a default module, so that if I have the site module as default, and you go to site.com/something1/something2, it will actually take you to site.com/site/something1/something2.
I want to achieve the same thing 1 level further: say if you go to site.com/something, it should take you to site.com/site/index/something. I'm not talking about a redirect, just a re-routing.
Would something like this be possible?
If I understand correctly, it is possible and here is an example you can put in your Bootstrap:
protected function _initControllerDefaults()
{
$this->bootstrap('frontcontroller');
$front = Zend_Controller_Front::getInstance();
// set default action in controllers to "something" instead of index
$front->setDefaultAction('something');
// You can also override the default controller from "index" to something else
$front->setDefaultControllerName('default');
}
If you need the default action name to be dynamic based on the URL accessed, then I think you are looking for a custom route. In that case try:
protected function _initRoutes()
{
$router = Zend_Controller_Front::getInstance()->getRouter();
// Custom route:
// - Matches : site.com/foo or site.com/foo/
// - Routes to: site.com/site/index/foo
$route = new Zend_Controller_Router_Route_Regex(
'^(\w+)\/?$',
array(
'module' => 'site',
'controller' => 'index',
),
array(1 => 'action')
);
$router->addRoute('actions', $route);
}
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"
The things I did is
zf create project demo1 in command prompt
add the lines to application.ini
appnamespace = "Application"
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
add a layout with header and footer using partial() (They are perfectly worked)
create Data.php in models directory and add this simple class
<?php class Application_Model_Data{ }//Application for appnamespace
then I tried to load this class(by creating instance)from index controller index action
$data = new Application_Model_Data();
but when I test it even in this level it gives an error
Fatal error: Class 'Application_Model_Data' not found in C:\Zend\...\IndexController.php
Question
Do I want to add a autoloader to
load models in the application( I'm not used modules)
if not what was I missed to add
please help I'm stuck in the beginning,Thank you
this should work!!
add this function to bootstrap:
protected function _initResourceAutoloader()
{
$autoloader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => APPLICATION_PATH,
'namespace' => 'Application',
));
$autoloader->addResourceType( 'model', 'models', 'Model');
return $autoloader;
}
You need to setup a resource Autoloader in your Bootstrap, something like this:
protected function _initResourceAutoloader()
{
$autoloader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => 'path/to/application/directory',
'namespace' => 'Application_',
));
return $autoloader;
}
With that, Zend can load the modules in your application, and just not models, but DbTable, Forms, Plugins, etc.
write the following in your bootstrap file:
protected function _initDefaultModuleAutoloader()
{
$resourceLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH,
));
return $resourceLoader;
}
in your models folder create new file and name it "Data.php"
in the Data.php declare the class like this:
class Model_Data extends Zend_Db_Table_Abstract {.....}
you can now instantiate your data model like so:
$data = new Model_Data();
good luck :-)
in your application ini you should have
autoloadernamespaces.0 = 'Application' instead of appnamespace
then your model would be in
/library/Application/Model/Data.php
but why dont you use the default "models" folder in the suggested application structure.
I had forgotten to add the file extension .php to the file, just in case someone else makes the same mistake
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.