Let's say I have the following in my ini file:
resources.frontController.plugins.auth = AuthPlugin
Where should the AuthPlugin class be placed? Let's say I would like it under controllers/plugins.
UPDATE:
Based on the suggestions below I am still having trouble. Let me be exact in what I currently have:
1) main part of application.ini
includePaths.library = APPLICATION_PATH "/../library"
bootstrap.path = APPLICATION_PATH "/Bootstrap.php"
bootstrap.class = "Bootstrap"
resources.layout.layoutPath = APPLICATION_PATH "/layouts/scripts"
resources.view[] =
resources.frontController.controllerDirectory = APPLICATION_PATH "/controllers"
resources.frontController.plugins.authplugin.class = "AuthPlugin"
2) my Bootstrap.php has nothing (I had lots of things in there, but still get the error with nothing):
class Bootstrap extends Zend_Application_Bootstrap_Bootstrap
{
}
3) I have an AuthPlugin.php class in application/plugins directory
class AuthPlugin extends Zend_Controller_Plugin_Abstract
{
public function preDispatch(Zend_Controller_Request_Abstract $request)
{
// code here
}
}
I get the following error:
Fatal error: Class 'AuthPlugin' not found in C:\[my dir structure here]\Application\Resource\Frontcontroller.php on line 111
I assume I'm missing something obvious here. Thanks in advance. Zend Framework 1.10
This is how I register a plugin named Foo_Plugin_SuperDuperPlugin in my application config:
resources.frontController.plugins.superduperplugin.class = "Foo_Plugin_SuperDuperPlugin"
The plugin is located at
APPLICATION_PATH/plugins/Foo_Plugin_SuperDuperPlugin.php and is autoloaded from there because the Resource Module Autoloader automatically looks in that (recommended) location for plugin type resources. If I wanted to load the plugin from, say,
APPLICATION_PATH/controllers/plugins/Foo_Plugin_SuperDuperPlugin.php then I would register a new resource loader with the autoloader and define a type of resource named 'plugin' and the path to those plugin resources. So in my bootstrap.php
protected function _initAutoloader()
{
$autoloader = new Zend_Loader_Autoloader_Resource(
array(
'basePath' => APPLICATION_PATH,
'namespace' => 'Foo',
'resourceTypes' => array(
'plugin' => array(
'path' => 'controllers/plugins',
'namespace' => 'Plugin',
)
)
)
);
}
and then I need to ensure that this method is bootstrapped before the SuperDuperPlugin is registered (which, in this example, happens when the application config is read resources.frontcontroller.plugins.superduperplugin.class = ...). This can be achieved by placing the _initAutoloader method at the top of the bootstrap.php or by calling $this->bootstrap('autoLoader'); from any other _init method, before the frontController resource is initialised.
UPDATED: Try adding this to your bootstrap:
protected function _initAutoloader()
{
$autoloader = new Zend_Loader_Autoloader_Resource(
array(
'basePath' => APPLICATION_PATH,
'resourceTypes' => array(
'plugin' => array(
'path' => 'controllers/plugins',
'namespace' => '',
)
)
)
);
}
and maybe even leave off the namespace. Or: add appnamespace = "Foo" to your config and rename the class to Foo_Plugin_AuthPlugin.
hmm am having the exact same issue in zf 1.11. It seems the autoloader does not exists before the plugins get loaded :s
I think in /application/plugins/
But you could also set another Directory for it.
Since the application will bootstrap itself from the config file after registering the Autoloader, you should put AuthPlugin.php (which should contain the AuthPlugin class) in the include path.
I realise this is an old question, but I've just been searching around for ages for a solution to autoloading plugins outside of the library and have finally figured it out. Generally, I have been writing generic plugins to use across many different projects and keeping them in the library made sense, providing you follow the standard ZF naming conventions these will autoload anyway. Recently, I was writing a project specific plugin and I wanted to keep it somewhere within my application directory, but how to autoload? I've never found that using the "application/plugins" directory worked. Hopefully this might benefit someone else:
If you are using a modular directory structure then rather than using the "application/plugins" directory you can use "application/module_name/plugins". You can then take advantage of the Module Resource Autoloader, which is a massively useful and underused part of ZF. If you set it up in your bootstrap, by default it is set up to autoload a whole bunch of stuff including forms, models and (I discovered today) plugins. You can also define your own custom resource types. For example below is an _initAutoloader function from a bootstrap in a project which has a default and admin module and a custom 'vo' resource type contained in the admin module:
public function _initAutoLoader() {
$autoloader = Zend_Loader_Autoloader::getInstance();
$defaultLoader = new Zend_Application_Module_Autoloader(
array(
'namespace' => '',
'basePath' => APPLICATION_PATH . '/modules/default'
)
);
$adminLoader = new Zend_Application_Module_Autoloader(
array(
'namespace' => 'Admin',
'basePath' => APPLICATION_PATH . '/modules/admin',
)
);
$adminLoader->addResourceTypes(
array(
'vo' => array(
'path' => 'models/vo',
'namespace' => 'Vo',
)
)
);
$autoloader->pushAutoloader($defaultLoader);
$autoloader->pushAutoloader($adminLoader);
}
Here I have two modules, default and admin. Assuming the following directory structure:
application/default/forms/FooForm.php
application/default/models/FooModel.php
application/default/plugins/FooPlugin.php
application/admin/forms/FooForm.php
application/admin/models/FooModel.php
application/admin/models/vo/FooVo.php
application/admin/plugins/FooPlugin.php
I can autoload across any module just by instantiating an object of each class:
new Form_FooForm();
new Model_FooModel();
new Plugin_FooPlugin(); // or add plugin to application.ini
new Admin_Form_FooForm();
new Admin_Model_FooModel();
new Admin_Vo_FooVo(); // custom resource type
new Admin_Plugin_FooPlugin(); // or add plugin to application.ini
Related
I'm trying to add a new folder to the application folder in zend framework, but none of the classes I create in the new folder can be found.
What I have is this structure:
application/
models/
modules/
services/
Test.php
I tried to call on the class Test.php:
class Service_Test{
}
$test = new Service_Test()
This results in the error:
PHP Warning: include_once(): Failed opening 'Service/Test.php' for inclusion (include_path='...') in library/Zend/Loader.php on line 146.
(The include_path contains a list of directories, which I removed for privacy).
I thought that Services would be automatically found in the same way that Models are automatically found. Does anyone know how I can make Zend framework find the Services folder?
I tried this as well:
require_once('Zend/Loader.php');
Zend_Loader::registerAutoload();
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => ROOT_PATH . '/application',
'namespace' => 'Service',
));
PHP Fatal error: Class 'Service_Test' not found
In your bootstrap
protected function _initNamespace(){
Zend_Loader_Autoloader::getInstance()->registerNamespace('Service_');
}
Then you call call any class that starts with 'Service_'
Thanks everyone for your help. I finally figured out what was going on. The site I am working on has an atypical setup. It's not extending any Zend Framework bootstrap class, or calling Zend_Application. The way classes were being autoloaded is by using:
set_include_path(ROOT_PATH . '/application/models'.PATH_SEPARATOR .
ROOT_PATH . '/library'.PATH_SEPARATOR .
get_include_path());
require_once('Zend/Loader.php');
#Zend_Loader::registerAutoload();
I changed it to:
set_include_path(ROOT_PATH . '/application/models'.PATH_SEPARATOR .
ROOT_PATH . '/library'.PATH_SEPARATOR .
get_include_path());
require_once 'Zend/Loader/Autoloader.php';
$autoloader = Zend_Loader_Autoloader::getInstance();
$autoloader->setFallbackAutoloader(true);
$resources = new Zend_Loader_Autoloader_Resource(array(
'namespace' => '',
'basePath' => ROOT_PATH . '/application/',
));
$resources->addResourceTypes(array(
'service' => array(
'path' => 'services',
'namespace' => 'Service',
)));
Technically, I did not have to add the resource, but if I didn't, and just relied on putting /application/services into the include path, then I would not be able to prefix my classes with 'Service_'.
I'm not sure I would recommend this setup (no Bootstrap class extension or use of Zend_Application) for anyone else. It would be interesting to see what other people thought of this practice. Good or bad? In any case, that is how I solved the issue.
I have an auth module, and would like to keep a Login form in the forms folder in the module. I have my class named Auth_Form_Login and the code I use to instantiate it in auth's Index controller is:
$loginForm = new Auth_Form_Login($_POST);
However, Zend is complaining that it can't find the class. What am I doing wrong?
Edit
My directory structure is like so:
application
configs
layouts
modules
auth
controllers
models
views
forms <--- This is what I want to autoload from
default
controllers
models
views
library
public
Also, modules are set up correctly:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.frontController.params.prefixDefaultModule = false
Seems like you're missing module bootstrap for Auth module:
application
modules
auth
Bootstrap.php
Which might consist of this only line - just to make autoloading magic work:
class Auth_Bootstrap extends Zend_Application_Module_Bootstrap {}
You're doing everything right in your form initialisation. The autoloader simply doesn't know where to find it so you need to setup zend autoloader correctly.
I am not sure how you created your module based structure. I use the cli tool which configures everything.
So in my application.ini file I have:
resources.frontController.moduleDirectory = APPLICATION_PATH "/modules"
resources.modules = ''
resources.frontController.params.prefixDefaultModule = "1"
And in my Boostrap.php:
$modelLoader = new Zend_Application_Module_Autoloader (
array ('namespace' => '', 'basePath'
=> APPLICATION_PATH .
'/modules/default' ) );
You also can setup the autoloader manually by registering your resources:
$resourceLoader = new Zend_Loader_Autoloader_Resource(array(
'basePath' => 'path/to/my/directory',
'namespace' => 'Auth',
'resourceType' => array(
'form' => array(
'path' => 'forms/'
'namespace' => 'Form'
)
//...your code
)
)
);
I'm having a lot of trouble figuring out how we can have a modular directory structure, with the ability to load resources that are to be shared across modules. I.e.,
application
--- /forms
--- /models
--- /modules
------/module1/
---------/models
------/module2/
---------/models
Now, what I'm trying to do is load forms in /application/forms from within the modules. Everything I've tried results in these classes to not being loaded.
I've tried:
1) Letting Zend try and figure it out automagically.
2) Specifying all the paths in the main bootstrap for the application path as well as the modules. I.e.,
protected function _initAutoload()
{
$front = $this->bootstrap("frontController")->frontController;
$modules = $front->getControllerDirectory();
$default = $front->getDefaultModule();
$moduleloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Application',
'basePath' => APPLICATION_PATH
));
foreach (array_keys($modules) as $module) {
$moduleloader = new Zend_Application_Module_Autoloader(array(
'namespace' => ucfirst(strtolower($module)),
'basePath' => $front->getModuleDirectory($module))
);
}
}
3) Smashing my head on my desk many times.
.. and yes, I realize I do not need that loop for modules, as I have blank bootstraps in each module directory.
Any suggestions are welcome. Thanks!
Try this:
protected function _initAutoload()
{
$autoloader = new Zend_Application_Autoloader_Resource(array(
'namespace' => 'Application',
'basePath' => APPLICATION_PATH,
'resourceTypes' => array(
'form' => array(
'path' => 'forms/',
'namespace' => 'Form'
)
)
));
return $autoloader;
}
you don't need the module part, as you already seem to know. Add other resource types as required.
Since this is very close to what you have already, there may be another issue. The above should work assuming that:
APPLICATION_PATH points at the /application directory in your app
The form classes are named Application_Form_Something
The filenames of these classes are Something.php (case sensitive)
e.g. if you have a contact form, you might call the class Application_Form_Contact and this would live at application/forms/Contact.php.
If you're still having issues, please include an example of a form class that isn't being found, along with how and where you are calling it from.
I really can't figure this out:
I've created a file called User.php in application/models. The classname in it is Model_User.
When I try to create an object in my Controller, I get this error:
Fatal error: Class 'Model_User' not found in C:\xampplite\htdocs\code\application\controllers\IndexController.php on line 14
I googled around, and found this code, which is supposed to autoload controllers for me, it is located in bootstrap.php The code isn't working though. The example that used this code was working with ZF 1.8 so that might be the reason but I can't figure it out.
How should I autoload my models?!
private function _initAutoload(){
$modelLoader = new Zend_Application_Module_Autoloader(array(
'namespace' => '',
'basePath' => APPLICATION_PATH
));
return $modelLoader;
}
Any ideas?
The important bit in the answer to the question I linked above is the namespace:
$resourceLoader->addResourceTypes(array(
'model' => array(
'namespace' => 'Model',
'path' => 'models'
)
));
The namespace parameter tells the Autoloader to look in the defined path (relative to basePath) when encountering a class that starts with Model_. You have the first part right, but you're missing the call to addResourceTypes.
I have developed a small application and now I want to create and administrator module. In the future I would like to add different modules but for now i would like to treat this admin as a module and to access it like http://host/module/controller
I have read about zend_autoloader and wrote this in my Bootstrap.php
protected function _initAutoload() {
$autoloader = new Zend_Application_Module_Autoloader(array(
'namespace' => 'Admin',
'basePath' => '/modules/admin'
));
I have created a default IndexController with the default index view file. When I try to access http://host/admin or http://host/admin/index i get an application error and of course the view is not loaded.
What am i doing wrong?
For everyone having the problem this guy sorts it out in the most newbish way possible.
http://www.zfforums.com/zend-framework-general-discussions-1/resources-developers-37/setup-multi-modules-zend-framework-v1-9-13-steps-3737.html